OpenGL ES environment texture partial implementation Change-Id: I0dcce9f2659cfdde8cc4d5a0a541bea7728b3f97 Reviewed-on: https://swiftshader-review.googlesource.com/1850 Tested-by: Maxime Grégoire <mgregoire@google.com> Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp index 653933e..ba0025a 100644 --- a/src/OpenGL/libGLES_CM/Context.cpp +++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -103,6 +103,8 @@ mState.colorMaskAlpha = true; mState.depthMask = true; + mState.textureEnvMode = GL_MODULATE; + if(shareContext != NULL) { mResourceManager = shareContext->mResourceManager; @@ -1757,7 +1759,9 @@ void Context::applyTextures() { - for(int samplerIndex = 0; samplerIndex < MAX_TEXTURE_UNITS; samplerIndex++) + GLenum texEnvMode = getTextureEnvMode(); + + for(int samplerIndex = 0; samplerIndex < MAX_TEXTURE_UNITS; samplerIndex++) { Texture *texture = getSamplerTexture(samplerIndex, TEXTURE_2D); @@ -1784,29 +1788,57 @@ applyTexture(samplerIndex, texture); - device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE); - device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); - device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0); + sw::TextureStage::StageOperation rgbOperation, alphaOperation; + es2sw::ConvertTextureOperations(texEnvMode, texFormat, &rgbOperation, &alphaOperation); - device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE); - device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); - device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setStageOperation(samplerIndex, rgbOperation); + device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); + device->setFirstModifier(samplerIndex, sw::TextureStage::MODIFIER_COLOR); + device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setSecondModifier(samplerIndex, sw::TextureStage::MODIFIER_COLOR); + + device->setStageOperationAlpha(samplerIndex, alphaOperation); + device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); + device->setFirstModifierAlpha(samplerIndex, sw::TextureStage::MODIFIER_ALPHA); + device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setSecondModifierAlpha(samplerIndex, sw::TextureStage::MODIFIER_ALPHA); } else { applyTexture(samplerIndex, 0); device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); - device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); - device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setFirstModifier(samplerIndex, sw::TextureStage::MODIFIER_COLOR); + device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setSecondModifier(samplerIndex, sw::TextureStage::MODIFIER_COLOR); device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); - device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); - device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setFirstModifierAlpha(samplerIndex, sw::TextureStage::MODIFIER_ALPHA); + device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); + device->setSecondModifierAlpha(samplerIndex, sw::TextureStage::MODIFIER_ALPHA); } } } +void Context::setTextureEnvMode(GLenum texEnvMode) +{ + switch(texEnvMode) + { + case GL_MODULATE: + case GL_DECAL: + case GL_BLEND: + case GL_ADD: + case GL_REPLACE: + mState.textureEnvMode = texEnvMode; + break; + default: + UNREACHABLE(); + } +} + void Context::applyTexture(int index, Texture *baseTexture) { sw::Resource *resource = 0; @@ -2633,6 +2665,11 @@ return mState.activeSampler; } +GLenum Context::getTextureEnvMode() +{ + return mState.textureEnvMode; +} + } // Exported functions for use by EGL
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h index 58af663..cdffd6f 100644 --- a/src/OpenGL/libGLES_CM/Context.h +++ b/src/OpenGL/libGLES_CM/Context.h
@@ -252,6 +252,8 @@ GLint unpackAlignment; GLint packAlignment; + + GLenum textureEnvMode; }; class Context : public egl::Context @@ -326,6 +328,9 @@ GLenum getClientActiveTexture() const; unsigned int getActiveTexture() const; + void setTextureEnvMode(GLenum texEnvMode); + GLenum getTextureEnvMode(); + void setLineWidth(GLfloat width); void setGenerateMipmapHint(GLenum hint);
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp index c4a9283..3cac667 100644 --- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp +++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -3269,7 +3269,85 @@ void GL_APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { - UNIMPLEMENTED(); + es1::Context *context = es1::getContext(); + if(context) + { + switch(target) + { + case GL_POINT_SPRITE_OES: + UNIMPLEMENTED(); + break; + case GL_TEXTURE_ENV: + switch(pname) + { + case GL_TEXTURE_ENV_MODE: + switch((GLenum)param) + { + case GL_REPLACE: + case GL_MODULATE: + case GL_DECAL: + case GL_BLEND: + case GL_ADD: + case GL_COMBINE: + break; + default: + error(GL_INVALID_ENUM); + } + + context->setTextureEnvMode((GLenum)param); + break; + case GL_TEXTURE_ENV_COLOR: + UNIMPLEMENTED(); + break; + case GL_COMBINE_RGB: + switch((GLenum)param) + { + case GL_REPLACE: + UNIMPLEMENTED(); + break; + case GL_MODULATE: + UNIMPLEMENTED(); + break; + case GL_ADD: + context->setTextureEnvMode((GLenum)param); + break; + case GL_ADD_SIGNED: + UNIMPLEMENTED(); + break; + case GL_INTERPOLATE: + UNIMPLEMENTED(); + break; + case GL_SUBTRACT: + UNIMPLEMENTED(); + break; + case GL_DOT3_RGB: + UNIMPLEMENTED(); + break; + case GL_DOT3_RGBA: + UNIMPLEMENTED(); + break; + default: + error(GL_INVALID_ENUM); + } + + break; + case GL_COMBINE_ALPHA: + UNIMPLEMENTED(); + break; + case GL_RGB_SCALE: + UNIMPLEMENTED(); + break; + case GL_ALPHA_SCALE: + UNIMPLEMENTED(); + break; + default: + return error(GL_INVALID_ENUM); + } + break; + default: + return error(GL_INVALID_ENUM); + } + } } void GL_APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) @@ -3279,7 +3357,7 @@ void GL_APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { - UNIMPLEMENTED(); + glTexEnvf(target, pname, (float)param); } void GL_APIENTRY glTexEnvx(GLenum target, GLenum pname, GLfixed param)
diff --git a/src/OpenGL/libGLES_CM/utilities.cpp b/src/OpenGL/libGLES_CM/utilities.cpp index c275089..d91d5ca 100644 --- a/src/OpenGL/libGLES_CM/utilities.cpp +++ b/src/OpenGL/libGLES_CM/utilities.cpp
@@ -467,6 +467,59 @@ default: UNREACHABLE(); return sw::FORMAT_A8R8G8B8; } } + + void ConvertTextureOperations(GLenum texEnvMode, GLenum texFormat, sw::TextureStage::StageOperation *rgbOperation, sw::TextureStage::StageOperation *alphaOperation) + { + switch(texEnvMode) + { + case GL_MODULATE: + switch(texFormat) + { + case GL_LUMINANCE_ALPHA: + *rgbOperation = sw::TextureStage::STAGE_MODULATE; + *alphaOperation = sw::TextureStage::STAGE_MODULATE; + break; + case GL_RGB: + *rgbOperation = sw::TextureStage::STAGE_MODULATE; + *alphaOperation = sw::TextureStage::STAGE_SELECTARG2; + break; + case GL_RGBA: + *rgbOperation = sw::TextureStage::STAGE_MODULATE; + *alphaOperation = sw::TextureStage::STAGE_MODULATE; + break; + case GL_ALPHA: + case GL_LUMINANCE: + UNIMPLEMENTED(); + // Default operations for compatibility + *rgbOperation = sw::TextureStage::STAGE_MODULATE; + *alphaOperation = sw::TextureStage::STAGE_MODULATE; + break; + default: UNREACHABLE(); + } + break; + + case GL_REPLACE: + *rgbOperation = sw::TextureStage::STAGE_SELECTARG1; + *alphaOperation = sw::TextureStage::STAGE_SELECTARG1; + break; + + case GL_ADD: + *rgbOperation = sw::TextureStage::STAGE_ADD; + *alphaOperation = sw::TextureStage::STAGE_SELECTARG1; + break; + + case GL_DECAL: + case GL_BLEND: + // Default operations for compatibility + *rgbOperation = sw::TextureStage::STAGE_MODULATE; + *alphaOperation = sw::TextureStage::STAGE_MODULATE; + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + } + } } namespace sw2es
diff --git a/src/OpenGL/libGLES_CM/utilities.h b/src/OpenGL/libGLES_CM/utilities.h index 4f6421f..c64d600 100644 --- a/src/OpenGL/libGLES_CM/utilities.h +++ b/src/OpenGL/libGLES_CM/utilities.h
@@ -61,6 +61,7 @@ void ConvertMinFilter(GLenum texFilter, sw::FilterType *minFilter, sw::MipmapType *mipFilter, float maxAnisotropy); bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, es1::PrimitiveType &swPrimitiveType, int &primitiveCount); sw::Format ConvertRenderbufferFormat(GLenum format); + void ConvertTextureOperations(GLenum texOperation, GLenum texFormat, sw::TextureStage::StageOperation *rgbOperation, sw::TextureStage::StageOperation *alphaOperation); } namespace sw2es