OSDN Git Service

gl_VertexID implementation
authorAlexis Hetu <sugoi@google.com>
Tue, 25 Jul 2017 21:48:00 +0000 (17:48 -0400)
committerAlexis Hétu <sugoi@google.com>
Thu, 27 Jul 2017 12:03:16 +0000 (12:03 +0000)
This cl implements support for gl_VertexID.

Passes the functional.shaders.builtin_variable.vertex_id test.

Change-Id: I5550e3ecba30e29f1e38ace608d730833a1e9598
Reviewed-on: https://swiftshader-review.googlesource.com/10958
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
16 files changed:
src/OpenGL/compiler/BaseTypes.h
src/OpenGL/compiler/Initialize.cpp
src/OpenGL/compiler/OutputASM.cpp
src/OpenGL/compiler/ParseHelper.cpp
src/Shader/PixelProgram.cpp
src/Shader/PixelShader.cpp
src/Shader/Shader.cpp
src/Shader/Shader.hpp
src/Shader/VertexPipeline.cpp
src/Shader/VertexPipeline.hpp
src/Shader/VertexProgram.cpp
src/Shader/VertexProgram.hpp
src/Shader/VertexRoutine.cpp
src/Shader/VertexRoutine.hpp
src/Shader/VertexShader.cpp
src/Shader/VertexShader.hpp

index 58c0856..01f9948 100644 (file)
@@ -369,6 +369,7 @@ enum TQualifier : unsigned char
        EvqPosition,
        EvqPointSize,
        EvqInstanceID,
+       EvqVertexID,
 
        // built-ins read by fragment shader
        EvqFragCoord,
@@ -446,6 +447,7 @@ inline const char *getQualifierString(TQualifier qualifier)
        case EvqPosition:       return "Position";       break;
        case EvqPointSize:      return "PointSize";      break;
        case EvqInstanceID:     return "InstanceID";     break;
+       case EvqVertexID:       return "VertexID";       break;
        case EvqFragCoord:      return "FragCoord";      break;
        case EvqFrontFacing:    return "FrontFacing";    break;
        case EvqFragColor:      return "FragColor";      break;
index 1948a57..c374531 100644 (file)
@@ -471,6 +471,7 @@ void IdentifyBuiltIns(GLenum shaderType,
                symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition,    4)));
                symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
                symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
+               symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
                break;
        default: assert(false && "Language not supported");
        }
index 8a84692..2c8222e 100644 (file)
@@ -2554,6 +2554,7 @@ namespace glsl
                case EvqPosition:            return sw::Shader::PARAMETER_OUTPUT;
                case EvqPointSize:           return sw::Shader::PARAMETER_OUTPUT;
                case EvqInstanceID:          return sw::Shader::PARAMETER_MISCTYPE;
+               case EvqVertexID:            return sw::Shader::PARAMETER_MISCTYPE;
                case EvqFragCoord:           return sw::Shader::PARAMETER_MISCTYPE;
                case EvqFrontFacing:         return sw::Shader::PARAMETER_MISCTYPE;
                case EvqPointCoord:          return sw::Shader::PARAMETER_INPUT;
@@ -2606,9 +2607,10 @@ namespace glsl
                case EvqConstReadOnly:       return temporaryRegister(operand);
                case EvqPosition:            return varyingRegister(operand);
                case EvqPointSize:           return varyingRegister(operand);
-               case EvqInstanceID:          vertexShader->declareInstanceId(); return 0;
-               case EvqFragCoord:           pixelShader->declareVPos();  return 0;
-               case EvqFrontFacing:         pixelShader->declareVFace(); return 1;
+               case EvqInstanceID:          vertexShader->declareInstanceId(); return sw::Shader::InstanceIDIndex;
+               case EvqVertexID:            vertexShader->declareVertexId(); return sw::Shader::VertexIDIndex;
+               case EvqFragCoord:           pixelShader->declareVPos();  return sw::Shader::VPosIndex;
+               case EvqFrontFacing:         pixelShader->declareVFace(); return sw::Shader::VFaceIndex;
                case EvqPointCoord:          return varyingRegister(operand);
                case EvqFragColor:           return 0;
                case EvqFragData:            return fragmentOutputRegister(operand);
index 83f58ce..7cca42c 100644 (file)
@@ -406,6 +406,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIn
        case EvqFrontFacing:    message = "can't modify gl_FrontFacing"; break;
        case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
        case EvqInstanceID:     message = "can't modify gl_InstanceID";  break;
