Commit 8b695ee3 by Austin Kinross Committed by Jamie Madill

Reduce unnecessary built-in varying usage in D3D renderer

Change-Id: I0c404e77aa3f56ddc5b97a206b06c7907edfb1eb Reviewed-on: https://chromium-review.googlesource.com/259812Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent c8ef69d2
...@@ -598,8 +598,8 @@ struct DynamicHLSL::SemanticInfo ...@@ -598,8 +598,8 @@ struct DynamicHLSL::SemanticInfo
BuiltinInfo glPointSize; BuiltinInfo glPointSize;
}; };
DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool position, bool fragCoord,
bool pointSize, bool pixelShader) const bool pointCoord, bool pointSize, bool pixelShader) const
{ {
SemanticInfo info; SemanticInfo info;
bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4); bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4);
...@@ -620,7 +620,10 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool ...@@ -620,7 +620,10 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool
info.dxPosition.enableSystem("POSITION"); info.dxPosition.enableSystem("POSITION");
} }
if (position)
{
info.glPosition.enable(varyingSemantic, reservedRegisterIndex++); info.glPosition.enable(varyingSemantic, reservedRegisterIndex++);
}
if (fragCoord) if (fragCoord)
{ {
...@@ -654,10 +657,13 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const ...@@ -654,10 +657,13 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
{ {
std::string linkHLSL = "{\n"; std::string linkHLSL = "{\n";
ASSERT(info.dxPosition.enabled && info.glPosition.enabled); ASSERT(info.dxPosition.enabled);
linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n"; linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n";
if (info.glPosition.enabled)
{
linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n"; linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n";
}
if (info.glFragCoord.enabled) if (info.glFragCoord.enabled)
{ {
...@@ -669,13 +675,14 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const ...@@ -669,13 +675,14 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n"; linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n";
} }
linkHLSL += varyingHLSL;
if (info.glPointSize.enabled) if (info.glPointSize.enabled)
{ {
linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n"; linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n";
} }
// Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the same register.
linkHLSL += varyingHLSL;
linkHLSL += "};\n"; linkHLSL += "};\n";
return linkHLSL; return linkHLSL;
...@@ -684,10 +691,11 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const ...@@ -684,10 +691,11 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
std::vector<LinkedVarying> *linkedVaryings) const std::vector<LinkedVarying> *linkedVaryings) const
{ {
ASSERT(info.glPosition.enabled); if (info.glPosition.enabled)
{
linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic, linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic,
info.glPosition.index, 1)); info.glPosition.index, 1));
}
if (info.glFragCoord.enabled) if (info.glFragCoord.enabled)
{ {
...@@ -763,6 +771,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -763,6 +771,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3); const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3);
const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1); const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
// gl_Position only needs to be outputted from the vertex shader if transform feedback is active.
// This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from the vertex shader in this case.
// This saves us 1 output vector.
bool outputPositionFromVS = !(shaderModel >= 4 && mRenderer->getShaderModelSuffix() != "");
int shaderVersion = vertexShader->getShaderVersion(); int shaderVersion = vertexShader->getShaderVersion();
if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors) if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
...@@ -778,9 +791,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -778,9 +791,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
// GeometryShader PointSprite emulation does not require this additional entry because the // GeometryShader PointSprite emulation does not require this additional entry because the
// GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the PS_INPUT of the // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the PS_INPUT of the
// generated pixel shader. // generated pixel shader.
const SemanticInfo &vertexSemantics = getSemanticInfo(registers, usesFragCoord, // The Geometry Shader point sprite implementation needs gl_PointSize to be in VS_OUTPUT and GS_INPUT.
(useInstancedPointSpriteEmulation && usesPointCoord), // Instanced point sprites doesn't need gl_PointSize in VS_OUTPUT.
usesPointSize, false); const SemanticInfo &vertexSemantics = getSemanticInfo(registers, outputPositionFromVS,
usesFragCoord, (useInstancedPointSpriteEmulation && usesPointCoord),
(!useInstancedPointSpriteEmulation && usesPointSize), false);
storeUserLinkedVaryings(vertexShader, linkedVaryings); storeUserLinkedVaryings(vertexShader, linkedVaryings);
storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings); storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings);
...@@ -809,8 +824,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -809,8 +824,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
vertexHLSL += "\n" vertexHLSL += "\n"
" gl_main();\n" " gl_main();\n"
"\n" "\n"
" VS_OUTPUT output;\n" " VS_OUTPUT output;\n";
" output.gl_Position = gl_Position;\n";
if (outputPositionFromVS)
{
vertexHLSL += " output.gl_Position = gl_Position;\n";
}
// On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust. // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust.
if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
...@@ -828,7 +847,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -828,7 +847,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
" output.dx_Position.w = gl_Position.w;\n"; " output.dx_Position.w = gl_Position.w;\n";
} }
if (usesPointSize && shaderModel >= 3) // We don't need to output gl_PointSize if we use are emulating point sprites via instancing.
if (usesPointSize && shaderModel >= 3 && !useInstancedPointSpriteEmulation)
{ {
vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; vertexHLSL += " output.gl_PointSize = gl_PointSize;\n";
} }
...@@ -877,8 +897,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -877,8 +897,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
{ {
vertexHLSL += "\n" vertexHLSL += "\n"
" gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n" " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n"
" output.dx_Position.xyz += float3(input.spriteVertexPos.x * gl_PointSize / (dx_ViewCoords.x*2), input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * output.dx_Position.w;\n" " output.dx_Position.xyz += float3(input.spriteVertexPos.x * gl_PointSize / (dx_ViewCoords.x*2), input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * output.dx_Position.w;\n";
" output.gl_PointSize = gl_PointSize;\n";
if (usesPointCoord) if (usesPointCoord)
{ {
...@@ -891,8 +910,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -891,8 +910,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
" return output;\n" " return output;\n"
"}\n"; "}\n";
const SemanticInfo &pixelSemantics = getSemanticInfo(registers, usesFragCoord, usesPointCoord, const SemanticInfo &pixelSemantics = getSemanticInfo(registers, outputPositionFromVS, usesFragCoord, usesPointCoord,
usesPointSize, true); (!useInstancedPointSpriteEmulation && usesPointSize), true);
pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n"; pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n";
...@@ -1111,9 +1130,9 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragm ...@@ -1111,9 +1130,9 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragm
std::string geomHLSL; std::string geomHLSL;
const SemanticInfo &inSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord, const SemanticInfo &inSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord,
false, true, false); false, true, false);
const SemanticInfo &outSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord, const SemanticInfo &outSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord,
fragmentShader->mUsesPointCoord, true, false); fragmentShader->mUsesPointCoord, true, false);
std::string varyingHLSL = generateVaryingHLSL(vertexShader); std::string varyingHLSL = generateVaryingHLSL(vertexShader);
......
...@@ -81,8 +81,8 @@ class DynamicHLSL ...@@ -81,8 +81,8 @@ class DynamicHLSL
struct SemanticInfo; struct SemanticInfo;
std::string getVaryingSemantic(bool pointSize) const; std::string getVaryingSemantic(bool pointSize) const;
SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize, SemanticInfo getSemanticInfo(int startRegisters, bool position, bool fragCoord, bool pointCoord,
bool pixelShader) const; bool pointSize, bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const; std::string generateVaryingHLSL(const ShaderD3D *shader) const;
void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const; void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
......
...@@ -568,7 +568,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) ...@@ -568,7 +568,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX; case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX;
// No constants for D3D9 viewport size limits, use the maximum texture sizes // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum texture sizes
case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
...@@ -676,7 +676,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) ...@@ -676,7 +676,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
// Uniform blocks not supported in D3D9 feature levels // Uniform blocks not supported on D3D11 Feature Level 9
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 0; case D3D_FEATURE_LEVEL_9_1: return 0;
...@@ -685,10 +685,33 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) ...@@ -685,10 +685,33 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
} }
} }
static size_t GetReservedVertexOutputVectors() static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
{ {
// We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize // According to The OpenGL ES Shading Language specifications
return 4; // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21)
// built-in special variables (e.g. gl_FragCoord, or gl_PointCoord)
// which are statically used in the shader should be included in the variable packing algorithm.
// Therefore, we should not reserve output vectors for them.
switch (featureLevel)
{
// We must reserve one output vector for dx_Position.
// We also reserve one for gl_Position, which we unconditionally output on Feature Levels 10_0+,
// even if it's unused in the shader (e.g. for transform feedback). TODO: This could be improved.
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return 2;
// Just reserve dx_Position on Feature Level 9, since we don't ever need to output gl_Position.
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 1;
default: UNREACHABLE(); return 0;
}
return 1;
} }
static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
...@@ -698,15 +721,15 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) ...@@ -698,15 +721,15 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel) switch (featureLevel)
{ {
case D3D_FEATURE_LEVEL_11_1: case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
// Use D3D9 SM3 and SM2 limits // Use Shader Model 2.X limits
case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel);
default: UNREACHABLE(); return 0; default: UNREACHABLE(); return 0;
} }
...@@ -722,7 +745,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) ...@@ -722,7 +745,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
// Vertex textures not supported in D3D9 feature levels according to // Vertex textures not supported on D3D11 Feature Level 9 according to
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
// ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
...@@ -769,7 +792,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) ...@@ -769,7 +792,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
// Uniform blocks not supported in D3D9 feature levels // Uniform blocks not supported on D3D11 Feature Level 9
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 0; case D3D_FEATURE_LEVEL_9_1: return 0;
...@@ -783,15 +806,15 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) ...@@ -783,15 +806,15 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel) switch (featureLevel)
{ {
case D3D_FEATURE_LEVEL_11_1: case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
// Use D3D9 SM3 and SM2 limits // Use Shader Model 2.X limits
case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_3: return 8 - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel);
default: UNREACHABLE(); return 0; default: UNREACHABLE(); return 0;
} }
......
...@@ -106,7 +106,9 @@ protected: ...@@ -106,7 +106,9 @@ protected:
} }
} }
void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, std::string* fragmentShader, std::string* vertexShader) void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
std::string* fragmentShader, std::string* vertexShader)
{ {
// Generate a string declaring the varyings, to share between the fragment shader and the vertex shader. // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
std::string varyingDeclaration; std::string varyingDeclaration;
...@@ -149,6 +151,18 @@ protected: ...@@ -149,6 +151,18 @@ protected:
varyingCount += 1; varyingCount += 1;
} }
for (GLint i = 0; i < vec4Count; i++)
{
varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
varyingCount += 1;
}
for (GLint i = 0; i < vec4ArrayCount; i++)
{
varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
varyingCount += 1;
}
// Generate the vertex shader // Generate the vertex shader
vertexShader->clear(); vertexShader->clear();
vertexShader->append(varyingDeclaration); vertexShader->append(varyingDeclaration);
...@@ -192,6 +206,23 @@ protected: ...@@ -192,6 +206,23 @@ protected:
currentVSVarying += 1; currentVSVarying += 1;
} }
for (GLint i = 0; i < vec4Count; i++)
{
vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
currentVSVarying += 1;
}
for (GLint i = 0; i < vec4ArrayCount; i++)
{
vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
currentVSVarying += 1;
}
if (usePointSize)
{
vertexShader->append("gl_PointSize = 1.0;\n");
}
vertexShader->append("}\n"); vertexShader->append("}\n");
// Generate the fragment shader // Generate the fragment shader
...@@ -252,10 +283,64 @@ protected: ...@@ -252,10 +283,64 @@ protected:
} }
fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n"); fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
fragmentShader->append("\tgl_FragColor = retColor;\n}");
// Make use of the vec4 varyings
fragmentShader->append("\tretColor += ");
for (GLint i = 0; i < vec4Count; i++)
{
fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
currentFSVarying += 1;
}
for (GLint i = 0; i < vec4ArrayCount; i++)
{
fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
currentFSVarying += 1;
}
fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
// Set gl_FragColor, and use special variables if requested
fragmentShader->append("\tgl_FragColor = retColor");
if (useFragCoord)
{
fragmentShader->append(" + gl_FragCoord");
}
if (usePointCoord)
{
fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
}
fragmentShader->append(";\n}");
}
void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
{
std::string fragmentShaderSource;
std::string vertexShaderSource;
GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
&fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
if (expectSuccess)
{
EXPECT_NE(0u, program);
}
else
{
EXPECT_EQ(0u, program);
}
} }
std::string mSimpleVSSource; std::string mSimpleVSSource;
T fixtureType;
}; };
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
...@@ -465,6 +550,17 @@ TYPED_TEST(GLSLTest, InvariantVaryingOut) ...@@ -465,6 +550,17 @@ TYPED_TEST(GLSLTest, InvariantVaryingOut)
TYPED_TEST(GLSLTest, FrontFacingAndVarying) TYPED_TEST(GLSLTest, FrontFacingAndVarying)
{ {
EGLPlatformParameters platform = fixtureType.GetPlatform();
// Disable this test on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
if (platform.majorVersion == 9 && platform.minorVersion == 3)
{
return;
}
}
const std::string vertexShaderSource = SHADER_SOURCE const std::string vertexShaderSource = SHADER_SOURCE
( (
attribute vec4 a_position; attribute vec4 a_position;
...@@ -580,77 +676,93 @@ TYPED_TEST(GLSLTest, InvariantAll) ...@@ -580,77 +676,93 @@ TYPED_TEST(GLSLTest, InvariantAll)
EXPECT_NE(0u, program); EXPECT_NE(0u, program);
} }
TYPED_TEST(GLSLTest, MaxVaryingVec3) TYPED_TEST(GLSLTest, MaxVaryingVec4)
{ {
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
std::string vertexShaderSource; }
GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource); TYPED_TEST(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
{
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
EXPECT_NE(0u, program); VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
} }
TYPED_TEST(GLSLTest, MaxVaryingVec3Array) TYPED_TEST(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
{ {
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
std::string vertexShaderSource; VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
}
GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource); TYPED_TEST(GLSLTest, MaxVaryingVec4PlusFragCoord)
{
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
EXPECT_NE(0u, program); // This test should fail, since we are really using (maxVaryings + 1) varyings.
VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
} }
// Disabled because of a failure in D3D9 TYPED_TEST(GLSLTest, MaxVaryingVec4PlusPointCoord)
TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3AndOneFloat)
{ {
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
std::string vertexShaderSource; // This test should fail, since we are really using (maxVaryings + 1) varyings.
VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
}
GenerateGLSLWithVaryings(1, 0, 0, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource); TYPED_TEST(GLSLTest, MaxVaryingVec3)
{
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
EXPECT_NE(0u, program);
} }
// Disabled because of a failure in D3D9 TYPED_TEST(GLSLTest, MaxVaryingVec3Array)
TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndOneFloatArray)
{ {
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
std::string vertexShaderSource; }
GenerateGLSLWithVaryings(0, 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource); // Disabled because of a failure in D3D9
TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3AndOneFloat)
{
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
EXPECT_NE(0u, program);
} }
// Disabled because of a failure in D3D9 // Disabled because of a failure in D3D9
TYPED_TEST(GLSLTest, DISABLED_TwiceMaxVaryingVec2) TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndOneFloatArray)
{ {
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
std::string vertexShaderSource; }
GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource); // Disabled because of a failure in D3D9
TYPED_TEST(GLSLTest, DISABLED_TwiceMaxVaryingVec2)
{
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
EXPECT_NE(0u, program);
} }
// Disabled because of a failure in D3D9 // Disabled because of a failure in D3D9
...@@ -659,13 +771,7 @@ TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec2Arrays) ...@@ -659,13 +771,7 @@ TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec2Arrays)
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
std::string vertexShaderSource;
GenerateGLSLWithVaryings(0, 0, 0, maxVaryings, 0, 0, &fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
} }
TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3) TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3)
...@@ -673,13 +779,7 @@ TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3) ...@@ -673,13 +779,7 @@ TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3)
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
std::string vertexShaderSource;
GenerateGLSLWithVaryings(0, 0, 0, 0, maxVaryings + 1, 0, &fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_EQ(0u, program);
} }
TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array) TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array)
...@@ -687,13 +787,7 @@ TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array) ...@@ -687,13 +787,7 @@ TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array)
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
std::string vertexShaderSource;
GenerateGLSLWithVaryings(0, 0, 0, 0, 0, maxVaryings / 2 + 1, &fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_EQ(0u, program);
} }
TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2) TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2)
...@@ -701,13 +795,7 @@ TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2) ...@@ -701,13 +795,7 @@ TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2)
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
std::string vertexShaderSource;
GenerateGLSLWithVaryings(0, 0, 1, 0, maxVaryings, 0, &fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_EQ(0u, program);
} }
TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2) TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2)
...@@ -715,13 +803,7 @@ TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2) ...@@ -715,13 +803,7 @@ TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2)
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
std::string vertexShaderSource;
GenerateGLSLWithVaryings(0, 0, 2 * maxVaryings + 1, 0, 0, 0, &fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_EQ(0u, program);
} }
TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray) TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
...@@ -729,13 +811,7 @@ TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray) ...@@ -729,13 +811,7 @@ TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
GLint maxVaryings = 0; GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
std::string fragmentShaderSource; VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
std::string vertexShaderSource;
GenerateGLSLWithVaryings(0, maxVaryings / 2 + 1, 0, 0, 0, maxVaryings / 2, &fragmentShaderSource, &vertexShaderSource);
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_EQ(0u, program);
} }
// Verify shader source with a fixed length that is less than the null-terminated length will compile. // Verify shader source with a fixed length that is less than the null-terminated length will compile.
......
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