diff options
Diffstat (limited to 'libs/rs/rsProgramVertex.cpp')
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 444 |
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; } - } } |