Commit c2157a09 by Olli Etuaho Committed by Commit Bot

HLSL: Fix handling nested structs in interface blocks

Make sure that the type definitions for nested structs get added to the HLSL header, and that the std140 padding information gets recorded. Prior to this trying to use nested structs in interface blocks crashed. BUG=angleproject:2084 TEST=angle_end2end_tests Change-Id: If57870285c6feaf0c2e462f98f50f20730dd6470 Reviewed-on: https://chromium-review.googlesource.com/608449Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent d23bcd8e
...@@ -248,6 +248,20 @@ TString StructureHLSL::addConstructor(const TType &type, ...@@ -248,6 +248,20 @@ TString StructureHLSL::addConstructor(const TType &type,
const TStructure *structure = type.getStruct(); const TStructure *structure = type.getStruct();
if (structure) if (structure)
{ {
const TFieldList &fields = structure->fields();
for (const TField *field : fields)
{
const TType *fieldType = field->type();
if (!IsSampler(fieldType->getBasicType()))
{
ctorParameters.push_back(*fieldType);
}
if (fieldType->getBasicType() == EbtStruct)
{
addConstructor(*fieldType, StructNameString(*fieldType->getStruct()), nullptr);
}
}
mStructNames.insert(name); mStructNames.insert(name);
// Add element index // Add element index
...@@ -275,15 +289,6 @@ TString StructureHLSL::addConstructor(const TType &type, ...@@ -275,15 +289,6 @@ TString StructureHLSL::addConstructor(const TType &type,
mStructDeclarations.push_back(std140RowMajorString); mStructDeclarations.push_back(std140RowMajorString);
} }
const TFieldList &fields = structure->fields();
for (const TField *field : fields)
{
const TType *fieldType = field->type();
if (!IsSampler(fieldType->getBasicType()))
{
ctorParameters.push_back(*fieldType);
}
}
constructorFunctionName = TString(name); constructorFunctionName = TString(name);
} }
else if (parameters) else if (parameters)
...@@ -556,9 +561,9 @@ void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, ...@@ -556,9 +561,9 @@ void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
Std140PaddingHelper padHelper = getPaddingHelper(); Std140PaddingHelper padHelper = getPaddingHelper();
const TFieldList &fields = structure.fields(); const TFieldList &fields = structure.fields();
for (unsigned int i = 0; i < fields.size(); i++) for (const TField *field : fields)
{ {
padHelper.prePadding(*fields[i]->type()); padHelper.prePadding(*field->type());
} }
// Add remaining element index to the global map, for use with nested structs in standard // Add remaining element index to the global map, for use with nested structs in standard
...@@ -566,4 +571,5 @@ void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, ...@@ -566,4 +571,5 @@ void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true); const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true);
mStd140StructElementIndexes[structName] = padHelper.elementIndex(); mStd140StructElementIndexes[structName] = padHelper.elementIndex();
} }
}
} // namespace sh
...@@ -906,6 +906,55 @@ TEST_P(UniformBufferTest, BlockContainingArrayOfStructsContainingArrays) ...@@ -906,6 +906,55 @@ TEST_P(UniformBufferTest, BlockContainingArrayOfStructsContainingArrays)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// Test with a block containing nested structs.
TEST_P(UniformBufferTest, BlockContainingNestedStructs)
{
const std::string &fragmentShader =
"#version 300 es\n"
"precision highp float;\n"
"out vec4 my_FragColor;\n"
"struct light_t {\n"
" vec4 intensity;\n"
"};\n"
"struct lightWrapper_t {\n"
" light_t light;\n"
"};\n"
"const int maxLights = 2;\n"
"layout(std140) uniform lightData { lightWrapper_t lightWrapper; };\n"
"vec4 processLight(vec4 lighting, lightWrapper_t aLightWrapper)\n"
"{\n"
" return lighting + aLightWrapper.light.intensity;\n"
"}\n"
"void main()\n"
"{\n"
" vec4 lighting = vec4(0, 0, 0, 1);\n"
" for (int n = 0; n < maxLights; n++)\n"
" {\n"
" lighting = processLight(lighting, lightWrapper);\n"
" }\n"
" my_FragColor = lighting;\n"
"}\n";
ANGLE_GL_PROGRAM(program, mVertexShaderSource, fragmentShader);
GLint uniformBufferIndex = glGetUniformBlockIndex(program, "lightData");
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
const GLsizei kVectorsPerStruct = 3;
const GLsizei kElementsPerVector = 4;
const GLsizei kBytesPerElement = 4;
const GLsizei kDataSize = kVectorsPerStruct * kElementsPerVector * kBytesPerElement;
std::vector<GLubyte> v(kDataSize, 0);
float *vAsFloat = reinterpret_cast<float *>(v.data());
vAsFloat[1] = 1.0f;
glBufferData(GL_UNIFORM_BUFFER, kDataSize, v.data(), GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
glUniformBlockBinding(program, uniformBufferIndex, 0);
drawQuad(program.get(), "position", 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, 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(UniformBufferTest, ANGLE_INSTANTIATE_TEST(UniformBufferTest,
ES3_D3D11(), ES3_D3D11(),
......
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