blob: 3bca794ea9d6c7bb4a776c6921f95d81627107c6 [file] [log] [blame]
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
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,
33 const char * shaderText, uint32_t shaderLength) {
34
35 mUserShader.setTo(shaderText, shaderLength);
36 mRSProgram = p;
37 mType = type;
38 initMemberVars();
39 initAttribAndUniformArray();
40 init();
41}
42
43RsdShader::~RsdShader() {
44 if (mShaderID) {
45 glDeleteShader(mShaderID);
46 }
47
48 delete[] mAttribNames;
49 delete[] mUniformNames;
50 delete[] mUniformArraySizes;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070051 delete[] mTextureTargets;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070052}
53
54void RsdShader::initMemberVars() {
55 mDirty = true;
56 mShaderID = 0;
57 mAttribCount = 0;
58 mUniformCount = 0;
59
60 mAttribNames = NULL;
61 mUniformNames = NULL;
62 mUniformArraySizes = NULL;
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070063 mTextureTargets = NULL;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070064
65 mIsValid = false;
66}
67
68void RsdShader::init() {
69 uint32_t attribCount = 0;
70 uint32_t uniformCount = 0;
71 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -070072 initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070073 }
74 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
75 initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
76 }
77
78 mTextureUniformIndexStart = uniformCount;
79 char buf[256];
80 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
81 snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
82 mUniformNames[uniformCount].setTo(buf);
83 mUniformArraySizes[uniformCount] = 1;
84 uniformCount++;
85 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -070086
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070087}
88
89String8 RsdShader::getGLSLInputString() const {
90 String8 s;
91 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -070092 const Element *e = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -080093 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
94 const Element *f = e->mHal.state.fields[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070095
96 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -080097 rsAssert(!f->mHal.state.fieldsCount);
98 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070099 case 1: s.append("attribute float ATTRIB_"); break;
100 case 2: s.append("attribute vec2 ATTRIB_"); break;
101 case 3: s.append("attribute vec3 ATTRIB_"); break;
102 case 4: s.append("attribute vec4 ATTRIB_"); break;
103 default:
104 rsAssert(0);
105 }
106
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800107 s.append(e->mHal.state.fieldNames[field]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700108 s.append(";\n");
109 }
110 }
111 return s;
112}
113
114void RsdShader::appendAttributes() {
115 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700116 const Element *e = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800117 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
118 const Element *f = e->mHal.state.fields[field];
119 const char *fn = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700120
121 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800122 rsAssert(!f->mHal.state.fieldsCount);
123 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700124 case 1: mShader.append("attribute float ATTRIB_"); break;
125 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
126 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
127 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
128 default:
129 rsAssert(0);
130 }
131
132 mShader.append(fn);
133 mShader.append(";\n");
134 }
135 }
136}
137
138void RsdShader::appendTextures() {
139 char buf[256];
140 for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
141 if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800142 Allocation *a = mRSProgram->mHal.state.textures[ct];
143 if (a && a->mHal.state.surfaceTextureID) {
144 snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct);
145 } else {
146 snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
147 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700148 mTextureTargets[ct] = GL_TEXTURE_2D;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700149 } else {
150 snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700151 mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700152 }
153 mShader.append(buf);
154 }
155}
156
157bool RsdShader::createShader() {
158
159 if (mType == GL_FRAGMENT_SHADER) {
160 mShader.append("precision mediump float;\n");
161 }
162 appendUserConstants();
163 appendAttributes();
164 appendTextures();
165
166 mShader.append(mUserShader);
167
168 return true;
169}
170
171bool RsdShader::loadShader(const Context *rsc) {
172 mShaderID = glCreateShader(mType);
173 rsAssert(mShaderID);
174
175 if (rsc->props.mLogShaders) {
Steve Block71f2cf12011-10-20 11:56:00 +0100176 ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
177 ALOGV("%s", mShader.string());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700178 }
179
180 if (mShaderID) {
181 const char * ss = mShader.string();
Jason Sams5316b9e2011-09-13 15:41:01 -0700182 RSD_CALL_GL(glShaderSource, mShaderID, 1, &ss, NULL);
183 RSD_CALL_GL(glCompileShader, mShaderID);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700184
185 GLint compiled = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700186 RSD_CALL_GL(glGetShaderiv, mShaderID, GL_COMPILE_STATUS, &compiled);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700187 if (!compiled) {
188 GLint infoLen = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700189 RSD_CALL_GL(glGetShaderiv, mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700190 if (infoLen) {
191 char* buf = (char*) malloc(infoLen);
192 if (buf) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700193 RSD_CALL_GL(glGetShaderInfoLog, mShaderID, infoLen, NULL, buf);
Alex Sakhartchouk257e8a92012-02-07 18:06:13 -0800194 rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700195 free(buf);
196 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700197 RSD_CALL_GL(glDeleteShader, mShaderID);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700198 mShaderID = 0;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700199 return false;
200 }
201 }
202 }
203
204 if (rsc->props.mLogShaders) {
Steve Block71f2cf12011-10-20 11:56:00 +0100205 ALOGV("--Shader load result %x ", glGetError());
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700206 }
207 mIsValid = true;
208 return true;
209}
210
211void RsdShader::appendUserConstants() {
212 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
213 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800214 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
215 const Element *f = e->mHal.state.fields[field];
216 const char *fn = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700217
218 // Cannot be complex
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800219 rsAssert(!f->mHal.state.fieldsCount);
220 if (f->mHal.state.dataType == RS_TYPE_MATRIX_4X4) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700221 mShader.append("uniform mat4 UNI_");
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800222 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_3X3) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700223 mShader.append("uniform mat3 UNI_");
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800224 } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_2X2) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700225 mShader.append("uniform mat2 UNI_");
226 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800227 switch (f->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700228 case 1: mShader.append("uniform float UNI_"); break;
229 case 2: mShader.append("uniform vec2 UNI_"); break;
230 case 3: mShader.append("uniform vec3 UNI_"); break;
231 case 4: mShader.append("uniform vec4 UNI_"); break;
232 default:
233 rsAssert(0);
234 }
235 }
236
237 mShader.append(fn);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800238 if (e->mHal.state.fieldArraySizes[field] > 1) {
239 mShader.appendFormat("[%d]", e->mHal.state.fieldArraySizes[field]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700240 }
241 mShader.append(";\n");
242 }
243 }
244}
245
246void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800247 RsDataType dataType = field->mHal.state.dataType;
248 uint32_t elementSize = field->mHal.state.elementSizeBytes / sizeof(float);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700249 for (uint32_t i = 0; i < arraySize; i ++) {
250 if (arraySize > 1) {
Steve Block71f2cf12011-10-20 11:56:00 +0100251 ALOGV("Array Element [%u]", i);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700252 }
253 if (dataType == RS_TYPE_MATRIX_4X4) {
Steve Block71f2cf12011-10-20 11:56:00 +0100254 ALOGV("Matrix4x4");
255 ALOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
256 ALOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
257 ALOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
258 ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700259 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Steve Block71f2cf12011-10-20 11:56:00 +0100260 ALOGV("Matrix3x3");
261 ALOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
262 ALOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
263 ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700264 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Steve Block71f2cf12011-10-20 11:56:00 +0100265 ALOGV("Matrix2x2");
266 ALOGV("{%f, %f", fd[0], fd[2]);
267 ALOGV(" %f, %f}", fd[1], fd[3]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700268 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800269 switch (field->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700270 case 1:
Steve Block71f2cf12011-10-20 11:56:00 +0100271 ALOGV("Uniform 1 = %f", fd[0]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700272 break;
273 case 2:
Steve Block71f2cf12011-10-20 11:56:00 +0100274 ALOGV("Uniform 2 = %f %f", fd[0], fd[1]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700275 break;
276 case 3:
Steve Block71f2cf12011-10-20 11:56:00 +0100277 ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700278 break;
279 case 4:
Steve Block71f2cf12011-10-20 11:56:00 +0100280 ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700281 break;
282 default:
283 rsAssert(0);
284 }
285 }
Steve Block3762c312012-01-06 19:20:56 +0000286 ALOGE("Element size %u data=%p", elementSize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700287 fd += elementSize;
Steve Block3762c312012-01-06 19:20:56 +0000288 ALOGE("New data=%p", fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700289 }
290}
291
292void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
293 int32_t slot, uint32_t arraySize ) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800294 RsDataType dataType = field->mHal.state.dataType;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700295 if (dataType == RS_TYPE_MATRIX_4X4) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700296 RSD_CALL_GL(glUniformMatrix4fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700297 } else if (dataType == RS_TYPE_MATRIX_3X3) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700298 RSD_CALL_GL(glUniformMatrix3fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700299 } else if (dataType == RS_TYPE_MATRIX_2X2) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700300 RSD_CALL_GL(glUniformMatrix2fv, slot, arraySize, GL_FALSE, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700301 } else {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800302 switch (field->mHal.state.vectorSize) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700303 case 1:
Jason Sams5316b9e2011-09-13 15:41:01 -0700304 RSD_CALL_GL(glUniform1fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700305 break;
306 case 2:
Jason Sams5316b9e2011-09-13 15:41:01 -0700307 RSD_CALL_GL(glUniform2fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700308 break;
309 case 3:
Jason Sams5316b9e2011-09-13 15:41:01 -0700310 RSD_CALL_GL(glUniform3fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700311 break;
312 case 4:
Jason Sams5316b9e2011-09-13 15:41:01 -0700313 RSD_CALL_GL(glUniform4fv, slot, arraySize, fd);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700314 break;
315 default:
316 rsAssert(0);
317 }
318 }
319}
320
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700321void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) {
322 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
323
324 GLenum trans[] = {
325 GL_NEAREST, //RS_SAMPLER_NEAREST,
326 GL_LINEAR, //RS_SAMPLER_LINEAR,
327 GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
328 GL_REPEAT, //RS_SAMPLER_WRAP,
329 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
330 GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
331 };
332
333 GLenum transNP[] = {
334 GL_NEAREST, //RS_SAMPLER_NEAREST,
335 GL_LINEAR, //RS_SAMPLER_LINEAR,
336 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
337 GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
338 GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
339 GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
340 };
341
342 // This tells us the correct texture type
Jason Sams7e8aae72011-05-26 16:33:01 -0700343 DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv;
344 const GLenum target = drvTex->glTarget;
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700345
346 if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) {
347 if (tex->getHasGraphicsMipmaps() &&
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800348 (dc->gl.gl.NV_texture_npot_2D_mipmap || dc->gl.gl.IMG_texture_npot)) {
349 if (dc->gl.gl.NV_texture_npot_2D_mipmap) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700350 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
351 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700352 } else {
353 switch (trans[s->mHal.state.minFilter]) {
354 case GL_LINEAR_MIPMAP_LINEAR:
Jason Sams5316b9e2011-09-13 15:41:01 -0700355 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
356 GL_LINEAR_MIPMAP_NEAREST);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700357 break;
358 default:
Jason Sams5316b9e2011-09-13 15:41:01 -0700359 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
360 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700361 break;
362 }
363 }
364 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700365 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
366 transNP[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700367 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700368 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER,
369 transNP[s->mHal.state.magFilter]);
370 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]);
371 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700372 } else {
373 if (tex->getHasGraphicsMipmaps()) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700374 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
375 trans[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700376 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700377 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
378 transNP[s->mHal.state.minFilter]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700379 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700380 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MAG_FILTER, trans[s->mHal.state.magFilter]);
381 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]);
382 RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700383 }
384
385 float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso);
386 if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700387 RSD_CALL_GL(glTexParameterf, target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700388 }
389
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700390 rsdGLCheckError(rsc, "Sampler::setup tex env");
Alex Sakhartchouk43850542011-05-05 16:56:27 -0700391}
392
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700393void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
394 if (mRSProgram->mHal.state.texturesCount == 0) {
395 return;
396 }
397
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700398 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
399
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700400 uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700401 uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700402 if (numTexturesToBind >= numTexturesAvailable) {
Steve Block3762c312012-01-06 19:20:56 +0000403 ALOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700404 mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable);
405 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
406 numTexturesToBind = numTexturesAvailable;
407 }
408
409 for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700410 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0 + ct);
411 RSD_CALL_GL(glUniform1i, sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700412
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700413 if (!mRSProgram->mHal.state.textures[ct]) {
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700414 // if nothing is bound, reset to default GL texture
Jason Sams5316b9e2011-09-13 15:41:01 -0700415 RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700416 continue;
417 }
418
Jason Sams7e8aae72011-05-26 16:33:01 -0700419 DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
420 if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) {
Steve Block3762c312012-01-06 19:20:56 +0000421 ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700422 rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
423 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700424 RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700425 rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700426 if (mRSProgram->mHal.state.samplers[ct]) {
427 setupSampler(rsc, mRSProgram->mHal.state.samplers[ct],
428 mRSProgram->mHal.state.textures[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700429 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700430 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
431 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
432 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
433 RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700434 rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700435 }
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700436 rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700437 }
438
Jason Sams5316b9e2011-09-13 15:41:01 -0700439 RSD_CALL_GL(glActiveTexture, GL_TEXTURE0);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700440 mDirty = false;
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700441 rsdGLCheckError(rsc, "ProgramFragment::setup");
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700442}
443
444void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
445 uint32_t uidx = 0;
446 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700447 Allocation *alloc = mRSProgram->mHal.state.constants[ct];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700448 if (!alloc) {
Steve Block3762c312012-01-06 19:20:56 +0000449 ALOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set",
Jason Sams5316b9e2011-09-13 15:41:01 -0700450 (uint32_t)this, ct);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700451 rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
452 continue;
453 }
454
455 const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
456 const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800457 for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
458 const Element *f = e->mHal.state.fields[field];
459 const char *fieldName = e->mHal.state.fieldNames[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700460
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800461 uint32_t offset = e->mHal.state.fieldOffsetBytes[field];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700462 const float *fd = reinterpret_cast<const float *>(&data[offset]);
463
464 int32_t slot = -1;
465 uint32_t arraySize = 1;
466 if (!isFragment) {
467 slot = sc->vtxUniformSlot(uidx);
468 arraySize = sc->vtxUniformSize(uidx);
469 } else {
470 slot = sc->fragUniformSlot(uidx);
471 arraySize = sc->fragUniformSize(uidx);
472 }
473 if (rsc->props.mLogShadersUniforms) {
Steve Block71f2cf12011-10-20 11:56:00 +0100474 ALOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
Jason Sams5316b9e2011-09-13 15:41:01 -0700475 slot, offset, ct, field, uidx, fieldName);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700476 }
477 uidx ++;
478 if (slot < 0) {
479 continue;
480 }
481
482 if (rsc->props.mLogShadersUniforms) {
483 logUniform(f, fd, arraySize);
484 }
485 setUniform(rsc, f, fd, slot, arraySize);
486 }
487 }
488}
489
490void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) {
491
492 setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER);
493 setupTextures(rsc, sc);
494}
495
496void RsdShader::initAttribAndUniformArray() {
497 mAttribCount = 0;
498 for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
Alex Sakhartchouk5ef2f532011-10-18 10:54:29 -0700499 const Element *elem = mRSProgram->mHal.state.inputElements[ct];
Alex Sakhartchouk61cd9432012-01-05 14:55:11 -0800500 mAttribCount += elem->mHal.state.fieldsCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700501 }
502
503 mUniformCount = 0;
504 for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
505 const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800506 mUniformCount += elem->mHal.state.fieldsCount;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700507 }
508 mUniformCount += mRSProgram->mHal.state.texturesCount;
509
510 if (mAttribCount) {
511 mAttribNames = new String8[mAttribCount];
512 }
513 if (mUniformCount) {
514 mUniformNames = new String8[mUniformCount];
515 mUniformArraySizes = new uint32_t[mUniformCount];
516 }
Alex Sakhartchoukbbc41c02011-08-05 15:27:25 -0700517
518 mTextureCount = mRSProgram->mHal.state.texturesCount;
519 if (mTextureCount) {
520 mTextureTargets = new uint32_t[mTextureCount];
521 }
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700522}
523
Jason Sams5316b9e2011-09-13 15:41:01 -0700524void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths,
525 uint32_t *count, const char *prefix) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800526 rsAssert(e->mHal.state.fieldsCount);
527 for (uint32_t ct=0; ct < e->mHal.state.fieldsCount; ct++) {
528 const Element *ce = e->mHal.state.fields[ct];
529 if (ce->mHal.state.fieldsCount) {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700530 initAddUserElement(ce, names, arrayLengths, count, prefix);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800531 } else {
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700532 String8 tmp(prefix);
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800533 tmp.append(e->mHal.state.fieldNames[ct]);
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700534 names[*count].setTo(tmp.string());
535 if (arrayLengths) {
Alex Sakhartchouk36a7d602011-12-28 13:47:05 -0800536 arrayLengths[*count] = e->mHal.state.fieldArraySizes[ct];
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700537 }
538 (*count)++;
539 }
540 }
541}