Commit 10887984 by Jamie Madill Committed by Commit Bot

Vulkan: Sampler structs in arrays.

Samplers are extracted from arrays of struct uniforms similarly as with non-arrays. They are named according to the variable name, array element and sampler field name. Nested structs to come later. Bug: angleproject:2494 Change-Id: Ie2f5f7bd1f747e73b3c6b505b2b1043cfe1073b5 Reviewed-on: https://chromium-review.googlesource.com/1101568 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent d07c52e2
...@@ -16,10 +16,6 @@ namespace sh ...@@ -16,10 +16,6 @@ namespace sh
namespace namespace
{ {
// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
static const unsigned int kESSLMaxIdentifierLength = 1024u;
constexpr const ImmutableString kHashedNamePrefix("webgl_"); constexpr const ImmutableString kHashedNamePrefix("webgl_");
// Can't prefix with just _ because then we might introduce a double underscore, which is not safe // Can't prefix with just _ because then we might introduce a double underscore, which is not safe
......
...@@ -51,7 +51,6 @@ class ImmutableStringBuilder ...@@ -51,7 +51,6 @@ class ImmutableStringBuilder
mData[mPos++] = digitChar; mData[mPos++] = digitChar;
--index; --index;
} }
return;
} }
private: private:
...@@ -66,6 +65,9 @@ class ImmutableStringBuilder ...@@ -66,6 +65,9 @@ class ImmutableStringBuilder
char *mData; char *mData;
}; };
// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
constexpr unsigned int kESSLMaxIdentifierLength = 1024u;
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_ #endif // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
...@@ -82,14 +82,35 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -82,14 +82,35 @@ class RewriteStructSamplers final : public TIntermTraverser
{ {
if (node->getOp() == EOpIndexDirectStruct && node->getType().isSampler()) if (node->getOp() == EOpIndexDirectStruct && node->getType().isSampler())
{ {
TIntermTyped *lhs = node->getLeft(); TIntermTyped *lhs = node->getLeft();
const ImmutableString &structName = lhs->getAsSymbolNode()->variable().name(); const TType &lhsType = lhs->getType();
const TStructure *structure = lhs->getType().getStruct(); const TStructure *structure = lhsType.getStruct();
int index = node->getRight()->getAsConstantUnion()->getIConst(0); int index = node->getRight()->getAsConstantUnion()->getIConst(0);
const ImmutableString &fieldName = structure->fields()[index]->name(); const ImmutableString &fieldName = structure->fields()[index]->name();
ImmutableStringBuilder stringBuilder(structName.length() + fieldName.length() + 1); ImmutableStringBuilder stringBuilder(kESSLMaxIdentifierLength + fieldName.length() +
stringBuilder << structName << "_" << fieldName; 10);
TIntermBinary *lhsAsBinary = lhs->getAsBinaryNode();
if (lhsAsBinary)
{
ASSERT(lhsAsBinary->getOp() == EOpIndexDirect);
TIntermTyped *lhsLhs = lhsAsBinary->getLeft();
const int lhsIndex = lhsAsBinary->getRight()->getAsConstantUnion()->getIConst(0);
const ImmutableString &structName = lhsLhs->getAsSymbolNode()->variable().name();
stringBuilder << structName << "_";
stringBuilder.appendHex(lhsIndex);
stringBuilder << "_";
}
else
{
const ImmutableString &structName = lhs->getAsSymbolNode()->variable().name();
stringBuilder << structName << "_";
}
stringBuilder << fieldName;
TVariable *samplerReplacement = mExtractedSamplers[stringBuilder]; TVariable *samplerReplacement = mExtractedSamplers[stringBuilder];
ASSERT(samplerReplacement); ASSERT(samplerReplacement);
...@@ -110,6 +131,8 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -110,6 +131,8 @@ class RewriteStructSamplers final : public TIntermTraverser
TFieldList *newFieldList = new TFieldList; TFieldList *newFieldList = new TFieldList;
ASSERT(structure->containsSamplers()); ASSERT(structure->containsSamplers());
// Removing the sampler field may produce struct indexing bugs.
// TODO(jmadill): Fix potential bug. http://anglebug.com/2494
for (const TField *field : structure->fields()) for (const TField *field : structure->fields())
{ {
// TODO(jmadill): Nested struct samplers. http://anglebug.com/2494 // TODO(jmadill): Nested struct samplers. http://anglebug.com/2494
...@@ -154,26 +177,34 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -154,26 +177,34 @@ class RewriteStructSamplers final : public TIntermTraverser
for (const TField *field : structure->fields()) for (const TField *field : structure->fields())
{ {
// TODO(jmadill): Nested struct samplers. http://anglebug.com/2494 // TODO(jmadill): Nested struct samplers. http://anglebug.com/2494
ASSERT(!field->type()->isStructureContainingSamplers()); const TType *fieldType = field->type();
if (field->type()->isSampler()) ASSERT(!fieldType->isStructureContainingSamplers());
if (fieldType->isSampler())
{ {
// Name the sampler internally as varName_fieldName const TType &variableType = variable.getType();
ImmutableStringBuilder stringBuilder(variable.name().length() + if (variableType.isArray())
field->name().length() + 1); {
stringBuilder << variable.name() << "_" << field->name(); // Name the samplers internally as varName_<index>_fieldName
ImmutableString newName(stringBuilder); const TVector<unsigned int> &arraySizes = *variableType.getArraySizes();
TType *newType = new TType(*field->type()); for (unsigned int arrayElement = 0; arrayElement < arraySizes[0];
newType->setQualifier(EvqUniform); ++arrayElement)
TVariable *newVariable = {
new TVariable(mSymbolTable, newName, newType, SymbolType::AngleInternal); ImmutableStringBuilder stringBuilder(variable.name().length() +
TIntermSymbol *newRef = new TIntermSymbol(newVariable); field->name().length() + 10);
stringBuilder << variable.name() << "_";
TIntermDeclaration *samplerDecl = new TIntermDeclaration; stringBuilder.appendHex(arrayElement);
samplerDecl->appendDeclarator(newRef); stringBuilder << "_" << field->name();
extractSampler(stringBuilder, fieldType, newSequence);
newSequence->push_back(samplerDecl); }
}
mExtractedSamplers[newName] = newVariable; else
{
// Name the sampler internally as varName_fieldName
ImmutableStringBuilder stringBuilder(variable.name().length() +
field->name().length() + 1);
stringBuilder << variable.name() << "_" << field->name();
extractSampler(stringBuilder, fieldType, newSequence);
}
} }
else else
{ {
...@@ -192,6 +223,24 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -192,6 +223,24 @@ class RewriteStructSamplers final : public TIntermTraverser
} }
} }
void extractSampler(const ImmutableString &newName,
const TType *fieldType,
TIntermSequence *newSequence)
{
TType *newType = new TType(*fieldType);
newType->setQualifier(EvqUniform);
TVariable *newVariable =
new TVariable(mSymbolTable, newName, newType, SymbolType::AngleInternal);
TIntermSymbol *newRef = new TIntermSymbol(newVariable);
TIntermDeclaration *samplerDecl = new TIntermDeclaration;
samplerDecl->appendDeclarator(newRef);
newSequence->push_back(samplerDecl);
mExtractedSamplers[newName] = newVariable;
}
int mRemovedUniformsCount; int mRemovedUniformsCount;
std::map<ImmutableString, TVariable *> mExtractedSamplers; std::map<ImmutableString, TVariable *> mExtractedSamplers;
}; };
......
...@@ -235,6 +235,11 @@ gl::LinkResult GlslangWrapper::linkProgram(const gl::Context *glContext, ...@@ -235,6 +235,11 @@ gl::LinkResult GlslangWrapper::linkProgram(const gl::Context *glContext,
// Samplers in structs are extracted. // Samplers in structs are extracted.
std::replace(samplerName.begin(), samplerName.end(), '.', '_'); std::replace(samplerName.begin(), samplerName.end(), '.', '_');
// Samplers in arrays of structs are also extracted.
std::replace(samplerName.begin(), samplerName.end(), '[', '_');
samplerName.erase(std::remove(samplerName.begin(), samplerName.end(), ']'),
samplerName.end());
ASSERT(samplerUniform.isActive(gl::ShaderType::Vertex) || ASSERT(samplerUniform.isActive(gl::ShaderType::Vertex) ||
samplerUniform.isActive(gl::ShaderType::Fragment)); samplerUniform.isActive(gl::ShaderType::Fragment));
if (samplerUniform.isActive(gl::ShaderType::Vertex)) if (samplerUniform.isActive(gl::ShaderType::Vertex))
......
...@@ -233,7 +233,6 @@ ...@@ -233,7 +233,6 @@
2161 VULKAN : dEQP-GLES2.functional.vertex_arrays.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.vertex_arrays.* = SKIP
2598 VULKAN : dEQP-GLES2.functional.rasterization.primitives.line* = SKIP 2598 VULKAN : dEQP-GLES2.functional.rasterization.primitives.line* = SKIP
2599 VULKAN : dEQP-GLES2.functional.rasterization.limits.points = SKIP 2599 VULKAN : dEQP-GLES2.functional.rasterization.limits.points = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.struct_in_array.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.nested_structs_arrays.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.nested_structs_arrays.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.multiple_nested_structs_arrays.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.multiple_nested_structs_arrays.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.unused_uniforms.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.info_query.unused_uniforms.sampler2D_* = SKIP
...@@ -252,7 +251,6 @@ ...@@ -252,7 +251,6 @@
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.get_uniform.nested_structs_arrays.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.get_uniform.nested_structs_arrays.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.get_uniform.basic_array_first_elem_without_brackets.sampler2D* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.get_uniform.basic_array_first_elem_without_brackets.sampler2D* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.basic.samplerCube* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.basic.samplerCube* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.struct_in_array.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic.sampler* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic.sampler* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic_array.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic_array.sampler2D_* = SKIP
...@@ -262,7 +260,6 @@ ...@@ -262,7 +260,6 @@
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.nested_structs_arrays.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.nested_structs_arrays.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic_array_first_elem_without_brackets.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic_array_first_elem_without_brackets.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.basic.samplerCube* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.basic.samplerCube* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.struct_in_array.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_full.array_in_struct.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_full.array_in_struct.sampler2D_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_full.basic_array.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_full.basic_array.sampler2D_* = SKIP
......
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