Commit 3860b6c0 by Olli Etuaho Committed by Commit Bot

Fix arrays of structs containing samplers as parameters on HLSL

In HLSL output, samplers are never passed to functions as arrays, but rather sampler array arguments are expanded into single sampler and/or texture arguments. This applies also when the samplers were inside arrays of structs in the original source. BUG=angleproject:2103 TEST=angle_end2end_tests Change-Id: Ib1fcba0c0ab3da592d15272eb56a03c3e536f349 Reviewed-on: https://chromium-review.googlesource.com/576041Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 191381fd
...@@ -2557,34 +2557,33 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) ...@@ -2557,34 +2557,33 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
{ {
ASSERT(qualifier != EvqOut && qualifier != EvqInOut); ASSERT(qualifier != EvqOut && qualifier != EvqInOut);
TVector<TIntermSymbol *> samplerSymbols; TVector<TIntermSymbol *> samplerSymbols;
type.createSamplerSymbols("angle" + nameStr, "", 0u, &samplerSymbols, nullptr); type.createSamplerSymbols("angle" + nameStr, "", type.isArray() ? type.getArraySize() : 0u,
&samplerSymbols, nullptr);
for (const TIntermSymbol *sampler : samplerSymbols) for (const TIntermSymbol *sampler : samplerSymbols)
{ {
if (mOutputType == SH_HLSL_4_1_OUTPUT) if (mOutputType == SH_HLSL_4_1_OUTPUT)
{ {
argString << ", const uint " << sampler->getSymbol() << ArrayString(type); ASSERT(!sampler->getType().isArray());
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(); const TType &samplerType = sampler->getType();
ASSERT((!type.isArray() && !samplerType.isArray()) || ASSERT(!samplerType.isArray());
type.getArraySize() == samplerType.getArraySize());
ASSERT(IsSampler(samplerType.getBasicType())); ASSERT(IsSampler(samplerType.getBasicType()));
argString << ", " << QualifierString(qualifier) << " " argString << ", " << QualifierString(qualifier) << " "
<< TextureString(samplerType.getBasicType()) << " texture_" << TextureString(samplerType.getBasicType()) << " texture_"
<< sampler->getSymbol() << ArrayString(type) << ", " << sampler->getSymbol() << ", " << QualifierString(qualifier) << " "
<< QualifierString(qualifier) << " "
<< SamplerString(samplerType.getBasicType()) << " sampler_" << SamplerString(samplerType.getBasicType()) << " sampler_"
<< sampler->getSymbol() << ArrayString(type); << sampler->getSymbol();
} }
else else
{ {
const TType &samplerType = sampler->getType(); const TType &samplerType = sampler->getType();
ASSERT((!type.isArray() && !samplerType.isArray()) || ASSERT(!samplerType.isArray());
type.getArraySize() == samplerType.getArraySize());
ASSERT(IsSampler(samplerType.getBasicType())); ASSERT(IsSampler(samplerType.getBasicType()));
argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType) argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType)
<< " " << sampler->getSymbol() << ArrayString(type); << " " << sampler->getSymbol();
} }
} }
} }
......
...@@ -3251,6 +3251,68 @@ TEST_P(GLSLTest_ES3, VaryingStructUsedInFragmentShader) ...@@ -3251,6 +3251,68 @@ TEST_P(GLSLTest_ES3, VaryingStructUsedInFragmentShader)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// This test covers passing an array of structs containing samplers as a function argument.
TEST_P(GLSLTest, ArrayOfStructsWithSamplersAsFunctionArg)
{
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 samplerMember; \n"
"};\n"
"uniform S uStructs[2];\n"
"uniform vec2 uTexCoord;\n"
"\n"
"vec4 foo(S[2] structs)\n"
"{\n"
" return texture2D(structs[0].samplerMember, uTexCoord);\n"
"}\n"
"void main()\n"
"{\n"
" gl_FragColor = foo(uStructs);\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, "uStructs[0].samplerMember");
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