OSDN Git Service

Implement flat interpolation qualifier support.
authorAlexis Hetu <sugoi@google.com>
Fri, 20 May 2016 17:01:11 +0000 (13:01 -0400)
committerNicolas Capens <capn@google.com>
Thu, 2 Jun 2016 15:19:20 +0000 (15:19 +0000)
By default vertex shader outputs/fragment shader inputs are
smoothly interpolated. The 'flat' keyword can be used to change
the interpolation to "flat", which basically means that no
interpolation is performed. "flat" is the only interpolation
qualifier accepted for integer types.

This change fixes all shaders/precision dEQP tests as well as a
few fragment output integer format types related tests.

Change-Id: Ic64b0ec40c705d885c255b3b671cf7460965dfee
Reviewed-on: https://swiftshader-review.googlesource.com/5390
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/compiler/OutputASM.cpp
src/OpenGL/compiler/OutputASM.h
src/OpenGL/libGLESv2/Program.cpp
src/Renderer/PixelProcessor.cpp
src/Renderer/SetupProcessor.cpp
src/Shader/Shader.hpp

index 00af34a..511b91e 100644 (file)
@@ -2568,6 +2568,12 @@ namespace glsl
                return sw::Shader::PARAMETER_VOID;
        }
 
+       bool OutputASM::hasFlatQualifier(TIntermTyped *operand)
+       {
+               const TQualifier qualifier = operand->getQualifier();
+               return qualifier == EvqFlat || qualifier == EvqFlatOut || qualifier == EvqFlatIn;
+       }
+
        unsigned int OutputASM::registerIndex(TIntermTyped *operand)
        {
                if(isSamplerRegister(operand))
@@ -2778,10 +2784,12 @@ namespace glsl
                                {
                                        for(int i = 0; i < varying->totalRegisterCount(); i++)
                                        {
-                                               if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
-                                               if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
-                                               if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
-                                               if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i);
+                                               bool flat = hasFlatQualifier(varying);
+
+                                               if(componentCount >= 1) pixelShader->semantic[var + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
+                                               if(componentCount >= 2) pixelShader->semantic[var + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
+                                               if(componentCount >= 3) pixelShader->semantic[var + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
+                                               if(componentCount >= 4) pixelShader->semantic[var + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat);
                                        }
                                }
                        }
index 66d0ce9..34f154a 100644 (file)
@@ -275,6 +275,7 @@ namespace glsl
                void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
                int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
                sw::Shader::ParameterType registerType(TIntermTyped *operand);
+               bool hasFlatQualifier(TIntermTyped *operand);
                unsigned int registerIndex(TIntermTyped *operand);
                int writeMask(TIntermTyped *destination, int index = 0);
                int readSwizzle(TIntermTyped *argument, int size);
index a425920..f32ef70 100644 (file)
@@ -1332,10 +1332,12 @@ namespace es2
 
                                                for(int i = 0; i < registers; i++)
                                                {
-                                                       if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
-                                                       if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
-                                                       if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
-                                                       if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
+                                                       bool flat = pixelBinary->semantic[in + i][0].flat;
+
+                                                       if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
+                                                       if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
+                                                       if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
+                                                       if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, flat);
                                                }
                                        }
                                        else   // Vertex varying is declared but not written to
index e3154b6..a4bf461 100644 (file)
@@ -1075,14 +1075,16 @@ namespace sw
                        {
                                for(int component = 0; component < 4; component++)
                                {
-                                       if(context->pixelShader->semantic[interpolant][component].active())
+                                       const Shader::Semantic &semantic = context->pixelShader->semantic[interpolant][component];
+
+                                       if(semantic.active())
                                        {
                                                bool flat = point;
 
-                                               switch(context->pixelShader->semantic[interpolant][component].usage)
+                                               switch(semantic.usage)
                                                {
-                                               case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
-                                               case Shader::USAGE_COLOR:    flat = flatShading;      break;
+                                               case Shader::USAGE_TEXCOORD: flat = point && !sprite;             break;
+                                               case Shader::USAGE_COLOR:    flat = semantic.flat || flatShading; break;
                                                }
 
                                                state.interpolant[interpolant].component |= 1 << component;
index 9075719..750846f 100644 (file)
@@ -129,13 +129,14 @@ namespace sw
                                for(int component = 0; component < 4; component++)
                                {
                                        int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0;
+                                       const Shader::Semantic& semantic = context->pixelShader->semantic[interpolant][component - project];
 
-                                       if(context->pixelShader->semantic[interpolant][component - project].active())
+                                       if(semantic.active())
                                        {
                                                int input = interpolant;
                                                for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
                                                {
-                                                       if(context->pixelShader->semantic[interpolant][component - project] == context->vertexShader->output[i][component - project])
+                                                       if(semantic == context->vertexShader->output[i][component - project])
                                                        {
                                                                input = i;
                                                                break;
@@ -144,10 +145,10 @@ namespace sw
 
                                                bool flat = point;
 
-                                               switch(context->pixelShader->semantic[interpolant][component - project].usage)
+                                               switch(semantic.usage)
                                                {
-                                               case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
-                                               case Shader::USAGE_COLOR:    flat = flatShading;      break;
+                                               case Shader::USAGE_TEXCOORD: flat = point && !sprite;             break;
+                                               case Shader::USAGE_COLOR:    flat = semantic.flat || flatShading; break;
                                                }
 
                                                state.gradient[interpolant][component].attribute = input;
@@ -162,19 +163,19 @@ namespace sw
                        {
                                for(int component = 0; component < 4; component++)
                                {
-                                       int index = context->pixelShader->semantic[interpolant][component].index;
+                                       const Shader::Semantic& semantic = context->pixelShader->semantic[interpolant][component];
 
-                                       switch(context->pixelShader->semantic[interpolant][component].usage)
+                                       switch(semantic.usage)
                                        {
                                        case 0xFF:
                                                break;
                                        case Shader::USAGE_TEXCOORD:
-                                               state.gradient[interpolant][component].attribute = T0 + index;
-                                               state.gradient[interpolant][component].flat = point && !sprite;
+                                               state.gradient[interpolant][component].attribute = T0 + semantic.index;
+                                               state.gradient[interpolant][component].flat = semantic.flat || (point && !sprite);
                                                break;
                                        case Shader::USAGE_COLOR:
-                                               state.gradient[interpolant][component].attribute = C0 + index;
-                                               state.gradient[interpolant][component].flat = flatShading;
+                                               state.gradient[interpolant][component].attribute = C0 + semantic.index;
+                                               state.gradient[interpolant][component].flat = semantic.flat || flatShading;
                                                break;
                                        default:
                                                ASSERT(false);
index 7e86360..6b93999 100644 (file)
@@ -572,7 +572,7 @@ namespace sw
 
                struct Semantic
                {
-                       Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF) : usage(usage), index(index), centroid(false)
+                       Semantic(unsigned char usage = 0xFF, unsigned char index = 0xFF, bool flat = false) : usage(usage), index(index), centroid(false), flat(flat)
                        {
                        }
 
@@ -589,6 +589,7 @@ namespace sw
                        unsigned char usage;
                        unsigned char index;
                        bool centroid;
+                       bool flat;
                };
 
                void optimize();