Commit f54e93d6 by Jamie Madill Committed by Commit Bot

Vulkan: Implement nested sampler structs.

Nested structs are handled similarly as to non-nested samplers in structs. They are extracted and named according to the same pattern. Also enables functional.shaders.random.all_features.fragment* The remaining work in the samplers-in-structs implementation is to translate function arguments. Bug: angleproject:2494 Bug: angleproject:2595 Change-Id: If8170feb71137d4036d352b2b0078518647d48a1 Reviewed-on: https://chromium-review.googlesource.com/1101569 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 10887984
...@@ -1648,6 +1648,17 @@ const TConstantUnion *TIntermBinary::getConstantValue() const ...@@ -1648,6 +1648,17 @@ const TConstantUnion *TIntermBinary::getConstantValue() const
return constIndexingResult; return constIndexingResult;
} }
const ImmutableString &TIntermBinary::getIndexStructFieldName() const
{
ASSERT(mOp == EOpIndexDirectStruct);
const TType &lhsType = mLeft->getType();
const TStructure *structure = lhsType.getStruct();
const int index = mRight->getAsConstantUnion()->getIConst(0);
return structure->fields()[index]->name();
}
TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics) TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
{ {
TConstantUnion *constArray = nullptr; TConstantUnion *constArray = nullptr;
......
...@@ -446,7 +446,10 @@ class TIntermBinary : public TIntermOperator ...@@ -446,7 +446,10 @@ class TIntermBinary : public TIntermOperator
TIntermTyped *fold(TDiagnostics *diagnostics) override; TIntermTyped *fold(TDiagnostics *diagnostics) override;
void setAddIndexClamp() { mAddIndexClamp = true; } void setAddIndexClamp() { mAddIndexClamp = true; }
bool getAddIndexClamp() { return mAddIndexClamp; } bool getAddIndexClamp() const { return mAddIndexClamp; }
// This method is only valid for EOpIndexDirectStruct. It returns the name of the field.
const ImmutableString &getIndexStructFieldName() const;
protected: protected:
TIntermTyped *mLeft; TIntermTyped *mLeft;
......
...@@ -82,37 +82,44 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -82,37 +82,44 @@ class RewriteStructSamplers final : public TIntermTraverser
{ {
if (node->getOp() == EOpIndexDirectStruct && node->getType().isSampler()) if (node->getOp() == EOpIndexDirectStruct && node->getType().isSampler())
{ {
TIntermTyped *lhs = node->getLeft(); std::string stringBuilder;
const TType &lhsType = lhs->getType();
const TStructure *structure = lhsType.getStruct();
int index = node->getRight()->getAsConstantUnion()->getIConst(0);
const ImmutableString &fieldName = structure->fields()[index]->name();
ImmutableStringBuilder stringBuilder(kESSLMaxIdentifierLength + fieldName.length() + TIntermTyped *currentNode = node;
10); while (currentNode->getAsBinaryNode())
TIntermBinary *lhsAsBinary = lhs->getAsBinaryNode();
if (lhsAsBinary)
{ {
ASSERT(lhsAsBinary->getOp() == EOpIndexDirect); TIntermBinary *asBinary = currentNode->getAsBinaryNode();
TIntermTyped *lhsLhs = lhsAsBinary->getLeft();
const int lhsIndex = lhsAsBinary->getRight()->getAsConstantUnion()->getIConst(0);
const ImmutableString &structName = lhsLhs->getAsSymbolNode()->variable().name();
stringBuilder << structName << "_"; switch (asBinary->getOp())
stringBuilder.appendHex(lhsIndex); {
stringBuilder << "_"; case EOpIndexDirect:
{
const int index = asBinary->getRight()->getAsConstantUnion()->getIConst(0);
const std::string strInt = Str(index);
stringBuilder.insert(0, strInt);
stringBuilder.insert(0, "_");
break;
} }
else case EOpIndexDirectStruct:
{ {
const ImmutableString &structName = lhs->getAsSymbolNode()->variable().name(); stringBuilder.insert(0, asBinary->getIndexStructFieldName().data());
stringBuilder << structName << "_"; stringBuilder.insert(0, "_");
break;
} }
stringBuilder << fieldName; default:
UNREACHABLE();
break;
}
currentNode = asBinary->getLeft();
}
TVariable *samplerReplacement = mExtractedSamplers[stringBuilder]; const ImmutableString &variableName = currentNode->getAsSymbolNode()->variable().name();
stringBuilder.insert(0, variableName.data());
ImmutableString newName(stringBuilder);
TVariable *samplerReplacement = mExtractedSamplers[newName];
ASSERT(samplerReplacement); ASSERT(samplerReplacement);
TIntermSymbol *replacement = new TIntermSymbol(samplerReplacement); TIntermSymbol *replacement = new TIntermSymbol(samplerReplacement);
...@@ -125,8 +132,7 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -125,8 +132,7 @@ class RewriteStructSamplers final : public TIntermTraverser
} }
private: private:
void stripStructSpecifierSamplers(const TStructure *structure, void stripStructSpecifierSamplers(const TStructure *structure, TIntermSequence *newSequence)
TIntermSequence *newSequence) const
{ {
TFieldList *newFieldList = new TFieldList; TFieldList *newFieldList = new TFieldList;
ASSERT(structure->containsSamplers()); ASSERT(structure->containsSamplers());
...@@ -135,11 +141,10 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -135,11 +141,10 @@ class RewriteStructSamplers final : public TIntermTraverser
// TODO(jmadill): Fix potential bug. http://anglebug.com/2494 // 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 const TType &fieldType = *field->type();
ASSERT(!field->type()->isStructureContainingSamplers()); if (!fieldType.isSampler() && !isRemovedStructType(fieldType))
if (!field->type()->isSampler())
{ {
TType *newType = new TType(*field->type()); TType *newType = new TType(fieldType);
TField *newField = TField *newField =
new TField(newType, field->name(), field->line(), field->symbolType()); new TField(newType, field->name(), field->line(), field->symbolType());
newFieldList->push_back(newField); newFieldList->push_back(newField);
...@@ -149,6 +154,7 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -149,6 +154,7 @@ class RewriteStructSamplers final : public TIntermTraverser
// Prune empty structs. // Prune empty structs.
if (newFieldList->empty()) if (newFieldList->empty())
{ {
mRemovedStructs.insert(structure->name());
return; return;
} }
...@@ -165,6 +171,12 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -165,6 +171,12 @@ class RewriteStructSamplers final : public TIntermTraverser
newSequence->push_back(structDecl); newSequence->push_back(structDecl);
} }
bool isRemovedStructType(const TType &type) const
{
const TStructure *structure = type.getStruct();
return (structure && (mRemovedStructs.count(structure->name()) > 0));
}
void extractStructSamplerUniforms(TIntermDeclaration *oldDeclaration, void extractStructSamplerUniforms(TIntermDeclaration *oldDeclaration,
const TVariable &variable, const TVariable &variable,
const TStructure *structure, const TStructure *structure,
...@@ -176,58 +188,86 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -176,58 +188,86 @@ 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 nonSamplerCount +=
const TType *fieldType = field->type(); extractFieldSamplers(variable.name(), field, variable.getType(), newSequence);
ASSERT(!fieldType->isStructureContainingSamplers()); }
if (fieldType->isSampler())
if (nonSamplerCount > 0)
{ {
const TType &variableType = variable.getType(); // Keep the old declaration around if it has other members.
if (variableType.isArray()) newSequence->push_back(oldDeclaration);
}
else
{ {
mRemovedUniformsCount++;
}
}
size_t extractFieldSamplers(const ImmutableString &prefix,
const TField *field,
const TType &containingType,
TIntermSequence *newSequence)
{
if (containingType.isArray())
{
size_t nonSamplerCount = 0;
// Name the samplers internally as varName_<index>_fieldName // Name the samplers internally as varName_<index>_fieldName
const TVector<unsigned int> &arraySizes = *variableType.getArraySizes(); const TVector<unsigned int> &arraySizes = *containingType.getArraySizes();
for (unsigned int arrayElement = 0; arrayElement < arraySizes[0]; for (unsigned int arrayElement = 0; arrayElement < arraySizes[0]; ++arrayElement)
++arrayElement)
{ {
ImmutableStringBuilder stringBuilder(variable.name().length() + ImmutableStringBuilder stringBuilder(prefix.length() + 10);
field->name().length() + 10); stringBuilder << prefix << "_";
stringBuilder << variable.name() << "_";
stringBuilder.appendHex(arrayElement); stringBuilder.appendHex(arrayElement);
stringBuilder << "_" << field->name(); nonSamplerCount = extractFieldSamplersImpl(stringBuilder, field, newSequence);
extractSampler(stringBuilder, fieldType, newSequence);
} }
return nonSamplerCount;
} }
else
{ return extractFieldSamplersImpl(prefix, field, newSequence);
// 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);
} }
size_t extractFieldSamplersImpl(const ImmutableString &prefix,
const TField *field,
TIntermSequence *newSequence)
{
size_t nonSamplerCount = 0;
const TType &fieldType = *field->type();
if (fieldType.isSampler() || fieldType.isStructureContainingSamplers())
{
ImmutableStringBuilder stringBuilder(prefix.length() + field->name().length() + 1);
stringBuilder << prefix << "_" << field->name();
ImmutableString newPrefix(stringBuilder);
if (fieldType.isSampler())
{
extractSampler(newPrefix, fieldType, newSequence);
} }
else else
{ {
nonSamplerCount++; const TStructure *structure = fieldType.getStruct();
for (const TField *nestedField : structure->fields())
{
nonSamplerCount +=
extractFieldSamplers(newPrefix, nestedField, fieldType, newSequence);
} }
} }
if (nonSamplerCount > 0)
{
// Keep the old declaration around if it has other members.
newSequence->push_back(oldDeclaration);
} }
else else
{ {
mRemovedUniformsCount++; nonSamplerCount++;
} }
return nonSamplerCount;
} }
void extractSampler(const ImmutableString &newName, void extractSampler(const ImmutableString &newName,
const TType *fieldType, const TType &fieldType,
TIntermSequence *newSequence) TIntermSequence *newSequence)
{ {
TType *newType = new TType(*fieldType); TType *newType = new TType(fieldType);
newType->setQualifier(EvqUniform); newType->setQualifier(EvqUniform);
TVariable *newVariable = TVariable *newVariable =
new TVariable(mSymbolTable, newName, newType, SymbolType::AngleInternal); new TVariable(mSymbolTable, newName, newType, SymbolType::AngleInternal);
...@@ -243,6 +283,7 @@ class RewriteStructSamplers final : public TIntermTraverser ...@@ -243,6 +283,7 @@ class RewriteStructSamplers final : public TIntermTraverser
int mRemovedUniformsCount; int mRemovedUniformsCount;
std::map<ImmutableString, TVariable *> mExtractedSamplers; std::map<ImmutableString, TVariable *> mExtractedSamplers;
std::set<ImmutableString> mRemovedStructs;
}; };
// This traverser translates embedded uniform structs into a specifier and declaration. // This traverser translates embedded uniform structs into a specifier and declaration.
......
...@@ -227,13 +227,14 @@ ...@@ -227,13 +227,14 @@
2580 VULKAN : dEQP-GLES2.functional.buffer.write.recreate_store.different_size = SKIP 2580 VULKAN : dEQP-GLES2.functional.buffer.write.recreate_store.different_size = SKIP
2580 VULKAN : dEQP-GLES2.functional.buffer.write.recreate_store.random_* = SKIP 2580 VULKAN : dEQP-GLES2.functional.buffer.write.recreate_store.random_* = SKIP
2580 VULKAN : dEQP-GLES2.functional.buffer.write.random.* = SKIP 2580 VULKAN : dEQP-GLES2.functional.buffer.write.random.* = SKIP
2494 VULKAN : dEQP-GLES2.functional.shaders.struct.uniform.sampler_* = SKIP 2494 VULKAN : dEQP-GLES2.functional.shaders.struct.uniform.sampler_in_function_arg_* = SKIP
2494 VULKAN : dEQP-GLES2.functional.shaders.struct.uniform.sampler_in_array_function_arg_* = SKIP
2592 VULKAN : dEQP-GLES2.functional.shaders.builtin_variable.depth_range* = SKIP 2592 VULKAN : dEQP-GLES2.functional.shaders.builtin_variable.depth_range* = SKIP
2595 VULKAN : dEQP-GLES2.functional.shaders.random.all_features.fragment* = SKIP 2597 VULKAN : dEQP-GLES2.functional.fbo.render.recreate_stencilbuffer.no_rebind_rbo_rgb* = SKIP
2597 VULKAN : dEQP-GLES2.functional.fbo.render.stencil_clear.tex2d_rgb_stencil_index8 = SKIP
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.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
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.basic.sampler* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.basic.sampler* = SKIP
...@@ -251,7 +252,6 @@ ...@@ -251,7 +252,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.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
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic_struct.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.by_value.get_uniform.basic_struct.sampler2D_* = SKIP
...@@ -260,7 +260,6 @@ ...@@ -260,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.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
2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_partial.basic_array.sampler2D_* = SKIP 2161 VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.basic_array_assign_partial.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