OSDN Git Service

Enable glsl integer code
authorAlexis Hetu <sugoi@google.com>
Thu, 20 Aug 2015 18:10:33 +0000 (14:10 -0400)
committerAlexis Hétu <sugoi@google.com>
Mon, 31 Aug 2015 14:17:57 +0000 (14:17 +0000)
This cl enables true integer support in glsl shaders.
It still uses floating point registers to store all
registers, regardless of the type, so integer and
unsigned integer variables are simply reinterpreted
as integers or unsigned integers and used as such by
the appropriate instructions.

Change-Id: If62213c917b4b0c907e58db9cd36944dd198beaa
Reviewed-on: https://swiftshader-review.googlesource.com/3910
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
13 files changed:
src/D3D9/D3D9.rc
src/OpenGL/compiler/ConstantUnion.h
src/OpenGL/compiler/OutputASM.cpp
src/OpenGL/compiler/OutputASM.h
src/OpenGL/libGL/libGL.cpp
src/OpenGL/libGLESv2/Context.h
src/OpenGL/libGLESv2/Program.cpp
src/OpenGL/libGLESv2/VertexDataManager.cpp
src/OpenGL/libGLESv2/libGLESv2.cpp
src/Shader/PixelProgram.cpp
src/Shader/ShaderCore.cpp
src/Shader/ShaderCore.hpp
src/Shader/VertexProgram.cpp

index fbd29af..e927519 100644 (file)
@@ -7,7 +7,7 @@
 //
 // Generated from the TEXTINCLUDE 2 resource.
 //
-#include "afxres.h"
+#include "windows.h"
 #include "../Common/Version.h"
 /////////////////////////////////////////////////////////////////////////////
 #undef APSTUDIO_READONLY_SYMBOLS
index d1802c8..e6bec81 100644 (file)
@@ -93,15 +93,16 @@ public:
     float getFConst() const { return fConst; }
     bool getBConst() const { return bConst; }
 
-       float getAsFloat()
+       float getAsFloat() const
        {
                const int FFFFFFFFh = 0xFFFFFFFF;
 
                switch(type)
                {
-        case EbtInt:   return (float)iConst;
+        case EbtInt:   return reinterpret_cast<const float&>(iConst);
+               case EbtUInt:  return reinterpret_cast<const float&>(uConst);
         case EbtFloat: return fConst;
-               case EbtBool:  return (bConst == true) ? (float&)FFFFFFFFh : 0;
+               case EbtBool:  return (bConst == true) ? reinterpret_cast<const float&>(FFFFFFFFh) : 0;
         default:       return 0;
         }
        }
index e722baa..cc7d25e 100644 (file)
@@ -166,6 +166,94 @@ namespace glsl
                free(temporaries, temporary);\r
        }\r
 \r
+       sw::Shader::Opcode OutputASM::getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const\r
+       {\r
+               TBasicType baseType = in->getType().getBasicType();\r
+\r
+               switch(op)\r
+               {\r
+               case sw::Shader::OPCODE_NEG:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_INEG;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               case sw::Shader::OPCODE_ADD:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_IADD;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               case sw::Shader::OPCODE_SUB:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_ISUB;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               case sw::Shader::OPCODE_MUL:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_IMUL;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               case sw::Shader::OPCODE_DIV:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                               return sw::Shader::OPCODE_IDIV;\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_UDIV;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               case sw::Shader::OPCODE_IMOD:\r
+                       return baseType == EbtUInt ? sw::Shader::OPCODE_UMOD : op;\r
+               case sw::Shader::OPCODE_ISHR:\r
+                       return baseType == EbtUInt ? sw::Shader::OPCODE_USHR : op;\r
+               case sw::Shader::OPCODE_MIN:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                               return sw::Shader::OPCODE_IMIN;\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_UMIN;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               case sw::Shader::OPCODE_MAX:\r
+                       switch(baseType)\r
+                       {\r
+                       case EbtInt:\r
+                               return sw::Shader::OPCODE_IMAX;\r
+                       case EbtUInt:\r
+                               return sw::Shader::OPCODE_UMAX;\r
+                       case EbtFloat:\r
+                       default:\r
+                               return op;\r
+                       }\r
+               default:\r
+                       return op;\r
+               }\r
+       }\r
+\r
        void OutputASM::visitSymbol(TIntermSymbol *symbol)\r
        {\r
                // Vertex varyings don't have to be actively used to successfully link\r
@@ -375,23 +463,37 @@ namespace glsl
                                mov->src[0].swizzle = swizzle;\r
                        }\r
                        break;\r
-               case EOpAddAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_ADD, result, left, left, right); break;\r
-               case EOpAdd:       if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_ADD, result, left, right);       break;\r
-               case EOpSubAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_SUB, result, left, left, right); break;\r
-               case EOpSub:       if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_SUB, result, left, right);       break;\r
-               case EOpMulAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_MUL, result, left, left, right); break;\r
-               case EOpMul:       if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_MUL, result, left, right);       break;\r
-               case EOpDivAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_DIV, result, left, left, right); break;\r
-               case EOpDiv:       if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_DIV, result, left, right);       break;\r
+               case EOpAddAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_ADD, result), result, left, left, right); break;\r
+               case EOpAdd:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_ADD, result), result, left, right);       break;\r
+               case EOpSubAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_SUB, result), result, left, left, right); break;\r
+               case EOpSub:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_SUB, result), result, left, right);       break;\r
+               case EOpMulAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_MUL, result), result, left, left, right); break;\r
+               case EOpMul:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_MUL, result), result, left, right);       break;\r
+               case EOpDivAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_DIV, result), result, left, left, right); break;\r
+               case EOpDiv:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_DIV, result), result, left, right);       break;\r
+               case EOpIModAssign:          if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_IMOD, result), result, left, left, right); break;\r
+               case EOpIMod:                if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_IMOD, result), result, left, right);       break;\r
+               case EOpBitShiftLeftAssign:  if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_SHL, result, left, left, right); break;\r
+               case EOpBitShiftLeft:        if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_SHL, result, left, right);       break;\r
+               case EOpBitShiftRightAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_ISHR, result), result, left, left, right); break;\r
+               case EOpBitShiftRight:       if(visit == PostVisit) emitBinary(getOpcode(sw::Shader::OPCODE_ISHR, result), result, left, right);       break;\r
+               case EOpBitwiseAndAssign:    if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_AND, result, left, left, right); break;\r
+               case EOpBitwiseAnd:          if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_AND, result, left, right);       break;\r
+               case EOpBitwiseXorAssign:    if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_XOR, result, left, left, right); break;\r
+               case EOpBitwiseXor:          if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_XOR, result, left, right);       break;\r
+               case EOpBitwiseOrAssign:     if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_OR, result, left, left, right);  break;\r
+               case EOpBitwiseOr:           if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_OR, result, left, right);        break;\r
                case EOpEqual:\r
                        if(visit == PostVisit)\r
                        {\r
-                               emitCmp(sw::Shader::CONTROL_EQ, result, left, right);\r
+                               emitBinary(sw::Shader::OPCODE_EQ, result, left, right);\r
 \r
                                for(int index = 1; index < left->totalRegisterCount(); index++)\r
                                {\r
                                        Temporary equal(this);\r
-                                       emitCmp(sw::Shader::CONTROL_EQ, &equal, left, right, index);\r
+                                       Instruction *eq = emit(sw::Shader::OPCODE_EQ, &equal, left, right);\r
+                                       argument(eq->src[0], left, index);\r
+                                       argument(eq->src[1], right, index);\r
                                        emit(sw::Shader::OPCODE_AND, result, result, &equal);\r
                                }\r
                        }\r
@@ -399,12 +501,14 @@ namespace glsl
                case EOpNotEqual:\r
                        if(visit == PostVisit)\r
                        {\r
-                               emitCmp(sw::Shader::CONTROL_NE, result, left, right);\r
+                               emitBinary(sw::Shader::OPCODE_NE, result, left, right);\r
 \r
                                for(int index = 1; index < left->totalRegisterCount(); index++)\r
                                {\r
                                        Temporary notEqual(this);\r
-                                       emitCmp(sw::Shader::CONTROL_NE, &notEqual, left, right, index);\r
+                                       Instruction *eq = emit(sw::Shader::OPCODE_NE, &notEqual, left, right);\r
+                                       argument(eq->src[0], left, index);\r
+                                       argument(eq->src[1], right, index);\r
                                        emit(sw::Shader::OPCODE_OR, result, result, &notEqual);\r
                                }\r
                        }\r
@@ -413,8 +517,8 @@ namespace glsl
                case EOpGreaterThan:             if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GT, result, left, right); break;\r
                case EOpLessThanEqual:           if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_LE, result, left, right); break;\r
                case EOpGreaterThanEqual:        if(visit == PostVisit) emitCmp(sw::Shader::CONTROL_GE, result, left, right); break;\r
-               case EOpVectorTimesScalarAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_MUL, result, left, left, right); break;\r
-               case EOpVectorTimesScalar:       if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, left, right); break;\r
+               case EOpVectorTimesScalarAssign: if(visit == PostVisit) emitAssign(getOpcode(sw::Shader::OPCODE_MUL, left), result, left, left, right); break;\r
+               case EOpVectorTimesScalar:       if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MUL, left), result, left, right); break;\r
                case EOpMatrixTimesScalar:\r
                        if(visit == PostVisit)\r
                        {\r
@@ -536,24 +640,40 @@ namespace glsl
                        return false;\r
                }\r
 \r
-               Constant one(1.0f, 1.0f, 1.0f, 1.0f);\r
-               Constant rad(1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f);\r
-               Constant deg(5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f);\r
-\r
                TIntermTyped *result = node;\r
                TIntermTyped *arg = node->getOperand();\r
+               TBasicType basicType = arg->getType().getBasicType();\r
+\r
+               union\r
+               {\r
+                       float f;\r
+                       int i;\r
+               } one_value;\r
+\r
+               if(basicType == EbtInt || basicType == EbtUInt)\r
+               {\r
+                       one_value.i = 1;\r
+               }\r
+               else\r
+               {\r
+                       one_value.f = 1.0f;\r
+               }\r
+\r
+               Constant one(one_value.f, one_value.f, one_value.f, one_value.f);\r
+               Constant rad(1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f, 1.74532925e-2f);\r
+               Constant deg(5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f, 5.72957795e+1f);\r
 \r
                switch(node->getOp())\r
                {\r
                case EOpNegative:\r
                        if(visit == PostVisit)\r
                        {\r
+                               sw::Shader::Opcode negOpcode = getOpcode(sw::Shader::OPCODE_NEG, arg);\r
                                for(int index = 0; index < arg->totalRegisterCount(); index++)\r
                                {\r
-                                       Instruction *neg = emit(sw::Shader::OPCODE_MOV, result, arg);\r
+                                       Instruction *neg = emit(negOpcode, result, arg);\r
                                        neg->dst.index += index;\r
                                        argument(neg->src[0], arg, index);\r
-                                       neg->src[0].modifier = sw::Shader::MODIFIER_NEGATE;\r
                                }\r
                        }\r
                        break;\r
@@ -564,9 +684,10 @@ namespace glsl
                        {\r
                                copy(result, arg);\r
 \r
+                               sw::Shader::Opcode addOpcode = getOpcode(sw::Shader::OPCODE_ADD, arg);\r
                                for(int index = 0; index < arg->totalRegisterCount(); index++)\r
                                {\r
-                                       Instruction *add = emit(sw::Shader::OPCODE_ADD, arg, arg, &one);\r
+                                       Instruction *add = emit(addOpcode, arg, arg, &one);\r
                                        add->dst.index += index;\r
                                        argument(add->src[0], arg, index);\r
                                }\r
@@ -579,9 +700,10 @@ namespace glsl
                        {\r
                                copy(result, arg);\r
 \r
+                               sw::Shader::Opcode subOpcode = getOpcode(sw::Shader::OPCODE_SUB, arg);\r
                                for(int index = 0; index < arg->totalRegisterCount(); index++)\r
                                {\r
-                                       Instruction *sub = emit(sw::Shader::OPCODE_SUB, arg, arg, &one);\r
+                                       Instruction *sub = emit(subOpcode, arg, arg, &one);\r
                                        sub->dst.index += index;\r
                                        argument(sub->src[0], arg, index);\r
                                }\r
@@ -592,9 +714,10 @@ namespace glsl
                case EOpPreIncrement:\r
                        if(visit == PostVisit)\r
                        {\r
+                               sw::Shader::Opcode addOpcode = getOpcode(sw::Shader::OPCODE_ADD, arg);\r
                                for(int index = 0; index < arg->totalRegisterCount(); index++)\r
                                {\r
-                                       Instruction *add = emit(sw::Shader::OPCODE_ADD, result, arg, &one);\r
+                                       Instruction *add = emit(addOpcode, result, arg, &one);\r
                                        add->dst.index += index;\r
                                        argument(add->src[0], arg, index);\r
                                }\r
@@ -605,9 +728,10 @@ namespace glsl
                case EOpPreDecrement:\r
                        if(visit == PostVisit)\r
                        {\r
+                               sw::Shader::Opcode subOpcode = getOpcode(sw::Shader::OPCODE_SUB, arg);\r
                                for(int index = 0; index < arg->totalRegisterCount(); index++)\r
                                {\r
-                                       Instruction *sub = emit(sw::Shader::OPCODE_SUB, result, arg, &one);\r
+                                       Instruction *sub = emit(subOpcode, result, arg, &one);\r
                                        sub->dst.index += index;\r
                                        argument(sub->src[0], arg, index);\r
                                }\r
@@ -1064,13 +1188,13 @@ namespace glsl
                case EOpMod:              if(visit == PostVisit) emit(sw::Shader::OPCODE_MOD, result, arg[0], arg[1]); break;\r
                case EOpPow:              if(visit == PostVisit) emit(sw::Shader::OPCODE_POW, result, arg[0], arg[1]); break;\r
                case EOpAtan:             if(visit == PostVisit) emit(sw::Shader::OPCODE_ATAN2, result, arg[0], arg[1]); break;\r
-               case EOpMin:              if(visit == PostVisit) emit(sw::Shader::OPCODE_MIN, result, arg[0], arg[1]); break;\r
-               case EOpMax:              if(visit == PostVisit) emit(sw::Shader::OPCODE_MAX, result, arg[0], arg[1]); break;\r
+               case EOpMin:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, arg[0], arg[1]); break;\r
+               case EOpMax:              if(visit == PostVisit) emit(getOpcode(sw::Shader::OPCODE_MAX, result), result, arg[0], arg[1]); break;\r
                case EOpClamp:\r
                        if(visit == PostVisit)\r
                        {\r
-                               emit(sw::Shader::OPCODE_MAX, result, arg[0], arg[1]);\r
-                               emit(sw::Shader::OPCODE_MIN, result, result, arg[2]);\r
+                               emit(getOpcode(sw::Shader::OPCODE_MAX, result), result, arg[0], arg[1]);\r
+                               emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, result, arg[2]);\r
                        }\r
                        break;\r
                case EOpMix:         if(visit == PostVisit) emit(sw::Shader::OPCODE_LRP, result, arg[2], arg[1], arg[0]); break;\r
@@ -1391,18 +1515,44 @@ namespace glsl
 \r
        Instruction *OutputASM::emitCast(TIntermTyped *dst, TIntermTyped *src)\r
        {\r
-               // Integers are implemented as float\r
-               if((dst->getBasicType() == EbtFloat || dst->getBasicType() == EbtInt) && src->getBasicType() == EbtBool)\r
+               switch(src->getBasicType())\r
                {\r
-                       return emit(sw::Shader::OPCODE_B2F, dst, src);\r
-               }\r
-               if(dst->getBasicType() == EbtBool && (src->getBasicType() == EbtFloat || src->getBasicType() == EbtInt))\r
-               {\r
-                       return emit(sw::Shader::OPCODE_F2B, dst, src);\r
-               }\r
-               if(dst->getBasicType() == EbtInt && src->getBasicType() == EbtFloat)\r
-               {\r
-                       return emit(sw::Shader::OPCODE_TRUNC, dst, src);\r
+               case EbtBool:\r
+                       switch(dst->getBasicType())\r
+                       {\r
+                       case EbtInt:   return emit(sw::Shader::OPCODE_B2I, dst, src);\r
+                       case EbtUInt:  return emit(sw::Shader::OPCODE_B2U, dst, src);\r
+                       case EbtFloat: return emit(sw::Shader::OPCODE_B2F, dst, src);\r
+                       default:       break;\r
+                       }\r
+                       break;\r
+               case EbtInt:\r
+                       switch(dst->getBasicType())\r
+                       {\r
+                       case EbtBool:  return emit(sw::Shader::OPCODE_I2B, dst, src);\r
+                       case EbtFloat: return emit(sw::Shader::OPCODE_I2F, dst, src);\r
+                       default:       break;\r
+                       }\r
+                       break;\r
+               case EbtUInt:\r
+                       switch(dst->getBasicType())\r
+                       {\r
+                       case EbtBool:  return emit(sw::Shader::OPCODE_U2B, dst, src);\r
+                       case EbtFloat: return emit(sw::Shader::OPCODE_U2F, dst, src);\r
+                       default:       break;\r
+                       }\r
+                       break;\r
+               case EbtFloat:\r
+                       switch(dst->getBasicType())\r
+                       {\r
+                       case EbtBool: return emit(sw::Shader::OPCODE_F2B, dst, src);\r
+                       case EbtInt:  return emit(sw::Shader::OPCODE_F2I, dst, src);\r
+                       case EbtUInt: return emit(sw::Shader::OPCODE_F2U, dst, src);\r
+                       default:      break;\r
+                       }\r
+                       break;\r
+               default:\r
+                       break;\r
                }\r
 \r
                return emit(sw::Shader::OPCODE_MOV, dst, src);\r
@@ -1424,8 +1574,20 @@ namespace glsl
 \r
        void OutputASM::emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index)\r
        {\r
-               bool boolean = (left->getAsTyped()->getBasicType() == EbtBool);\r
-               sw::Shader::Opcode opcode = boolean ? sw::Shader::OPCODE_ICMP : sw::Shader::OPCODE_CMP;\r
+               sw::Shader::Opcode opcode;\r
+               switch(left->getAsTyped()->getBasicType())\r
+               {\r
+               case EbtBool:\r
+               case EbtInt:\r
+                       opcode = sw::Shader::OPCODE_ICMP;\r
+                       break;\r
+               case EbtUInt:\r
+                       opcode = sw::Shader::OPCODE_UCMP;\r
+                       break;\r
+               default:\r
+                       opcode = sw::Shader::OPCODE_CMP;\r
+                       break;\r
+               }\r
 \r
                Instruction *cmp = emit(opcode, dst, left, right);\r
                cmp->control = cmpOp;\r
@@ -1745,19 +1907,19 @@ namespace glsl
                                                        if(scale == 1)\r
                                                        {\r
                                                                Constant oldScale((int)dst.rel.scale);\r
-                                                               Instruction *mad = emit(sw::Shader::OPCODE_MAD, &address, &address, &oldScale, right);\r
+                                                               Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);\r
                                                                mad->src[0].index = dst.rel.index;\r
                                                                mad->src[0].type = dst.rel.type;\r
                                                        }\r
                                                        else\r
                                                        {\r
                                                                Constant oldScale((int)dst.rel.scale);\r
-                                                               Instruction *mul = emit(sw::Shader::OPCODE_MUL, &address, &address, &oldScale);\r
+                                                               Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);\r
                                                                mul->src[0].index = dst.rel.index;\r
                                                                mul->src[0].type = dst.rel.type;\r
 \r
                                                                Constant newScale(scale);\r
-                                                               emit(sw::Shader::OPCODE_MAD, &address, right, &newScale, &address);\r
+                                                               emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);\r
                                                        }\r
 \r
                                                        dst.rel.type = sw::Shader::PARAMETER_TEMP;\r
@@ -1768,12 +1930,12 @@ namespace glsl
                                                {\r
                                                        if(scale == 1)\r
                                                        {\r
-                                                               emit(sw::Shader::OPCODE_ADD, &address, &address, right);\r
+                                                               emit(sw::Shader::OPCODE_IADD, &address, &address, right);\r
                                                        }\r
                                                        else\r
                                                        {\r
                                                                Constant newScale(scale);\r
-                                                               emit(sw::Shader::OPCODE_MAD, &address, right, &newScale, &address);\r
+                                                               emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);\r
                                                        }\r
                                                }\r
                                        }\r
@@ -2210,7 +2372,6 @@ namespace glsl
        int OutputASM::attributeRegister(TIntermTyped *attribute)\r
        {\r
                ASSERT(!attribute->isArray());\r
-               ASSERT(attribute->getBasicType() == EbtFloat);\r
 \r
                int index = lookup(attributes, attribute);\r
 \r
index ccee01a..4e3a641 100644 (file)
@@ -175,6 +175,7 @@ namespace glsl
                virtual bool visitLoop(Visit visit, TIntermLoop*);\r
                virtual bool visitBranch(Visit visit, TIntermBranch*);\r
 \r
+               sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;\r
                Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, int index = 0);\r
                Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);\r
                void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);\r
index 9b4516a..0aa62f4 100644 (file)
@@ -2994,9 +2994,9 @@ void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype
        case GL_LOW_INT:\r
        case GL_MEDIUM_INT:\r
        case GL_HIGH_INT:\r
-               // Single-precision floating-point numbers can accurately represent integers up to +/-16777216\r
-               range[0] = 24;\r
-               range[1] = 24;\r
+               // Full integer precision is supported\r
+               range[0] = 31;\r
+               range[1] = 30;\r
                *precision = 0;\r
                break;\r
        default:\r
index 87209a1..6e4240d 100644 (file)
@@ -169,7 +169,12 @@ public:
         return mStride ? mStride : typeSize();\r
     }\r
 \r
