diff --git a/src/libANGLE/renderer/d3d/ProgramExecutableD3D.cpp b/src/libANGLE/renderer/d3d/ProgramExecutableD3D.cpp index 5d545a61bf..40fb589523 100644 --- a/src/libANGLE/renderer/d3d/ProgramExecutableD3D.cpp +++ b/src/libANGLE/renderer/d3d/ProgramExecutableD3D.cpp @@ -1809,8 +1809,19 @@ void ProgramExecutableD3D::defineUniformBase(gl::ShaderType shaderType, } const SharedCompiledShaderStateD3D &shaderD3D = mAttachedShaders[shaderType]; - unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name); - ShShaderOutput outputType = shaderD3D->compilerOutputType; + if (!shaderD3D->hasUniform(uniform.name)) + { + // The uniform was reported as active by the front end but ended up unreferenced in the + // translated HLSL for this stage. Encode it with the stub encoder so that the D3DUniform + // is still created. + UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::None, &stubEncoder, + uniformMap); + sh::TraverseShaderVariable(uniform, false, &visitor); + return; + } + + unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name); + ShShaderOutput outputType = shaderD3D->compilerOutputType; sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true); encoder.skipRegisters(startRegister); diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp index cd8223f2d6..fc5e35b65b 100644 --- a/src/tests/gl_tests/GLSLTest.cpp +++ b/src/tests/gl_tests/GLSLTest.cpp @@ -9162,6 +9162,34 @@ void main() EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); } +// Test linking and using a program where a uniform is referenced only as a side-effect-free +// argument of an array constructor that is used as a statement. The other constructor argument +// has a side effect that the program output depends on. +TEST_P(GLSLTest_ES3, UniformReferencedOnlyInArrayConstructorStatement) +{ + constexpr char kFS[] = R"(#version 300 es +precision highp float; +uniform int u_zero; +out vec4 my_FragColor; +void main() +{ + int i = 0; + int[2](u_zero, i++); + my_FragColor = (i == 1) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1); +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); + glUseProgram(program); + GLint loc = glGetUniformLocation(program, "u_zero"); + if (loc != -1) + { + glUniform1i(loc, 0); + } + drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + // Test calling array length() with a "this" expression having side effects inside an if condition. // This is an issue if the the side effect can be short circuited. TEST_P(GLSLTest_ES3, ArrayLengthOnShortCircuitedExpressionWithSideEffectsInIfCondition)