Redesign the code that uses block layouts to use a generic base class.

The cleaner code also has the benefit of allowing us to separate the HLSL-specific parts out of the shader validator.

TRAC #23083

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Authored-by: Jamie Madill
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 2bf96e5..450ce83 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -13,6 +13,7 @@
 #include "compiler/InfoSink.h"
 #include "compiler/SearchSymbol.h"
 #include "compiler/UnfoldShortCircuit.h"
+#include "compiler/HLSLLayoutEncoder.h"
 
 #include <algorithm>
 #include <cfloat>
@@ -284,6 +285,37 @@
     return hlsl;
 }
 
+// Use the same layout for packed and shared
+void setBlockLayout(InterfaceBlock *interfaceBlock, BlockLayoutType newLayout)
+{
+    interfaceBlock->layout = newLayout;
+    interfaceBlock->blockInfo.clear();
+
+    switch (newLayout)
+    {
+      case BLOCKLAYOUT_SHARED:
+      case BLOCKLAYOUT_PACKED:
+        {
+            HLSLBlockEncoder hlslEncoder(&interfaceBlock->blockInfo);
+            hlslEncoder.encodeFields(interfaceBlock->activeUniforms);
+            interfaceBlock->dataSize = hlslEncoder.getBlockSize();
+        }
+        break;
+
+      case BLOCKLAYOUT_STANDARD:
+        {
+            Std140BlockEncoder stdEncoder(&interfaceBlock->blockInfo);
+            stdEncoder.encodeFields(interfaceBlock->activeUniforms);
+            interfaceBlock->dataSize = stdEncoder.getBlockSize();
+        }
+        break;
+
+      default:
+        UNREACHABLE();
+        break;
+    }
+}
+
 void OutputHLSL::header()
 {
     ShShaderType shaderType = mContext.shaderType;
@@ -335,7 +367,7 @@
         mInterfaceBlockRegister += std::max(1u, interfaceBlock.arraySize);
 
         // TODO: handle other block layouts
-        interfaceBlock.setBlockLayout(BLOCKLAYOUT_SHARED);
+        setBlockLayout(&interfaceBlock, BLOCKLAYOUT_SHARED);
         mActiveInterfaceBlocks.push_back(interfaceBlock);
 
         if (interfaceBlockType.hasInstanceName())