Commit cfaaf2ab by Shahbaz Youssefi Committed by Angle LUCI CQ

Vulkan: SPIR-V Gen: Fixes to std430 block definition

Bug: angleproject:4889 Change-Id: I18feff0916f348c8514cc97ba438d42fc00d0cba Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2999023Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent d91af7b8
...@@ -55,6 +55,12 @@ uint32_t GetTotalArrayElements(const SpirvType &type) ...@@ -55,6 +55,12 @@ uint32_t GetTotalArrayElements(const SpirvType &type)
return arraySizeProduct; return arraySizeProduct;
} }
uint32_t GetOutermostArraySize(const SpirvType &type)
{
uint32_t size = type.arraySizes.back();
return size ? size : 1;
}
spirv::IdRef SPIRVBuilder::getNewId(const SpirvDecorations &decorations) spirv::IdRef SPIRVBuilder::getNewId(const SpirvDecorations &decorations)
{ {
spirv::IdRef newId = mNextAvailableId; spirv::IdRef newId = mNextAvailableId;
...@@ -70,14 +76,20 @@ spirv::IdRef SPIRVBuilder::getNewId(const SpirvDecorations &decorations) ...@@ -70,14 +76,20 @@ spirv::IdRef SPIRVBuilder::getNewId(const SpirvDecorations &decorations)
TLayoutBlockStorage SPIRVBuilder::getBlockStorage(const TType &type) const TLayoutBlockStorage SPIRVBuilder::getBlockStorage(const TType &type) const
{ {
// Default to std140. // Default to std140 for uniform and std430 for buffer blocks.
TLayoutBlockStorage blockStorage = type.getLayoutQualifier().blockStorage; TLayoutBlockStorage blockStorage = type.getLayoutQualifier().blockStorage;
if (!IsShaderIoBlock(type.getQualifier()) && blockStorage != EbsStd430) if (IsShaderIoBlock(type.getQualifier()) || blockStorage == EbsStd140 ||
blockStorage == EbsStd430)
{
return blockStorage;
}
if (type.getQualifier() == EvqBuffer)
{ {
blockStorage = EbsStd140; return EbsStd430;
} }
return blockStorage; return EbsStd140;
} }
SpirvType SPIRVBuilder::getSpirvType(const TType &type, TLayoutBlockStorage blockStorage) const SpirvType SPIRVBuilder::getSpirvType(const TType &type, TLayoutBlockStorage blockStorage) const
...@@ -418,12 +430,12 @@ SpirvTypeData SPIRVBuilder::declareType(const SpirvType &type, const TSymbol *bl ...@@ -418,12 +430,12 @@ SpirvTypeData SPIRVBuilder::declareType(const SpirvType &type, const TSymbol *bl
// Write decorations for interface block fields. // Write decorations for interface block fields.
if (type.blockStorage != EbsUnspecified) if (type.blockStorage != EbsUnspecified)
{ {
if (!isOpaqueType && !type.arraySizes.empty()) if (!isOpaqueType && !type.arraySizes.empty() && type.block == nullptr)
{ {
// Write the ArrayStride decoration for arrays inside interface blocks. // Write the ArrayStride decoration for arrays inside interface blocks.
spirv::WriteDecorate( spirv::WriteDecorate(
&mSpirvDecorations, typeId, spv::DecorationArrayStride, &mSpirvDecorations, typeId, spv::DecorationArrayStride,
{spirv::LiteralInteger(sizeInStorageBlock / GetTotalArrayElements(type))}); {spirv::LiteralInteger(sizeInStorageBlock / GetOutermostArraySize(type))});
} }
else if (type.arraySizes.empty() && type.block != nullptr) else if (type.arraySizes.empty() && type.block != nullptr)
{ {
...@@ -1425,6 +1437,7 @@ uint32_t SPIRVBuilder::calculateBaseAlignmentAndSize(const SpirvType &type, ...@@ -1425,6 +1437,7 @@ uint32_t SPIRVBuilder::calculateBaseAlignmentAndSize(const SpirvType &type,
const SpirvTypeData &baseTypeData = getSpirvTypeData(baseType, nullptr); const SpirvTypeData &baseTypeData = getSpirvTypeData(baseType, nullptr);
uint32_t baseAlignment = baseTypeData.baseAlignment; uint32_t baseAlignment = baseTypeData.baseAlignment;
uint32_t baseSizeInStorageBlock = baseTypeData.sizeInStorageBlock;
// For std140 only: // For std140 only:
// > Rule 4. ... and rounded up to the base alignment of a vec4. // > Rule 4. ... and rounded up to the base alignment of a vec4.
...@@ -1432,16 +1445,16 @@ uint32_t SPIRVBuilder::calculateBaseAlignmentAndSize(const SpirvType &type, ...@@ -1432,16 +1445,16 @@ uint32_t SPIRVBuilder::calculateBaseAlignmentAndSize(const SpirvType &type,
// of the structure is vec4. // of the structure is vec4.
if (type.blockStorage != EbsStd430) if (type.blockStorage != EbsStd430)
{ {
baseAlignment = std::max(baseAlignment, 16u); baseAlignment = std::max(baseAlignment, 16u);
baseSizeInStorageBlock = std::max(baseSizeInStorageBlock, 16u);
} }
// Note that matrix arrays follow a similar rule (rules 6 and 8). The matrix base alignment // Note that matrix arrays follow a similar rule (rules 6 and 8). The matrix base alignment
// is the same as its column or row base alignment, and arrays of that matrix don't change // is the same as its column or row base alignment, and arrays of that matrix don't change
// the base alignment. // the base alignment.
// The size occupied by the array is simply the size of each element (which is already // The size occupied by the array is simply the size of each element (which is already
// aligned to baseAlignment) multiplied by the number of elements. // aligned to baseAlignment) multiplied by the number of elements.
*sizeInStorageBlockOut = baseTypeData.sizeInStorageBlock * GetTotalArrayElements(type); *sizeInStorageBlockOut = baseSizeInStorageBlock * GetTotalArrayElements(type);
return baseAlignment; return baseAlignment;
} }
......
...@@ -310,7 +310,7 @@ spv::StorageClass GetStorageClass(const TType &type) ...@@ -310,7 +310,7 @@ spv::StorageClass GetStorageClass(const TType &type)
// Uniform and storage buffers have the Uniform storage class. Default uniforms are gathered in // Uniform and storage buffers have the Uniform storage class. Default uniforms are gathered in
// a uniform block as well. // a uniform block as well.
if (type.isInterfaceBlock() || qualifier == EvqUniform) if (type.getInterfaceBlock() != nullptr || qualifier == EvqUniform)
{ {
// I/O blocks must have already been classified as input or output above. // I/O blocks must have already been classified as input or output above.
ASSERT(!IsShaderIoBlock(qualifier)); ASSERT(!IsShaderIoBlock(qualifier));
......
...@@ -9464,7 +9464,7 @@ void main() ...@@ -9464,7 +9464,7 @@ void main()
WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \ WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \
WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES()) WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES())
ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE()); ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE());
ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest); ANGLE_INSTANTIATE_TEST_ES2_AND(TextureCubeTest, WithDirectSPIRVGeneration(ES2_VULKAN()));
ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale); ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest); ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest); ANGLE_INSTANTIATE_TEST_ES2(SamplerArrayTest);
...@@ -9566,6 +9566,6 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES31); ...@@ -9566,6 +9566,6 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES31);
ANGLE_INSTANTIATE_TEST_ES31_AND(TextureBufferTestES31, WithDirectSPIRVGeneration(ES31_VULKAN())); ANGLE_INSTANTIATE_TEST_ES31_AND(TextureBufferTestES31, WithDirectSPIRVGeneration(ES31_VULKAN()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyImageTestES31); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyImageTestES31);
ANGLE_INSTANTIATE_TEST_ES31(CopyImageTestES31); ANGLE_INSTANTIATE_TEST_ES31_AND(CopyImageTestES31, WithDirectSPIRVGeneration(ES31_VULKAN()));
} // anonymous namespace } // anonymous namespace
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