OSDN Git Service

gl_VertexID implementation
[android-x86/external-swiftshader.git] / src / OpenGL / compiler / OutputASM.cpp
index d88ce14..2c8222e 100644 (file)
@@ -24,6 +24,8 @@
 #include <GLES2/gl2ext.h>
 #include <GLES3/gl3.h>
 
+#include <stdlib.h>
+
 namespace glsl
 {
        // Integer to TString conversion
@@ -1508,8 +1510,8 @@ namespace glsl
                        if(visit == PostVisit)
                        {
                                TIntermTyped *arg0 = arg[0]->getAsTyped();
-                               TIntermTyped *arg1 = arg[1]->getAsTyped();
-                               ASSERT((arg0->getNominalSize() == arg1->getNominalSize()) && (arg0->getSecondarySize() == arg1->getSecondarySize()));
+                               ASSERT((arg0->getNominalSize() == arg[1]->getAsTyped()->getNominalSize()) &&
+                                      (arg0->getSecondarySize() == arg[1]->getAsTyped()->getSecondarySize()));
 
                                int size = arg0->getNominalSize();
                                for(int i = 0; i < size; i++)
@@ -2169,8 +2171,7 @@ namespace glsl
 
                                if(memberType.getBasicType() == EbtBool)
                                {
-                                       int arraySize = (memberType.isArray() ? memberType.getArraySize() : 1);
-                                       ASSERT(argumentInfo.clampedIndex < arraySize);
+                                       ASSERT(argumentInfo.clampedIndex < (memberType.isArray() ? memberType.getArraySize() : 1)); // index < arraySize
 
                                        // Convert the packed bool, which is currently an int, to a true bool
                                        Instruction *instruction = new Instruction(sw::Shader::OPCODE_I2B);
@@ -2189,9 +2190,8 @@ namespace glsl
                                {
                                        int numCols = memberType.getNominalSize();
                                        int numRows = memberType.getSecondarySize();
-                                       int arraySize = (memberType.isArray() ? memberType.getArraySize() : 1);
 
-                                       ASSERT(argumentInfo.clampedIndex < (numCols * arraySize));
+                                       ASSERT(argumentInfo.clampedIndex < (numCols * (memberType.isArray() ? memberType.getArraySize() : 1))); // index < cols * arraySize
 
                                        unsigned int dstIndex = registerIndex(&unpackedUniform);
                                        unsigned int srcSwizzle = (argumentInfo.clampedIndex % numCols) * 0x55;
@@ -2457,7 +2457,7 @@ namespace glsl
 
                                        dst.type = registerType(left);
                                        dst.index += fieldOffset;
-                                       dst.mask = writeMask(right);
+                                       dst.mask = writeMask(result);
 
                                        return 0xE4;
                                }
@@ -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);
@@ -2944,9 +2946,19 @@ namespace glsl
                TIntermSymbol *symbol = sampler->getAsSymbolNode();
                TIntermBinary *binary = sampler->getAsBinaryNode();
 
-               if(symbol && type.getQualifier() == EvqUniform)
+               if(symbol)
                {
-                       return samplerRegister(symbol);
+                       switch(type.getQualifier())
+                       {
+                       case EvqUniform:
+                               return samplerRegister(symbol);
+                       case EvqIn:
+                       case EvqConstReadOnly:
+                               // Function arguments are not (uniform) sampler registers
+                               return -1;
+                       default:
+                               UNREACHABLE(type.getQualifier());
+                       }
                }
                else if(binary)
                {
@@ -2992,7 +3004,7 @@ namespace glsl
                }
 
                UNREACHABLE(0);
-               return -1;   // Not a sampler register
+               return -1;   // Not a (uniform) sampler register
        }
 
        int OutputASM::samplerRegister(TIntermSymbol *sampler)
@@ -3507,11 +3519,11 @@ namespace glsl
                                TIntermSequence &sequence = init->getSequence();
                                TIntermTyped *variable = sequence[0]->getAsTyped();
 
-                               if(variable && variable->getQualifier() == EvqTemporary)
+                               if(variable && variable->getQualifier() == EvqTemporary && variable->getBasicType() == EbtInt)
                                {
                                        TIntermBinary *assign = variable->getAsBinaryNode();
 
-                                       if(assign->getOp() == EOpInitialize)
+                                       if(assign && assign->getOp() == EOpInitialize)
                                        {
                                                TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode();
                                                TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion();
@@ -3598,14 +3610,32 @@ namespace glsl
                                comparator = EOpLessThan;
                                limit += 1;
                        }
+                       else if(comparator == EOpGreaterThanEqual)
+                       {
+                               comparator = EOpLessThan;
+                               limit -= 1;
+                               std::swap(initial, limit);
+                               increment = -increment;
+                       }
+                       else if(comparator == EOpGreaterThan)
+                       {
+                               comparator = EOpLessThan;
+                               std::swap(initial, limit);
+                               increment = -increment;
+                       }
 
                        if(comparator == EOpLessThan)
                        {
-                               int iterations = (limit - initial) / increment;
+                               if(!(initial < limit))   // Never loops
+                               {
+                                       return 0;
+                               }
+
+                               int iterations = (limit - initial + abs(increment) - 1) / increment;   // Ceiling division
 
-                               if(iterations <= 0)
+                               if(iterations < 0)
                                {
-                                       iterations = 0;
+                                       return ~0u;
                                }
 
                                return iterations;