Commit d87b3a85 by Alexis Hetu Committed by Alexis Hétu

Fixed sampler within struct uniform used as function argument

The sampler was simply not declared in that case, as if the uniform was unused in the shader, so making sure structures containing samplers call samplerRegister solves this issue. It was working properly if the sampler was used anywhere else in the shader, but failed when the only use in the shader was being passed as an argument to a function through a containing structure. Added a unit test since this isn't covered by dEQP. Fixes 2 WebGL tests: conformance/glsl/bugs/sampler-array-struct-function-arg.html conformance/glsl/bugs/sampler-struct-function-arg.html Change-Id: I81767d7c6415de7aefefecffcc66265d944a94ab Reviewed-on: https://swiftshader-review.googlesource.com/18628Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 99be318a
...@@ -2859,6 +2859,10 @@ namespace glsl ...@@ -2859,6 +2859,10 @@ namespace glsl
{ {
return samplerRegister(operand); return samplerRegister(operand);
} }
else if(operand->getType().totalSamplerRegisterCount() > 0) // Struct containing a sampler
{
samplerRegister(operand); // Make sure the sampler is declared
}
switch(operand->getQualifier()) switch(operand->getQualifier())
{ {
......
...@@ -233,6 +233,10 @@ protected: ...@@ -233,6 +233,10 @@ protected:
glLinkProgram(ph.program); glLinkProgram(ph.program);
EXPECT_GLENUM_EQ(GL_NONE, glGetError()); EXPECT_GLENUM_EQ(GL_NONE, glGetError());
GLint linkStatus = 0;
glGetProgramiv(ph.program, GL_LINK_STATUS, &linkStatus);
EXPECT_NE(linkStatus, 0);
return ph; return ph;
} }
...@@ -243,7 +247,7 @@ protected: ...@@ -243,7 +247,7 @@ protected:
glDeleteProgram(ph.program); glDeleteProgram(ph.program);
} }
void drawQuad(GLuint program) void drawQuad(GLuint program, const char* textureName)
{ {
GLint prevProgram = 0; GLint prevProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram); glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);
...@@ -254,7 +258,7 @@ protected: ...@@ -254,7 +258,7 @@ protected:
GLint posLoc = glGetAttribLocation(program, "position"); GLint posLoc = glGetAttribLocation(program, "position");
EXPECT_GLENUM_EQ(GL_NONE, glGetError()); EXPECT_GLENUM_EQ(GL_NONE, glGetError());
GLint location = glGetUniformLocation(program, "tex"); GLint location = glGetUniformLocation(program, textureName);
ASSERT_NE(-1, location); ASSERT_NE(-1, location);
glUniform1i(location, 0); glUniform1i(location, 0);
...@@ -306,6 +310,64 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -306,6 +310,64 @@ TEST_F(SwiftShaderTest, Initalization)
Uninitialize(); Uninitialize();
} }
// Test sampling from a sampler in a struct as a function argument
TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg)
{
Initialize(3, false);
GLuint tex = 1;
glBindTexture(GL_TEXTURE_2D, tex);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
unsigned char green[4] = { 0, 255, 0, 255 };
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
const std::string vs =
"#version 300 es\n"
"in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position.xy, 0.0, 1.0);\n"
"}\n";
const std::string fs =
"#version 300 es\n"
"precision mediump float;\n"
"struct SamplerStruct{ sampler2D tex[2]; };\n"
"vec4 doSample(in SamplerStruct s[2])\n"
"{\n"
" return texture(s[1].tex[1], vec2(0.0));\n"
"}\n"
"uniform SamplerStruct samplerStruct[2];\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
" fragColor = doSample(samplerStruct);\n"
"}\n";
const ProgramHandles ph = createProgram(vs, fs);
glUseProgram(ph.program);
GLint location = glGetUniformLocation(ph.program, "samplerStruct[1].tex[1]");
ASSERT_NE(-1, location);
glUniform1i(location, 0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
drawQuad(ph.program, "samplerStruct[1].tex[1]");
deleteProgram(ph);
compareColor(green);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
Uninitialize();
}
// Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo // Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo
// GL_ARB_texture_rectangle // GL_ARB_texture_rectangle
#ifndef GL_ARB_texture_rectangle #ifndef GL_ARB_texture_rectangle
...@@ -558,7 +620,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle) ...@@ -558,7 +620,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GLENUM_EQ(GL_NONE, glGetError()); EXPECT_GLENUM_EQ(GL_NONE, glGetError());
drawQuad(ph.program); drawQuad(ph.program, "tex");
deleteProgram(ph); deleteProgram(ph);
...@@ -612,7 +674,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3) ...@@ -612,7 +674,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GLENUM_EQ(GL_NONE, glGetError()); EXPECT_GLENUM_EQ(GL_NONE, glGetError());
drawQuad(ph.program); drawQuad(ph.program, "tex");
deleteProgram(ph); deleteProgram(ph);
...@@ -976,7 +1038,7 @@ protected: ...@@ -976,7 +1038,7 @@ protected:
const ProgramHandles ph = createProgram(vs, fs); const ProgramHandles ph = createProgram(vs, fs);
drawQuad(ph.program); drawQuad(ph.program, "tex");
deleteProgram(ph); deleteProgram(ph);
......
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