-       inline float getCurrentValue(int i) const\r
+       inline float getCurrentValueBitsAsFloat(int i) const\r
+       {\r
+               return mCurrentValue[i].f;\r
+       }\r
+\r
+       inline float getCurrentValueF(int i) const\r
        {\r
                switch(mCurrentValueType)\r
                {\r
index 13e7103..18fa089 100644 (file)
@@ -2192,11 +2192,11 @@ namespace es2
 \r
        bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[i];\r
+                       vector[i][0] = v[i];\r
                        vector[i][1] = 0;\r
                        vector[i][2] = 0;\r
                        vector[i][3] = 0;\r
@@ -2251,12 +2251,12 @@ namespace es2
 \r
        bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[0];\r
-                       vector[i][1] = (float)v[1];\r
+                       vector[i][0] = v[0];\r
+                       vector[i][1] = v[1];\r
                        vector[i][2] = 0;\r
                        vector[i][3] = 0;\r
 \r
@@ -2280,13 +2280,13 @@ namespace es2
 \r
        bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[0];\r
-                       vector[i][1] = (float)v[1];\r
-                       vector[i][2] = (float)v[2];\r
+                       vector[i][0] = v[0];\r
+                       vector[i][1] = v[1];\r
+                       vector[i][2] = v[2];\r
                        vector[i][3] = 0;\r
 \r
                        v += 3;\r
@@ -2309,14 +2309,14 @@ namespace es2
 \r
        bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[0];\r
-                       vector[i][1] = (float)v[1];\r
-                       vector[i][2] = (float)v[2];\r
-                       vector[i][3] = (float)v[3];\r
+                       vector[i][0] = v[0];\r
+                       vector[i][1] = v[1];\r
+                       vector[i][2] = v[2];\r
+                       vector[i][3] = v[3];\r
 \r
                        v += 4;\r
                }\r
@@ -2338,11 +2338,11 @@ namespace es2
 \r
        bool Program::applyUniform1uiv(GLint location, GLsizei count, const GLuint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLuint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[i];\r
+                       vector[i][0] = v[i];\r
                        vector[i][1] = 0;\r
                        vector[i][2] = 0;\r
                        vector[i][3] = 0;\r
@@ -2397,12 +2397,12 @@ namespace es2
 \r
        bool Program::applyUniform2uiv(GLint location, GLsizei count, const GLuint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLuint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[0];\r
-                       vector[i][1] = (float)v[1];\r
+                       vector[i][0] = v[0];\r
+                       vector[i][1] = v[1];\r
                        vector[i][2] = 0;\r
                        vector[i][3] = 0;\r
 \r
@@ -2426,13 +2426,13 @@ namespace es2
 \r
        bool Program::applyUniform3uiv(GLint location, GLsizei count, const GLuint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLuint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[0];\r
-                       vector[i][1] = (float)v[1];\r
-                       vector[i][2] = (float)v[2];\r
+                       vector[i][0] = v[0];\r
+                       vector[i][1] = v[1];\r
+                       vector[i][2] = v[2];\r
                        vector[i][3] = 0;\r
 \r
                        v += 3;\r
@@ -2455,14 +2455,14 @@ namespace es2
 \r
        bool Program::applyUniform4uiv(GLint location, GLsizei count, const GLuint *v)\r
        {\r
-               float vector[MAX_UNIFORM_VECTORS][4];\r
+               GLuint vector[MAX_UNIFORM_VECTORS][4];\r
 \r
                for(int i = 0; i < count; i++)\r
                {\r
-                       vector[i][0] = (float)v[0];\r
-                       vector[i][1] = (float)v[1];\r
-                       vector[i][2] = (float)v[2];\r
-                       vector[i][3] = (float)v[3];\r
+                       vector[i][0] = v[0];\r
+                       vector[i][1] = v[1];\r
+                       vector[i][2] = v[2];\r
+                       vector[i][3] = v[3];\r
 \r
                        v += 4;\r
                }\r
index 7bda77f..51aa4fb 100644 (file)
@@ -200,7 +200,7 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
                 if(mDirtyCurrentValue[i])\r
                 {\r
                     delete mCurrentValueBuffer[i];\r
-                    mCurrentValueBuffer[i] = new ConstantVertexBuffer(attrib.getCurrentValue(0), attrib.getCurrentValue(1), attrib.getCurrentValue(2), attrib.getCurrentValue(3));\r
+                    mCurrentValueBuffer[i] = new ConstantVertexBuffer(attrib.getCurrentValueBitsAsFloat(0), attrib.getCurrentValueBitsAsFloat(1), attrib.getCurrentValueBitsAsFloat(2), attrib.getCurrentValueBitsAsFloat(3));\r
                     mDirtyCurrentValue[i] = false;\r
                 }\r
 \r
index 2aea581..311037b 100644 (file)
@@ -3582,9 +3582,9 @@ void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* ra
        case GL_LOW_INT:\r
        case GL_MEDIUM_INT:\r
        case GL_HIGH_INT:\r
-               // Single-precision floating-point numbers can accurately represent integers up to +/-16777216\r
-               range[0] = 24;\r
-               range[1] = 24;\r
+               // Full integer precision is supported\r
+               range[0] = 31;\r
+               range[1] = 30;\r
                *precision = 0;\r
                break;\r
        default:\r
@@ -4155,7 +4155,7 @@ void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
                                const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];\r
                                for(int i = 0; i < 4; ++i)\r
                                {\r
-                                       params[i] = attrib.getCurrentValue(i);\r
+                                       params[i] = attrib.getCurrentValueF(i);\r
                                }\r
                        }\r
                        break;\r
@@ -4228,7 +4228,7 @@ void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
                                const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];\r
                                for(int i = 0; i < 4; ++i)\r
                                {\r
-                                       float currentValue = attrib.getCurrentValue(i);\r
+                                       float currentValue = attrib.getCurrentValueF(i);\r
                                        params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));\r
                                }\r
                        }\r
index 415117d..9b5673d 100644 (file)
@@ -760,7 +760,7 @@ namespace sw
                        }
                        else if(src.rel.type == Shader::PARAMETER_TEMP)
                        {
-                               reg.x = As<Float4>(Int4(i) + RoundInt(r.rf[src.rel.index].x));
+                               reg.x = As<Float4>(Int4(i) + As<Int4>(r.rf[src.rel.index].x));
                        }
                        return reg;
                case Shader::PARAMETER_PREDICATE:   return reg; // Dummy
@@ -898,21 +898,21 @@ namespace sw
 
                if(var.rel.type == Shader::PARAMETER_TEMP)
                {
-                       return RoundInt(Extract(r.rf[var.rel.index].x, 0)) * var.rel.scale;
+                       return As<Int>(Extract(r.rf[var.rel.index].x, 0)) * var.rel.scale;
                }
                else if(var.rel.type == Shader::PARAMETER_INPUT)
                {
-                       return RoundInt(Extract(r.vf[var.rel.index].x, 0)) * var.rel.scale;
+                       return As<Int>(Extract(r.vf[var.rel.index].x, 0)) * var.rel.scale;
                }
                else if(var.rel.type == Shader::PARAMETER_OUTPUT)
                {
-                       return RoundInt(Extract(r.oC[var.rel.index].x, 0)) * var.rel.scale;
+                       return As<Int>(Extract(r.oC[var.rel.index].x, 0)) * var.rel.scale;
                }
                else if(var.rel.type == Shader::PARAMETER_CONST)
                {
-                       RValue<Float4> c = *Pointer<Float4>(r.data + OFFSET(DrawData, ps.c[var.rel.index]));
+                       RValue<Int4> c = *Pointer<Int4>(r.data + OFFSET(DrawData, ps.c[var.rel.index]));
 
-                       return RoundInt(Extract(c, 0)) * var.rel.scale;
+                       return Extract(c, 0) * var.rel.scale;
                }
                else ASSERT(false);
 
