blob: 1e73b95b6cd60ea5a6ebff87eb63d635b3d5454e [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);
42 createTexturesString(textureNames, textureNamesCount, textureNamesLength);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070043}
44
45RsdShader::~RsdShader() {
46 if (mShaderID) {
47 glDeleteShader(mShaderID);
48 }
49
50 delete[] mAttribNames;
51 delete[] mUniformNames;
52 delete[] mUniformArraySizes;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070053 delete[] mTextureTargets;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070054}
55
56void RsdShader::initMemberVars() {
57 mDirty = true;
58 mShaderID = 0;
59 mAttribCount = 0;
60 mUniformCount = 0;
61
62 mAttribNames = NULL;
63 mUniformNames = NULL;
64 mUniformArraySizes = NULL;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070065 mTextureTargets = NULL;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070066
67 mIsValid = false;
68}
69
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080070void RsdShader::init(const char** textureNames, size_t textureNamesCount,
71 const size_t *textureNamesLength) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070072 uint32_t attribCount = 0;
73 uint32_t uniformCount = 0;
74 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080075 initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames,
76 NULL, &attribCount, RS_SHADER_ATTR);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070077 }
78 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080079 initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(),
80 mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070081 }
82
83 mTextureUniformIndexStart = uniformCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070084 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080085 mUniformNames[uniformCount].setTo("UNI_");
86 mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070087 mUniformArraySizes[uniformCount] = 1;
88 uniformCount++;
89 }
90}
91
92String8 RsdShader::getGLSLInputString() const {
93 String8 s;
94 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -070095 const Element *e = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -080096 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
97 const Element *f = e->mHal.state.fields[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070098
99 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800100 rsAssert(!f->mHal.state.fieldsCount);
101 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700102 case 1: s.append("attribute float ATTRIB_"); break;
103 case 2: s.append("attribute vec2 ATTRIB_"); break;
104 case 3: s.append("attribute vec3 ATTRIB_"); break;
105 case 4: s.append("attribute vec4 ATTRIB_"); break;
106 default:
107 rsAssert(0);
108 }
109
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800110 s.append(e->mHal.state.fieldNames[field]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700111 s.append(";\n");
112 }
113 }
114 return s;
115}
116
117void RsdShader::appendAttributes() {
118 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700119 const Element *e = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800120 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
121 const Element *f = e->mHal.state.fields[field];
122 const char *fn = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700123
124 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800125 rsAssert(!f->mHal.state.fieldsCount);
126 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700127 case 1: mShader.append("attribute float ATTRIB_"); break;
128 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
129 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
130 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
131 default:
132 rsAssert(0);
133 }
134
135 mShader.append(fn);
136 mShader.append(";\n");
137 }
138 }
139}
140
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800141void RsdShader::createTexturesString(const char** textureNames, size_t textureNamesCount,
142 const size_t *textureNamesLength) {
143 mShaderTextures.setTo("");
144 for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700145 if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800146 Allocation *a = mRSProgram->mHal.state.textures[ct];
147 if (a && a->mHal.state.surfaceTextureID) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800148 mShaderTextures.append("uniform samplerExternalOES UNI_");
Jason Sams615e7ce2012-01-13 14:01:20 -0800149 } else {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800150 mShaderTextures.append("uniform sampler2D UNI_");
Jason Sams615e7ce2012-01-13 14:01:20 -0800151 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700152 mTextureTargets[ct] = GL_TEXTURE_2D;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700153 } else {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800154 mShaderTextures.append("uniform samplerCube UNI_");
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700155 mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700156 }
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800157
158 mShaderTextures.append(textureNames[ct], textureNamesLength[ct]);
159 mShaderTextures.append(";\n");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700160 }
161}
162
163bool RsdShader::createShader() {
164
165 if (mType == GL_FRAGMENT_SHADER) {
166 mShader.append("precision mediump float;\n");
167 }
168 appendUserConstants();
169 appendAttributes();
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800170 mShader.append(mShaderTextures);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700171
172 mShader.append(mUserShader);
173
174 return true;
175}
176
177bool RsdShader::loadShader(const Context *rsc) {
178 mShaderID = glCreateShader(mType);
179 rsAssert(mShaderID);
180
181 if (rsc->props.mLogShaders) {
Steve Block71f2cf12011-10-20 11:56:00 +0100182 ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
183 ALOGV("%s", mShader.string());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700184 }
185
186 if (mShaderID) {
187 const char * ss = mShader.string();
Jason Sams5316b9e2011-09-13 15:41:01 -0700188 RSD_CALL_GL(glShaderSource, mShaderID, 1, &ss, NULL);
189 RSD_CALL_GL(glCompileShader, mShaderID);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700190
191 GLint compiled = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700192 RSD_CALL_GL(glGetShaderiv, mShaderID, GL_COMPILE_STATUS, &compiled);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700193 if (!compiled) {
194 GLint infoLen = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700195 RSD_CALL_GL(glGetShaderiv, mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700196 if (infoLen) {
197 char* buf = (char*) malloc(infoLen);
198 if (buf) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700199 RSD_CALL_GL(glGetShaderInfoLog, mShaderID, infoLen, NULL, buf);
Alex Sakhartchouk257e8a92012-02-07 18:06:13 -0800200 rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700201 free(buf);
202 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700203 RSD_CALL_GL(glDeleteShader, mShaderID);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700204 mShaderID = 0;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700205 return false;
206 }
207 }
208 }
209
210 if (rsc->props.mLogShaders) {
Steve Block71f2cf12011-10-20 11:56:00 +0100211 ALOGV("--Shader load result %x ", glGetError());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700212 }
213 mIsValid = true;
214 return true;
215}
216
217void RsdShader::appendUserConstants() {
218 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
219 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800220 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
221 const Element *f = e->mHal.state.fields[field];
222 const char *fn = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700223
224 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800225 rsAssert(!f->mHal.state.fieldsCount);
226 if (f->mHal.state.dataType == RS_TYPE_MATRIX_4X4) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700227 mShader.append("uniform mat4 UNI_");
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800228 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_3X3) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700229 mShader.append("uniform mat3 UNI_");
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800230 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_2X2) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700231 mShader.append("uniform mat2 UNI_");
232 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800233 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700234 case 1: mShader.append("uniform float UNI_"); break;
235 case 2: mShader.append("uniform vec2 UNI_"); break;
236 case 3: mShader.append("uniform vec3 UNI_"); break;
237 case 4: mShader.append("uniform vec4 UNI_"); break;
238 default:
239 rsAssert(0);
240 }
241 }
242
243 mShader.append(fn);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800244 if (e->mHal.state.fieldArraySizes[field] > 1) {
245 mShader.appendFormat("[%d]", e->mHal.state.fieldArraySizes[field]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700246 }
247 mShader.append(";\n");
248 }
249 }
250}
251
252void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800253 RsDataType dataType = field->mHal.state.dataType;
254 uint32_t elementSize = field->mHal.state.elementSizeBytes / sizeof(float);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700255 for (uint32_t i = 0; i < arraySize; i ++) {
256 if (arraySize > 1) {
Steve Block71f2cf12011-10-20 11:56:00 +0100257 ALOGV("Array Element [%u]", i);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700258 }
259 if (dataType == RS_TYPE_MATRIX_4X4) {
Steve Block71f2cf12011-10-20 11:56:00 +0100260 ALOGV("Matrix4x4");
261 ALOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
262 ALOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
263 ALOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
264 ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700265 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Steve Block71f2cf12011-10-20 11:56:00 +0100266 ALOGV("Matrix3x3");
267 ALOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
268 ALOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
269 ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700270 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Steve Block71f2cf12011-10-20 11:56:00 +0100271 ALOGV("Matrix2x2");
272 ALOGV("{%f, %f", fd[0], fd[2]);
273 ALOGV(" %f, %f}", fd[1], fd[3]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700274 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800275 switch (field->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700276 case 1:
Steve Block71f2cf12011-10-20 11:56:00 +0100277 ALOGV("Uniform 1 = %f", fd[0]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700278 break;
279 case 2:
Steve Block71f2cf12011-10-20 11:56:00 +0100280 ALOGV("Uniform 2 = %f %f", fd[0], fd[1]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700281 break;
282 case 3:
Steve Block71f2cf12011-10-20 11:56:00 +0100283 ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700284 break;
285 case 4:
Steve Block71f2cf12011-10-20 11:56:00 +0100286 ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700287 break;
288 default:
289 rsAssert(0);
290 }
291 }
Steve Block3762c312012-01-06 19:20:56 +0000292 ALOGE("Element size %u data=%p", elementSize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700293 fd += elementSize;
Steve Block3762c312012-01-06 19:20:56 +0000294 ALOGE("New data=%p", fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700295 }
296}
297
298void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
299 int32_t slot, uint32_t arraySize ) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800300 RsDataType dataType = field->mHal.state.dataType;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700301 if (dataType == RS_TYPE_MATRIX_4X4) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700302 RSD_CALL_GL(glUniformMatrix4fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700303 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700304 RSD_CALL_GL(glUniformMatrix3fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700305 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700306 RSD_CALL_GL(glUniformMatrix2fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700307 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800308 switch (field->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700309 case 1:
Jason Sams5316b9e2011-09-13 15:41:01 -0700310 RSD_CALL_GL(glUniform1fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700311 break;
312 case 2:
Jason Sams5316b9e2011-09-13 15:41:01 -0700313 RSD_CALL_GL(glUniform2fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700314 break;
315 case 3:
Jason Sams5316b9e2011-09-13 15:41:01 -0700316 RSD_CALL_GL(glUniform3fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700317 break;
318 case 4:
Jason Sams5316b9e2011-09-13 15:41:01 -0700319 RSD_CALL_GL(glUniform4fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700320 break;
321 default:
322 rsAssert(0);
323 }
324 }
325}
326
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700327void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) {
328 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
329
330 GLenum trans[] = {
331 GL_NEAREST, //RS_SAMPLER_NEAREST,
332 GL_LINEAR, //RS_SAMPLER_LINEAR,
333 GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
334 GL_REPEAT, //RS_SAMPLER_WRAP,
335 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
336 GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
337 };
338
339 GLenum transNP[] = {
340 GL_NEAREST, //RS_SAMPLER_NEAREST,
341 GL_LINEAR, //RS_SAMPLER_LINEAR,
342 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
343 GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
344 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
345 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
346 };
347
348 // This tells us the correct texture type
Jason Sams7e8aae72011-05-26 16:33:01 -0700349 DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv;
350 const GLenum target = drvTex->glTarget;
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700351
352 if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) {
353 if (tex->getHasGraphicsMipmaps() &&
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800354 (dc->gl.gl.NV_texture_npot_2D_mipmap || dc->gl.gl.IMG_texture_npot)) {
355 if (dc->gl.gl.NV_texture_npot_2D_mipmap) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700356 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
357 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700358 } else {
359 switch (trans[s->mHal.state.minFilter]) {
360 case GL_LINEAR_MIPMAP_LINEAR:
Jason Sams5316b9e2011-09-13 15:41:01 -0700361 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
362 GL_LINEAR_MIPMAP_NEAREST);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700363 break;
364 default:
Jason Sams5316b9e2011-09-13 15:41:01 -0700365 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
366 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700367 break;
368 }
369 }
370 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700371 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
372 transNP[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700373 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700374 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER,
375 transNP[s->mHal.state.magFilter]);
376 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]);
377 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700378 } else {
379 if (tex->getHasGraphicsMipmaps()) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700380 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
381 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700382 } 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, trans[s->mHal.state.magFilter]);
387 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]);
388 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700389 }
390
391 float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso);
392 if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700393 RSD_CALL_GL(glTexParameterf, target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700394 }
395
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700396 rsdGLCheckError(rsc, "Sampler::setup tex env");
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700397}
398
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700399void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
400 if (mRSProgram->mHal.state.texturesCount == 0) {
401 return;
402 }
403
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700404 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
405
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700406 uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700407 uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700408 if (numTexturesToBind >= numTexturesAvailable) {
Steve Block3762c312012-01-06 19:20:56 +0000409 ALOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700410 mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable);
411 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
412 numTexturesToBind = numTexturesAvailable;
413 }
414
415 for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700416 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0 + ct);
417 RSD_CALL_GL(glUniform1i, sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700418
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700419 if (!mRSProgram->mHal.state.textures[ct]) {
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700420 // if nothing is bound, reset to default GL texture
Jason Sams5316b9e2011-09-13 15:41:01 -0700421 RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700422 continue;
423 }
424
Jason Sams7e8aae72011-05-26 16:33:01 -0700425 DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
426 if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800427 ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u",
428 (uint)this, ct);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700429 rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
430 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700431 RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700432 rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700433 if (mRSProgram->mHal.state.samplers[ct]) {
434 setupSampler(rsc, mRSProgram->mHal.state.samplers[ct],
435 mRSProgram->mHal.state.textures[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700436 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700437 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
438 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
439 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
440 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700441 rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700442 }
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700443 rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700444 }
445
Jason Sams5316b9e2011-09-13 15:41:01 -0700446 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700447 mDirty = false;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700448 rsdGLCheckError(rsc, "ProgramFragment::setup");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700449}
450
451void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
452 uint32_t uidx = 0;
453 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700454 Allocation *alloc = mRSProgram->mHal.state.constants[ct];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700455 if (!alloc) {
Steve Block3762c312012-01-06 19:20:56 +0000456 ALOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set",
Jason Sams5316b9e2011-09-13 15:41:01 -0700457 (uint32_t)this, ct);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700458 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
459 continue;
460 }
461
462 const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
463 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800464 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
465 const Element *f = e->mHal.state.fields[field];
466 const char *fieldName = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700467
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800468 uint32_t offset = e->mHal.state.fieldOffsetBytes[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700469 const float *fd = reinterpret_cast<const float *>(&data[offset]);
470
471 int32_t slot = -1;
472 uint32_t arraySize = 1;
473 if (!isFragment) {
474 slot = sc->vtxUniformSlot(uidx);
475 arraySize = sc->vtxUniformSize(uidx);
476 } else {
477 slot = sc->fragUniformSlot(uidx);
478 arraySize = sc->fragUniformSize(uidx);
479 }
480 if (rsc->props.mLogShadersUniforms) {
Steve Block71f2cf12011-10-20 11:56:00 +0100481 ALOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
Jason Sams5316b9e2011-09-13 15:41:01 -0700482 slot, offset, ct, field, uidx, fieldName);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700483 }
484 uidx ++;
485 if (slot < 0) {
486 continue;
487 }
488
489 if (rsc->props.mLogShadersUniforms) {
490 logUniform(f, fd, arraySize);
491 }
492 setUniform(rsc, f, fd, slot, arraySize);
493 }
494 }
495}
496
497void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) {
498
499 setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER);
500 setupTextures(rsc, sc);
501}
502
503void RsdShader::initAttribAndUniformArray() {
504 mAttribCount = 0;
505 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700506 const Element *elem = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk61cd9432012-01-05 14:55:11 -0800507 mAttribCount += elem->mHal.state.fieldsCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700508 }
509
510 mUniformCount = 0;
511 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
512 const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800513 mUniformCount += elem->mHal.state.fieldsCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700514 }
515 mUniformCount += mRSProgram->mHal.state.texturesCount;
516
517 if (mAttribCount) {
518 mAttribNames = new String8[mAttribCount];
519 }
520 if (mUniformCount) {
521 mUniformNames = new String8[mUniformCount];
522 mUniformArraySizes = new uint32_t[mUniformCount];
523 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700524
525 mTextureCount = mRSProgram->mHal.state.texturesCount;
526 if (mTextureCount) {
527 mTextureTargets = new uint32_t[mTextureCount];
528 }
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700529}
530
Jason Sams5316b9e2011-09-13 15:41:01 -0700531void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths,
532 uint32_t *count, const char *prefix) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800533 rsAssert(e->mHal.state.fieldsCount);
534 for (uint32_t ct=0; ct < e->mHal.state.fieldsCount; ct++) {
535 const Element *ce = e->mHal.state.fields[ct];
536 if (ce->mHal.state.fieldsCount) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700537 initAddUserElement(ce, names, arrayLengths, count, prefix);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800538 } else {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700539 String8 tmp(prefix);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800540 tmp.append(e->mHal.state.fieldNames[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700541 names[*count].setTo(tmp.string());
542 if (arrayLengths) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800543 arrayLengths[*count] = e->mHal.state.fieldArraySizes[ct];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700544 }
545 (*count)++;
546 }
547 }
548}