blob: 3fd2981be0baa700006e20b69f4df359125111c1 [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,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080037 uint32_t paramLength)
38 : Program(rsc, shaderText, shaderLength, params, paramLength) {
Jason Sams4815c0d2009-12-15 12:58:36 -080039 init(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -070040}
41
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080042ProgramVertex::~ProgramVertex() {
43 if (mShaderID) {
Alex Sakhartchouk889fe502010-10-01 10:54:06 -070044 mRSC->mShaderCache.cleanupVertex(mShaderID);
45 }
Jason Sams56bc1af2009-06-16 17:49:58 -070046}
47
Jason Samscd506532009-12-15 19:10:11 -080048void ProgramVertex::loadShader(Context *rsc) {
49 Program::loadShader(rsc, GL_VERTEX_SHADER);
Jason Samsc460e552009-11-25 13:22:07 -080050}
51
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080052void ProgramVertex::createShader() {
Jason Samsf2a5d732009-11-30 14:49:55 -080053 if (mUserShader.length() > 1) {
Jason Sams9ebb0c42010-01-12 12:12:28 -080054
Alex Sakhartchouk6e934212010-08-31 12:02:01 -070055 appendUserConstants();
Jason Sams9ebb0c42010-01-12 12:12:28 -080056
Jason Samsb4d35682010-01-04 16:52:27 -080057 for (uint32_t ct=0; ct < mInputCount; ct++) {
58 const Element *e = mInputElements[ct].get();
59 for (uint32_t field=0; field < e->getFieldCount(); field++) {
60 const Element *f = e->getField(field);
Jason Samsbdb04602010-06-17 18:05:38 -070061 const char *fn = e->getFieldName(field);
62
63 if (fn[0] == '#') {
64 continue;
65 }
Jason Samsb4d35682010-01-04 16:52:27 -080066
67 // Cannot be complex
68 rsAssert(!f->getFieldCount());
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080069 switch (f->getComponent().getVectorSize()) {
Jason Samsb4d35682010-01-04 16:52:27 -080070 case 1: mShader.append("attribute float ATTRIB_"); break;
71 case 2: mShader.append("attribute vec2 ATTRIB_"); break;
72 case 3: mShader.append("attribute vec3 ATTRIB_"); break;
73 case 4: mShader.append("attribute vec4 ATTRIB_"); break;
74 default:
75 rsAssert(0);
76 }
77
Jason Samsbdb04602010-06-17 18:05:38 -070078 mShader.append(fn);
Jason Samsb4d35682010-01-04 16:52:27 -080079 mShader.append(";\n");
80 }
81 }
Jason Samsf2a5d732009-11-30 14:49:55 -080082 mShader.append(mUserShader);
Jason Samsc460e552009-11-25 13:22:07 -080083 } else {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -070084 LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
85 rsAssert(0);
Jason Samsc460e552009-11-25 13:22:07 -080086 }
Jason Samsc460e552009-11-25 13:22:07 -080087}
88
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080089void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc) {
Jason Samsc460e552009-11-25 13:22:07 -080090 //LOGE("sgl2 vtx1 %x", glGetError());
91 if ((state->mLast.get() == this) && !mDirty) {
Jason Samse64c2f12010-06-22 17:22:13 -070092 return;
Jason Samsc460e552009-11-25 13:22:07 -080093 }
94
Jason Sams3eb28f02010-01-27 14:41:43 -080095 rsc->checkError("ProgramVertex::setupGL2 start");
Jason Samse9ed6cc2009-12-16 14:13:06 -080096
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080097 if (!isUserProgram()) {
98 if (mConstants[0].get() == NULL) {
Alex Sakhartchouk0bd3c862010-09-27 10:29:47 -070099 LOGE("Unable to set fixed function emulation matrices because allocation is missing");
100 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
101 return;
102 }
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700103 float *f = static_cast<float *>(mConstants[0]->getPtr());
104 Matrix mvp;
105 mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
106 Matrix t;
107 t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
108 mvp.multiply(&t);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800109 for (uint32_t i = 0; i < 16; i ++) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700110 f[RS_PROGRAM_VERTEX_MVP_OFFSET + i] = mvp.m[i];
111 }
Jason Samsc460e552009-11-25 13:22:07 -0800112 }
113
Jason Sams3eb28f02010-01-27 14:41:43 -0800114 rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700115 setupUserConstants(rsc, sc, false);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800116
Jason Samsc460e552009-11-25 13:22:07 -0800117 state->mLast.set(this);
Jason Sams433eca32010-01-06 11:57:52 -0800118 rsc->checkError("ProgramVertex::setupGL2");
Jason Samsc460e552009-11-25 13:22:07 -0800119}
120
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800121void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const {
122 if (isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700123 LOGE("Attempting to set fixed function emulation matrix projection on user program");
124 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader");
125 return;
126 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800127 if (mConstants[0].get() == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700128 LOGE("Unable to set fixed function emulation matrix projection because allocation is missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700129 return;
130 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800131 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Samsc9d43db2009-07-28 12:02:16 -0700132 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
Jason Samscfb1d112009-08-05 13:57:03 -0700133 mDirty = true;
Jason Samsc9d43db2009-07-28 12:02:16 -0700134}
135
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800136void ProgramVertex::setModelviewMatrix(Context *rsc, const rsc_Matrix *m) const {
137 if (isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700138 LOGE("Attempting to set fixed function emulation matrix modelview on user program");
139 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader");
140 return;
141 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800142 if (mConstants[0].get() == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700143 LOGE("Unable to set fixed function emulation matrix modelview because allocation is missing");
144 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700145 return;
146 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800147 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Samsc9d43db2009-07-28 12:02:16 -0700148 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
Jason Samscfb1d112009-08-05 13:57:03 -0700149 mDirty = true;
Jason Samsc9d43db2009-07-28 12:02:16 -0700150}
151
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800152void ProgramVertex::setTextureMatrix(Context *rsc, const rsc_Matrix *m) const {
153 if (isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700154 LOGE("Attempting to set fixed function emulation matrix texture on user program");
155 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set emulation matrix on user shader");
156 return;
157 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800158 if (mConstants[0].get() == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700159 LOGE("Unable to set fixed function emulation matrix texture because allocation is missing");
160 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700161 return;
162 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800163 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Samsc9d43db2009-07-28 12:02:16 -0700164 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
Jason Samscfb1d112009-08-05 13:57:03 -0700165 mDirty = true;
Jason Samsc9d43db2009-07-28 12:02:16 -0700166}
167
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800168void ProgramVertex::getProjectionMatrix(Context *rsc, rsc_Matrix *m) const {
169 if (isUserProgram()) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700170 LOGE("Attempting to get fixed function emulation matrix projection on user program");
171 rsc->setError(RS_ERROR_BAD_SHADER, "Cannot get emulation matrix on user shader");
172 return;
173 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800174 if (mConstants[0].get() == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700175 LOGE("Unable to get fixed function emulation matrix projection because allocation is missing");
176 rsc->setError(RS_ERROR_BAD_SHADER, "Fixed function allocation missing");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700177 return;
178 }
Alex Sakhartchouk95333f92010-08-16 17:40:10 -0700179 float *f = static_cast<float *>(mConstants[0]->getPtr());
180 memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix));
181}
182
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800183void ProgramVertex::transformToScreen(Context *rsc, float *v4out, const float *v3in) const {
184 if (isUserProgram()) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700185 return;
186 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800187 float *f = static_cast<float *>(mConstants[0]->getPtr());
Jason Sams3a97c592009-09-30 17:36:20 -0700188 Matrix mvp;
189 mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
190 (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
191 mvp.vectorMultiply(v4out, v3in);
192}
Jason Sams326e0dd2009-05-22 14:03:28 -0700193
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800194void ProgramVertex::init(Context *rsc) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800195 uint32_t attribCount = 0;
196 uint32_t uniformCount = 0;
Jason Sams433eca32010-01-06 11:57:52 -0800197 if (mUserShader.size() > 0) {
Jason Sams433eca32010-01-06 11:57:52 -0800198 for (uint32_t ct=0; ct < mInputCount; ct++) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800199 initAddUserElement(mInputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800200 }
Jason Sams4c9a2082010-01-13 14:52:46 -0800201 for (uint32_t ct=0; ct < mConstantCount; ct++) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800202 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
Jason Sams433eca32010-01-06 11:57:52 -0800203 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800204 }
Jason Samsc460e552009-11-25 13:22:07 -0800205 createShader();
206}
207
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800208void ProgramVertex::serialize(OStream *stream) const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700209}
210
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800211ProgramVertex *ProgramVertex::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700212 return NULL;
213}
214
Jason Sams4815c0d2009-12-15 12:58:36 -0800215
Jason Samsc460e552009-11-25 13:22:07 -0800216///////////////////////////////////////////////////////////////////////
217
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800218ProgramVertexState::ProgramVertexState() {
Jason Sams326e0dd2009-05-22 14:03:28 -0700219}
220
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800221ProgramVertexState::~ProgramVertexState() {
Jason Sams326e0dd2009-05-22 14:03:28 -0700222}
223
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800224void ProgramVertexState::init(Context *rsc) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700225 const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1);
Alex Sakhartchouk7ffcaf22010-10-06 11:15:01 -0700226 const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700227 const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
228 const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
Jason Sams8287c0c2009-09-24 12:33:45 -0700229
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700230 rsc->mStateElement.elementBuilderBegin();
231 rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1);
232 rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1);
233 rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1);
234 rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1);
235 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
Jason Sams8287c0c2009-09-24 12:33:45 -0700236
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700237 rsc->mStateElement.elementBuilderBegin();
238 rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1);
239 rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1);
240 rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1);
Alex Sakhartchouk7ffcaf22010-10-06 11:15:01 -0700241 rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700242 const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
243
Jason Samsf0c1df42010-10-26 13:09:17 -0700244 Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700245
246 String8 shaderString(RS_SHADER_INTERNAL);
247 shaderString.append("varying vec4 varColor;\n");
Alex Sakhartchouk7ffcaf22010-10-06 11:15:01 -0700248 shaderString.append("varying vec2 varTex0;\n");
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700249 shaderString.append("void main() {\n");
250 shaderString.append(" gl_Position = UNI_MVP * ATTRIB_position;\n");
251 shaderString.append(" gl_PointSize = 1.0;\n");
252 shaderString.append(" varColor = ATTRIB_color;\n");
253 shaderString.append(" varTex0 = ATTRIB_texture0;\n");
254 shaderString.append("}\n");
255
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800256 uint32_t tmp[4];
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700257 tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
258 tmp[1] = (uint32_t)inputType;
259 tmp[2] = RS_PROGRAM_PARAM_INPUT;
260 tmp[3] = (uint32_t)attrElem;
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700261
262 ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800263 shaderString.length(), tmp, 4);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700264 Allocation *alloc = new Allocation(rsc, inputType);
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700265 pv->bindAllocation(rsc, alloc, 0);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700266
Jason Sams8ce125b2009-06-17 16:52:59 -0700267 mDefaultAlloc.set(alloc);
268 mDefault.set(pv);
Jason Samscfb1d112009-08-05 13:57:03 -0700269
Jason Sams771565f2010-05-14 15:30:29 -0700270 updateSize(rsc);
Jason Samse18844a2009-11-12 16:09:45 -0800271}
272
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800273void ProgramVertexState::updateSize(Context *rsc) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700274 float *f = static_cast<float *>(mDefaultAlloc->getPtr());
275
Jason Sams8ce125b2009-06-17 16:52:59 -0700276 Matrix m;
Jason Sams771565f2010-05-14 15:30:29 -0700277 m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700278 memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
279 memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
Jason Sams8ce125b2009-06-17 16:52:59 -0700280
281 m.loadIdentity();
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700282 memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m.m, sizeof(m));
283 memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m.m, sizeof(m));
Jason Sams8ce125b2009-06-17 16:52:59 -0700284}
Jason Sams326e0dd2009-05-22 14:03:28 -0700285
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800286void ProgramVertexState::deinit(Context *rsc) {
Jason Samsf2649a92009-09-25 16:37:33 -0700287 mDefaultAlloc.clear();
288 mDefault.clear();
Jason Samsf2649a92009-09-25 16:37:33 -0700289 mLast.clear();
Jason Samsf2649a92009-09-25 16:37:33 -0700290}
291
Jason Sams326e0dd2009-05-22 14:03:28 -0700292
293namespace android {
294namespace renderscript {
295
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700296RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText,
Jason Sams4815c0d2009-12-15 12:58:36 -0800297 uint32_t shaderLength, const uint32_t * params,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800298 uint32_t paramLength) {
Jason Sams4815c0d2009-12-15 12:58:36 -0800299 ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength);
300 pv->incUserRef();
301 return pv;
Jason Samsb5909ce2009-07-21 12:20:54 -0700302}
Jason Sams326e0dd2009-05-22 14:03:28 -0700303
Jason Sams326e0dd2009-05-22 14:03:28 -0700304}
305}