diff options
author | Alex Sakhartchouk <alexst@google.com> | 2010-11-18 15:22:43 -0800 |
---|---|---|
committer | Alex Sakhartchouk <alexst@google.com> | 2010-11-18 15:27:28 -0800 |
commit | 67f2e442a31b8395e3c1951f8e91139ec7f2be99 (patch) | |
tree | 9e3001eb5181faec98ac13fa85c7915fb8c96c1a /libs/rs | |
parent | 3d019afcdb167a04d9c879285b448f9be1de3c67 (diff) | |
download | frameworks_base-67f2e442a31b8395e3c1951f8e91139ec7f2be99.zip frameworks_base-67f2e442a31b8395e3c1951f8e91139ec7f2be99.tar.gz frameworks_base-67f2e442a31b8395e3c1951f8e91139ec7f2be99.tar.bz2 |
Support for cubemaps.
Change-Id: Iaf6087f614451a8e233b3e5bc49c834ab0ad08ee
Diffstat (limited to 'libs/rs')
-rw-r--r-- | libs/rs/RenderScript.h | 8 | ||||
-rw-r--r-- | libs/rs/java/Samples/res/drawable/cubemap_test.png | bin | 0 -> 2898 bytes | |||
-rw-r--r-- | libs/rs/java/Samples/res/raw/shadercubef.glsl | 8 | ||||
-rw-r--r-- | libs/rs/java/Samples/res/raw/shadercubev.glsl | 10 | ||||
-rw-r--r-- | libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java | 29 | ||||
-rw-r--r-- | libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs | 44 | ||||
-rw-r--r-- | libs/rs/rsAdapter.cpp | 11 | ||||
-rw-r--r-- | libs/rs/rsAllocation.cpp | 143 | ||||
-rw-r--r-- | libs/rs/rsAllocation.h | 5 | ||||
-rw-r--r-- | libs/rs/rsFont.cpp | 4 | ||||
-rw-r--r-- | libs/rs/rsProgram.cpp | 17 | ||||
-rw-r--r-- | libs/rs/rsProgram.h | 2 | ||||
-rw-r--r-- | libs/rs/rsProgramFragment.cpp | 27 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 6 | ||||
-rw-r--r-- | libs/rs/rsSampler.cpp | 25 |
15 files changed, 290 insertions, 49 deletions
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index 20e289d..0ed129f 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -160,6 +160,11 @@ enum RsSamplerValue { RS_SAMPLER_CLAMP }; +enum RsTextureTarget { + RS_TEXTURE_2D, + RS_TEXTURE_CUBE +}; + enum RsDimension { RS_DIMENSION_X, RS_DIMENSION_Y, @@ -218,7 +223,7 @@ enum RsProgramParam { RS_PROGRAM_PARAM_INPUT, RS_PROGRAM_PARAM_OUTPUT, RS_PROGRAM_PARAM_CONSTANT, - RS_PROGRAM_PARAM_TEXTURE_COUNT, + RS_PROGRAM_PARAM_TEXTURE_TYPE, }; enum RsPrimitive { @@ -322,6 +327,7 @@ RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimCount, const RsDimension *dims, const uint32_t *vals); RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype); RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data); +RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data); #ifndef NO_RS_FUNCS #include "rsgApiFuncDecl.h" diff --git a/libs/rs/java/Samples/res/drawable/cubemap_test.png b/libs/rs/java/Samples/res/drawable/cubemap_test.png Binary files differnew file mode 100644 index 0000000..75ad0a4 --- /dev/null +++ b/libs/rs/java/Samples/res/drawable/cubemap_test.png diff --git a/libs/rs/java/Samples/res/raw/shadercubef.glsl b/libs/rs/java/Samples/res/raw/shadercubef.glsl new file mode 100644 index 0000000..15696a4 --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shadercubef.glsl @@ -0,0 +1,8 @@ + +varying vec3 worldNormal; + +void main() { + lowp vec4 col = textureCube(UNI_Tex0, worldNormal); + gl_FragColor = col; +} + diff --git a/libs/rs/java/Samples/res/raw/shadercubev.glsl b/libs/rs/java/Samples/res/raw/shadercubev.glsl new file mode 100644 index 0000000..70f5cd6 --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shadercubev.glsl @@ -0,0 +1,10 @@ +varying vec3 worldNormal; + +// This is where actual shader code begins +void main() { + vec4 worldPos = UNI_model * ATTRIB_position; + gl_Position = UNI_proj * worldPos; + + mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz); + worldNormal = model3 * ATTRIB_normal; +} diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java index f0b69d1..766601b 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java @@ -22,6 +22,8 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.renderscript.*; +import android.renderscript.Allocation.CubemapLayout; +import android.renderscript.Program.TextureType; import android.renderscript.ProgramStore.DepthFunc; import android.renderscript.Sampler.Value; import android.util.Log; @@ -80,6 +82,9 @@ public class RsRenderStatesRS { private ProgramVertex mProgVertexCustom2; private ProgramFragment mProgFragmentCustom2; + private ProgramVertex mProgVertexCube; + private ProgramFragment mProgFragmentCube; + private ProgramRaster mCullBack; private ProgramRaster mCullFront; private ProgramRaster mCullNone; @@ -88,6 +93,7 @@ public class RsRenderStatesRS { private Allocation mTexOpaque; private Allocation mTexTransparent; private Allocation mTexChecker; + private Allocation mTexCube; private Mesh mMbyNMesh; private Mesh mTorus; @@ -240,6 +246,19 @@ public class RsRenderStatesRS { mProgFragmentCustom2 = pfbCustom.create(); mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0); + // Cubemap test shaders + pvbCustom = new ProgramVertex.ShaderBuilder(mRS); + pvbCustom.setShader(mRes, R.raw.shadercubev); + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + pvbCustom.addConstant(mVSConst.getAllocation().getType()); + mProgVertexCube = pvbCustom.create(); + mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0); + + pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + pfbCustom.setShader(mRes, R.raw.shadercubef); + pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE); + mProgFragmentCube = pfbCustom.create(); + pfbCustom = new ProgramFragment.ShaderBuilder(mRS); pfbCustom.setShader(mRes, R.raw.multitexf); pfbCustom.setTextureCount(3); @@ -247,10 +266,11 @@ public class RsRenderStatesRS { mScript.set_gProgVertexCustom(mProgVertexCustom); mScript.set_gProgFragmentCustom(mProgFragmentCustom); - mScript.set_gProgFragmentMultitex(mProgFragmentMultitex); - mScript.set_gProgVertexCustom2(mProgVertexCustom2); mScript.set_gProgFragmentCustom2(mProgFragmentCustom2); + mScript.set_gProgVertexCube(mProgVertexCube); + mScript.set_gProgFragmentCube(mProgFragmentCube); + mScript.set_gProgFragmentMultitex(mProgFragmentMultitex); } private Allocation loadTextureRGB(int id) { @@ -272,11 +292,16 @@ public class RsRenderStatesRS { mTexOpaque = loadTextureRGB(R.drawable.data); mTexTransparent = loadTextureARGB(R.drawable.leaf); mTexChecker = loadTextureRGB(R.drawable.checker); + Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test); + mTexCube = Allocation.createCubemapFromBitmap(mRS, b, Element.RGB_565(mRS), false, + Allocation.CubemapLayout.VERTICAL_FACE_LIST); + mTexCube.uploadToTexture(0); mScript.set_gTexTorus(mTexTorus); mScript.set_gTexOpaque(mTexOpaque); mScript.set_gTexTransparent(mTexTransparent); mScript.set_gTexChecker(mTexChecker); + mScript.set_gTexCube(mTexCube); } private void initFonts() { diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs index f26633d..39b0834 100644 --- a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs +++ b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs @@ -19,7 +19,7 @@ #include "rs_graphics.rsh" #include "shader_def.rsh" -const int gMaxModes = 10; +const int gMaxModes = 11; rs_program_vertex gProgVertex; rs_program_fragment gProgFragmentColor; @@ -34,6 +34,7 @@ rs_allocation gTexOpaque; rs_allocation gTexTorus; rs_allocation gTexTransparent; rs_allocation gTexChecker; +rs_allocation gTexCube; rs_mesh gMbyNMesh; rs_mesh gTorusMesh; @@ -71,6 +72,8 @@ rs_program_vertex gProgVertexCustom; rs_program_fragment gProgFragmentCustom; rs_program_vertex gProgVertexCustom2; rs_program_fragment gProgFragmentCustom2; +rs_program_vertex gProgVertexCube; +rs_program_fragment gProgFragmentCube; rs_program_fragment gProgFragmentMultitex; float gDt = 0; @@ -506,6 +509,42 @@ void displayCustomShaderSamples2() { rsgDrawText("Custom shader sample with array uniforms", 10, rsgGetHeight() - 10); } +void displayCubemapShaderSample() { + // Update vertex shader constants + // Load model matrix + // Aplly a rotation to our mesh + gTorusRotation += 50.0f * gDt; + if (gTorusRotation > 360.0f) { + gTorusRotation -= 360.0f; + } + + // Position our model on the screen + // Position our model on the screen + rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + // Setup the projectioni matrix + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f); + rsAllocationMarkDirty(rsGetAllocation(gFSConstants)); + + rsgBindProgramVertex(gProgVertexCube); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNoneDepth); + rsgBindProgramFragment(gProgFragmentCube); + rsgBindSampler(gProgFragmentCube, 0, gLinearClamp); + rsgBindTexture(gProgFragmentCube, 0, gTexCube); + + // Use back face culling + rsgBindProgramRaster(gCullBack); + rsgDrawMesh(gTorusMesh); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Cubemap shader sample", 10, rsgGetHeight() - 10); +} + void displayMultitextureSample() { bindProgramVertexOrtho(); rs_matrix4x4 matrix; @@ -632,6 +671,9 @@ int root(int launchID) { case 9: displayCustomShaderSamples2(); break; + case 10: + displayCubemapShaderSample(); + break; } return 10; diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp index 2a705a1..8d363fd 100644 --- a/libs/rs/rsAdapter.cpp +++ b/libs/rs/rsAdapter.cpp @@ -143,8 +143,19 @@ void * Adapter2D::getElement(uint32_t x, uint32_t y) const { rsAssert(mAllocation.get()); rsAssert(mAllocation->getPtr()); rsAssert(mAllocation->getType()); + if (mFace != 0 && !mAllocation->getType()->getDimFaces()) { + LOGE("Adapter wants cubemap face, but allocation has none"); + return NULL; + } + uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr()); ptr += mAllocation->getType()->getLODOffset(mLOD, x, y); + + if (mFace != 0) { + uint32_t totalSizeBytes = mAllocation->getType()->getSizeBytes(); + uint32_t faceOffset = totalSizeBytes / 6; + ptr += faceOffset * mFace; + } return ptr; } diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 23135e2..4ade714 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -123,8 +123,22 @@ void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint mTextureGenMipmap = !mType->getDimLOD() && genMipmap; } +uint32_t Allocation::getGLTarget() const { + if (mIsTexture) { + if (mType->getDimFaces()) { + return GL_TEXTURE_CUBE_MAP; + } else { + return GL_TEXTURE_2D; + } + } + if (mIsVertexBuffer) { + return GL_ARRAY_BUFFER; + } + return 0; +} + + void Allocation::uploadToTexture(const Context *rsc) { - //rsAssert(!mTextureId); mIsTexture = true; if (!rsc->checkDriver()) { @@ -155,9 +169,30 @@ void Allocation::uploadToTexture(const Context *rsc) { } isFirstUpload = true; } - glBindTexture(GL_TEXTURE_2D, mTextureID); + + GLenum target = (GLenum)getGLTarget(); + glBindTexture(target, mTextureID); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (target == GL_TEXTURE_2D) { + upload2DTexture(isFirstUpload); + } else if (target == GL_TEXTURE_CUBE_MAP) { + uploadCubeTexture(isFirstUpload); + } + + if (mTextureGenMipmap) { +#ifndef ANDROID_RS_BUILD_FOR_HOST + glGenerateMipmap(target); +#endif //ANDROID_RS_BUILD_FOR_HOST + } + + rsc->checkError("Allocation::uploadToTexture"); +} + +void Allocation::upload2DTexture(bool isFirstUpload) { + GLenum type = mType->getElement()->getComponent().getGLType(); + GLenum format = mType->getElement()->getComponent().getGLFormat(); + Adapter2D adapt(getContext(), this); for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) { adapt.setLOD(lod+mTextureLOD); @@ -169,17 +204,45 @@ void Allocation::uploadToTexture(const Context *rsc) { 0, format, type, ptr); } else { glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0, - adapt.getDimX(), adapt.getDimY(), - format, type, ptr); + adapt.getDimX(), adapt.getDimY(), + format, type, ptr); } } - if (mTextureGenMipmap) { -#ifndef ANDROID_RS_BUILD_FOR_HOST - glGenerateMipmap(GL_TEXTURE_2D); -#endif //ANDROID_RS_BUILD_FOR_HOST - } +} - rsc->checkError("Allocation::uploadToTexture"); +void Allocation::uploadCubeTexture(bool isFirstUpload) { + GLenum type = mType->getElement()->getComponent().getGLType(); + GLenum format = mType->getElement()->getComponent().getGLFormat(); + + GLenum faceOrder[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + }; + + Adapter2D adapt(getContext(), this); + for (uint32_t face = 0; face < 6; face ++) { + adapt.setFace(face); + + for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) { + adapt.setLOD(lod+mTextureLOD); + + uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); + + if (isFirstUpload) { + glTexImage2D(faceOrder[face], lod, format, + adapt.getDimX(), adapt.getDimY(), + 0, format, type, ptr); + } else { + glTexSubImage2D(faceOrder[face], lod, 0, 0, + adapt.getDimX(), adapt.getDimY(), + format, type, ptr); + } + } + } } void Allocation::deferedUploadToBufferObject(const Context *rsc) { @@ -205,10 +268,10 @@ void Allocation::uploadToBufferObject(const Context *rsc) { mUploadDefered = true; return; } - - glBindBuffer(GL_ARRAY_BUFFER, mBufferID); - glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + GLenum target = (GLenum)getGLTarget(); + glBindBuffer(target, mBufferID); + glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW); + glBindBuffer(target, 0); rsc->checkError("Allocation::uploadToBufferObject"); } @@ -816,3 +879,55 @@ RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h return texAlloc; } + +RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data) { + Context *rsc = static_cast<Context *>(con); + const Element *src = static_cast<const Element *>(_src); + const Element *dst = static_cast<const Element *>(_dst); + + // Cubemap allocation's faces should be Width by Width each. + // Source data should have 6 * Width by Width pixels + // Error checking is done in the java layer + RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD, RS_DIMENSION_FACE}; + uint32_t dimValues[] = {w, w, genMips, true}; + RsType type = rsaTypeCreate(rsc, _dst, 4, dims, dimValues); + + RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, type); + Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); + if (texAlloc == NULL) { + LOGE("Memory allocation failure"); + return NULL; + } + + uint8_t *sourcePtr = (uint8_t*)data; + ElementConverter_t cvt = pickConverter(dst, src); + if (cvt) { + for (uint32_t face = 0; face < 6; face ++) { + Adapter2D faceAdapter(rsc, texAlloc); + faceAdapter.setFace(face); + + cvt(faceAdapter.getElement(0, 0), sourcePtr, w * w); + + // Move the data pointer to the next cube face + sourcePtr += w * w * src->getSizeBytes(); + + if (genMips) { + Adapter2D adapt(rsc, texAlloc); + Adapter2D adapt2(rsc, texAlloc); + adapt.setFace(face); + adapt2.setFace(face); + for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { + adapt.setLOD(lod); + adapt2.setLOD(lod + 1); + mip(adapt2, adapt); + } + } + } + } else { + rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format"); + delete texAlloc; + return NULL; + } + + return texAlloc; +} diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index f9a0fc9..5b432f2 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -48,6 +48,8 @@ public: void uploadToTexture(const Context *rsc); uint32_t getTextureID() const {return mTextureID;} + uint32_t getGLTarget() const; + void deferedUploadToBufferObject(const Context *rsc); void uploadToBufferObject(const Context *rsc); uint32_t getBufferObjectID() const {return mBufferID;} @@ -134,7 +136,8 @@ protected: private: void init(Context *rsc, const Type *); - + void upload2DTexture(bool isFirstUpload); + void uploadCubeTexture(bool isFirstUpload); }; } diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index e4d77b2..107022d 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -498,8 +498,8 @@ void FontState::initRenderState() { uint32_t tmp[4]; tmp[0] = RS_PROGRAM_PARAM_CONSTANT; tmp[1] = (uint32_t)inputType; - tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT; - tmp[3] = 1; + tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE; + tmp[3] = RS_TEXTURE_2D; mFontShaderFConstant.set(new Allocation(mRSC, inputType)); ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 1c44e71..39b85e3 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -48,13 +48,14 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { mConstantCount++; } - if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) { - mTextureCount = params[ct+1]; + if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) { + mTextureCount++; } } mTextures = new ObjectBaseRef<Allocation>[mTextureCount]; mSamplers = new ObjectBaseRef<Sampler>[mTextureCount]; + mTextureTargets = new RsTextureTarget[mTextureCount]; mInputElements = new ObjectBaseRef<Element>[mInputCount]; mOutputElements = new ObjectBaseRef<Element>[mOutputCount]; mConstantTypes = new ObjectBaseRef<Type>[mConstantCount]; @@ -63,6 +64,7 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, uint32_t input = 0; uint32_t output = 0; uint32_t constant = 0; + uint32_t texture = 0; for (uint32_t ct=0; ct < paramLength; ct+=2) { if (params[ct] == RS_PROGRAM_PARAM_INPUT) { mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1])); @@ -73,6 +75,9 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1])); } + if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) { + mTextureTargets[texture++] = (RsTextureTarget)params[ct+1]; + } } mIsInternal = false; uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL); @@ -106,6 +111,7 @@ Program::~Program() { } delete[] mTextures; delete[] mSamplers; + delete[] mTextureTargets; delete[] mInputElements; delete[] mOutputElements; delete[] mConstantTypes; @@ -127,6 +133,7 @@ void Program::initMemberVars() { mTextures = NULL; mSamplers = NULL; + mTextureTargets = NULL; mInputElements = NULL; mOutputElements = NULL; mConstantTypes = NULL; @@ -176,6 +183,12 @@ void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) { return; } + if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) { + LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot); + rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot"); + return; + } + //LOGE("bindtex %i %p", slot, a); mTextures[slot].set(a); mDirty = true; diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index b682b97..c48464d 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -105,7 +105,7 @@ protected: // Constants are strictly accessed by programetic loads. ObjectBaseRef<Allocation> *mTextures; ObjectBaseRef<Sampler> *mSamplers; - + RsTextureTarget *mTextureTargets; bool loadShader(Context *, uint32_t type); }; diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 407522b..ffa7d26 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -99,15 +99,20 @@ void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, Shader } mTextures[ct]->uploadCheck(rsc); - glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); + GLenum target = (GLenum)mTextures[ct]->getGLTarget(); + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) { + LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct); + rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader"); + } + glBindTexture(target, mTextures[ct]->getTextureID()); rsc->checkError("ProgramFragment::setupGL2 tex bind"); if (mSamplers[ct].get()) { mSamplers[ct]->setupGL(rsc, mTextures[ct].get()); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); rsc->checkError("ProgramFragment::setupGL2 tex env"); } @@ -130,7 +135,11 @@ void ProgramFragment::createShader() { appendUserConstants(); char buf[256]; for (uint32_t ct=0; ct < mTextureCount; ct++) { - sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct); + if (mTextureTargets[ct] == RS_TEXTURE_2D) { + sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct); + } else { + sprintf(buf, "uniform samplerCube UNI_Tex%i;\n", ct); + } mShader.append(buf); } mShader.append(mUserShader); @@ -191,15 +200,13 @@ void ProgramFragmentState::init(Context *rsc) { Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false); - uint32_t tmp[4]; + uint32_t tmp[2]; tmp[0] = RS_PROGRAM_PARAM_CONSTANT; tmp[1] = (uint32_t)inputType; - tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT; - tmp[3] = 0; Allocation *constAlloc = new Allocation(rsc, inputType); ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), - shaderString.length(), tmp, 4); + shaderString.length(), tmp, 2); pf->bindAllocation(rsc, constAlloc, 0); pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index e165967..3fd2981 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -253,16 +253,14 @@ void ProgramVertexState::init(Context *rsc) { shaderString.append(" varTex0 = ATTRIB_texture0;\n"); shaderString.append("}\n"); - uint32_t tmp[6]; + 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; - tmp[4] = RS_PROGRAM_PARAM_TEXTURE_COUNT; - tmp[5] = 0; ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), - shaderString.length(), tmp, 6); + shaderString.length(), tmp, 4); Allocation *alloc = new Allocation(rsc, inputType); pv->bindAllocation(rsc, alloc, 0); diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp index 1d0d270..54282a8 100644 --- a/libs/rs/rsSampler.cpp +++ b/libs/rs/rsSampler.cpp @@ -71,29 +71,32 @@ void Sampler::setupGL(const Context *rsc, const Allocation *tex) { GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP }; + // This tells us the correct texture type + GLenum target = (GLenum)tex->getGLTarget(); + if (!rsc->ext_OES_texture_npot() && tex->getType()->getIsNp2()) { if (tex->getHasGraphicsMipmaps() && rsc->ext_GL_NV_texture_npot_2D_mipmap()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, transNP[mMagFilter]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, transNP[mWrapS]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, transNP[mWrapT]); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, transNP[mMagFilter]); + glTexParameteri(target, GL_TEXTURE_WRAP_S, transNP[mWrapS]); + glTexParameteri(target, GL_TEXTURE_WRAP_T, transNP[mWrapT]); } else { if (tex->getHasGraphicsMipmaps()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, trans[mWrapS]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, trans[mWrapT]); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]); + glTexParameteri(target, GL_TEXTURE_WRAP_S, trans[mWrapS]); + glTexParameteri(target, GL_TEXTURE_WRAP_T, trans[mWrapT]); } float anisoValue = rsMin(rsc->ext_texture_max_aniso(), mAniso); if (rsc->ext_texture_max_aniso() > 1.0f) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue); + glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue); } rsc->checkError("Sampler::setupGL2 tex env"); |