blob: a386735978ae6341f31d73738f589bd9ee16affb [file] [log] [blame]
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -07001/*
Alex Sakhartchouk2123b462012-02-15 16:21:46 -08002 * Copyright (C) 2011-2012 The Android Open Source Project
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <GLES2/gl2.h>
18#include <GLES2/gl2ext.h>
19
20#include <rs_hal.h>
21#include <rsContext.h>
22#include <rsProgram.h>
23
Alex Sakhartchouk43850542011-05-05 16:56:27 -070024#include "rsdCore.h"
Jason Sams7e8aae72011-05-26 16:33:01 -070025#include "rsdAllocation.h"
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070026#include "rsdShader.h"
27#include "rsdShaderCache.h"
28
29using namespace android;
30using namespace android::renderscript;
31
32RsdShader::RsdShader(const Program *p, uint32_t type,
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080033 const char * shaderText, size_t shaderLength,
34 const char** textureNames, size_t textureNamesCount,
35 const size_t *textureNamesLength) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070036 mUserShader.setTo(shaderText, shaderLength);
37 mRSProgram = p;
38 mType = type;
39 initMemberVars();
40 initAttribAndUniformArray();
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080041 init(textureNames, textureNamesCount, textureNamesLength);
Jason Samsfe1d5ff2012-03-23 11:47:26 -070042
43 for(size_t i=0; i < textureNamesCount; i++) {
44 mTextureNames.push(String8(textureNames[i], textureNamesLength[i]));
45 }
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070046}
47
48RsdShader::~RsdShader() {
49 if (mShaderID) {
50 glDeleteShader(mShaderID);
51 }
52
53 delete[] mAttribNames;
54 delete[] mUniformNames;
55 delete[] mUniformArraySizes;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070056 delete[] mTextureTargets;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070057}
58
59void RsdShader::initMemberVars() {
60 mDirty = true;
61 mShaderID = 0;
62 mAttribCount = 0;
63 mUniformCount = 0;
64
65 mAttribNames = NULL;
66 mUniformNames = NULL;
67 mUniformArraySizes = NULL;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070068 mTextureTargets = NULL;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070069
70 mIsValid = false;
71}
72
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080073void RsdShader::init(const char** textureNames, size_t textureNamesCount,
74 const size_t *textureNamesLength) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070075 uint32_t attribCount = 0;
76 uint32_t uniformCount = 0;
77 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080078 initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames,
79 NULL, &attribCount, RS_SHADER_ATTR);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070080 }
81 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080082 initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(),
83 mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070084 }
85
86 mTextureUniformIndexStart = uniformCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070087 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080088 mUniformNames[uniformCount].setTo("UNI_");
89 mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070090 mUniformArraySizes[uniformCount] = 1;
91 uniformCount++;
92 }
93}
94
95String8 RsdShader::getGLSLInputString() const {
96 String8 s;
97 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -070098 const Element *e = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -080099 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
100 const Element *f = e->mHal.state.fields[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700101
102 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800103 rsAssert(!f->mHal.state.fieldsCount);
104 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700105 case 1: s.append("attribute float ATTRIB_"); break;
106 case 2: s.append("attribute vec2 ATTRIB_"); break;
107 case 3: s.append("attribute vec3 ATTRIB_"); break;
108 case 4: s.append("attribute vec4 ATTRIB_"); break;
109 default:
110 rsAssert(0);
111 }
112
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800113 s.append(e->mHal.state.fieldNames[field]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700114 s.append(";\n");
115 }
116 }
117 return s;
118}
119
120void RsdShader::appendAttributes() {
121 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700122 const Element *e = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800123 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
124 const Element *f = e->mHal.state.fields[field];
125 const char *fn = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700126
127 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800128 rsAssert(!f->mHal.state.fieldsCount);
129 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700130 case 1: mShader.append("attribute float ATTRIB_"); break;
131 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
132 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
133 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
134 default:
135 rsAssert(0);
136 }
137
138 mShader.append(fn);
139 mShader.append(";\n");
140 }
141 }
142}
143
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700144void RsdShader::appendTextures() {
145
146 // TODO: this does not yet handle cases where the texture changes between IO
147 // input and local
148 bool appendUsing = true;
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800149 for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700150 if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800151 Allocation *a = mRSProgram->mHal.state.textures[ct];
152 if (a && a->mHal.state.surfaceTextureID) {
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700153 if(appendUsing) {
154 mShader.append("#extension GL_OES_EGL_image_external : require\n");
155 appendUsing = false;
156 }
157 mShader.append("uniform samplerExternalOES UNI_");
158 mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
Jason Sams615e7ce2012-01-13 14:01:20 -0800159 } else {
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700160 mShader.append("uniform sampler2D UNI_");
161 mTextureTargets[ct] = GL_TEXTURE_2D;
Jason Sams615e7ce2012-01-13 14:01:20 -0800162 }
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700163 } else {
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700164 mShader.append("uniform samplerCube UNI_");
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700165 mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700166 }
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800167
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700168 mShader.append(mTextureNames[ct]);
169 mShader.append(";\n");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700170 }
171}
172
173bool RsdShader::createShader() {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700174 if (mType == GL_FRAGMENT_SHADER) {
175 mShader.append("precision mediump float;\n");
176 }
177 appendUserConstants();
178 appendAttributes();
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700179 appendTextures();
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700180 mShader.append(mUserShader);
181
182 return true;
183}
184
185bool RsdShader::loadShader(const Context *rsc) {
186 mShaderID = glCreateShader(mType);
187 rsAssert(mShaderID);
188
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700189 if(!mShader.length()) {
190 createShader();
191 }
192
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700193 if (rsc->props.mLogShaders) {
Steve Block71f2cf12011-10-20 11:56:00 +0100194 ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
195 ALOGV("%s", mShader.string());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700196 }
197
198 if (mShaderID) {
199 const char * ss = mShader.string();
Jason Sams5316b9e2011-09-13 15:41:01 -0700200 RSD_CALL_GL(glShaderSource, mShaderID, 1, &ss, NULL);
201 RSD_CALL_GL(glCompileShader, mShaderID);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700202
203 GLint compiled = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700204 RSD_CALL_GL(glGetShaderiv, mShaderID, GL_COMPILE_STATUS, &compiled);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700205 if (!compiled) {
206 GLint infoLen = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700207 RSD_CALL_GL(glGetShaderiv, mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700208 if (infoLen) {
209 char* buf = (char*) malloc(infoLen);
210 if (buf) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700211 RSD_CALL_GL(glGetShaderInfoLog, mShaderID, infoLen, NULL, buf);
Alex Sakhartchouk257e8a92012-02-07 18:06:13 -0800212 rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700213 free(buf);
214 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700215 RSD_CALL_GL(glDeleteShader, mShaderID);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700216 mShaderID = 0;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700217 return false;
218 }
219 }
220 }
221
222 if (rsc->props.mLogShaders) {
Steve Block71f2cf12011-10-20 11:56:00 +0100223 ALOGV("--Shader load result %x ", glGetError());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700224 }
225 mIsValid = true;
226 return true;
227}
228
229void RsdShader::appendUserConstants() {
230 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
231 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800232 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
233 const Element *f = e->mHal.state.fields[field];
234 const char *fn = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700235
236 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800237 rsAssert(!f->mHal.state.fieldsCount);
238 if (f->mHal.state.dataType == RS_TYPE_MATRIX_4X4) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700239 mShader.append("uniform mat4 UNI_");
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800240 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_3X3) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700241 mShader.append("uniform mat3 UNI_");
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800242 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_2X2) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700243 mShader.append("uniform mat2 UNI_");
244 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800245 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700246 case 1: mShader.append("uniform float UNI_"); break;
247 case 2: mShader.append("uniform vec2 UNI_"); break;
248 case 3: mShader.append("uniform vec3 UNI_"); break;
249 case 4: mShader.append("uniform vec4 UNI_"); break;
250 default:
251 rsAssert(0);
252 }
253 }
254
255 mShader.append(fn);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800256 if (e->mHal.state.fieldArraySizes[field] > 1) {
257 mShader.appendFormat("[%d]", e->mHal.state.fieldArraySizes[field]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700258 }
259 mShader.append(";\n");
260 }
261 }
262}
263
264void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800265 RsDataType dataType = field->mHal.state.dataType;
266 uint32_t elementSize = field->mHal.state.elementSizeBytes / sizeof(float);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700267 for (uint32_t i = 0; i < arraySize; i ++) {
268 if (arraySize > 1) {
Steve Block71f2cf12011-10-20 11:56:00 +0100269 ALOGV("Array Element [%u]", i);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700270 }
271 if (dataType == RS_TYPE_MATRIX_4X4) {
Steve Block71f2cf12011-10-20 11:56:00 +0100272 ALOGV("Matrix4x4");
273 ALOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
274 ALOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
275 ALOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
276 ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700277 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Steve Block71f2cf12011-10-20 11:56:00 +0100278 ALOGV("Matrix3x3");
279 ALOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
280 ALOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
281 ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700282 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Steve Block71f2cf12011-10-20 11:56:00 +0100283 ALOGV("Matrix2x2");
284 ALOGV("{%f, %f", fd[0], fd[2]);
285 ALOGV(" %f, %f}", fd[1], fd[3]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700286 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800287 switch (field->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700288 case 1:
Steve Block71f2cf12011-10-20 11:56:00 +0100289 ALOGV("Uniform 1 = %f", fd[0]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700290 break;
291 case 2:
Steve Block71f2cf12011-10-20 11:56:00 +0100292 ALOGV("Uniform 2 = %f %f", fd[0], fd[1]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700293 break;
294 case 3:
Steve Block71f2cf12011-10-20 11:56:00 +0100295 ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700296 break;
297 case 4:
Steve Block71f2cf12011-10-20 11:56:00 +0100298 ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700299 break;
300 default:
301 rsAssert(0);
302 }
303 }
Steve Block3762c312012-01-06 19:20:56 +0000304 ALOGE("Element size %u data=%p", elementSize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700305 fd += elementSize;
Steve Block3762c312012-01-06 19:20:56 +0000306 ALOGE("New data=%p", fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700307 }
308}
309
310void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
311 int32_t slot, uint32_t arraySize ) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800312 RsDataType dataType = field->mHal.state.dataType;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700313 if (dataType == RS_TYPE_MATRIX_4X4) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700314 RSD_CALL_GL(glUniformMatrix4fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700315 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700316 RSD_CALL_GL(glUniformMatrix3fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700317 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700318 RSD_CALL_GL(glUniformMatrix2fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700319 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800320 switch (field->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700321 case 1:
Jason Sams5316b9e2011-09-13 15:41:01 -0700322 RSD_CALL_GL(glUniform1fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700323 break;
324 case 2:
Jason Sams5316b9e2011-09-13 15:41:01 -0700325 RSD_CALL_GL(glUniform2fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700326 break;
327 case 3:
Jason Sams5316b9e2011-09-13 15:41:01 -0700328 RSD_CALL_GL(glUniform3fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700329 break;
330 case 4:
Jason Sams5316b9e2011-09-13 15:41:01 -0700331 RSD_CALL_GL(glUniform4fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700332 break;
333 default:
334 rsAssert(0);
335 }
336 }
337}
338
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700339void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) {
340 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
341
342 GLenum trans[] = {
343 GL_NEAREST, //RS_SAMPLER_NEAREST,
344 GL_LINEAR, //RS_SAMPLER_LINEAR,
345 GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
346 GL_REPEAT, //RS_SAMPLER_WRAP,
347 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
348 GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
349 };
350
351 GLenum transNP[] = {
352 GL_NEAREST, //RS_SAMPLER_NEAREST,
353 GL_LINEAR, //RS_SAMPLER_LINEAR,
354 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
355 GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
356 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
357 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
358 };
359
360 // This tells us the correct texture type
Jason Sams7e8aae72011-05-26 16:33:01 -0700361 DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv;
362 const GLenum target = drvTex->glTarget;
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700363
364 if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) {
365 if (tex->getHasGraphicsMipmaps() &&
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800366 (dc->gl.gl.NV_texture_npot_2D_mipmap || dc->gl.gl.IMG_texture_npot)) {
367 if (dc->gl.gl.NV_texture_npot_2D_mipmap) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700368 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
369 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700370 } else {
371 switch (trans[s->mHal.state.minFilter]) {
372 case GL_LINEAR_MIPMAP_LINEAR:
Jason Sams5316b9e2011-09-13 15:41:01 -0700373 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
374 GL_LINEAR_MIPMAP_NEAREST);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700375 break;
376 default:
Jason Sams5316b9e2011-09-13 15:41:01 -0700377 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
378 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700379 break;
380 }
381 }
382 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700383 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
384 transNP[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700385 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700386 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER,
387 transNP[s->mHal.state.magFilter]);
388 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]);
389 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700390 } else {
391 if (tex->getHasGraphicsMipmaps()) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700392 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
393 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700394 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700395 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
396 transNP[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700397 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700398 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER, trans[s->mHal.state.magFilter]);
399 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]);
400 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700401 }
402
403 float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso);
404 if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700405 RSD_CALL_GL(glTexParameterf, target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700406 }
407
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700408 rsdGLCheckError(rsc, "Sampler::setup tex env");
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700409}
410
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700411void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
412 if (mRSProgram->mHal.state.texturesCount == 0) {
413 return;
414 }
415
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700416 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
417
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700418 uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700419 uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700420 if (numTexturesToBind >= numTexturesAvailable) {
Steve Block3762c312012-01-06 19:20:56 +0000421 ALOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700422 mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable);
423 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
424 numTexturesToBind = numTexturesAvailable;
425 }
426
427 for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700428 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0 + ct);
429 RSD_CALL_GL(glUniform1i, sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700430
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700431 if (!mRSProgram->mHal.state.textures[ct]) {
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700432 // if nothing is bound, reset to default GL texture
Jason Sams5316b9e2011-09-13 15:41:01 -0700433 RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700434 continue;
435 }
436
Jason Sams7e8aae72011-05-26 16:33:01 -0700437 DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700438 if (drvTex->glTarget != GL_TEXTURE_2D &&
439 drvTex->glTarget != GL_TEXTURE_CUBE_MAP &&
440 drvTex->glTarget != GL_TEXTURE_EXTERNAL_OES) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800441 ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u",
442 (uint)this, ct);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700443 rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
444 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700445 RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700446 rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700447 if (mRSProgram->mHal.state.samplers[ct]) {
448 setupSampler(rsc, mRSProgram->mHal.state.samplers[ct],
449 mRSProgram->mHal.state.textures[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700450 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700451 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
452 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
453 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
454 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700455 rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700456 }
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700457 rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700458 }
459
Jason Sams5316b9e2011-09-13 15:41:01 -0700460 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700461 mDirty = false;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700462 rsdGLCheckError(rsc, "ProgramFragment::setup");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700463}
464
465void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
466 uint32_t uidx = 0;
467 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700468 Allocation *alloc = mRSProgram->mHal.state.constants[ct];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700469 if (!alloc) {
Steve Block3762c312012-01-06 19:20:56 +0000470 ALOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set",
Jason Sams5316b9e2011-09-13 15:41:01 -0700471 (uint32_t)this, ct);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700472 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
473 continue;
474 }
475
476 const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
477 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800478 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
479 const Element *f = e->mHal.state.fields[field];
480 const char *fieldName = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700481
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800482 uint32_t offset = e->mHal.state.fieldOffsetBytes[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700483 const float *fd = reinterpret_cast<const float *>(&data[offset]);
484
485 int32_t slot = -1;
486 uint32_t arraySize = 1;
487 if (!isFragment) {
488 slot = sc->vtxUniformSlot(uidx);
489 arraySize = sc->vtxUniformSize(uidx);
490 } else {
491 slot = sc->fragUniformSlot(uidx);
492 arraySize = sc->fragUniformSize(uidx);
493 }
494 if (rsc->props.mLogShadersUniforms) {
Steve Block71f2cf12011-10-20 11:56:00 +0100495 ALOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
Jason Sams5316b9e2011-09-13 15:41:01 -0700496 slot, offset, ct, field, uidx, fieldName);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700497 }
498 uidx ++;
499 if (slot < 0) {
500 continue;
501 }
502
503 if (rsc->props.mLogShadersUniforms) {
504 logUniform(f, fd, arraySize);
505 }
506 setUniform(rsc, f, fd, slot, arraySize);
507 }
508 }
509}
510
511void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) {
512
513 setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER);
514 setupTextures(rsc, sc);
515}
516
517void RsdShader::initAttribAndUniformArray() {
518 mAttribCount = 0;
519 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700520 const Element *elem = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk61cd9432012-01-05 14:55:11 -0800521 mAttribCount += elem->mHal.state.fieldsCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700522 }
523
524 mUniformCount = 0;
525 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
526 const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800527 mUniformCount += elem->mHal.state.fieldsCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700528 }
529 mUniformCount += mRSProgram->mHal.state.texturesCount;
530
531 if (mAttribCount) {
532 mAttribNames = new String8[mAttribCount];
533 }
534 if (mUniformCount) {
535 mUniformNames = new String8[mUniformCount];
536 mUniformArraySizes = new uint32_t[mUniformCount];
537 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700538
539 mTextureCount = mRSProgram->mHal.state.texturesCount;
540 if (mTextureCount) {
541 mTextureTargets = new uint32_t[mTextureCount];
542 }
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700543}
544
Jason Sams5316b9e2011-09-13 15:41:01 -0700545void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths,
546 uint32_t *count, const char *prefix) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800547 rsAssert(e->mHal.state.fieldsCount);
548 for (uint32_t ct=0; ct < e->mHal.state.fieldsCount; ct++) {
549 const Element *ce = e->mHal.state.fields[ct];
550 if (ce->mHal.state.fieldsCount) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700551 initAddUserElement(ce, names, arrayLengths, count, prefix);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800552 } else {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700553 String8 tmp(prefix);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800554 tmp.append(e->mHal.state.fieldNames[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700555 names[*count].setTo(tmp.string());
556 if (arrayLengths) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800557 arrayLengths[*count] = e->mHal.state.fieldArraySizes[ct];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700558 }
559 (*count)++;
560 }
561 }
562}