summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp439
1 files changed, 439 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
new file mode 100644
index 0000000000..f4eeab5ab9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
@@ -0,0 +1,439 @@
+//
+// Copyright 2018 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.
+//
+// ShaderStorageBlockFunctionHLSL: Wrapper functions for RWByteAddressBuffer Load/Store functions.
+//
+
+#include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOLoadFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ const char *convertString;
+ switch (ssboFunction.type.getBasicType())
+ {
+ case EbtFloat:
+ convertString = "asfloat(";
+ break;
+ case EbtInt:
+ convertString = "asint(";
+ break;
+ case EbtUInt:
+ convertString = "asuint(";
+ break;
+ case EbtBool:
+ convertString = "asint(";
+ break;
+ default:
+ UNREACHABLE();
+ return;
+ }
+
+ size_t bytesPerComponent =
+ gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
+ out << " " << ssboFunction.typeString << " result";
+ if (ssboFunction.type.isScalar())
+ {
+ size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
+ out << " = " << convertString << "buffer.Load(loc + " << offset << "));\n ";
+ }
+ else if (ssboFunction.type.isVector())
+ {
+ if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
+ {
+ size_t componentStride = bytesPerComponent;
+ if (ssboFunction.rowMajor)
+ {
+ componentStride = ssboFunction.matrixStride;
+ }
+
+ out << " = {";
+ for (const int offset : ssboFunction.swizzleOffsets)
+ {
+ size_t offsetInBytes = offset * componentStride;
+ out << convertString << "buffer.Load(loc + " << offsetInBytes << ")),";
+ }
+ out << "};\n";
+ }
+ else
+ {
+ out << " = " << convertString << "buffer.Load"
+ << static_cast<uint32_t>(ssboFunction.type.getNominalSize()) << "(loc));\n";
+ }
+ }
+ else if (ssboFunction.type.isMatrix())
+ {
+ if (ssboFunction.rowMajor)
+ {
+ out << ";";
+ out << " float" << static_cast<uint32_t>(ssboFunction.type.getRows()) << "x"
+ << static_cast<uint32_t>(ssboFunction.type.getCols()) << " tmp_ = {";
+ for (uint8_t rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
+ {
+ out << "asfloat(buffer.Load" << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << "(loc + " << rowIndex * ssboFunction.matrixStride << ")), ";
+ }
+ out << "};\n";
+ out << " result = transpose(tmp_);\n";
+ }
+ else
+ {
+ out << " = {";
+ for (uint8_t columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
+ {
+ out << "asfloat(buffer.Load" << static_cast<uint32_t>(ssboFunction.type.getRows())
+ << "(loc + " << columnIndex * ssboFunction.matrixStride << ")), ";
+ }
+ out << "};\n";
+ }
+ }
+ else
+ {
+ // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
+ out << ";\n";
+ }
+
+ out << " return result;\n";
+ return;
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOStoreFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ size_t bytesPerComponent =
+ gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
+ if (ssboFunction.type.isScalar())
+ {
+ size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
+ if (ssboFunction.type.getBasicType() == EbtBool)
+ {
+ out << " buffer.Store(loc + " << offset << ", uint(value));\n";
+ }
+ else
+ {
+ out << " buffer.Store(loc + " << offset << ", asuint(value));\n";
+ }
+ }
+ else if (ssboFunction.type.isVector())
+ {
+ out << " uint" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << " _value;\n";
+ if (ssboFunction.type.getBasicType() == EbtBool)
+ {
+ out << " _value = uint" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << "(value);\n";
+ }
+ else
+ {
+ out << " _value = asuint(value);\n";
+ }
+
+ if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
+ {
+ size_t componentStride = bytesPerComponent;
+ if (ssboFunction.rowMajor)
+ {
+ componentStride = ssboFunction.matrixStride;
+ }
+ const TVector<int> &swizzleOffsets = ssboFunction.swizzleOffsets;
+ for (int index = 0; index < static_cast<int>(swizzleOffsets.size()); index++)
+ {
+ size_t offsetInBytes = swizzleOffsets[index] * componentStride;
+ out << "buffer.Store(loc + " << offsetInBytes << ", _value[" << index << "]);\n";
+ }
+ }
+ else
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << "(loc, _value);\n";
+ }
+ }
+ else if (ssboFunction.type.isMatrix())
+ {
+ if (ssboFunction.rowMajor)
+ {
+ out << " float" << static_cast<uint32_t>(ssboFunction.type.getRows()) << "x"
+ << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << " tmp_ = transpose(value);\n";
+ for (uint8_t rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << "(loc + " << rowIndex * ssboFunction.matrixStride << ", asuint(tmp_["
+ << static_cast<uint32_t>(rowIndex) << "]));\n";
+ }
+ }
+ else
+ {
+ for (uint8_t columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getRows())
+ << "(loc + " << columnIndex * ssboFunction.matrixStride << ", asuint(value["
+ << static_cast<uint32_t>(columnIndex) << "]));\n";
+ }
+ }
+ }
+ else
+ {
+ // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
+ }
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOLengthFunctionBody(TInfoSinkBase &out,
+ int unsizedArrayStride)
+{
+ out << " uint dim = 0;\n";
+ out << " buffer.GetDimensions(dim);\n";
+ out << " return int((dim - loc)/uint(" << unsizedArrayStride << "));\n";
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOAtomicMemoryFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ out << " " << ssboFunction.typeString << " original_value;\n";
+ switch (ssboFunction.method)
+ {
+ case SSBOMethod::ATOMIC_ADD:
+ out << " buffer.InterlockedAdd(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_MIN:
+ out << " buffer.InterlockedMin(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_MAX:
+ out << " buffer.InterlockedMax(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_AND:
+ out << " buffer.InterlockedAnd(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_OR:
+ out << " buffer.InterlockedOr(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_XOR:
+ out << " buffer.InterlockedXor(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ out << " buffer.InterlockedExchange(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ out << " buffer.InterlockedCompareExchange(loc, compare_value, value, "
+ "original_value);\n";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ out << " return original_value;\n";
+}
+
+bool ShaderStorageBlockFunctionHLSL::ShaderStorageBlockFunction::operator<(
+ const ShaderStorageBlockFunction &rhs) const
+{
+ return functionName < rhs.functionName;
+}
+
+TString ShaderStorageBlockFunctionHLSL::registerShaderStorageBlockFunction(
+ const TType &type,
+ SSBOMethod method,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ int matrixStride,
+ int unsizedArrayStride,
+ TIntermSwizzle *swizzleNode)
+{
+ ShaderStorageBlockFunction ssboFunction;
+ ssboFunction.typeString = TypeString(type);
+ ssboFunction.method = method;
+ switch (method)
+ {
+ case SSBOMethod::LOAD:
+ ssboFunction.functionName = "_Load_";
+ break;
+ case SSBOMethod::STORE:
+ ssboFunction.functionName = "_Store_";
+ break;
+ case SSBOMethod::LENGTH:
+ ssboFunction.unsizedArrayStride = unsizedArrayStride;
+ ssboFunction.functionName = "_Length_" + str(unsizedArrayStride);
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_ADD:
+ ssboFunction.functionName = "_ssbo_atomicAdd_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_MIN:
+ ssboFunction.functionName = "_ssbo_atomicMin_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_MAX:
+ ssboFunction.functionName = "_ssbo_atomicMax_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_AND:
+ ssboFunction.functionName = "_ssbo_atomicAnd_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_OR:
+ ssboFunction.functionName = "_ssbo_atomicOr_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_XOR:
+ ssboFunction.functionName = "_ssbo_atomicXor_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ ssboFunction.functionName = "_ssbo_atomicExchange_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ ssboFunction.functionName = "_ssbo_atomicCompSwap_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ default:
+ UNREACHABLE();
+ }
+
+ ssboFunction.functionName += ssboFunction.typeString;
+ ssboFunction.type = type;
+ if (swizzleNode != nullptr)
+ {
+ ssboFunction.swizzleOffsets = swizzleNode->getSwizzleOffsets();
+ ssboFunction.isDefaultSwizzle = false;
+ }
+ else
+ {
+ if (ssboFunction.type.getNominalSize() > 1)
+ {
+ for (uint8_t index = 0; index < ssboFunction.type.getNominalSize(); index++)
+ {
+ ssboFunction.swizzleOffsets.push_back(index);
+ }
+ }
+ else
+ {
+ ssboFunction.swizzleOffsets.push_back(0);
+ }
+
+ ssboFunction.isDefaultSwizzle = true;
+ }
+ ssboFunction.rowMajor = rowMajor;
+ ssboFunction.matrixStride = matrixStride;
+ ssboFunction.functionName += "_" + TString(getBlockStorageString(storage));
+
+ if (rowMajor)
+ {
+ ssboFunction.functionName += "_rm_";
+ }
+ else
+ {
+ ssboFunction.functionName += "_cm_";
+ }
+
+ for (const int offset : ssboFunction.swizzleOffsets)
+ {
+ switch (offset)
+ {
+ case 0:
+ ssboFunction.functionName += "x";
+ break;
+ case 1:
+ ssboFunction.functionName += "y";
+ break;
+ case 2:
+ ssboFunction.functionName += "z";
+ break;
+ case 3:
+ ssboFunction.functionName += "w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+}
+
+void ShaderStorageBlockFunctionHLSL::shaderStorageBlockFunctionHeader(TInfoSinkBase &out)
+{
+ for (const ShaderStorageBlockFunction &ssboFunction : mRegisteredShaderStorageBlockFunctions)
+ {
+ switch (ssboFunction.method)
+ {
+ case SSBOMethod::LOAD:
+ {
+ // Function header
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc)\n";
+ out << "{\n";
+ OutputSSBOLoadFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::STORE:
+ {
+ // Function header
+ out << "void " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " value)\n";
+ out << "{\n";
+ OutputSSBOStoreFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::LENGTH:
+ {
+ out << "int " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc)\n";
+ out << "{\n";
+ OutputSSBOLengthFunctionBody(out, ssboFunction.unsizedArrayStride);
+ break;
+ }
+ case SSBOMethod::ATOMIC_ADD:
+ case SSBOMethod::ATOMIC_MIN:
+ case SSBOMethod::ATOMIC_MAX:
+ case SSBOMethod::ATOMIC_AND:
+ case SSBOMethod::ATOMIC_OR:
+ case SSBOMethod::ATOMIC_XOR:
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ {
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " value)\n";
+ out << "{\n";
+
+ OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ {
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " compare_value, " << ssboFunction.typeString << " value)\n";
+ out << "{\n";
+ OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh