OSDN Git Service

Fix for the remaining vertex array issues
authorAlexis Hetu <sugoi@google.com>
Thu, 22 Sep 2016 19:36:45 +0000 (15:36 -0400)
committerAlexis Hétu <sugoi@google.com>
Mon, 26 Sep 2016 19:15:08 +0000 (19:15 +0000)
Fixes all failures in dEQP.functional.vertex_arrays.*

In OpenGL ES 3.0, vertex attributes streams can be of a
different type from the vertex attribute in the shader.
For this reason, some conversion may be required. This
cl solves this issue by:
1) Sending the information about the vertex attribute's
   type in the shader to the vertex routine.
2) Handling this information by adding conversion where
   appropriate.

Change-Id: I04a5a34aea12684209e584aa5f15a3edfd57f956
Reviewed-on: https://swiftshader-review.googlesource.com/7254
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/compiler/OutputASM.cpp
src/Renderer/VertexProcessor.cpp
src/Renderer/VertexProcessor.hpp
src/Shader/VertexRoutine.cpp
src/Shader/VertexShader.cpp
src/Shader/VertexShader.hpp

index 29da8e4..4cc379a 100644 (file)
@@ -2890,12 +2890,25 @@ namespace glsl
                                index = allocate(attributes, attribute);
                                const TType &type = attribute->getType();
                                int registerCount = attribute->totalRegisterCount();
+                               sw::VertexShader::AttribType attribType = sw::VertexShader::ATTRIBTYPE_FLOAT;
+                               switch(type.getBasicType())
+                               {
+                               case EbtInt:
+                                       attribType = sw::VertexShader::ATTRIBTYPE_INT;
+                                       break;
+                               case EbtUInt:
+                                       attribType = sw::VertexShader::ATTRIBTYPE_UINT;
+                                       break;
+                               case EbtFloat:
+                               default:
+                                       break;
+                               }
 
                                if(vertexShader && (index + registerCount) <= sw::MAX_VERTEX_INPUTS)
                                {
                                        for(int i = 0; i < registerCount; i++)
                                        {
-                                               vertexShader->setInput(index + i, sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, index + i));
+                                               vertexShader->setInput(index + i, sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, index + i, false), attribType);
                                        }
                                }
 
index ced0870..a64c010 100644 (file)
@@ -958,6 +958,7 @@ namespace sw
                        state.input[i].type = context->input[i].type;
                        state.input[i].count = context->input[i].count;
                        state.input[i].normalized = context->input[i].normalized;
+                       state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
                }
 
                if(!context->vertexShader)
index f0cf124..278c9b1 100644 (file)
@@ -18,6 +18,7 @@
 #include "Matrix.hpp"
 #include "Context.hpp"
 #include "RoutineCache.hpp"
+#include "Shader/VertexShader.hpp"
 
 namespace sw
 {
@@ -102,6 +103,7 @@ namespace sw
                                StreamType type    : BITS(STREAMTYPE_LAST);
                                unsigned int count : 3;
                                bool normalized    : 1;
+                               unsigned int attribType : BITS(VertexShader::ATTRIBTYPE_LAST);
                        };
 
                        struct Output
index c67a8bc..087e481 100644 (file)
@@ -148,6 +148,8 @@ namespace sw
                Pointer<Byte> source2 = source1 + (!textureSampling ? stride : 0);
                Pointer<Byte> source3 = source2 + (!textureSampling ? stride : 0);
 
