Commit 877ddfc5 by Alexis Hetu Committed by Alexis Hétu

gl_VertexID implementation

This cl implements support for gl_VertexID. Passes the functional.shaders.builtin_variable.vertex_id test. Change-Id: I5550e3ecba30e29f1e38ace608d730833a1e9598 Reviewed-on: https://swiftshader-review.googlesource.com/10958Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 0f70a7fa
......@@ -369,6 +369,7 @@ enum TQualifier : unsigned char
EvqPosition,
EvqPointSize,
EvqInstanceID,
EvqVertexID,
// built-ins read by fragment shader
EvqFragCoord,
......@@ -446,6 +447,7 @@ inline const char *getQualifierString(TQualifier qualifier)
case EvqPosition: return "Position"; break;
case EvqPointSize: return "PointSize"; break;
case EvqInstanceID: return "InstanceID"; break;
case EvqVertexID: return "VertexID"; break;
case EvqFragCoord: return "FragCoord"; break;
case EvqFrontFacing: return "FrontFacing"; break;
case EvqFragColor: return "FragColor"; break;
......
......@@ -471,6 +471,7 @@ void IdentifyBuiltIns(GLenum shaderType,
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
break;
default: assert(false && "Language not supported");
}
......
......@@ -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);
......
......@@ -406,6 +406,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIn
case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break;
case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
case EvqInstanceID: message = "can't modify gl_InstanceID"; break;
case EvqVertexID: message = "can't modify gl_VertexID"; break;
default:
//
......
......@@ -846,8 +846,8 @@ namespace sw
reg = v[2 + i];
break;
case Shader::PARAMETER_MISCTYPE:
if(src.index == 0) reg = vPos;
if(src.index == 1) reg = vFace;
if(src.index == Shader::VPosIndex) reg = vPos;
if(src.index == Shader::VFaceIndex) reg = vFace;
break;
case Shader::PARAMETER_SAMPLER:
if(src.rel.type == Shader::PARAMETER_VOID)
......
......@@ -700,11 +700,11 @@ namespace sw
{
unsigned char index = instruction[i]->dst.index;
if(index == 0)
if(index == Shader::VPosIndex)
{
vPosDeclared = true;
}
else if(index == 1)
else if(index == Shader::VFaceIndex)
{
vFaceDeclared = true;
}
......
......@@ -1059,9 +1059,14 @@ namespace sw
case PARAMETER_LOOP: return "aL";
// case PARAMETER_TEMPFLOAT16: return "";
case PARAMETER_MISCTYPE:
if(index == 0) return "vPos";
else if(index == 1) return "vFace";
else ASSERT(false);
switch(index)
{
case VPosIndex: return "vPos";
case VFaceIndex: return "vFace";
case InstanceIDIndex: return "iID";
case VertexIDIndex: return "vID";
default: ASSERT(false);
}
case PARAMETER_LABEL: return "l";
case PARAMETER_PREDICATE: return "p0";
case PARAMETER_FLOAT4LITERAL: return "";
......
......@@ -358,6 +358,14 @@ namespace sw
PARAMETER_VOID
};
enum MiscParameterIndex
{
VPosIndex = 0,
VFaceIndex = 1,
InstanceIDIndex = 2,
VertexIDIndex = 3,
};
enum Modifier
{
MODIFIER_NONE,
......
......@@ -158,7 +158,7 @@ namespace sw
return dst;
}
void VertexPipeline::pipeline()
void VertexPipeline::pipeline(UInt &index)
{
Vector4f position;
Vector4f normal;
......
......@@ -30,7 +30,7 @@ namespace sw
virtual ~VertexPipeline();
private:
void pipeline() override;
void pipeline(UInt &index) override;
void processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position);
void processPointSize();
......
......@@ -64,7 +64,7 @@ namespace sw
}
}
void VertexProgram::pipeline()
void VertexProgram::pipeline(UInt& index)
{
for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
{
......@@ -73,7 +73,7 @@ namespace sw
if(!state.preTransformed)
{
program();
program(index);
}
else
{
......@@ -81,7 +81,7 @@ namespace sw
}
}
void VertexProgram::program()
void VertexProgram::program(UInt& index)
{
// shader->print("VertexShader-%0.8X.txt", state.shaderID);
......@@ -95,6 +95,21 @@ namespace sw
enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
if(shader->isVertexIdDeclared())
{
if(state.textureSampling)
{
vertexID = Int4(index);
}
else
{
vertexID = Insert(vertexID, As<Int>(index), 0);
vertexID = Insert(vertexID, As<Int>(index + 1), 1);
vertexID = Insert(vertexID, As<Int>(index + 2), 2);
vertexID = Insert(vertexID, As<Int>(index + 3), 3);
}
}
// Create all call site return blocks up front
for(size_t i = 0; i < shader->getLength(); i++)
{
......@@ -721,7 +736,15 @@ namespace sw
}
break;
case Shader::PARAMETER_MISCTYPE:
reg.x = As<Float>(Int(instanceID));
if(src.index == Shader::InstanceIDIndex)
{
reg.x = As<Float>(instanceID);
}
else if(src.index == Shader::VertexIDIndex)
{
reg.x = As<Float4>(vertexID);
}
else ASSERT(false);
return reg;
default:
ASSERT(false);
......@@ -861,7 +884,17 @@ namespace sw
case Shader::PARAMETER_INPUT: a = v[src.rel.index][component]; break;
case Shader::PARAMETER_OUTPUT: a = o[src.rel.index][component]; break;
case Shader::PARAMETER_CONST: a = *Pointer<Float>(uniformAddress(src.bufferIndex, src.rel.index) + component * sizeof(float)); break;
case Shader::PARAMETER_MISCTYPE: a = As<Float4>(Int4(instanceID)); break;
case Shader::PARAMETER_MISCTYPE:
if(src.rel.index == Shader::InstanceIDIndex)
{
a = As<Float4>(Int4(instanceID)); break;
}
else if(src.rel.index == Shader::VertexIDIndex)
{
a = As<Float4>(vertexID); break;
}
else ASSERT(false);
break;
default: ASSERT(false);
}
......
......@@ -56,14 +56,15 @@ namespace sw
Int4 enableLeave;
Int instanceID;
Int4 vertexID;
typedef Shader::DestinationParameter Dst;
typedef Shader::SourceParameter Src;
typedef Shader::Control Control;
typedef Shader::Usage Usage;
void pipeline() override;
void program();
void pipeline(UInt &index) override;
void program(UInt &index);
void passThrough();
Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
......
......@@ -62,7 +62,7 @@ namespace sw
*Pointer<UInt>(tagCache + tagIndex) = indexQ;
readInput(indexQ);
pipeline();
pipeline(indexQ);
postTransform();
computeClipFlags();
......
......@@ -54,7 +54,7 @@ namespace sw
const VertexProcessor::State &state;
private:
virtual void pipeline() = 0;
virtual void pipeline(UInt &index) = 0;
typedef VertexProcessor::State::Input Stream;
......
......@@ -27,6 +27,7 @@ namespace sw
positionRegister = Pos;
pointSizeRegister = Unused;
instanceIdDeclared = false;
vertexIdDeclared = false;
textureSampling = false;
for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
......@@ -48,6 +49,7 @@ namespace sw
positionRegister = vs->positionRegister;
pointSizeRegister = vs->pointSizeRegister;
instanceIdDeclared = vs->instanceIdDeclared;
vertexIdDeclared = vs->vertexIdDeclared;
usedSamplers = vs->usedSamplers;
optimize();
......@@ -62,6 +64,7 @@ namespace sw
positionRegister = Pos;
pointSizeRegister = Unused;
instanceIdDeclared = false;
vertexIdDeclared = false;
textureSampling = false;
for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
......
......@@ -45,6 +45,7 @@ namespace sw
void setPositionRegister(int posReg);
void setPointSizeRegister(int ptSizeReg);
void declareInstanceId() { instanceIdDeclared = true; }
void declareVertexId() { vertexIdDeclared = true; }
const Semantic& getInput(int inputIdx) const;
const Semantic& getOutput(int outputIdx, int component) const;
......@@ -52,6 +53,7 @@ namespace sw
int getPositionRegister() const { return positionRegister; }
int getPointSizeRegister() const { return pointSizeRegister; }
bool isInstanceIdDeclared() const { return instanceIdDeclared; }
bool isVertexIdDeclared() const { return vertexIdDeclared; }
private:
void analyze();
......@@ -68,6 +70,7 @@ namespace sw
int pointSizeRegister;
bool instanceIdDeclared;
bool vertexIdDeclared;
bool textureSampling;
};
}
......
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