index 17659cf..406b038 100644 (file)
@@ -583,11 +583,14 @@ namespace sw
                }
        }
 
-       void ShaderCore::mov(Vector4f &dst, const Vector4f &src, bool floorToInteger)
+       void ShaderCore::mov(Vector4f &dst, const Vector4f &src, bool integerDestination)
        {
-               if(floorToInteger)
+               if(integerDestination)
                {
-                       dst.x = Floor(src.x);
+                       dst.x = As<Float4>(RoundInt(src.x));
+                       dst.y = As<Float4>(RoundInt(src.y));
+                       dst.z = As<Float4>(RoundInt(src.z));
+                       dst.w = As<Float4>(RoundInt(src.w));
                }
                else
                {
index 3432eab..c3308aa 100644 (file)
@@ -238,7 +238,7 @@ namespace sw
                typedef Shader::Control Control;\r
 \r
        public:\r
-               void mov(Vector4f &dst, const Vector4f &src, bool floorToInteger = false);\r
+               void mov(Vector4f &dst, const Vector4f &src, bool integerDestination = false);\r
                void neg(Vector4f &dst, const Vector4f &src);\r
                void ineg(Vector4f &dst, const Vector4f &src);\r
                void f2b(Vector4f &dst, const Vector4f &src);\r
index eaa5b12..35581af 100644 (file)
@@ -188,7 +188,7 @@ namespace sw
                        case Shader::OPCODE_IMIN:       imin(d, s0, s1);                break;
                        case Shader::OPCODE_UMIN:       umin(d, s0, s1);                break;
                        case Shader::OPCODE_MOV:                mov(d, s0, integer);                    break;
-                       case Shader::OPCODE_MOVA:               mov(d, s0);                                             break;
+                       case Shader::OPCODE_MOVA:       mov(d, s0, true);               break;
                        case Shader::OPCODE_NEG:        neg(d, s0);                     break;
                        case Shader::OPCODE_INEG:       ineg(d, s0);                    break;
                        case Shader::OPCODE_F2B:                f2b(d, s0);                                             break;
@@ -680,7 +680,7 @@ namespace sw
                        }
                        else if(src.rel.type == Shader::PARAMETER_TEMP)
                        {
-                               reg.x = As<Float4>(Int4(i) + RoundInt(r.r[src.rel.index].x));
+                               reg.x = As<Float4>(Int4(i) + As<Int4>(r.r[src.rel.index].x));
                        }
                        return reg;
                case Shader::PARAMETER_OUTPUT:
@@ -694,7 +694,7 @@ namespace sw
                        }
                        break;
                case Shader::PARAMETER_MISCTYPE:
