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/10958
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
EvqPosition,
EvqPointSize,
EvqInstanceID,
+ EvqVertexID,
// built-ins read by fragment shader
EvqFragCoord,
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;
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");
}
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;
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);
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:
//
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)
{
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;
}
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 "";
PARAMETER_VOID
};
+ enum MiscParameterIndex
+ {
+ VPosIndex = 0,
+ VFaceIndex = 1,
+ InstanceIDIndex = 2,
+ VertexIDIndex = 3,
+ };
+
enum Modifier
{
MODIFIER_NONE,
return dst;
}
- void VertexPipeline::pipeline()
+ void VertexPipeline::pipeline(UInt &index)
{
Vector4f position;
Vector4f normal;
virtual ~VertexPipeline();
private:
- void pipeline() override;
+ void pipeline(UInt &index) override;
void processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position);
void processPointSize();
}
}
- void VertexProgram::pipeline()
+ void VertexProgram::pipeline(UInt& index)
{
for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
{
if(!state.preTransformed)
{
- program();
+ program(index);
}
else
{
}
}
- void VertexProgram::program()
+ void VertexProgram::program(UInt& index)
{
// shader->print("VertexShader-%0.8X.txt", state.shaderID);
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++)
{
}
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);
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);
}
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);
*Pointer<UInt>(tagCache + tagIndex) = indexQ;
readInput(indexQ);
- pipeline();
+ pipeline(indexQ);
postTransform();
computeClipFlags();
const VertexProcessor::State &state;
private:
- virtual void pipeline() = 0;
+ virtual void pipeline(UInt &index) = 0;
typedef VertexProcessor::State::Input Stream;
positionRegister = Pos;
pointSizeRegister = Unused;
instanceIdDeclared = false;
+ vertexIdDeclared = false;
textureSampling = false;
for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
positionRegister = vs->positionRegister;
pointSizeRegister = vs->pointSizeRegister;
instanceIdDeclared = vs->instanceIdDeclared;
+ vertexIdDeclared = vs->vertexIdDeclared;
usedSamplers = vs->usedSamplers;
optimize();
positionRegister = Pos;
pointSizeRegister = Unused;
instanceIdDeclared = false;
+ vertexIdDeclared = false;
textureSampling = false;
for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
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;
int getPositionRegister() const { return positionRegister; }
int getPointSizeRegister() const { return pointSizeRegister; }
bool isInstanceIdDeclared() const { return instanceIdDeclared; }
+ bool isVertexIdDeclared() const { return vertexIdDeclared; }
private:
void analyze();
int pointSizeRegister;
bool instanceIdDeclared;
+ bool vertexIdDeclared;
bool textureSampling;
};
}