+               bool isNativeFloatAttrib = (stream.attribType == VertexShader::ATTRIBTYPE_FLOAT) || stream.normalized;
+
                switch(stream.type)
                {
                case STREAMTYPE_FLOAT:
@@ -156,25 +158,47 @@ namespace sw
                                {
                                        // Null stream, all default components
                                }
-                               else if(stream.count == 1)
-                               {
-                                       v.x.x = *Pointer<Float>(source0);
-                                       v.x.y = *Pointer<Float>(source1);
-                                       v.x.z = *Pointer<Float>(source2);
-                                       v.x.w = *Pointer<Float>(source3);
-                               }
                                else
                                {
-                                       v.x = *Pointer<Float4>(source0);
-                                       v.y = *Pointer<Float4>(source1);
-                                       v.z = *Pointer<Float4>(source2);
-                                       v.w = *Pointer<Float4>(source3);
+                                       if(stream.count == 1)
+                                       {
+                                               v.x.x = *Pointer<Float>(source0);
+                                               v.x.y = *Pointer<Float>(source1);
+                                               v.x.z = *Pointer<Float>(source2);
+                                               v.x.w = *Pointer<Float>(source3);
+                                       }
+                                       else
+                                       {
+                                               v.x = *Pointer<Float4>(source0);
+                                               v.y = *Pointer<Float4>(source1);
+                                               v.z = *Pointer<Float4>(source2);
+                                               v.w = *Pointer<Float4>(source3);
 
-                                       transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                                       }
+
+                                       switch(stream.attribType)
+                                       {
+                                       case VertexShader::ATTRIBTYPE_INT:
+                                               if(stream.count >= 1) v.x = As<Float4>(Int4(v.x));
+                                               if(stream.count >= 2) v.x = As<Float4>(Int4(v.y));
+                                               if(stream.count >= 3) v.x = As<Float4>(Int4(v.z));
+                                               if(stream.count >= 4) v.x = As<Float4>(Int4(v.w));
+                                               break;
+                                       case VertexShader::ATTRIBTYPE_UINT:
+                                               if(stream.count >= 1) v.x = As<Float4>(UInt4(v.x));
+                                               if(stream.count >= 2) v.x = As<Float4>(UInt4(v.y));
+                                               if(stream.count >= 3) v.x = As<Float4>(UInt4(v.z));
+                                               if(stream.count >= 4) v.x = As<Float4>(UInt4(v.w));
+                                               break;
+                                       default:
+                                               break;
+                                       }
                                }
                        }
                        break;
                case STREAMTYPE_BYTE:
+                       if(isNativeFloatAttrib) // Stream: UByte, Shader attrib: Float
                        {
                                v.x = Float4(*Pointer<Byte4>(source0));
                                v.y = Float4(*Pointer<Byte4>(source1));
@@ -191,8 +215,18 @@ namespace sw
                                        if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleByte));
                                }
                        }
+                       else // Stream: UByte, Shader attrib: Int / UInt
+                       {
+                               v.x = As<Float4>(Int4(*Pointer<Byte4>(source0)));
+                               v.y = As<Float4>(Int4(*Pointer<Byte4>(source1)));
+                               v.z = As<Float4>(Int4(*Pointer<Byte4>(source2)));
+                               v.w = As<Float4>(Int4(*Pointer<Byte4>(source3)));
+
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                       }
                        break;
                case STREAMTYPE_SBYTE:
+                       if(isNativeFloatAttrib) // Stream: SByte, Shader attrib: Float
                        {
                                v.x = Float4(*Pointer<SByte4>(source0));
                                v.y = Float4(*Pointer<SByte4>(source1));
@@ -209,6 +243,15 @@ namespace sw
                                        if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleSByte));
                                }
                        }
+                       else // Stream: SByte, Shader attrib: Int / UInt
+                       {
+                               v.x = As<Float4>(Int4(*Pointer<SByte4>(source0)));
+                               v.y = As<Float4>(Int4(*Pointer<SByte4>(source1)));
+                               v.z = As<Float4>(Int4(*Pointer<SByte4>(source2)));
+                               v.w = As<Float4>(Int4(*Pointer<SByte4>(source3)));
+
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                       }
                        break;
                case STREAMTYPE_COLOR:
                        {
@@ -226,6 +269,7 @@ namespace sw
                        }
                        break;
                case STREAMTYPE_SHORT:
+                       if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
                        {
                                v.x = Float4(*Pointer<Short4>(source0));
                                v.y = Float4(*Pointer<Short4>(source1));
@@ -242,8 +286,18 @@ namespace sw
                                        if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleShort));
                                }
                        }
+                       else // Stream: Short, Shader attrib: Int/UInt, no type conversion
+                       {
+                               v.x = As<Float4>(Int4(*Pointer<Short4>(source0)));
+                               v.y = As<Float4>(Int4(*Pointer<Short4>(source1)));
+                               v.z = As<Float4>(Int4(*Pointer<Short4>(source2)));
+                               v.w = As<Float4>(Int4(*Pointer<Short4>(source3)));
+
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                       }
                        break;
                case STREAMTYPE_USHORT:
+                       if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
                        {
                                v.x = Float4(*Pointer<UShort4>(source0));
                                v.y = Float4(*Pointer<UShort4>(source1));
@@ -260,59 +314,70 @@ namespace sw
                                        if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleUShort));
                                }
                        }
+                       else // Stream: UShort, Shader attrib: Int/UInt, no type conversion
+                       {
+                               v.x = As<Float4>(Int4(*Pointer<UShort4>(source0)));
+                               v.y = As<Float4>(Int4(*Pointer<UShort4>(source1)));
+                               v.z = As<Float4>(Int4(*Pointer<UShort4>(source2)));
+                               v.w = As<Float4>(Int4(*Pointer<UShort4>(source3)));
+
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                       }
                        break;
                case STREAMTYPE_INT:
+                       if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
                        {
-                               if(stream.normalized)
-                               {
-                                       v.x = Float4(*Pointer<Int4>(source0));
-                                       v.y = Float4(*Pointer<Int4>(source1));
-                                       v.z = Float4(*Pointer<Int4>(source2));
-                                       v.w = Float4(*Pointer<Int4>(source3));
+                               v.x = Float4(*Pointer<Int4>(source0));
+                               v.y = Float4(*Pointer<Int4>(source1));
+                               v.z = Float4(*Pointer<Int4>(source2));
+                               v.w = Float4(*Pointer<Int4>(source3));
 
-                                       transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
 
+                               if(stream.normalized)
+                               {
                                        if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
                                        if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
                                        if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
                                        if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
                                }
-                               else
-                               {
-                                       v.x = As<Float4>(*Pointer<Int4>(source0));
-                                       v.y = As<Float4>(*Pointer<Int4>(source1));
-                                       v.z = As<Float4>(*Pointer<Int4>(source2));
-                                       v.w = As<Float4>(*Pointer<Int4>(source3));
+                       }
+                       else // Stream: Int, Shader attrib: Int/UInt, no type conversion
+                       {
+                               v.x = *Pointer<Float4>(source0);
+                               v.y = *Pointer<Float4>(source1);
+                               v.z = *Pointer<Float4>(source2);
+                               v.w = *Pointer<Float4>(source3);
 
-                                       transpose4xN(v.x, v.y, v.z, v.w, stream.count);
-                               }
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
                        }
                        break;
                case STREAMTYPE_UINT:
+                       if(isNativeFloatAttrib) // Stream: UInt, Shader attrib: Float
                        {
-                               if(stream.normalized)
-                               {
-                                       v.x = Float4(*Pointer<UInt4>(source0));
-                                       v.y = Float4(*Pointer<UInt4>(source1));
-                                       v.z = Float4(*Pointer<UInt4>(source2));
-                                       v.w = Float4(*Pointer<UInt4>(source3));
+                               v.x = Float4(*Pointer<UInt4>(source0));
+                               v.y = Float4(*Pointer<UInt4>(source1));
+                               v.z = Float4(*Pointer<UInt4>(source2));
+                               v.w = Float4(*Pointer<UInt4>(source3));
 
-                                       transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
 
+                               if(stream.normalized)
+                               {
                                        if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
                                        if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
                                        if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
                                        if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
                                }
-                               else
-                               {
-                                       v.x = As<Float4>(*Pointer<UInt4>(source0));
-                                       v.y = As<Float4>(*Pointer<UInt4>(source1));
-                                       v.z = As<Float4>(*Pointer<UInt4>(source2));
-                                       v.w = As<Float4>(*Pointer<UInt4>(source3));
+                       }
+                       else // Stream: UInt, Shader attrib: Int/UInt, no type conversion
+                       {
+                               v.x = *Pointer<Float4>(source0);
+                               v.y = *Pointer<Float4>(source1);
+                               v.z = *Pointer<Float4>(source2);
+                               v.w = *Pointer<Float4>(source3);
 
-                                       transpose4xN(v.x, v.y, v.z, v.w, stream.count);
-                               }
+                               transpose4xN(v.x, v.y, v.z, v.w, stream.count);
                        }
                        break;
                case STREAMTYPE_UDEC3:
@@ -538,7 +603,7 @@ namespace sw
                if(stream.count < 1) v.x = Float4(0.0f);
                if(stream.count < 2) v.y = Float4(0.0f);
                if(stream.count < 3) v.z = Float4(0.0f);
-               if(stream.count < 4) v.w = Float4(1.0f);
+               if(stream.count < 4) v.w = isNativeFloatAttrib ? Float4(1.0f) : As<Float4>(Int4(0));
 
                return v;
        }
index dd62b4b..a98932b 100644 (file)
@@ -32,6 +32,7 @@ namespace sw
                for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
                {
                        input[i] = Semantic();
+                       attribType[i] = ATTRIBTYPE_FLOAT;
                }
 
                if(vs)   // Make a copy
@@ -43,6 +44,7 @@ namespace sw
 
                        memcpy(output, vs->output, sizeof(output));
                        memcpy(input, vs->input, sizeof(input));
+                       memcpy(attribType, vs->attribType, sizeof(attribType));
                        positionRegister = vs->positionRegister;
                        pointSizeRegister = vs->pointSizeRegister;
                        instanceIdDeclared = vs->instanceIdDeclared;
@@ -65,6 +67,7 @@ namespace sw
                for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
                {
                        input[i] = Semantic();
+                       attribType[i] = ATTRIBTYPE_FLOAT;
                }
 
                optimize();
@@ -151,9 +154,10 @@ namespace sw
                return textureSampling;
        }
 