-                       reg.x = Float(r.instanceID);
+                       reg.x = As<Float>(Int(r.instanceID));
                        return reg;
                default:
                        ASSERT(false);
@@ -821,7 +821,7 @@ namespace sw
                                default: ASSERT(false);
                                }
 
-                               Int4 index = Int4(i) + RoundInt(a) * Int4(src.rel.scale);
+                               Int4 index = Int4(i) + As<Int4>(a) * Int4(src.rel.scale);
 
                                index = Min(As<UInt4>(index), UInt4(256));   // Clamp to constant register range, c[256] = {0, 0, 0, 0}
                                
@@ -848,21 +848,21 @@ namespace sw
 
                if(var.rel.type == Shader::PARAMETER_TEMP)
                {
-                       return RoundInt(Extract(r.r[var.rel.index].x, 0)) * var.rel.scale;
+                       return As<Int>(Extract(r.r[var.rel.index].x, 0)) * var.rel.scale;
                }
                else if(var.rel.type == Shader::PARAMETER_INPUT)
                {
-                       return RoundInt(Extract(r.v[var.rel.index].x, 0)) * var.rel.scale;
+                       return As<Int>(Extract(r.v[var.rel.index].x, 0)) * var.rel.scale;
                }
                else if(var.rel.type == Shader::PARAMETER_OUTPUT)
                {
-                       return RoundInt(Extract(r.o[var.rel.index].x, 0)) * var.rel.scale;
+                       return As<Int>(Extract(r.o[var.rel.index].x, 0)) * var.rel.scale;
                }
                else if(var.rel.type == Shader::PARAMETER_CONST)
                {
-                       RValue<Float4> c = *Pointer<Float4>(r.data + OFFSET(DrawData,vs.c[var.rel.index]));
+                       RValue<Int4> c = *Pointer<Int4>(r.data + OFFSET(DrawData, vs.c[var.rel.index]));
 
-                       return RoundInt(Extract(c, 0)) * var.rel.scale;
+                       return Extract(c, 0) * var.rel.scale;
                }
                else ASSERT(false);