Commit b3dced29 by Gregoire Payen de La Garanderie Committed by Jamie Madill

Implementing gl_InstanceID in the HLSL compiler.

Fixes: dEQP-GLES3.functional.instanced.draw_arrays_instanced.instance_id dEQP-GLES3.functional.instanced.draw_arrays_instanced.mixed dEQP-GLES3.functional.instanced.draw_elements_instanced.instance_id dEQP-GLES3.functional.instanced.draw_elements_instanced.mixed BUG=angle:601 Change-Id: I6e120eebc90d00e025fc58f096064e6ed1da826b Reviewed-on: https://chromium-review.googlesource.com/246911Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGregoire Payen de La Garanderie <Gregory.Payen@imgtec.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent c38fa8a5
......@@ -298,6 +298,9 @@ enum TQualifier
EvqInOut,
EvqConstReadOnly,
// built-ins read by vertex shader
EvqInstanceID,
// built-ins written by vertex shader
EvqPosition,
EvqPointSize,
......@@ -392,6 +395,7 @@ inline const char* getQualifierString(TQualifier q)
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break;
case EvqInstanceID: return "InstanceID"; break;
case EvqPosition: return "Position"; break;
case EvqPointSize: return "PointSize"; break;
case EvqFragCoord: return "FragCoord"; break;
......
......@@ -745,6 +745,7 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
case GL_VERTEX_SHADER:
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)));
break;
default: assert(false && "Language not supported");
......
......@@ -110,6 +110,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
mUsesPointCoord = false;
mUsesFrontFacing = false;
mUsesPointSize = false;
mUsesInstanceID = false;
mUsesFragDepth = false;
mUsesXor = false;
mUsesDiscardRewriting = false;
......@@ -498,6 +499,11 @@ void OutputHLSL::header(const BuiltInFunctionEmulatorHLSL *builtInFunctionEmulat
out << "static float gl_PointSize = float(1);\n";
}
if (mUsesInstanceID)
{
out << "static int gl_InstanceID;";
}
out << "\n"
"// Varyings\n";
out << varyings;
......@@ -1305,6 +1311,11 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesPointSize = true;
out << name;
}
else if (qualifier == EvqInstanceID)
{
mUsesInstanceID = true;
out << name;
}
else if (name == "gl_FragDepthEXT")
{
mUsesFragDepth = true;
......
......@@ -132,6 +132,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesPointCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
bool mUsesInstanceID;
bool mUsesFragDepth;
bool mUsesXor;
bool mUsesDiscardRewriting;
......
......@@ -142,6 +142,7 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mPointCoordAdded(false),
mFrontFacingAdded(false),
mFragCoordAdded(false),
mInstanceIDAdded(false),
mPositionAdded(false),
mPointSizeAdded(false),
mLastFragDataAdded(false),
......@@ -250,6 +251,22 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
mPointCoordAdded = true;
}
return;
case EvqInstanceID:
if (!mInstanceIDAdded)
{
Attribute info;
const char kName[] = "gl_InstanceID";
info.name = kName;
info.mappedName = kName;
info.type = GL_INT;
info.arraySize = 0;
info.precision = GL_HIGH_INT; // Defined by spec.
info.staticUse = true;
info.location = -1;
mAttribs->push_back(info);
mInstanceIDAdded = true;
}
return;
case EvqPosition:
if (!mPositionAdded)
{
......
......@@ -51,6 +51,7 @@ class CollectVariables : public TIntermTraverser
bool mFrontFacingAdded;
bool mFragCoordAdded;
bool mInstanceIDAdded;
bool mPositionAdded;
bool mPointSizeAdded;
bool mLastFragDataAdded;
......
......@@ -392,11 +392,31 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
else
{
GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
if (shaderAttribute.name == "gl_InstanceID")
{
// The input type of the instance ID in HLSL (uint) differs from the one in ESSL (int).
structHLSL += " uint";
}
else
{
structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
}
}
structHLSL += " " + decorateVariable(shaderAttribute.name) + " : ";
if (shaderAttribute.name == "gl_InstanceID")
{
structHLSL += "SV_InstanceID";
}
else
{
structHLSL += "TEXCOORD" + Str(semanticIndex);
semanticIndex += VariableRegisterCount(shaderAttribute.type);
}
structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
semanticIndex += VariableRegisterCount(shaderAttribute.type);
structHLSL += ";\n";
// HLSL code for initialization
initHLSL += " " + decorateVariable(shaderAttribute.name) + " = ";
......
......@@ -258,6 +258,14 @@ protected:
std::string mSimpleVSSource;
};
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_TYPED_TEST_CASE(GLSLTest_ES3, ES3_D3D11);
template<typename T>
class GLSLTest_ES3 : public GLSLTest<T>
{
};
TYPED_TEST(GLSLTest, NamelessScopedStructs)
{
const std::string fragmentShaderSource = SHADER_SOURCE
......@@ -905,3 +913,61 @@ TYPED_TEST(GLSLTest, GlobalStaticAndVarying)
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
}
// Tests that using a global static initialized from gl_InstanceID works as expected.
TYPED_TEST(GLSLTest_ES3, GlobalStaticAndInstanceID)
{
const std::string &vertexShaderSource =
"#version 300 es\n"
"precision highp float;\n"
"in vec4 a_position;\n"
"out vec4 vColour;"
"int x = gl_InstanceID;"
"int global_v = x;"
"void main() {\n"
" gl_Position = a_position;\n"
" vColour = vec4(float(global_v)/255., 0.0, 0.0, 1.0);\n"
"}\n";
const std::string &fragmentShaderSource =
"#version 300 es\n"
"precision highp float;\n"
"in vec4 vColour;"
"out vec4 colour;"
"void main() {\n"
" colour = vColour;\n"
"}\n";
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
ASSERT_NE(0u, program);
GLint positionLocation = glGetAttribLocation(program, "a_position");
glUseProgram(program);
const GLfloat vertices[] =
{
-1.0f, 1.0f, 0.5f,
-1.0f, -1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
-1.0f, 1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
1.0f, 1.0f, 0.5f,
};
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(positionLocation);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 7);
glDisableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glUseProgram(0);
swapBuffers();
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(0, 0, 6, 0, 0, 255);
}
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