-       void VertexShader::setInput(int inputIdx, const sw::Shader::Semantic& semantic)
+       void VertexShader::setInput(int inputIdx, const sw::Shader::Semantic& semantic, AttribType aType)
        {
                input[inputIdx] = semantic;
+               attribType[inputIdx] = aType;
        }
 
        void VertexShader::setOutput(int outputIdx, int nbComponents, const sw::Shader::Semantic& semantic)
@@ -181,6 +185,11 @@ namespace sw
                return input[inputIdx];
        }
 
+       VertexShader::AttribType VertexShader::getAttribType(int inputIdx) const
+       {
+               return attribType[inputIdx];
+       }
+
        const sw::Shader::Semantic& VertexShader::getOutput(int outputIdx, int component) const
        {
                return output[outputIdx][component];
index 4eb6786..0ca7b93 100644 (file)
@@ -23,6 +23,15 @@ namespace sw
        class VertexShader : public Shader
        {
        public:
+               enum AttribType : unsigned char
+               {
+                       ATTRIBTYPE_FLOAT,
+                       ATTRIBTYPE_INT,
+                       ATTRIBTYPE_UINT,
+
+                       ATTRIBTYPE_LAST = ATTRIBTYPE_UINT
+               };
+
                explicit VertexShader(const VertexShader *vs = 0);
                explicit VertexShader(const unsigned long *token);
 
@@ -31,7 +40,7 @@ namespace sw
                static int validate(const unsigned long *const token);   // Returns number of instructions if valid
                bool containsTextureSampling() const;
 
-               void setInput(int inputIdx, const Semantic& semantic);
+               void setInput(int inputIdx, const Semantic& semantic, AttribType attribType = ATTRIBTYPE_FLOAT);
                void setOutput(int outputIdx, int nbComponents, const Semantic& semantic);
                void setPositionRegister(int posReg);
                void setPointSizeRegister(int ptSizeReg);
@@ -39,6 +48,7 @@ namespace sw
 
                const Semantic& getInput(int inputIdx) const;
                const Semantic& getOutput(int outputIdx, int component) const;
+               AttribType getAttribType(int inputIndex) const;
                int getPositionRegister() const { return positionRegister; }
                int getPointSizeRegister() const { return pointSizeRegister; }
                bool isInstanceIdDeclared() const { return instanceIdDeclared; }
@@ -52,6 +62,8 @@ namespace sw
                Semantic input[MAX_VERTEX_INPUTS];
                Semantic output[MAX_VERTEX_OUTPUTS][4];
 
+               AttribType attribType[MAX_VERTEX_INPUTS];
+
                int positionRegister;
                int pointSizeRegister;