+       case EvqVertexID:       message = "can't modify gl_VertexID";    break;
        default:
 
                //
index ecf164f..948f103 100644 (file)
@@ -846,8 +846,8 @@ namespace sw
                        reg = v[2 + i];
                        break;
                case Shader::PARAMETER_MISCTYPE:
-                       if(src.index == 0) reg = vPos;
-                       if(src.index == 1) reg = vFace;
+                       if(src.index == Shader::VPosIndex) reg = vPos;
+                       if(src.index == Shader::VFaceIndex) reg = vFace;
                        break;
                case Shader::PARAMETER_SAMPLER:
                        if(src.rel.type == Shader::PARAMETER_VOID)
index 0b78c14..c659248 100644 (file)
@@ -700,11 +700,11 @@ namespace sw
                                        {
                                                unsigned char index = instruction[i]->dst.index;
 
-                                               if(index == 0)
+                                               if(index == Shader::VPosIndex)
                                                {
                                                        vPosDeclared = true;
                                                }
-                                               else if(index == 1)
+                                               else if(index == Shader::VFaceIndex)
                                                {
                                                        vFaceDeclared = true;
                                                }
index c861069..ff1482e 100644 (file)
@@ -1059,9 +1059,14 @@ namespace sw
                case PARAMETER_LOOP:                    return "aL";
        //      case PARAMETER_TEMPFLOAT16:             return "";
                case PARAMETER_MISCTYPE:
-                       if(index == 0)                          return "vPos";
-                       else if(index == 1)                     return "vFace";
-                       else                                            ASSERT(false);
+                       switch(index)
+                       {
+                       case VPosIndex:                         return "vPos";
+                       case VFaceIndex:                        return "vFace";
+                       case InstanceIDIndex:           return "iID";
+                       case VertexIDIndex:                     return "vID";
+                       default: ASSERT(false);
+                       }
                case PARAMETER_LABEL:                   return "l";
                case PARAMETER_PREDICATE:               return "p0";
                case PARAMETER_FLOAT4LITERAL:   return "";
index f41d514..ee69e8b 100644 (file)
@@ -358,6 +358,14 @@ namespace sw
                        PARAMETER_VOID
                };
 
+               enum MiscParameterIndex
+               {
+                       VPosIndex = 0,
+                       VFaceIndex = 1,
+                       InstanceIDIndex = 2,
+                       VertexIDIndex = 3,
+               };
+
                enum Modifier
                {
                        MODIFIER_NONE,
index 8db3ca0..8792884 100644 (file)
@@ -158,7 +158,7 @@ namespace sw
                return dst;
        }
 
-       void VertexPipeline::pipeline()
+       void VertexPipeline::pipeline(UInt &index)
        {
                Vector4f position;
                Vector4f normal;
index e8b954c..e3c0cbe 100644 (file)
@@ -30,7 +30,7 @@ namespace sw
                virtual ~VertexPipeline();
 
        private:
-               void pipeline() override;
+               void pipeline(UInt &index) override;
                void processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position);
                void processPointSize();
 
index 26d61e0..c9ed8aa 100644 (file)
@@ -64,7 +64,7 @@ namespace sw
                }
        }
 
