diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 71 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 61 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang.h | 61 | ||||
| -rw-r--r-- | source/slang/ir-inst-defs.h | 8 | ||||
| -rw-r--r-- | source/slang/ir.h | 7 |
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) |
