Commit b7508b8e by Alexis Hetu Committed by Alexis Hétu

Fix for the remaining vertex array issues

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/7254Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent f483671b
...@@ -2890,12 +2890,25 @@ namespace glsl ...@@ -2890,12 +2890,25 @@ namespace glsl
index = allocate(attributes, attribute); index = allocate(attributes, attribute);
const TType &type = attribute->getType(); const TType &type = attribute->getType();
int registerCount = attribute->totalRegisterCount(); 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) if(vertexShader && (index + registerCount) <= sw::MAX_VERTEX_INPUTS)
{ {
for(int i = 0; i < registerCount; i++) 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);
} }
} }
......
...@@ -958,6 +958,7 @@ namespace sw ...@@ -958,6 +958,7 @@ namespace sw
state.input[i].type = context->input[i].type; state.input[i].type = context->input[i].type;
state.input[i].count = context->input[i].count; state.input[i].count = context->input[i].count;
state.input[i].normalized = context->input[i].normalized; state.input[i].normalized = context->input[i].normalized;
state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
} }
if(!context->vertexShader) if(!context->vertexShader)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "Matrix.hpp" #include "Matrix.hpp"
#include "Context.hpp" #include "Context.hpp"
#include "RoutineCache.hpp" #include "RoutineCache.hpp"
#include "Shader/VertexShader.hpp"
namespace sw namespace sw
{ {
...@@ -102,6 +103,7 @@ namespace sw ...@@ -102,6 +103,7 @@ namespace sw
StreamType type : BITS(STREAMTYPE_LAST); StreamType type : BITS(STREAMTYPE_LAST);
unsigned int count : 3; unsigned int count : 3;
bool normalized : 1; bool normalized : 1;
unsigned int attribType : BITS(VertexShader::ATTRIBTYPE_LAST);
}; };
struct Output struct Output
......
...@@ -148,6 +148,8 @@ namespace sw ...@@ -148,6 +148,8 @@ namespace sw
Pointer<Byte> source2 = source1 + (!textureSampling ? stride : 0); Pointer<Byte> source2 = source1 + (!textureSampling ? stride : 0);
Pointer<Byte> source3 = source2 + (!textureSampling ? stride : 0); Pointer<Byte> source3 = source2 + (!textureSampling ? stride : 0);
bool isNativeFloatAttrib = (stream.attribType == VertexShader::ATTRIBTYPE_FLOAT) || stream.normalized;
switch(stream.type) switch(stream.type)
{ {
case STREAMTYPE_FLOAT: case STREAMTYPE_FLOAT:
...@@ -156,25 +158,47 @@ namespace sw ...@@ -156,25 +158,47 @@ namespace sw
{ {
// Null stream, all default components // 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 else
{ {
v.x = *Pointer<Float4>(source0); if(stream.count == 1)
v.y = *Pointer<Float4>(source1); {
v.z = *Pointer<Float4>(source2); v.x.x = *Pointer<Float>(source0);
v.w = *Pointer<Float4>(source3); 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; break;
case STREAMTYPE_BYTE: case STREAMTYPE_BYTE:
if(isNativeFloatAttrib) // Stream: UByte, Shader attrib: Float
{ {
v.x = Float4(*Pointer<Byte4>(source0)); v.x = Float4(*Pointer<Byte4>(source0));
v.y = Float4(*Pointer<Byte4>(source1)); v.y = Float4(*Pointer<Byte4>(source1));
...@@ -191,8 +215,18 @@ namespace sw ...@@ -191,8 +215,18 @@ namespace sw
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleByte)); 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; break;
case STREAMTYPE_SBYTE: case STREAMTYPE_SBYTE:
if(isNativeFloatAttrib) // Stream: SByte, Shader attrib: Float
{ {
v.x = Float4(*Pointer<SByte4>(source0)); v.x = Float4(*Pointer<SByte4>(source0));
v.y = Float4(*Pointer<SByte4>(source1)); v.y = Float4(*Pointer<SByte4>(source1));
...@@ -209,6 +243,15 @@ namespace sw ...@@ -209,6 +243,15 @@ namespace sw
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleSByte)); 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; break;
case STREAMTYPE_COLOR: case STREAMTYPE_COLOR:
{ {
...@@ -226,6 +269,7 @@ namespace sw ...@@ -226,6 +269,7 @@ namespace sw
} }
break; break;
case STREAMTYPE_SHORT: case STREAMTYPE_SHORT:
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{ {
v.x = Float4(*Pointer<Short4>(source0)); v.x = Float4(*Pointer<Short4>(source0));
v.y = Float4(*Pointer<Short4>(source1)); v.y = Float4(*Pointer<Short4>(source1));
...@@ -242,8 +286,18 @@ namespace sw ...@@ -242,8 +286,18 @@ namespace sw
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleShort)); 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; break;
case STREAMTYPE_USHORT: case STREAMTYPE_USHORT:
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{ {
v.x = Float4(*Pointer<UShort4>(source0)); v.x = Float4(*Pointer<UShort4>(source0));
v.y = Float4(*Pointer<UShort4>(source1)); v.y = Float4(*Pointer<UShort4>(source1));
...@@ -260,59 +314,70 @@ namespace sw ...@@ -260,59 +314,70 @@ namespace sw
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants,unscaleUShort)); 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; break;
case STREAMTYPE_INT: 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.x = Float4(*Pointer<Int4>(source0)); v.z = Float4(*Pointer<Int4>(source2));
v.y = Float4(*Pointer<Int4>(source1)); v.w = Float4(*Pointer<Int4>(source3));
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 >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
if(stream.count >= 2) v.y *= *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 >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt)); if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
} }
else }
{ else // Stream: Int, Shader attrib: Int/UInt, no type conversion
v.x = As<Float4>(*Pointer<Int4>(source0)); {
v.y = As<Float4>(*Pointer<Int4>(source1)); v.x = *Pointer<Float4>(source0);
v.z = As<Float4>(*Pointer<Int4>(source2)); v.y = *Pointer<Float4>(source1);
v.w = As<Float4>(*Pointer<Int4>(source3)); 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; break;
case STREAMTYPE_UINT: 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.x = Float4(*Pointer<UInt4>(source0)); v.z = Float4(*Pointer<UInt4>(source2));
v.y = Float4(*Pointer<UInt4>(source1)); v.w = Float4(*Pointer<UInt4>(source3));
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 >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
if(stream.count >= 2) v.y *= *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 >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt)); if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
} }
else }
{ else // Stream: UInt, Shader attrib: Int/UInt, no type conversion
v.x = As<Float4>(*Pointer<UInt4>(source0)); {
v.y = As<Float4>(*Pointer<UInt4>(source1)); v.x = *Pointer<Float4>(source0);
v.z = As<Float4>(*Pointer<UInt4>(source2)); v.y = *Pointer<Float4>(source1);
v.w = As<Float4>(*Pointer<UInt4>(source3)); 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; break;
case STREAMTYPE_UDEC3: case STREAMTYPE_UDEC3:
...@@ -538,7 +603,7 @@ namespace sw ...@@ -538,7 +603,7 @@ namespace sw
if(stream.count < 1) v.x = Float4(0.0f); if(stream.count < 1) v.x = Float4(0.0f);
if(stream.count < 2) v.y = Float4(0.0f); if(stream.count < 2) v.y = Float4(0.0f);
if(stream.count < 3) v.z = 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; return v;
} }
......
...@@ -32,6 +32,7 @@ namespace sw ...@@ -32,6 +32,7 @@ namespace sw
for(int i = 0; i < MAX_VERTEX_INPUTS; i++) for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{ {
input[i] = Semantic(); input[i] = Semantic();
attribType[i] = ATTRIBTYPE_FLOAT;
} }
if(vs) // Make a copy if(vs) // Make a copy
...@@ -43,6 +44,7 @@ namespace sw ...@@ -43,6 +44,7 @@ namespace sw
memcpy(output, vs->output, sizeof(output)); memcpy(output, vs->output, sizeof(output));
memcpy(input, vs->input, sizeof(input)); memcpy(input, vs->input, sizeof(input));
memcpy(attribType, vs->attribType, sizeof(attribType));
positionRegister = vs->positionRegister; positionRegister = vs->positionRegister;
pointSizeRegister = vs->pointSizeRegister; pointSizeRegister = vs->pointSizeRegister;
instanceIdDeclared = vs->instanceIdDeclared; instanceIdDeclared = vs->instanceIdDeclared;
...@@ -65,6 +67,7 @@ namespace sw ...@@ -65,6 +67,7 @@ namespace sw
for(int i = 0; i < MAX_VERTEX_INPUTS; i++) for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
{ {
input[i] = Semantic(); input[i] = Semantic();
attribType[i] = ATTRIBTYPE_FLOAT;
} }
optimize(); optimize();
...@@ -151,9 +154,10 @@ namespace sw ...@@ -151,9 +154,10 @@ namespace sw
return textureSampling; 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; input[inputIdx] = semantic;
attribType[inputIdx] = aType;
} }
void VertexShader::setOutput(int outputIdx, int nbComponents, const sw::Shader::Semantic& semantic) void VertexShader::setOutput(int outputIdx, int nbComponents, const sw::Shader::Semantic& semantic)
...@@ -181,6 +185,11 @@ namespace sw ...@@ -181,6 +185,11 @@ namespace sw
return input[inputIdx]; return input[inputIdx];
} }
VertexShader::AttribType VertexShader::getAttribType(int inputIdx) const
{
return attribType[inputIdx];
}
const sw::Shader::Semantic& VertexShader::getOutput(int outputIdx, int component) const const sw::Shader::Semantic& VertexShader::getOutput(int outputIdx, int component) const
{ {
return output[outputIdx][component]; return output[outputIdx][component];
......
...@@ -23,6 +23,15 @@ namespace sw ...@@ -23,6 +23,15 @@ namespace sw
class VertexShader : public Shader class VertexShader : public Shader
{ {
public: public:
enum AttribType : unsigned char
{
ATTRIBTYPE_FLOAT,
ATTRIBTYPE_INT,
ATTRIBTYPE_UINT,
ATTRIBTYPE_LAST = ATTRIBTYPE_UINT
};
explicit VertexShader(const VertexShader *vs = 0); explicit VertexShader(const VertexShader *vs = 0);
explicit VertexShader(const unsigned long *token); explicit VertexShader(const unsigned long *token);
...@@ -31,7 +40,7 @@ namespace sw ...@@ -31,7 +40,7 @@ namespace sw
static int validate(const unsigned long *const token); // Returns number of instructions if valid static int validate(const unsigned long *const token); // Returns number of instructions if valid
bool containsTextureSampling() const; 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 setOutput(int outputIdx, int nbComponents, const Semantic& semantic);
void setPositionRegister(int posReg); void setPositionRegister(int posReg);
void setPointSizeRegister(int ptSizeReg); void setPointSizeRegister(int ptSizeReg);
...@@ -39,6 +48,7 @@ namespace sw ...@@ -39,6 +48,7 @@ namespace sw
const Semantic& getInput(int inputIdx) const; const Semantic& getInput(int inputIdx) const;
const Semantic& getOutput(int outputIdx, int component) const; const Semantic& getOutput(int outputIdx, int component) const;
AttribType getAttribType(int inputIndex) const;
int getPositionRegister() const { return positionRegister; } int getPositionRegister() const { return positionRegister; }
int getPointSizeRegister() const { return pointSizeRegister; } int getPointSizeRegister() const { return pointSizeRegister; }
bool isInstanceIdDeclared() const { return instanceIdDeclared; } bool isInstanceIdDeclared() const { return instanceIdDeclared; }
...@@ -52,6 +62,8 @@ namespace sw ...@@ -52,6 +62,8 @@ namespace sw
Semantic input[MAX_VERTEX_INPUTS]; Semantic input[MAX_VERTEX_INPUTS];
Semantic output[MAX_VERTEX_OUTPUTS][4]; Semantic output[MAX_VERTEX_OUTPUTS][4];
AttribType attribType[MAX_VERTEX_INPUTS];
int positionRegister; int positionRegister;
int pointSizeRegister; int pointSizeRegister;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment