summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
new file mode 100644
index 0000000000..9030c7f370
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// blocklayout.cpp:
+// Implementation for block layout classes and methods.
+//
+
+#include "compiler/translator/blocklayoutHLSL.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace sh
+{
+
+HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices)
+ : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices)
+{}
+
+void HLSLBlockEncoder::enterAggregateType(const ShaderVariable &structVar)
+{
+ align(kComponentsPerRegister);
+}
+
+void HLSLBlockEncoder::exitAggregateType(const ShaderVariable &structVar) {}
+
+void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
+ // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
+ ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == kBytesPerComponent);
+
+ int matrixStride = 0;
+ int arrayStride = 0;
+
+ // if variables are not to be packed, or we're about to
+ // pack a matrix or array, skip to the start of the next
+ // register
+ if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty())
+ {
+ align(kComponentsPerRegister);
+ }
+
+ if (gl::IsMatrixType(type))
+ {
+ matrixStride = kComponentsPerRegister;
+
+ if (!arraySizes.empty())
+ {
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ arrayStride = kComponentsPerRegister * numRegisters;
+ }
+ }
+ else if (!arraySizes.empty())
+ {
+ arrayStride = kComponentsPerRegister;
+ }
+ else if (isPacked())
+ {
+ int numComponents = gl::VariableComponentCount(type);
+ if ((numComponents + (mCurrentOffset % kComponentsPerRegister)) > kComponentsPerRegister)
+ {
+ align(kComponentsPerRegister);
+ }
+ }
+
+ *matrixStrideOut = matrixStride;
+ *arrayStrideOut = arrayStride;
+}
+
+void HLSLBlockEncoder::advanceOffset(GLenum typeIn,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride)
+{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
+ if (!arraySizes.empty())
+ {
+ unsigned int arraySize = gl::ArraySizeProduct(arraySizes);
+ if (arraySize > 0)
+ {
+ mCurrentOffset += arrayStride * (arraySize - 1);
+ }
+ }
+
+ if (gl::IsMatrixType(type))
+ {
+ ASSERT(matrixStride == kComponentsPerRegister);
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
+ mCurrentOffset += kComponentsPerRegister * (numRegisters - 1);
+ mCurrentOffset += numComponents;
+ }
+ else if (isPacked())
+ {
+ mCurrentOffset += gl::VariableComponentCount(type);
+ }
+ else
+ {
+ mCurrentOffset += kComponentsPerRegister;
+ }
+}
+
+void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
+{
+ mCurrentOffset += (numRegisters * kComponentsPerRegister);
+}
+
+HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(
+ ShShaderOutput outputType)
+{
+ switch (outputType)
+ {
+ case SH_HLSL_3_0_OUTPUT:
+ return ENCODE_LOOSE;
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
+ return ENCODE_PACKED;
+ default:
+ UNREACHABLE();
+ return ENCODE_PACKED;
+ }
+}
+
+template <class ShaderVarType>
+void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
+{
+ if (variable.isStruct())
+ {
+ for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++)
+ {
+ encoder->enterAggregateType(variable);
+
+ for (const ShaderVariable &field : variable.fields)
+ {
+ HLSLVariableRegisterCount(field, encoder);
+ }
+
+ encoder->exitAggregateType(variable);
+ }
+ }
+ else
+ {
+ // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
+ encoder->encodeType(variable.type, variable.arraySizes, false);
+ }
+}
+
+unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType)
+{
+ HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true);
+ HLSLVariableRegisterCount(variable, &encoder);
+
+ const size_t registerBytes = (encoder.kBytesPerComponent * encoder.kComponentsPerRegister);
+ return static_cast<unsigned int>(
+ rx::roundUp<size_t>(encoder.getCurrentOffset(), registerBytes) / registerBytes);
+}
+} // namespace sh