-       void VertexProgram::pipeline()
+       void VertexProgram::pipeline(UInt& index)
        {
                for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
                {
@@ -73,7 +73,7 @@ namespace sw
 
                if(!state.preTransformed)
                {
-                       program();
+                       program(index);
                }
                else
                {
@@ -81,7 +81,7 @@ namespace sw
                }
        }
 
-       void VertexProgram::program()
+       void VertexProgram::program(UInt& index)
        {
        //      shader->print("VertexShader-%0.8X.txt", state.shaderID);
 
@@ -95,6 +95,21 @@ namespace sw
                        enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
                }
 
+               if(shader->isVertexIdDeclared())
+               {
+                       if(state.textureSampling)
+                       {
+                               vertexID = Int4(index);
+                       }
+                       else
+                       {
+                               vertexID = Insert(vertexID, As<Int>(index), 0);
+                               vertexID = Insert(vertexID, As<Int>(index + 1), 1);
+                               vertexID = Insert(vertexID, As<Int>(index + 2), 2);
+                               vertexID = Insert(vertexID, As<Int>(index + 3), 3);
+                       }
+               }
+
                // Create all call site return blocks up front
                for(size_t i = 0; i < shader->getLength(); i++)
                {
@@ -721,7 +736,15 @@ namespace sw
                        }
                        break;
                case Shader::PARAMETER_MISCTYPE:
-                       reg.x = As<Float>(Int(instanceID));
+                       if(src.index == Shader::InstanceIDIndex)
+                       {
+                               reg.x = As<Float>(instanceID);
+                       }
+                       else if(src.index == Shader::VertexIDIndex)
+                       {
+                               reg.x = As<Float4>(vertexID);
+                       }
+                       else ASSERT(false);
                        return reg;
                default:
                        ASSERT(false);
@@ -861,7 +884,17 @@ namespace sw
                                case Shader::PARAMETER_INPUT:    a = v[src.rel.index][component]; break;
                                case Shader::PARAMETER_OUTPUT:   a = o[src.rel.index][component]; break;
                                case Shader::PARAMETER_CONST:    a = *Pointer<Float>(uniformAddress(src.bufferIndex, src.rel.index) + component * sizeof(float)); break;
-                               case Shader::PARAMETER_MISCTYPE: a = As<Float4>(Int4(instanceID)); break;
+                               case Shader::PARAMETER_MISCTYPE:
+                                       if(src.rel.index == Shader::InstanceIDIndex)
+                                       {
+                                               a = As<Float4>(Int4(instanceID)); break;
+                                       }
+                                       else if(src.rel.index == Shader::VertexIDIndex)
+                                       {
+                                               a = As<Float4>(vertexID); break;
+                                       }
+                                       else ASSERT(false);
+                                       break;
                                default: ASSERT(false);
                                }
 
index bcf4a20..b537af3 100644 (file)
@@ -56,14 +56,15 @@ namespace sw
                Int4 enableLeave;
 
                Int instanceID;
+               Int4 vertexID;
 
                typedef Shader::DestinationParameter Dst;
                typedef Shader::SourceParameter Src;
                typedef Shader::Control Control;
                typedef Shader::Usage Usage;
 
-               void pipeline() override;
-               void program();
+               void pipeline(UInt &index) override;
+               void program(UInt &index);
                void passThrough();
 
                Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
index 42faa80..0f1ccdf 100644 (file)
@@ -62,7 +62,7 @@ namespace sw
                                *Pointer<UInt>(tagCache + tagIndex) = indexQ;
 
                                readInput(indexQ);
-                               pipeline();
+                               pipeline(indexQ);
                                postTransform();
                                computeClipFlags();
 
index dd4bf13..905118b 100644 (file)
@@ -54,7 +54,7 @@ namespace sw
                const VertexProcessor::State &state;
 
        private:
-               virtual void pipeline() = 0;
+               virtual void pipeline(UInt &index) = 0;
 
                typedef VertexProcessor::State::Input Stream;
 
index a98932b..361c76f 100644 (file)
@@ -27,6 +27,7 @@ namespace sw
                positionRegister = Pos;
                pointSizeRegister = Unused;
                instanceIdDeclared = false;
+               vertexIdDeclared = false;
                textureSampling = false;
 
                for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
@@ -48,6 +49,7 @@ namespace sw
                        positionRegister = vs->positionRegister;
                        pointSizeRegister = vs->pointSizeRegister;
                        instanceIdDeclared = vs->instanceIdDeclared;
+                       vertexIdDeclared = vs->vertexIdDeclared;
                        usedSamplers = vs->usedSamplers;
 
                        optimize();
@@ -62,6 +64,7 @@ namespace sw
                positionRegister = Pos;
                pointSizeRegister = Unused;
                instanceIdDeclared = false;
+               vertexIdDeclared = false;
                textureSampling = false;
 
                for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
index 0ca7b93..9a9a0a6 100644 (file)
@@ -45,6 +45,7 @@ namespace sw
                void setPositionRegister(int posReg);
                void setPointSizeRegister(int ptSizeReg);
                void declareInstanceId() { instanceIdDeclared = true; }
+               void declareVertexId() { vertexIdDeclared = true; }
 
                const Semantic& getInput(int inputIdx) const;
                const Semantic& getOutput(int outputIdx, int component) const;
@@ -52,6 +53,7 @@ namespace sw
                int getPositionRegister() const { return positionRegister; }
                int getPointSizeRegister() const { return pointSizeRegister; }
                bool isInstanceIdDeclared() const { return instanceIdDeclared; }
+               bool isVertexIdDeclared() const { return vertexIdDeclared; }
 
        private:
                void analyze();
@@ -68,6 +70,7 @@ namespace sw
                int pointSizeRegister;
 
                bool instanceIdDeclared;
+               bool vertexIdDeclared;
                bool textureSampling;
        };
 }