blob: a785262af5c0a89deda1812709816dfd58349727 [file] [log] [blame]
Jason Sams326e0dd2009-05-22 14:03:28 -07001/*
2 * Copyright (C) 2009 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
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Sams326e0dd2009-05-22 14:03:28 -070018#include "rsContext.h"
Jason Sams1aa5a4e2009-06-22 17:15:15 -070019#include <GLES/gl.h>
20#include <GLES/glext.h>
Jason Samsc460e552009-11-25 13:22:07 -080021#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070023#else
24#include "rsContextHostStub.h"
25#include <OpenGL/gl.h>
26#include <OpenGL/glext.h>
27#endif //ANDROID_RS_BUILD_FOR_HOST
28
29#include "rsProgramVertex.h"
Jason Sams1aa5a4e2009-06-22 17:15:15 -070030
Jason Sams326e0dd2009-05-22 14:03:28 -070031using namespace android;
32using namespace android::renderscript;
33
34
Jason Sams4815c0d2009-12-15 12:58:36 -080035ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText,
36 uint32_t shaderLength, const uint32_t * params,
37 uint32_t paramLength) :
38 Program(rsc, shaderText, shaderLength, params, paramLength)
Jason Sams326e0dd2009-05-22 14:03:28 -070039{
Jason Samsf2649a92009-09-25 16:37:33 -070040 mAllocFile = __FILE__;
41 mAllocLine = __LINE__;
Jason Sams4815c0d2009-12-15 12:58:36 -080042
43 init(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -070044}
45
46ProgramVertex::~ProgramVertex()
47{
Alex Sakhartchouk889fe502010-10-01 10:54:06 -070048 if(mShaderID) {
49 mRSC->mShaderCache.cleanupVertex(mShaderID);
50 }
Jason Sams56bc1af2009-06-16 17:49:58 -070051}
52
Jason Samscd506532009-12-15 19:10:11 -080053void ProgramVertex::loadShader(Context *rsc) {
54 Program::loadShader(rsc, GL_VERTEX_SHADER);
Jason Samsc460e552009-11-25 13:22:07 -080055}
56
57void ProgramVertex::createShader()
58{
Jason Samsf2a5d732009-11-30 14:49:55 -080059 if (mUserShader.length() > 1) {
Jason Sams9ebb0c42010-01-12 12:12:28 -080060
Alex Sakhartchouk6e934212010-08-31 12:02:01 -070061 appendUserConstants();
Jason Sams9ebb0c42010-01-12 12:12:28 -080062
Jason Samsb4d35682010-01-04 16:52:27 -080063 for (uint32_t ct=0; ct < mInputCount; ct++) {
64 const Element *e = mInputElements[ct].get();
65 for (uint32_t field=0; field < e->getFieldCount(); field++) {
66 const Element *f = e->getField(field);
Jason Samsbdb04602010-06-17 18:05:38 -070067 const char *fn = e->getFieldName(field);
68
69 if (fn[0] == '#') {
70 continue;
71 }
Jason Samsb4d35682010-01-04 16:52:27 -080072
73 // Cannot be complex
74 rsAssert(!f->getFieldCount());
75 switch(f->getComponent().getVectorSize()) {
76 case 1: mShader.append("attribute float ATTRIB_"); break;
77 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
78 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
79 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
80 default:
81 rsAssert(0);
82 }
83
Jason Samsbdb04602010-06-17 18:05:38 -070084 mShader.append(fn);
Jason Samsb4d35682010-01-04 16:52:27 -080085 mShader.append(";\n");
86 }
87 }
Jason Samsf2a5d732009-11-30 14:49:55 -080088 mShader.append(mUserShader);
Jason Samsc460e552009-11-25 13:22:07 -080089 } else {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -070090 LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
91 rsAssert(0);
Jason Samsc460e552009-11-25 13:22:07 -080092 }
Jason Samsc460e552009-11-25 13:22:07 -080093}
94
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -070095void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc)
Jason Samsc460e552009-11-25 13:22:07 -080096{
97 //LOGE("sgl2 vtx1 %x", glGetError());
98 if ((state->mLast.get() == this) && !mDirty) {
Jason Samse64c2f12010-06-22 17:22:13 -070099 return;
Jason Samsc460e552009-11-25 13:22:07 -0800100 }
101
Jason Sams3eb28f02010-01-27 14:41:43 -0800102 rsc->checkError("ProgramVertex::setupGL2 start");
Jason Samse9ed6cc2009-12-16 14:13:06 -0800103
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700104 if(!isUserProgram()) {
Alex Sakhartchouk0bd3c862010-09-27 10:29:47 -0700105 if(mConstants[0].get() == NULL) {
106 LOGE("Unable to set fixed function emulation matrices because allocation is missing");
107 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
108 return;
109 }
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700110 float *f = static_cast<float *>(mConstants[0]->getPtr());
111 Matrix mvp;
112 mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
113 Matrix t;
114 t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
115 mvp.multiply(&t);
116 for(uint32_t i = 0; i < 16; i ++) {
117 f[RS_PROGRAM_VERTEX_MVP_OFFSET + i] = mvp.m[i];
118 }
Jason Samsc460e552009-11-25 13:22:07 -0800119 }
120
Jason Sams3eb28f02010-01-27 14:41:43 -0800121 rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700122 setupUserConstants(rsc, sc, false);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800123
Jason Samsc460e552009-11-25 13:22:07 -0800124 state->mLast.set(this);
Jason Sams433eca32010-01-06 11:57:52 -0800125 rsc->checkError("ProgramVertex::setupGL2");
Jason Samsc460e552009-11-25 13:22:07 -0800126}
127
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700128void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const
Jason Samsc9d43db2009-07-28 12:02:16 -0700129{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700130 if(isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700131 LOGE("Attempting to set fixed function emulation matrix projection on user program");
132 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader");
133 return;
134 }
135 if(mConstants[0].get() == NULL) {
136 LOGE("Unable to set fixed function emulation matrix projection because allocation is missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700137 return;
138 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800139 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Samsc9d43db2009-07-28 12:02:16 -0700140 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
Jason Samscfb1d112009-08-05 13:57:03 -0700141 mDirty = true;
Jason Samsc9d43db2009-07-28 12:02:16 -0700142}
143
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700144void ProgramVertex::setModelviewMatrix(Context *rsc, const rsc_Matrix *m) const
Jason Samsc9d43db2009-07-28 12:02:16 -0700145{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700146 if(isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700147 LOGE("Attempting to set fixed function emulation matrix modelview on user program");
148 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader");
149 return;
150 }
151 if(mConstants[0].get() == NULL) {
152 LOGE("Unable to set fixed function emulation matrix modelview because allocation is missing");
153 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700154 return;
155 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800156 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Samsc9d43db2009-07-28 12:02:16 -0700157 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
Jason Samscfb1d112009-08-05 13:57:03 -0700158 mDirty = true;
Jason Samsc9d43db2009-07-28 12:02:16 -0700159}
160
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700161void ProgramVertex::setTextureMatrix(Context *rsc, const rsc_Matrix *m) const
Jason Samsc9d43db2009-07-28 12:02:16 -0700162{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700163 if(isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700164 LOGE("Attempting to set fixed function emulation matrix texture on user program");
165 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader");
166 return;
167 }
168 if(mConstants[0].get() == NULL) {
169 LOGE("Unable to set fixed function emulation matrix texture because allocation is missing");
170 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700171 return;
172 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800173 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Samsc9d43db2009-07-28 12:02:16 -0700174 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
Jason Samscfb1d112009-08-05 13:57:03 -0700175 mDirty = true;
Jason Samsc9d43db2009-07-28 12:02:16 -0700176}
177
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700178void ProgramVertex::getProjectionMatrix(Context *rsc, rsc_Matrix *m) const
Alex Sakhartchouk95333f92010-08-16 17:40:10 -0700179{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700180 if(isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700181 LOGE("Attempting to get fixed function emulation matrix projection on user program");
182 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot get emulation matrix on user shader");
183 return;
184 }
185 if(mConstants[0].get() == NULL) {
186 LOGE("Unable to get fixed function emulation matrix projection because allocation is missing");
187 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700188 return;
189 }
Alex Sakhartchouk95333f92010-08-16 17:40:10 -0700190 float *f = static_cast<float *>(mConstants[0]->getPtr());
191 memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix));
192}
193
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700194void ProgramVertex::transformToScreen(Context *rsc, float *v4out, const float *v3in) const
Jason Sams3a97c592009-09-30 17:36:20 -0700195{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700196 if(isUserProgram()) {
197 return;
198 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800199 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Sams3a97c592009-09-30 17:36:20 -0700200 Matrix mvp;
201 mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
202 (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
203 mvp.vectorMultiply(v4out, v3in);
204}
Jason Sams326e0dd2009-05-22 14:03:28 -0700205
Jason Samsc460e552009-11-25 13:22:07 -0800206void ProgramVertex::init(Context *rsc)
207{
Jason Samsbe504f22010-01-25 12:31:24 -0800208 mAttribCount = 0;
Jason Sams433eca32010-01-06 11:57:52 -0800209 if (mUserShader.size() > 0) {
Jason Sams433eca32010-01-06 11:57:52 -0800210 for (uint32_t ct=0; ct < mInputCount; ct++) {
Alex Sakhartchouk886f11a2010-09-29 09:49:13 -0700211 initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, RS_SHADER_ATTR);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800212 }
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700213 mUniformCount = 0;
Jason Sams4c9a2082010-01-13 14:52:46 -0800214 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchouk886f11a2010-09-29 09:49:13 -0700215 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, RS_SHADER_UNI);
Jason Sams433eca32010-01-06 11:57:52 -0800216 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800217 }
Jason Samsc460e552009-11-25 13:22:07 -0800218 createShader();
219}
220
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700221void ProgramVertex::serialize(OStream *stream) const
222{
223
224}
225
226ProgramVertex *ProgramVertex::createFromStream(Context *rsc, IStream *stream)
227{
228 return NULL;
229}
230
Jason Sams4815c0d2009-12-15 12:58:36 -0800231
Jason Samsc460e552009-11-25 13:22:07 -0800232///////////////////////////////////////////////////////////////////////
233
Jason Sams326e0dd2009-05-22 14:03:28 -0700234ProgramVertexState::ProgramVertexState()
235{
Jason Sams326e0dd2009-05-22 14:03:28 -0700236}
237
238ProgramVertexState::~ProgramVertexState()
239{
Jason Sams326e0dd2009-05-22 14:03:28 -0700240}
241
Jason Sams771565f2010-05-14 15:30:29 -0700242void ProgramVertexState::init(Context *rsc)
Jason Sams8ce125b2009-06-17 16:52:59 -0700243{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700244 const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1);
Alex Sakhartchouk7ffcaf22010-10-06 11:15:01 -0700245 const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700246 const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
247 const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
Jason Sams8287c0c2009-09-24 12:33:45 -0700248
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700249 rsc->mStateElement.elementBuilderBegin();
250 rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1);
251 rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1);
252 rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1);
253 rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1);
254 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
Jason Sams8287c0c2009-09-24 12:33:45 -0700255
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700256 rsc->mStateElement.elementBuilderBegin();
257 rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1);
258 rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1);
259 rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1);
Alex Sakhartchouk7ffcaf22010-10-06 11:15:01 -0700260 rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700261 const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
262
263 Type *inputType = new Type(rsc);
264 inputType->setElement(constInput);
265 inputType->setDimX(1);
266 inputType->compute();
267
268 String8 shaderString(RS_SHADER_INTERNAL);
269 shaderString.append("varying vec4 varColor;\n");
Alex Sakhartchouk7ffcaf22010-10-06 11:15:01 -0700270 shaderString.append("varying vec2 varTex0;\n");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700271 shaderString.append("void main() {\n");
272 shaderString.append(" gl_Position = UNI_MVP * ATTRIB_position;\n");
273 shaderString.append(" gl_PointSize = 1.0;\n");
274 shaderString.append(" varColor = ATTRIB_color;\n");
275 shaderString.append(" varTex0 = ATTRIB_texture0;\n");
276 shaderString.append("}\n");
277
278 uint32_t tmp[6];
279 tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
280 tmp[1] = (uint32_t)inputType;
281 tmp[2] = RS_PROGRAM_PARAM_INPUT;
282 tmp[3] = (uint32_t)attrElem;
283 tmp[4] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
284 tmp[5] = 0;
285
286 ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
287 shaderString.length(), tmp, 6);
288 Allocation *alloc = new Allocation(rsc, inputType);
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700289 pv->bindAllocation(rsc, alloc, 0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700290
Jason Sams8ce125b2009-06-17 16:52:59 -0700291 mDefaultAlloc.set(alloc);
292 mDefault.set(pv);
Jason Samscfb1d112009-08-05 13:57:03 -0700293
Jason Sams771565f2010-05-14 15:30:29 -0700294 updateSize(rsc);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700295
Jason Samse18844a2009-11-12 16:09:45 -0800296}
297
Jason Sams771565f2010-05-14 15:30:29 -0700298void ProgramVertexState::updateSize(Context *rsc)
Jason Samse18844a2009-11-12 16:09:45 -0800299{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700300 float *f = static_cast<float *>(mDefaultAlloc->getPtr());
301
Jason Sams8ce125b2009-06-17 16:52:59 -0700302 Matrix m;
Jason Sams771565f2010-05-14 15:30:29 -0700303 m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700304 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
305 memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
Jason Sams8ce125b2009-06-17 16:52:59 -0700306
307 m.loadIdentity();
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700308 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m.m, sizeof(m));
309 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m.m, sizeof(m));
Jason Sams8ce125b2009-06-17 16:52:59 -0700310}
Jason Sams326e0dd2009-05-22 14:03:28 -0700311
Jason Samsf2649a92009-09-25 16:37:33 -0700312void ProgramVertexState::deinit(Context *rsc)
313{
314 mDefaultAlloc.clear();
315 mDefault.clear();
Jason Samsf2649a92009-09-25 16:37:33 -0700316 mLast.clear();
Jason Samsf2649a92009-09-25 16:37:33 -0700317}
318
Jason Sams326e0dd2009-05-22 14:03:28 -0700319
320namespace android {
321namespace renderscript {
322
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700323RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText,
Jason Sams4815c0d2009-12-15 12:58:36 -0800324 uint32_t shaderLength, const uint32_t * params,
325 uint32_t paramLength)
Jason Sams326e0dd2009-05-22 14:03:28 -0700326{
Jason Sams4815c0d2009-12-15 12:58:36 -0800327 ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength);
328 pv->incUserRef();
329 return pv;
Jason Samsb5909ce2009-07-21 12:20:54 -0700330}
Jason Sams326e0dd2009-05-22 14:03:28 -0700331
332
333}
334}