Added new swizzle parameters to Sampler's state The new parameters are: swizzleR, swizzleG, swizzleB, swizzleA. Also, parameters sent from the context that can be either originating from the Texture object or the Sampler object are now sent from the correct origin. An implementation for the swizzleR, swizzleG, swizzleB, swizzleA parameters was done in SamplerCore. All related dEQP tests pass. Change-Id: I45405a0d241d0e70a91a3c56357c7bc04c7dc75a Reviewed-on: https://swiftshader-review.googlesource.com/4017 Tested-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp index 85f2386..db33e8d 100644 --- a/src/OpenGL/libGLESv2/Context.cpp +++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3061,16 +3061,39 @@ if(texture->isSamplerComplete()) { - GLenum wrapS = texture->getWrapS(); - GLenum wrapT = texture->getWrapT(); - GLenum wrapR = texture->getWrapR(); - GLenum texFilter = texture->getMinFilter(); - GLenum magFilter = texture->getMagFilter(); + GLenum wrapS, wrapT, wrapR, texFilter, magFilter; + + Sampler *samplerObject = mState.sampler[textureUnit]; + if(samplerObject) + { + wrapS = samplerObject->getWrapS(); + wrapT = samplerObject->getWrapT(); + wrapR = samplerObject->getWrapR(); + texFilter = samplerObject->getMinFilter(); + magFilter = samplerObject->getMagFilter(); + } + else + { + wrapS = texture->getWrapS(); + wrapT = texture->getWrapT(); + wrapR = texture->getWrapR(); + texFilter = texture->getMinFilter(); + magFilter = texture->getMagFilter(); + } GLfloat maxAnisotropy = texture->getMaxAnisotropy(); + GLenum swizzleR = texture->getSwizzleR(); + GLenum swizzleG = texture->getSwizzleG(); + GLenum swizzleB = texture->getSwizzleB(); + GLenum swizzleA = texture->getSwizzleA(); + device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR)); + device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR)); + device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG)); + device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB)); + device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA)); sw::FilterType minFilter; sw::MipmapType mipFilter;
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp index 0b28b78..6442993 100644 --- a/src/OpenGL/libGLESv2/utilities.cpp +++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -822,6 +822,22 @@ return sw::ADDRESSING_WRAP; } + sw::SwizzleType ConvertSwizzleType(GLenum swizzleType) + { + switch(swizzleType) + { + case GL_RED: return sw::SWIZZLE_RED; + case GL_GREEN: return sw::SWIZZLE_GREEN; + case GL_BLUE: return sw::SWIZZLE_BLUE; + case GL_ALPHA: return sw::SWIZZLE_ALPHA; + case GL_ZERO: return sw::SWIZZLE_ZERO; + case GL_ONE: return sw::SWIZZLE_ONE; + default: UNREACHABLE(swizzleType); + } + + return sw::SWIZZLE_RED; + }; + sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace) { switch(cullFace)
diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h index 27ff9df..cc1a1d1 100644 --- a/src/OpenGL/libGLESv2/utilities.h +++ b/src/OpenGL/libGLESv2/utilities.h
@@ -68,6 +68,7 @@ sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation); sw::StencilOperation ConvertStencilOp(GLenum stencilOp); sw::AddressingMode ConvertTextureWrap(GLenum wrap); + sw::SwizzleType ConvertSwizzleType(GLenum swizzleType); sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace); unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha); sw::FilterType ConvertMagFilter(GLenum magFilter);
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp index 858772a..0803291 100644 --- a/src/Renderer/PixelProcessor.cpp +++ b/src/Renderer/PixelProcessor.cpp
@@ -416,6 +416,42 @@ else ASSERT(false); } + void PixelProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR) + { + if(sampler < TEXTURE_IMAGE_UNITS) + { + context->sampler[sampler].setSwizzleR(swizzleR); + } + else ASSERT(false); + } + + void PixelProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG) + { + if(sampler < TEXTURE_IMAGE_UNITS) + { + context->sampler[sampler].setSwizzleG(swizzleG); + } + else ASSERT(false); + } + + void PixelProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB) + { + if(sampler < TEXTURE_IMAGE_UNITS) + { + context->sampler[sampler].setSwizzleB(swizzleB); + } + else ASSERT(false); + } + + void PixelProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA) + { + if(sampler < TEXTURE_IMAGE_UNITS) + { + context->sampler[sampler].setSwizzleA(swizzleA); + } + else ASSERT(false); + } + void PixelProcessor::setWriteSRGB(bool sRGB) { context->setWriteSRGB(sRGB);
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp index 310d809..003c43c 100644 --- a/src/Renderer/PixelProcessor.hpp +++ b/src/Renderer/PixelProcessor.hpp
@@ -225,6 +225,10 @@ virtual void setMipmapLOD(unsigned int sampler, float bias); virtual void setBorderColor(unsigned int sampler, const Color<float> &borderColor); virtual void setMaxAnisotropy(unsigned int sampler, float maxAnisotropy); + virtual void setSwizzleR(unsigned int sampler, SwizzleType swizzleR); + virtual void setSwizzleG(unsigned int sampler, SwizzleType swizzleG); + virtual void setSwizzleB(unsigned int sampler, SwizzleType swizzleB); + virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA); virtual void setWriteSRGB(bool sRGB); virtual void setDepthBufferEnable(bool depthBufferEnable);
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp index e17bc11..6e86551 100644 --- a/src/Renderer/Renderer.cpp +++ b/src/Renderer/Renderer.cpp
@@ -2231,6 +2231,54 @@ } } + void Renderer::setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR) + { + if(type == SAMPLER_PIXEL) + { + PixelProcessor::setSwizzleR(sampler, swizzleR); + } + else + { + VertexProcessor::setSwizzleR(sampler, swizzleR); + } + } + + void Renderer::setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG) + { + if(type == SAMPLER_PIXEL) + { + PixelProcessor::setSwizzleG(sampler, swizzleG); + } + else + { + VertexProcessor::setSwizzleG(sampler, swizzleG); + } + } + + void Renderer::setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB) + { + if(type == SAMPLER_PIXEL) + { + PixelProcessor::setSwizzleB(sampler, swizzleB); + } + else + { + VertexProcessor::setSwizzleB(sampler, swizzleB); + } + } + + void Renderer::setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA) + { + if(type == SAMPLER_PIXEL) + { + PixelProcessor::setSwizzleA(sampler, swizzleA); + } + else + { + VertexProcessor::setSwizzleA(sampler, swizzleA); + } + } + void Renderer::setPointSpriteEnable(bool pointSpriteEnable) { context->setPointSpriteEnable(pointSpriteEnable);
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp index 235fc1c..3b85cdb 100644 --- a/src/Renderer/Renderer.hpp +++ b/src/Renderer/Renderer.hpp
@@ -325,6 +325,10 @@ virtual void setMipmapLOD(SamplerType type, int sampler, float bias); virtual void setBorderColor(SamplerType type, int sampler, const Color<float> &borderColor); virtual void setMaxAnisotropy(SamplerType type, int sampler, float maxAnisotropy); + virtual void setSwizzleR(SamplerType type, int sampler, SwizzleType swizzleR); + virtual void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG); + virtual void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB); + virtual void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA); virtual void setPointSpriteEnable(bool pointSpriteEnable); virtual void setPointScaleEnable(bool pointScaleEnable);
diff --git a/src/Renderer/Sampler.cpp b/src/Renderer/Sampler.cpp index f4d5061..93b7134 100644 --- a/src/Renderer/Sampler.cpp +++ b/src/Renderer/Sampler.cpp
@@ -87,6 +87,10 @@ state.mipmapFilter = mipmapFilter(); state.hasNPOTTexture = hasNPOTTexture(); state.sRGB = sRGB && Surface::isSRGBreadable(externalTextureFormat); + state.swizzleR = swizzleR; + state.swizzleG = swizzleG; + state.swizzleB = swizzleB; + state.swizzleA = swizzleA; #if PERF_PROFILE state.compressedFormat = Surface::isCompressed(externalTextureFormat); @@ -303,6 +307,26 @@ texture.maxAnisotropy = maxAnisotropy; } + void Sampler::setSwizzleR(SwizzleType swizzleR) + { + this->swizzleR = swizzleR; + } + + void Sampler::setSwizzleG(SwizzleType swizzleG) + { + this->swizzleG = swizzleG; + } + + void Sampler::setSwizzleB(SwizzleType swizzleB) + { + this->swizzleB = swizzleB; + } + + void Sampler::setSwizzleA(SwizzleType swizzleA) + { + this->swizzleA = swizzleA; + } + void Sampler::setFilterQuality(FilterType maximumFilterQuality) { Sampler::maximumTextureFilterQuality = maximumFilterQuality;
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp index ae8602b..a41bb29 100644 --- a/src/Renderer/Sampler.hpp +++ b/src/Renderer/Sampler.hpp
@@ -113,6 +113,18 @@ ADDRESSING_LAST = ADDRESSING_BORDER }; + enum SwizzleType : unsigned int + { + SWIZZLE_RED, + SWIZZLE_GREEN, + SWIZZLE_BLUE, + SWIZZLE_ALPHA, + SWIZZLE_ZERO, + SWIZZLE_ONE, + + SWIZZLE_LAST = SWIZZLE_ONE + }; + class Sampler { public: @@ -129,6 +141,10 @@ MipmapType mipmapFilter : BITS(FILTER_LAST); bool hasNPOTTexture : 1; bool sRGB : 1; + SwizzleType swizzleR : BITS(SWIZZLE_LAST); + SwizzleType swizzleG : BITS(SWIZZLE_LAST); + SwizzleType swizzleB : BITS(SWIZZLE_LAST); + SwizzleType swizzleA : BITS(SWIZZLE_LAST); #if PERF_PROFILE bool compressedFormat : 1; @@ -152,6 +168,10 @@ void setReadSRGB(bool sRGB); void setBorderColor(const Color<float> &borderColor); void setMaxAnisotropy(float maxAnisotropy); + void setSwizzleR(SwizzleType swizzleR); + void setSwizzleG(SwizzleType swizzleG); + void setSwizzleB(SwizzleType swizzleB); + void setSwizzleA(SwizzleType swizzleA); static void setFilterQuality(FilterType maximumFilterQuality); static void setMipmapQuality(MipmapType maximumFilterQuality); @@ -185,6 +205,10 @@ bool sRGB; bool gather; + SwizzleType swizzleR; + SwizzleType swizzleG; + SwizzleType swizzleB; + SwizzleType swizzleA; Texture texture; float exp2LOD;
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp index ae0be80..d4b9a99 100644 --- a/src/Renderer/VertexProcessor.cpp +++ b/src/Renderer/VertexProcessor.cpp
@@ -545,6 +545,42 @@ else ASSERT(false); } + void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR) + { + if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) + { + context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR); + } + else ASSERT(false); + } + + void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG) + { + if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) + { + context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG); + } + else ASSERT(false); + } + + void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB) + { + if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) + { + context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB); + } + else ASSERT(false); + } + + void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA) + { + if(sampler < VERTEX_TEXTURE_IMAGE_UNITS) + { + context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA); + } + else ASSERT(false); + } + void VertexProcessor::setPointSize(float pointSize) { point.pointSize = replicate(pointSize);
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp index 5d17a91..a8ba461 100644 --- a/src/Renderer/VertexProcessor.hpp +++ b/src/Renderer/VertexProcessor.hpp
@@ -243,6 +243,10 @@ virtual void setMipmapLOD(unsigned int sampler, float bias); virtual void setBorderColor(unsigned int sampler, const Color<float> &borderColor); virtual void setMaxAnisotropy(unsigned int stage, float maxAnisotropy); + virtual void setSwizzleR(unsigned int sampler, SwizzleType swizzleR); + virtual void setSwizzleG(unsigned int sampler, SwizzleType swizzleG); + virtual void setSwizzleB(unsigned int sampler, SwizzleType swizzleB); + virtual void setSwizzleA(unsigned int sampler, SwizzleType swizzleA); virtual void setPointSize(float pointSize); virtual void setPointSizeMin(float pointSizeMin);
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp index b13eb1b..c760ff7 100644 --- a/src/Shader/SamplerCore.cpp +++ b/src/Shader/SamplerCore.cpp
@@ -14,6 +14,37 @@ #include "Constants.hpp" #include "Debug.hpp" +namespace +{ + void applySwizzle(sw::SwizzleType swizzle, sw::Short4& s, const sw::Vector4s& c) + { + switch(swizzle) + { + case sw::SWIZZLE_RED: s = c.x; break; + case sw::SWIZZLE_GREEN: s = c.y; break; + case sw::SWIZZLE_BLUE: s = c.z; break; + case sw::SWIZZLE_ALPHA: s = c.w; break; + case sw::SWIZZLE_ZERO: s = sw::Short4(0x0000, 0x0000, 0x0000, 0x0000); break; + case sw::SWIZZLE_ONE: s = sw::Short4(0x1000, 0x1000, 0x1000, 0x1000); break; + default: ASSERT(false); + } + } + + void applySwizzle(sw::SwizzleType swizzle, sw::Float4& f, const sw::Vector4f& c) + { + switch(swizzle) + { + case sw::SWIZZLE_RED: f = c.x; break; + case sw::SWIZZLE_GREEN: f = c.y; break; + case sw::SWIZZLE_BLUE: f = c.z; break; + case sw::SWIZZLE_ALPHA: f = c.w; break; + case sw::SWIZZLE_ZERO: f = sw::Float4(0.0f, 0.0f, 0.0f, 0.0f); break; + case sw::SWIZZLE_ONE: f = sw::Float4(1.0f, 1.0f, 1.0f, 1.0f); break; + default: ASSERT(false); + } + } +} + namespace sw { SamplerCore::SamplerCore(Pointer<Byte> &constants, const Sampler::State &state) : constants(constants), state(state) @@ -215,6 +246,19 @@ } } } + + if(fixed12 && + ((state.swizzleR != SWIZZLE_RED) || + (state.swizzleG != SWIZZLE_GREEN) || + (state.swizzleB != SWIZZLE_BLUE) || + (state.swizzleA != SWIZZLE_ALPHA))) + { + const Vector4s col(c); + applySwizzle(state.swizzleR, c.x, col); + applySwizzle(state.swizzleG, c.y, col); + applySwizzle(state.swizzleB, c.z, col); + applySwizzle(state.swizzleA, c.w, col); + } } void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool bias, bool gradients, bool lodProvided) @@ -401,6 +445,18 @@ } } } + + if((state.swizzleR != SWIZZLE_RED) || + (state.swizzleG != SWIZZLE_GREEN) || + (state.swizzleB != SWIZZLE_BLUE) || + (state.swizzleA != SWIZZLE_ALPHA)) + { + const Vector4f col(c); + applySwizzle(state.swizzleR, c.x, col); + applySwizzle(state.swizzleG, c.y, col); + applySwizzle(state.swizzleB, c.z, col); + applySwizzle(state.swizzleA, c.w, col); + } } void SamplerCore::border(Short4 &mask, Float4 &coordinates)