Commit d0800d29 by Ian Elliott Committed by Commit Bot

Vulkan: Fix crashes/failures in array-of-struct uniforms

When array-of-struct support was added to ANGLE, it was not added to the shader cache serialize/deserialize functions. This affects many GLES 2/3/3.1 dEQP tests, such as: dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.struct_in_array.sampler2D_samplerCube_vertex Bug: angleproject:4475 Bug: b:151387995 Change-Id: I159f6340db255ec50c16b59fec23a61ed05aa8f7 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2118152 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent b91d2630
......@@ -5183,6 +5183,8 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi
stream.writeInt(uniform.bufferIndex);
WriteBlockMemberInfo(&stream, uniform.blockInfo);
stream.writeIntVector(uniform.outerArraySizes);
// Active shader info
for (ShaderType shaderType : gl::AllShaderTypes())
{
......@@ -5388,6 +5390,8 @@ angle::Result Program::deserialize(const Context *context,
uniform.bufferIndex = stream.readInt<int>();
LoadBlockMemberInfo(&stream, &uniform.blockInfo);
stream.readIntVector<unsigned int>(&uniform.outerArraySizes);
uniform.typeInfo = &GetUniformTypeInfo(uniform.type);
// Active shader info
......
......@@ -595,19 +595,6 @@
4016 SWIFTSHADER : dEQP-GLES3.functional.fragment_ops.interaction.basic_shader.27 = FAIL
4016 SWIFTSHADER : dEQP-GLES3.functional.fragment_ops.interaction.basic_shader.80 = FAIL
// These only fail on Android
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_samplerCube_both = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_samplerCube_fragment = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_samplerCube_vertex = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_pointer.render.struct_in_array.sampler2D_samplerCube_both = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_pointer.render.struct_in_array.sampler2D_samplerCube_fragment = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_pointer.render.struct_in_array.sampler2D_samplerCube_vertex = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_samplerCube_both = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_samplerCube_fragment = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_samplerCube_vertex = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_value.render.struct_in_array.sampler2D_samplerCube_both = FAIL
4045 SWIFTSHADER : dEQP-GLES3.functional.uniform_api.value.assigned.by_value.render.struct_in_array.sampler2D_samplerCube_fragment = FAIL
// Fails on SwANGLE bots
4416 SWIFTSHADER : dEQP-GLES3.functional.fbo.blit.conversion.r11f_g11f_b10f_to_r16f = FAIL
4416 SWIFTSHADER : dEQP-GLES3.functional.fbo.blit.conversion.r11f_g11f_b10f_to_rg16f = FAIL
......
......@@ -293,7 +293,7 @@ void ProgramBinaryES3Test::testBinaryAndUBOBlockIndexes(bool drawWithProgramFirs
// We can't run the test if no program binary formats are supported.
GLint binaryFormatCount = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &binaryFormatCount);
ANGLE_SKIP_TEST_IF(!binaryFormatCount);
ANGLE_SKIP_TEST_IF(binaryFormatCount == 0);
constexpr char kVS[] =
"#version 300 es\n"
......@@ -381,13 +381,147 @@ TEST_P(ProgramBinaryES3Test, UniformBlockBindingNoDraw)
testBinaryAndUBOBlockIndexes(false);
}
// Test the shaders with arrays-of-struct uniforms are properly saved and restored
TEST_P(ProgramBinaryES3Test, TestArrayOfStructUniform)
{
// We can't run the test if no program binary formats are supported.
GLint binaryFormatCount = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &binaryFormatCount);
ANGLE_SKIP_TEST_IF(binaryFormatCount == 0);
constexpr char kVS[] =
"#version 300 es\n"
"in highp vec4 position;\n"
"out mediump float v_vtxOut;\n"
"\n"
"struct structType\n"
"{\n"
" mediump vec4 m0;\n"
" mediump vec4 m1;\n"
"};\n"
"uniform structType u_var[3];\n"
"\n"
"mediump float compare_float(mediump float a, mediump float b)\n"
"{\n"
" return abs(a - b) < 0.05 ? 1.0 : 0.0;\n"
"}\n"
"mediump float compare_vec4(mediump vec4 a, mediump vec4 b)\n"
"{\n"
" return compare_float(a.x, b.x)*compare_float(a.y, b.y)*\n"
" compare_float(a.z, b.z)*compare_float(a.w, b.w);\n"
"}\n"
"\n"
"void main (void)\n"
"{\n"
" gl_Position = position;\n"
" v_vtxOut = 1.0;\n"
" v_vtxOut *= compare_vec4(u_var[0].m0, vec4(0.15, 0.52, 0.26, 0.35));\n"
" v_vtxOut *= compare_vec4(u_var[0].m1, vec4(0.88, 0.09, 0.30, 0.61));\n"
" v_vtxOut *= compare_vec4(u_var[1].m0, vec4(0.85, 0.59, 0.33, 0.71));\n"
" v_vtxOut *= compare_vec4(u_var[1].m1, vec4(0.62, 0.89, 0.09, 0.99));\n"
" v_vtxOut *= compare_vec4(u_var[2].m0, vec4(0.53, 0.89, 0.01, 0.08));\n"
" v_vtxOut *= compare_vec4(u_var[2].m1, vec4(0.26, 0.72, 0.60, 0.12));\n"
"}";
constexpr char kFS[] =
"#version 300 es\n"
"in mediump float v_vtxOut;\n"
"\n"
"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
"\n"
"void main (void)\n"
"{\n"
" mediump float result = v_vtxOut;\n"
" dEQP_FragColor = vec4(result, result, result, 1.0);\n"
"}";
// Init and draw with the program.
ANGLE_GL_PROGRAM(program, kVS, kFS);
glUseProgram(program.get());
int location = glGetUniformLocation(program.get(), "u_var[0].m0");
ASSERT_NE(location, -1);
glUniform4f(location, 0.15, 0.52, 0.26, 0.35);
location = glGetUniformLocation(program.get(), "u_var[0].m1");
ASSERT_NE(location, -1);
glUniform4f(location, 0.88, 0.09, 0.30, 0.61);
location = glGetUniformLocation(program.get(), "u_var[1].m0");
ASSERT_NE(location, -1);
glUniform4f(location, 0.85, 0.59, 0.33, 0.71);
location = glGetUniformLocation(program.get(), "u_var[1].m1");
ASSERT_NE(location, -1);
glUniform4f(location, 0.62, 0.89, 0.09, 0.99);
location = glGetUniformLocation(program.get(), "u_var[2].m0");
ASSERT_NE(location, -1);
glUniform4f(location, 0.53, 0.89, 0.01, 0.08);
location = glGetUniformLocation(program.get(), "u_var[2].m1");
ASSERT_NE(location, -1);
glUniform4f(location, 0.26, 0.72, 0.60, 0.12);
ASSERT_GL_NO_ERROR();
// Clear and draw with the original program:
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
drawQuad(program.get(), "position", 0.5f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
// Read back the binary.
GLint programLength = 0;
glGetProgramiv(program.get(), GL_PROGRAM_BINARY_LENGTH_OES, &programLength);
ASSERT_GL_NO_ERROR();
GLsizei readLength = 0;
GLenum binaryFormat = GL_NONE;
std::vector<uint8_t> binary(programLength);
glGetProgramBinary(program.get(), programLength, &readLength, &binaryFormat, binary.data());
ASSERT_GL_NO_ERROR();
EXPECT_EQ(static_cast<GLsizei>(programLength), readLength);
// Load a new program with the binary and draw.
ANGLE_GL_BINARY_ES3_PROGRAM(binaryProgram, binary, binaryFormat);
glUseProgram(binaryProgram.get());
location = glGetUniformLocation(binaryProgram.get(), "u_var[0].m0");
ASSERT_NE(location, -1);
glUniform4f(location, 0.15, 0.52, 0.26, 0.35);
location = glGetUniformLocation(binaryProgram.get(), "u_var[0].m1");
ASSERT_NE(location, -1);
glUniform4f(location, 0.88, 0.09, 0.30, 0.61);
location = glGetUniformLocation(binaryProgram.get(), "u_var[1].m0");
ASSERT_NE(location, -1);
glUniform4f(location, 0.85, 0.59, 0.33, 0.71);
location = glGetUniformLocation(binaryProgram.get(), "u_var[1].m1");
ASSERT_NE(location, -1);
glUniform4f(location, 0.62, 0.89, 0.09, 0.99);
location = glGetUniformLocation(binaryProgram.get(), "u_var[2].m0");
ASSERT_NE(location, -1);
glUniform4f(location, 0.53, 0.89, 0.01, 0.08);
location = glGetUniformLocation(binaryProgram.get(), "u_var[2].m1");
ASSERT_NE(location, -1);
glUniform4f(location, 0.26, 0.72, 0.60, 0.12);
ASSERT_GL_NO_ERROR();
// Clear and draw with the restored program:
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
drawQuad(binaryProgram.get(), "position", 0.5f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
}
// Tests the difference between uniform static and active use
TEST_P(ProgramBinaryES3Test, ActiveUniformShader)
{
// We can't run the test if no program binary formats are supported.
GLint binaryFormatCount = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &binaryFormatCount);
ANGLE_SKIP_TEST_IF(!binaryFormatCount);
ANGLE_SKIP_TEST_IF(binaryFormatCount == 0);
constexpr char kVS[] =
"#version 300 es\n"
......@@ -470,7 +604,7 @@ TEST_P(ProgramBinaryES3Test, BinaryWithLargeUniformCount)
// We can't run the test if no program binary formats are supported.
GLint binaryFormatCount = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &binaryFormatCount);
ANGLE_SKIP_TEST_IF(!binaryFormatCount);
ANGLE_SKIP_TEST_IF(binaryFormatCount == 0);
constexpr char kVS[] =
"#version 300 es\n"
......@@ -638,7 +772,7 @@ TEST_P(ProgramBinaryES31Test, ProgramBinaryWithComputeShader)
// We can't run the test if no program binary formats are supported.
GLint binaryFormatCount = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &binaryFormatCount);
ANGLE_SKIP_TEST_IF(!binaryFormatCount);
ANGLE_SKIP_TEST_IF(binaryFormatCount == 0);
// http://anglebug.com/4092
ANGLE_SKIP_TEST_IF(IsVulkan());
......@@ -750,7 +884,7 @@ TEST_P(ProgramBinaryES31Test, ImageTextureBinding)
// We can't run the test if no program binary formats are supported.
GLint binaryFormatCount = 0;
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &binaryFormatCount);
ANGLE_SKIP_TEST_IF(!binaryFormatCount);
ANGLE_SKIP_TEST_IF(binaryFormatCount == 0);
const char kComputeShader[] =
R"(#version 310 es
......
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