summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp71
-rw-r--r--source/slang/hlsl.meta.slang61
-rw-r--r--source/slang/hlsl.meta.slang.h61
-rw-r--r--source/slang/ir-inst-defs.h8
-rw-r--r--source/slang/ir.h7
5 files changed, 168 insertions, 40 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 8038561d0..a3b99691d 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -5999,6 +5999,66 @@ struct EmitVisitor
emit(";\n");
}
+ void emitIRByteAddressBuffer_GLSL(
+ EmitContext* ctx,
+ IRGlobalVar* varDecl,
+ IRByteAddressBufferTypeBase* /* byteAddressBufferType */)
+ {
+ // TODO: A lot of this logic is copy-pasted from `emitIRStructuredBuffer_GLSL`.
+ // It might be worthwhile to share the common code to avoid regressions sneaking
+ // in when one or the other, but not both, gets updated.
+
+ // Shader storage buffer is an OpenGL 430 feature
+ //
+ // TODO: we should require either the extension or the version...
+ requireGLSLVersion(430);
+
+ Emit("layout(std430");
+
+ auto layout = getVarLayout(ctx, varDecl);
+ if (layout)
+ {
+ LayoutResourceKind kind = LayoutResourceKind::DescriptorTableSlot;
+ EmitVarChain chain(layout);
+
+ const UInt index = getBindingOffset(&chain, kind);
+ const UInt space = getBindingSpace(&chain, kind);
+
+ Emit(", binding = ");
+ Emit(index);
+ if (space)
+ {
+ Emit(", set = ");
+ Emit(space);
+ }
+ }
+
+ emit(") buffer ");
+
+ // Generate a dummy name for the block
+ emit("_S");
+ Emit(ctx->shared->uniqueIDCounter++);
+ emit("\n{\n");
+ indent();
+
+ emit("uint ");
+ emit(getIRName(varDecl));
+ emit("[];\n");
+
+ dedent();
+ emit("}");
+
+ // TODO: we need to consider the case where the type of the variable is
+ // an *array* of structured buffers, in which case we need to declare
+ // the block as an array too.
+ //
+ // The main challenge here is that then the block will have a name,
+ // and also the field inside the block will have a name, so that when
+ // the user had written `a[i][j]` we now need to emit `a[i].someName[j]`.
+
+ emit(";\n");
+ }
+
void emitIRGlobalVar(
EmitContext* ctx,
IRGlobalVar* varDecl)
@@ -6048,6 +6108,17 @@ struct EmitVisitor
return;
}
+ // When outputting GLSL, we need to transform any declaration of
+ // a `*ByteAddressBuffer<T>` into an ordinary `buffer` declaration.
+ if( auto byteAddressBufferType = as<IRByteAddressBufferTypeBase>(unwrapArray(varType)) )
+ {
+ emitIRByteAddressBuffer_GLSL(
+ ctx,
+ varDecl,
+ byteAddressBufferType);
+ return;
+ }
+
// We want to skip the declaration of any system-value variables
// when outputting GLSL (well, except in the case where they
// actually *require* redeclaration...).
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 36cefc699..57c4e1324 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -18,19 +18,28 @@ __magic_type(HLSLByteAddressBufferType)
__intrinsic_type($(kIROp_HLSLByteAddressBufferType))
struct ByteAddressBuffer
{
+ __target_intrinsic(glsl, "$1 = $0.length()")
void GetDimensions(
out uint dim);
+ __target_intrinsic(glsl, "$0[$1]")
uint Load(int location);
+
uint Load(int location, out uint status);
+ __target_intrinsic(glsl, "uvec2($0[$1], $0[$1+1])")
uint2 Load2(int location);
+
uint2 Load2(int location, out uint status);
+ __target_intrinsic(glsl, "uvec3($0[$1], $0[$1+1], $0[$1+2])")
uint3 Load3(int location);
+
uint3 Load3(int location, out uint status);
+ __target_intrinsic(glsl, "uvec4($0[$1], $0[$1+1], $0[$1+2], $0[$1+3])")
uint4 Load4(int location);
+
uint4 Load4(int location, out uint status);
};
@@ -93,112 +102,136 @@ __magic_type(HLSL$(item.name)Type)
__intrinsic_type($(item.op))
struct $(item.name)
{
- // Note(tfoley): supports alll operations from `ByteAddressBuffer`
+ // Note(tfoley): supports all operations from `ByteAddressBuffer`
// TODO(tfoley): can this be made a sub-type?
+ __target_intrinsic(glsl, "$1 = $0.length()")
void GetDimensions(
out uint dim);
+ __target_intrinsic(glsl, "$0[$1]")
uint Load(int location);
+
uint Load(int location, out uint status);
+ __target_intrinsic(glsl, "uvec2($0[$1], $0[$1+4])")
uint2 Load2(int location);
+
uint2 Load2(int location, out uint status);
+ __target_intrinsic(glsl, "uvec3($0[$1], $0[$1+4], $0[$1+8])")
uint3 Load3(int location);
+
uint3 Load3(int location, out uint status);
+ __target_intrinsic(glsl, "uvec4($0[$1], $0[$1+4], $0[$1+8], $0[$1+12])")
uint4 Load4(int location);
+
uint4 Load4(int location, out uint status);
// Added operations:
+ __target_intrinsic(glsl, "($3 = atomicAdd($0[$1], $2))")
void InterlockedAdd(
UINT dest,
UINT value,
out UINT original_value);
+
+ __target_intrinsic(glsl, "atomicAdd($0[$1], $2)")
void InterlockedAdd(
UINT dest,
UINT value);
+ __target_intrinsic(glsl, "($3 = atomicAnd($0[$1], $2))")
void InterlockedAnd(
UINT dest,
UINT value,
out UINT original_value);
+
+ __target_intrinsic(glsl, "atomicAnd($0[$1], $2)")
void InterlockedAnd(
UINT dest,
UINT value);
+ __target_intrinsic(glsl, "($4 = atomicCompSwap($0[$1], $2, $3))")
void InterlockedCompareExchange(
UINT dest,
UINT compare_value,
UINT value,
out UINT original_value);
- void InterlockedCompareExchange(
- UINT dest,
- UINT compare_value,
- UINT value);
+ __target_intrinsic(glsl, "atomicCompSwap($0[$1], $2, $3)")
void InterlockedCompareStore(
UINT dest,
UINT compare_value,
UINT value);
- void InterlockedCompareStore(
- UINT dest,
- UINT compare_value);
+ __target_intrinsic(glsl, "($3 = atomicExchange($0[$1], $2))")
void InterlockedExchange(
UINT dest,
UINT value,
out UINT original_value);
- void InterlockedExchange(
- UINT dest,
- UINT value);
+ __target_intrinsic(glsl, "($3 = atomicMax($0[$1], $2))")
void InterlockedMax(
UINT dest,
UINT value,
out UINT original_value);
+
+ __target_intrinsic(glsl, "atomicMax($0[$1], $2)")
void InterlockedMax(
UINT dest,
UINT value);
+ __target_intrinsic(glsl, "($3 = atomicMin($0[$1], $2))")
void InterlockedMin(
UINT dest,
UINT value,
out UINT original_value);
+
+ __target_intrinsic(glsl, "atomicMin($0[$1], $2)")
void InterlockedMin(
UINT dest,
UINT value);
+ __target_intrinsic(glsl, "($3 = atomicOr($0[$1], $2))")
void InterlockedOr(
UINT dest,
UINT value,
out UINT original_value);
+
+ __target_intrinsic(glsl, "atomicOr($0[$1], $2)")
void InterlockedOr(
UINT dest,
UINT value);
+ __target_intrinsic(glsl, "($3 = atomicXor($0[$1], $2))")
void InterlockedXor(
UINT dest,
UINT value,
out UINT original_value);
+
+ __target_intrinsic(glsl, "atomicXor($0[$1], $2)")
void InterlockedXor(
UINT dest,
UINT value);
+ __target_intrinsic(glsl, "$0[$1] = $2")
void Store(
uint address,
uint value);
+ __target_intrinsic(glsl, "$0[$1] = $2.x, $0[$1+4] = $2.y")
void Store2(
uint address,
uint2 value);
+ __target_intrinsic(glsl, "$0[$1] = $2.x, $0[$1+4] = $2.y, $0[$1+8] = $2.z")
void Store3(
uint address,
uint3 value);
+ __target_intrinsic(glsl, "$0[$1] = $2.x, $0[$1+4] = $2.y, $0[$1+8] = $2.z, $0[$1+12] = $2.w")
void Store4(
uint address,
uint4 value);
@@ -687,12 +720,6 @@ void InterlockedCompareStore(__ref int dest, int compare_value, int value);
__target_intrinsic(glsl, "$atomicCompSwap($A, $1, $2)")
void InterlockedCompareStore(__ref uint dest, uint compare_value, uint value);
-__target_intrinsic(glsl, "$atomicExchange($A, $1)")
-void InterlockedExchange(__ref int dest, int value);
-
-__target_intrinsic(glsl, "$atomicExchange($A, $1)")
-void InterlockedExchange(__ref uint dest, uint value);
-
__target_intrinsic(glsl, "($2 = $atomicExchange($A, $1))")
void InterlockedExchange(__ref int dest, int value, out int original_value);
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h
index 7194c9990..9b8205536 100644
--- a/source/slang/hlsl.meta.slang.h
+++ b/source/slang/hlsl.meta.slang.h
@@ -24,19 +24,28 @@ SLANG_SPLICE(kIROp_HLSLByteAddressBufferType
SLANG_RAW(")\n")
SLANG_RAW("struct ByteAddressBuffer\n")
SLANG_RAW("{\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$1 = $0.length()\")\n")
SLANG_RAW(" void GetDimensions(\n")
SLANG_RAW(" out uint dim);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$0[$1]\")\n")
SLANG_RAW(" uint Load(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint Load(int location, out uint status);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"uvec2($0[$1], $0[$1+1])\")\n")
SLANG_RAW(" uint2 Load2(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint2 Load2(int location, out uint status);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"uvec3($0[$1], $0[$1+1], $0[$1+2])\")\n")
SLANG_RAW(" uint3 Load3(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint3 Load3(int location, out uint status);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"uvec4($0[$1], $0[$1+1], $0[$1+2], $0[$1+3])\")\n")
SLANG_RAW(" uint4 Load4(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint4 Load4(int location, out uint status);\n")
SLANG_RAW("};\n")
SLANG_RAW("\n")
@@ -120,112 +129,136 @@ SLANG_SPLICE(item.name
)
SLANG_RAW("\n")
SLANG_RAW("{\n")
-SLANG_RAW(" // Note(tfoley): supports alll operations from `ByteAddressBuffer`\n")
+SLANG_RAW(" // Note(tfoley): supports all operations from `ByteAddressBuffer`\n")
SLANG_RAW(" // TODO(tfoley): can this be made a sub-type?\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$1 = $0.length()\")\n")
SLANG_RAW(" void GetDimensions(\n")
SLANG_RAW(" out uint dim);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$0[$1]\")\n")
SLANG_RAW(" uint Load(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint Load(int location, out uint status);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"uvec2($0[$1], $0[$1+4])\")\n")
SLANG_RAW(" uint2 Load2(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint2 Load2(int location, out uint status);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"uvec3($0[$1], $0[$1+4], $0[$1+8])\")\n")
SLANG_RAW(" uint3 Load3(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint3 Load3(int location, out uint status);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"uvec4($0[$1], $0[$1+4], $0[$1+8], $0[$1+12])\")\n")
SLANG_RAW(" uint4 Load4(int location);\n")
+SLANG_RAW("\n")
SLANG_RAW(" uint4 Load4(int location, out uint status);\n")
SLANG_RAW("\n")
SLANG_RAW(" // Added operations:\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicAdd($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedAdd(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicAdd($0[$1], $2)\")\n")
SLANG_RAW(" void InterlockedAdd(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicAnd($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedAnd(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicAnd($0[$1], $2)\")\n")
SLANG_RAW(" void InterlockedAnd(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($4 = atomicCompSwap($0[$1], $2, $3))\")\n")
SLANG_RAW(" void InterlockedCompareExchange(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT compare_value,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
-SLANG_RAW(" void InterlockedCompareExchange(\n")
-SLANG_RAW(" UINT dest,\n")
-SLANG_RAW(" UINT compare_value,\n")
-SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicCompSwap($0[$1], $2, $3)\")\n")
SLANG_RAW(" void InterlockedCompareStore(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT compare_value,\n")
SLANG_RAW(" UINT value);\n")
-SLANG_RAW(" void InterlockedCompareStore(\n")
-SLANG_RAW(" UINT dest,\n")
-SLANG_RAW(" UINT compare_value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicExchange($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedExchange(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
-SLANG_RAW(" void InterlockedExchange(\n")
-SLANG_RAW(" UINT dest,\n")
-SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicMax($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedMax(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicMax($0[$1], $2)\")\n")
SLANG_RAW(" void InterlockedMax(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicMin($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedMin(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicMin($0[$1], $2)\")\n")
SLANG_RAW(" void InterlockedMin(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicOr($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedOr(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicOr($0[$1], $2)\")\n")
SLANG_RAW(" void InterlockedOr(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicXor($0[$1], $2))\")\n")
SLANG_RAW(" void InterlockedXor(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value,\n")
SLANG_RAW(" out UINT original_value);\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"atomicXor($0[$1], $2)\")\n")
SLANG_RAW(" void InterlockedXor(\n")
SLANG_RAW(" UINT dest,\n")
SLANG_RAW(" UINT value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$0[$1] = $2\")\n")
SLANG_RAW(" void Store(\n")
SLANG_RAW(" uint address,\n")
SLANG_RAW(" uint value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$0[$1] = $2.x, $0[$1+4] = $2.y\")\n")
SLANG_RAW(" void Store2(\n")
SLANG_RAW(" uint address,\n")
SLANG_RAW(" uint2 value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$0[$1] = $2.x, $0[$1+4] = $2.y, $0[$1+8] = $2.z\")\n")
SLANG_RAW(" void Store3(\n")
SLANG_RAW(" uint address,\n")
SLANG_RAW(" uint3 value);\n")
SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(glsl, \"$0[$1] = $2.x, $0[$1+4] = $2.y, $0[$1+8] = $2.z, $0[$1+12] = $2.w\")\n")
SLANG_RAW(" void Store4(\n")
SLANG_RAW(" uint address,\n")
SLANG_RAW(" uint4 value);\n")
@@ -732,12 +765,6 @@ SLANG_RAW("\n")
SLANG_RAW("__target_intrinsic(glsl, \"$atomicCompSwap($A, $1, $2)\")\n")
SLANG_RAW("void InterlockedCompareStore(__ref uint dest, uint compare_value, uint value);\n")
SLANG_RAW("\n")
-SLANG_RAW("__target_intrinsic(glsl, \"$atomicExchange($A, $1)\")\n")
-SLANG_RAW("void InterlockedExchange(__ref int dest, int value);\n")
-SLANG_RAW("\n")
-SLANG_RAW("__target_intrinsic(glsl, \"$atomicExchange($A, $1)\")\n")
-SLANG_RAW("void InterlockedExchange(__ref uint dest, uint value);\n")
-SLANG_RAW("\n")
SLANG_RAW("__target_intrinsic(glsl, \"($2 = $atomicExchange($A, $1))\")\n")
SLANG_RAW("void InterlockedExchange(__ref int dest, int value, out int original_value);\n")
SLANG_RAW("\n")
diff --git a/source/slang/ir-inst-defs.h b/source/slang/ir-inst-defs.h
index 14318bc91..8f997cbe2 100644
--- a/source/slang/ir-inst-defs.h
+++ b/source/slang/ir-inst-defs.h
@@ -90,9 +90,11 @@ INST(Nop, nop, 0, 0)
/* UntypedBufferResourceType */
- INST(HLSLByteAddressBufferType, ByteAddressBuffer, 0, 0)
- INST(HLSLRWByteAddressBufferType, RWByteAddressBuffer, 0, 0)
- INST(HLSLRasterizerOrderedByteAddressBufferType, RasterizerOrderedByteAddressBuffer, 0, 0)
+ /* ByteAddressBufferTypeBase */
+ INST(HLSLByteAddressBufferType, ByteAddressBuffer, 0, 0)
+ INST(HLSLRWByteAddressBufferType, RWByteAddressBuffer, 0, 0)
+ INST(HLSLRasterizerOrderedByteAddressBufferType, RasterizerOrderedByteAddressBuffer, 0, 0)
+ INST_RANGE(ByteAddressBufferTypeBase, HLSLByteAddressBufferType, HLSLRasterizerOrderedByteAddressBufferType)
INST(RaytracingAccelerationStructureType, RaytracingAccelerationStructure, 0, 0)
INST_RANGE(UntypedBufferResourceType, HLSLByteAddressBufferType, RaytracingAccelerationStructureType)
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 9c7637360..b3c690c26 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -787,9 +787,10 @@ SIMPLE_IR_TYPE(HLSLRWStructuredBufferType, HLSLStructuredBufferTypeBase)
SIMPLE_IR_TYPE(HLSLRasterizerOrderedStructuredBufferType, HLSLStructuredBufferTypeBase)
SIMPLE_IR_PARENT_TYPE(UntypedBufferResourceType, Type)
-SIMPLE_IR_TYPE(HLSLByteAddressBufferType, UntypedBufferResourceType)
-SIMPLE_IR_TYPE(HLSLRWByteAddressBufferType, UntypedBufferResourceType)
-SIMPLE_IR_TYPE(HLSLRasterizerOrderedByteAddressBufferType, UntypedBufferResourceType)
+SIMPLE_IR_PARENT_TYPE(ByteAddressBufferTypeBase, UntypedBufferResourceType)
+SIMPLE_IR_TYPE(HLSLByteAddressBufferType, ByteAddressBufferTypeBase)
+SIMPLE_IR_TYPE(HLSLRWByteAddressBufferType, ByteAddressBufferTypeBase)
+SIMPLE_IR_TYPE(HLSLRasterizerOrderedByteAddressBufferType, ByteAddressBufferTypeBase)
SIMPLE_IR_TYPE(HLSLAppendStructuredBufferType, HLSLStructuredBufferTypeBase)
SIMPLE_IR_TYPE(HLSLConsumeStructuredBufferType, HLSLStructuredBufferTypeBase)