summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsProgramVertex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsProgramVertex.cpp')
-rw-r--r--libs/rs/rsProgramVertex.cpp444
1 files changed, 160 insertions, 284 deletions
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index a2b2df4..a28b9bd 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -14,146 +14,59 @@
* limitations under the License.
*/
+#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
-#include "rsProgramVertex.h"
-
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgramVertex.h"
using namespace android;
using namespace android::renderscript;
-ProgramVertex::ProgramVertex(Context *rsc, bool texMat) :
- Program(rsc)
-{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
- mTextureMatrixEnable = texMat;
- mLightCount = 0;
- init(rsc);
-}
-
ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText,
uint32_t shaderLength, const uint32_t * params,
- uint32_t paramLength) :
- Program(rsc, shaderText, shaderLength, params, paramLength)
-{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
- mTextureMatrixEnable = false;
- mLightCount = 0;
-
+ uint32_t paramLength)
+ : Program(rsc, shaderText, shaderLength, params, paramLength) {
init(rsc);
}
-ProgramVertex::~ProgramVertex()
-{
-}
-
-static void logMatrix(const char *txt, const float *f)
-{
- LOGV("Matrix %s, %p", txt, f);
- LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[0], f[4], f[8], f[12]);
- LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[1], f[5], f[9], f[13]);
- LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[2], f[6], f[10], f[14]);
- LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[3], f[7], f[11], f[15]);
-}
-
-void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
-{
- if ((state->mLast.get() == this) && !mDirty) {
- return;
- }
- state->mLast.set(this);
-
- const float *f = static_cast<const float *>(mConstants[0]->getPtr());
-
- glMatrixMode(GL_TEXTURE);
- if (mTextureMatrixEnable) {
- glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
- } else {
- glLoadIdentity();
- }
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- if (mLightCount) {
- int v = 0;
- glEnable(GL_LIGHTING);
- glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v);
- for (uint32_t ct = 0; ct < mLightCount; ct++) {
- const Light *l = mLights[ct].get();
- glEnable(GL_LIGHT0 + ct);
- l->setupGL(ct);
- }
- for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) {
- glDisable(GL_LIGHT0 + ct);
- }
- } else {
- glDisable(GL_LIGHTING);
- }
-
- if (!f) {
- LOGE("Must bind constants to vertex program");
+ProgramVertex::~ProgramVertex() {
+ if (mShaderID) {
+ mRSC->mShaderCache.cleanupVertex(mShaderID);
}
-
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
-
- mDirty = false;
}
void ProgramVertex::loadShader(Context *rsc) {
Program::loadShader(rsc, GL_VERTEX_SHADER);
}
-void ProgramVertex::createShader()
-{
- mShader.setTo("");
-
- mShader.append("varying vec4 varColor;\n");
- mShader.append("varying vec4 varTex0;\n");
-
+void ProgramVertex::createShader(Context *rsc) {
if (mUserShader.length() > 1) {
- mShader.append("uniform mat4 ");
- mShader.append(mUniformNames[0]);
- mShader.append(";\n");
-
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- const Element *e = mConstantTypes[ct]->getElement();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
-
- // Cannot be complex
- rsAssert(!f->getFieldCount());
- switch(f->getComponent().getVectorSize()) {
- case 1: mShader.append("uniform float UNI_"); break;
- case 2: mShader.append("uniform vec2 UNI_"); break;
- case 3: mShader.append("uniform vec3 UNI_"); break;
- case 4: mShader.append("uniform vec4 UNI_"); break;
- default:
- rsAssert(0);
- }
-
- mShader.append(e->getFieldName(field));
- mShader.append(";\n");
- }
- }
+ appendUserConstants();
for (uint32_t ct=0; ct < mInputCount; ct++) {
const Element *e = mInputElements[ct].get();
for (uint32_t field=0; field < e->getFieldCount(); field++) {
const Element *f = e->getField(field);
+ const char *fn = e->getFieldName(field);
+
+ if (fn[0] == '#') {
+ continue;
+ }
// Cannot be complex
rsAssert(!f->getFieldCount());
- switch(f->getComponent().getVectorSize()) {
+ switch (f->getComponent().getVectorSize()) {
case 1: mShader.append("attribute float ATTRIB_"); break;
case 2: mShader.append("attribute vec2 ATTRIB_"); break;
case 3: mShader.append("attribute vec3 ATTRIB_"); break;
@@ -162,149 +75,115 @@ void ProgramVertex::createShader()
rsAssert(0);
}
- mShader.append(e->getFieldName(field));
+ mShader.append(fn);
mShader.append(";\n");
}
}
mShader.append(mUserShader);
} else {
- mShader.append("attribute vec4 ATTRIB_LegacyPosition;\n");
- mShader.append("attribute vec4 ATTRIB_LegacyColor;\n");
- mShader.append("attribute vec3 ATTRIB_LegacyNormal;\n");
- mShader.append("attribute float ATTRIB_LegacyPointSize;\n");
- mShader.append("attribute vec4 ATTRIB_LegacyTexture;\n");
-
- for (uint32_t ct=0; ct < mUniformCount; ct++) {
- mShader.append("uniform mat4 ");
- mShader.append(mUniformNames[ct]);
- mShader.append(";\n");
- }
-
- mShader.append("void main() {\n");
- mShader.append(" gl_Position = UNI_MVP * ATTRIB_LegacyPosition;\n");
- mShader.append(" gl_PointSize = ATTRIB_LegacyPointSize;\n");
-
- mShader.append(" varColor = ATTRIB_LegacyColor;\n");
- if (mTextureMatrixEnable) {
- mShader.append(" varTex0 = UNI_TexMatrix * ATTRIB_LegacyTexture;\n");
- } else {
- mShader.append(" varTex0 = ATTRIB_LegacyTexture;\n");
- }
- //mShader.append(" pos.x = pos.x / 480.0;\n");
- //mShader.append(" pos.y = pos.y / 800.0;\n");
- //mShader.append(" gl_Position = pos;\n");
- mShader.append("}\n");
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "ProgramFragment::createShader cannot create program, shader code not defined");
}
}
-void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc)
-{
- //LOGE("sgl2 vtx1 %x", glGetError());
+void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc) {
if ((state->mLast.get() == this) && !mDirty) {
- //return;
+ return;
}
rsc->checkError("ProgramVertex::setupGL2 start");
- glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]);
-
- const float *f = static_cast<const float *>(mConstants[0]->getPtr());
- Matrix mvp;
- mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
- Matrix t;
- t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
- mvp.multiply(&t);
-
- glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m);
- if (mTextureMatrixEnable) {
- glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE,
- &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
- }
-
- rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
- uint32_t uidx = 1;
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- Allocation *alloc = mConstants[ct+1].get();
- if (!alloc) {
- continue;
+ if (!isUserProgram()) {
+ if (mConstants[0].get() == NULL) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Unable to set fixed function emulation matrices because allocation is missing");
+ return;
}
-
- const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
- const Element *e = mConstantTypes[ct]->getElement();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- uint32_t offset = e->getFieldOffsetBytes(field);
- int32_t slot = sc->vtxUniformSlot(uidx);
-
- const float *fd = reinterpret_cast<const float *>(&data[offset]);
-
- //LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i", slot, offset, ct, field, uidx);
- if (slot >= 0) {
- switch(f->getComponent().getVectorSize()) {
- case 1:
- //LOGE("Uniform 1 = %f", fd[0]);
- glUniform1fv(slot, 1, fd);
- break;
- case 2:
- //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
- glUniform2fv(slot, 1, fd);
- break;
- case 3:
- //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
- glUniform3fv(slot, 1, fd);
- break;
- case 4:
- //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
- glUniform4fv(slot, 1, fd);
- break;
- default:
- rsAssert(0);
- }
- }
- uidx ++;
+ float *f = static_cast<float *>(mConstants[0]->getPtr());
+ Matrix mvp;
+ mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
+ Matrix t;
+ t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
+ mvp.multiply(&t);
+ for (uint32_t i = 0; i < 16; i ++) {
+ f[RS_PROGRAM_VERTEX_MVP_OFFSET + i] = mvp.m[i];
}
}
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- uint32_t glSlot = sc->vtxUniformSlot(ct + 1);
-
- }
+ rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
+ setupUserConstants(rsc, sc, false);
state->mLast.set(this);
rsc->checkError("ProgramVertex::setupGL2");
}
-void ProgramVertex::addLight(const Light *l)
-{
- if (mLightCount < MAX_LIGHTS) {
- mLights[mLightCount].set(l);
- mLightCount++;
+void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const {
+ if (isUserProgram()) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Attempting to set fixed function emulation matrix projection on user program");
+ return;
+ }
+ if (mConstants[0].get() == NULL) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Unable to set fixed function emulation matrix projection because allocation is missing");
+ return;
}
-}
-
-void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
-{
float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
-void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
-{
+void ProgramVertex::setModelviewMatrix(Context *rsc, const rsc_Matrix *m) const {
+ if (isUserProgram()) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Attempting to set fixed function emulation matrix modelview on user program");
+ return;
+ }
+ if (mConstants[0].get() == NULL) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Unable to set fixed function emulation matrix modelview because allocation is missing");
+ return;
+ }
float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
-void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
-{
+void ProgramVertex::setTextureMatrix(Context *rsc, const rsc_Matrix *m) const {
+ if (isUserProgram()) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Attempting to set fixed function emulation matrix texture on user program");
+ return;
+ }
+ if (mConstants[0].get() == NULL) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Unable to set fixed function emulation matrix texture because allocation is missing");
+ return;
+ }
float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
-void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const
-{
+void ProgramVertex::getProjectionMatrix(Context *rsc, rsc_Matrix *m) const {
+ if (isUserProgram()) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Attempting to get fixed function emulation matrix projection on user program");
+ return;
+ }
+ if (mConstants[0].get() == NULL) {
+ rsc->setError(RS_ERROR_FATAL_UNKNOWN,
+ "Unable to get fixed function emulation matrix projection because allocation is missing");
+ return;
+ }
+ float *f = static_cast<float *>(mConstants[0]->getPtr());
+ memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix));
+}
+
+void ProgramVertex::transformToScreen(Context *rsc, float *v4out, const float *v3in) const {
+ if (isUserProgram()) {
+ return;
+ }
float *f = static_cast<float *>(mConstants[0]->getPtr());
Matrix mvp;
mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
@@ -312,94 +191,101 @@ void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const fl
mvp.vectorMultiply(v4out, v3in);
}
-void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
-{
- rsAssert(e->getFieldCount());
- for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
- const Element *ce = e->getField(ct);
- if (ce->getFieldCount()) {
- initAddUserElement(ce, names, count, prefix);
- } else {
- String8 tmp(prefix);
- tmp.append(e->getFieldName(ct));
- names[*count].setTo(tmp.string());
- (*count)++;
- }
- }
-}
-
-
-void ProgramVertex::init(Context *rsc)
-{
- mAttribCount = 0;
+void ProgramVertex::init(Context *rsc) {
+ uint32_t attribCount = 0;
+ uint32_t uniformCount = 0;
if (mUserShader.size() > 0) {
for (uint32_t ct=0; ct < mInputCount; ct++) {
- initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_");
+ initAddUserElement(mInputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
}
-
- mUniformCount = 1;
- mUniformNames[0].setTo("UNI_MVP");
for (uint32_t ct=0; ct < mConstantCount; ct++) {
- initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
+ initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
}
- } else {
- mUniformCount = 2;
- mUniformNames[0].setTo("UNI_MVP");
- mUniformNames[1].setTo("UNI_TexMatrix");
}
+ createShader(rsc);
+}
+
+void ProgramVertex::serialize(OStream *stream) const {
+}
- createShader();
+ProgramVertex *ProgramVertex::createFromStream(Context *rsc, IStream *stream) {
+ return NULL;
}
///////////////////////////////////////////////////////////////////////
-ProgramVertexState::ProgramVertexState()
-{
+ProgramVertexState::ProgramVertexState() {
}
-ProgramVertexState::~ProgramVertexState()
-{
+ProgramVertexState::~ProgramVertexState() {
}
-void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
-{
- RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
-
- rsi_TypeBegin(rsc, e);
- rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
- mAllocType.set((Type *)rsi_TypeCreate(rsc));
+void ProgramVertexState::init(Context *rsc) {
+ const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1);
+ const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
+ const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
+ const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+
+ rsc->mStateElement.elementBuilderBegin();
+ rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1);
+ rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1);
+ rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1);
+ rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1);
+ const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
+
+ rsc->mStateElement.elementBuilderBegin();
+ rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1);
+ rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1);
+ rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1);
+ rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
+ const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
+
+ Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+
+ String8 shaderString(RS_SHADER_INTERNAL);
+ shaderString.append("varying vec4 varColor;\n");
+ shaderString.append("varying vec2 varTex0;\n");
+ shaderString.append("void main() {\n");
+ shaderString.append(" gl_Position = UNI_MVP * ATTRIB_position;\n");
+ shaderString.append(" gl_PointSize = 1.0;\n");
+ shaderString.append(" varColor = ATTRIB_color;\n");
+ shaderString.append(" varTex0 = ATTRIB_texture0;\n");
+ shaderString.append("}\n");
+
+ uint32_t tmp[4];
+ tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
+ tmp[1] = (uint32_t)inputType;
+ tmp[2] = RS_PROGRAM_PARAM_INPUT;
+ tmp[3] = (uint32_t)attrElem;
+
+ ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
+ shaderString.length(), tmp, 4);
+ Allocation *alloc = new Allocation(rsc, inputType);
+ pv->bindAllocation(rsc, alloc, 0);
- ProgramVertex *pv = new ProgramVertex(rsc, false);
- Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get());
mDefaultAlloc.set(alloc);
mDefault.set(pv);
- pv->init(rsc);
- pv->bindAllocation(alloc, 0);
- color[0] = 1.f;
- color[1] = 1.f;
- color[2] = 1.f;
- color[3] = 1.f;
-
- updateSize(rsc, w, h);
+ updateSize(rsc);
}
-void ProgramVertexState::updateSize(Context *rsc, int32_t w, int32_t h)
-{
+void ProgramVertexState::updateSize(Context *rsc) {
+ float *f = static_cast<float *>(mDefaultAlloc->getPtr());
+
Matrix m;
- m.loadOrtho(0,w, h,0, -1,1);
- mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
+ m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
+ memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
+ memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
m.loadIdentity();
- mDefaultAlloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
+ memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m.m, sizeof(m));
+ memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m.m, sizeof(m));
}
-void ProgramVertexState::deinit(Context *rsc)
-{
+void ProgramVertexState::deinit(Context *rsc) {
mDefaultAlloc.clear();
mDefault.clear();
- mAllocType.clear();
mLast.clear();
}
@@ -407,23 +293,13 @@ void ProgramVertexState::deinit(Context *rsc)
namespace android {
namespace renderscript {
-
-RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, bool texMat)
-{
- ProgramVertex *pv = new ProgramVertex(rsc, texMat);
- pv->incUserRef();
- return pv;
-}
-
-RsProgramVertex rsi_ProgramVertexCreate2(Context *rsc, const char * shaderText,
+RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText,
uint32_t shaderLength, const uint32_t * params,
- uint32_t paramLength)
-{
+ uint32_t paramLength) {
ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength);
pv->incUserRef();
return pv;
}
-
}
}