Browse Source

[spirv] Add support for VK_EXT_scalar_block_layout

Ref: https://github.com/KhronosGroup/Vulkan-Docs/issues/854
Lei Zhang 6 years ago
parent
commit
f8c493f577

+ 1 - 0
include/dxc/Support/SPIRVOptions.h

@@ -31,6 +31,7 @@ enum class SpirvLayoutRule {
   RelaxedGLSLStd430, // std430 with relaxed vector layout
   FxcCTBuffer,       // fxc.exe layout rule for cbuffer/tbuffer
   FxcSBuffer,        // fxc.exe layout rule for structured buffers
+  Scalar,            // VK_EXT_scalar_block_layout
   Max,               // This is an invalid layout rule
 };
 

+ 17 - 6
tools/clang/lib/SPIRV/AlignmentSizeCalculator.cpp

@@ -190,9 +190,10 @@ std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
       uint32_t alignment = 0, size = 0;
       std::tie(alignment, size) =
           getAlignmentAndSize(elemType, rule, isRowMajor, stride);
-      // Use element alignment for fxc rules
+      // Use element alignment for fxc rules and VK_EXT_scalar_block_layout
       if (rule != SpirvLayoutRule::FxcCTBuffer &&
-          rule != SpirvLayoutRule::FxcSBuffer)
+          rule != SpirvLayoutRule::FxcSBuffer &&
+          rule != SpirvLayoutRule::Scalar)
         alignment = (elemCount == 3 ? 4 : elemCount) * size;
 
       return {alignment, elemCount * size};
@@ -217,9 +218,11 @@ std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
 
       const uint32_t vecStorageSize = rowMajor ? rowCount : colCount;
 
-      if (rule == SpirvLayoutRule::FxcSBuffer) {
+      if (rule == SpirvLayoutRule::FxcSBuffer ||
+          rule == SpirvLayoutRule::Scalar) {
         *stride = vecStorageSize * size;
-        // Use element alignment for fxc structured buffers
+        // Use element alignment for fxc structured buffers and
+        // VK_EXT_scalar_block_layout
         return {alignment, rowCount * colCount * size};
       }
 
@@ -274,6 +277,12 @@ std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
       structSize += memberSize;
     }
 
+    if (rule == SpirvLayoutRule::Scalar) {
+      // A structure has a scalar alignment equal to the largest scalar
+      // alignment of any of its members in VK_EXT_scalar_block_layout.
+      return {maxAlignment, structSize};
+    }
+
     if (rule == SpirvLayoutRule::GLSLStd140 ||
         rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
         rule == SpirvLayoutRule::FxcCTBuffer) {
@@ -297,9 +306,11 @@ std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
     std::tie(alignment, size) = getAlignmentAndSize(arrayType->getElementType(),
                                                     rule, isRowMajor, stride);
 
-    if (rule == SpirvLayoutRule::FxcSBuffer) {
+    if (rule == SpirvLayoutRule::FxcSBuffer ||
+        rule == SpirvLayoutRule::Scalar) {
       *stride = size;
-      // Use element alignment for fxc structured buffers
+      // Use element alignment for fxc structured buffers and
+      // VK_EXT_scalar_block_layout
       return {alignment, size * elemCount};
     }