Commit 28839f03 by Olli Etuaho Committed by Commit Bot

Fix handling sampler arrays in structs as function arguments on HLSL

Some of the code was written under the mistaken assumption that createSamplerSymbols would be splitting sampler arrays in structs into individual samplers. Fix it by adding array dimensions to sampler parameters generated by createSamplerSymbols when necessary. BUG=angleproject:2128 TEST=angle_end2end_tests Change-Id: Ie622c777d78ae65b5629d12e0ae574800c1b78f5 Reviewed-on: https://chromium-review.googlesource.com/614882 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent afa75152
...@@ -2579,29 +2579,26 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) ...@@ -2579,29 +2579,26 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
&samplerSymbols, nullptr); &samplerSymbols, nullptr);
for (const TIntermSymbol *sampler : samplerSymbols) for (const TIntermSymbol *sampler : samplerSymbols)
{ {
const TType &samplerType = sampler->getType();
if (mOutputType == SH_HLSL_4_1_OUTPUT) if (mOutputType == SH_HLSL_4_1_OUTPUT)
{ {
ASSERT(!sampler->getType().isArray()); argString << ", const uint " << sampler->getSymbol() << ArrayString(samplerType);
argString << ", const uint " << sampler->getSymbol();
} }
else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
{ {
const TType &samplerType = sampler->getType();
ASSERT(!samplerType.isArray());
ASSERT(IsSampler(samplerType.getBasicType())); ASSERT(IsSampler(samplerType.getBasicType()));
argString << ", " << QualifierString(qualifier) << " " argString << ", " << QualifierString(qualifier) << " "
<< TextureString(samplerType.getBasicType()) << " texture_" << TextureString(samplerType.getBasicType()) << " texture_"
<< sampler->getSymbol() << ", " << QualifierString(qualifier) << " " << sampler->getSymbol() << ArrayString(samplerType) << ", "
<< QualifierString(qualifier) << " "
<< SamplerString(samplerType.getBasicType()) << " sampler_" << SamplerString(samplerType.getBasicType()) << " sampler_"
<< sampler->getSymbol(); << sampler->getSymbol() << ArrayString(samplerType);
} }
else else
{ {
const TType &samplerType = sampler->getType();
ASSERT(!samplerType.isArray());
ASSERT(IsSampler(samplerType.getBasicType())); ASSERT(IsSampler(samplerType.getBasicType()));
argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType) argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType)
<< " " << sampler->getSymbol(); << " " << sampler->getSymbol() << ArrayString(samplerType);
} }
} }
} }
......
...@@ -3313,6 +3313,68 @@ TEST_P(GLSLTest, ArrayOfStructsWithSamplersAsFunctionArg) ...@@ -3313,6 +3313,68 @@ TEST_P(GLSLTest, ArrayOfStructsWithSamplersAsFunctionArg)
EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green); EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
} }
// This test covers passing a struct containing an array of samplers as a function argument.
TEST_P(GLSLTest, StructWithSamplerArrayAsFunctionArg)
{
if (IsAndroid() && IsAdreno() && IsOpenGLES())
{
// Shader failed to compile on Android. http://anglebug.com/2114
std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
return;
}
const std::string &vertexShader =
"attribute vec2 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position, 0, 1);\n"
"}\n";
const std::string &fragmentShader =
"precision mediump float;\n"
"struct S\n"
"{\n"
" sampler2D samplerMembers[2];\n"
"};\n"
"uniform S uStruct;\n"
"uniform vec2 uTexCoord;\n"
"\n"
"vec4 foo(S str)\n"
"{\n"
" return texture2D(str.samplerMembers[0], uTexCoord);\n"
"}\n"
"void main()\n"
"{\n"
" gl_FragColor = foo(uStruct);\n"
"}\n";
ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
// Initialize the texture with green.
GLTexture tex;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
GLubyte texData[] = {0u, 255u, 0u, 255u};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
// Draw
glUseProgram(program);
GLint samplerMemberLoc = glGetUniformLocation(program, "uStruct.samplerMembers[0]");
ASSERT_NE(-1, samplerMemberLoc);
glUniform1i(samplerMemberLoc, 0);
GLint texCoordLoc = glGetUniformLocation(program, "uTexCoord");
ASSERT_NE(-1, texCoordLoc);
glUniform2f(texCoordLoc, 0.5f, 0.5f);
drawQuad(program, "position", 0.5f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
}
// 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.
ANGLE_INSTANTIATE_TEST(GLSLTest, ANGLE_INSTANTIATE_TEST(GLSLTest,
ES2_D3D9(), ES2_D3D9(),
......
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