diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-12-18 06:57:18 -0800 |
|---|---|---|
| committer | jsmall-nvidia <jsmall@nvidia.com> | 2018-12-18 09:57:18 -0500 |
| commit | b6a54744b6980041de0706fdcd9cba57cb706ff1 (patch) | |
| tree | f2fcfb6975ad7266c7814204629abf2058e9692e /source | |
| parent | 583c72af28d2dde5c564d5b56d3c5eb4ae4844f6 (diff) | |
Fix for byte-address buffers on Vulkan (#760)
* Fix output comparison for compute tests
There was some vestigial logic there that was first doing a string-based comparison of actual/expected output, and then falling back to a path that parsed the expected output as a float, then converted that to an integer, then printed that integer in hex, and did the comparison with the result of that conversion.
I'm not even clear on what that code was trying to accomplish, but its main effect was allowing a test failure to slide by unnoticed becaues somehow an all-zeroes actual output file was matching an expected output file with no zeros. My understanding is that it went something like this:
* The first line of expected output was `A` (as in hexidecimal for the decimal integer `10`), and the first line of actual output was `0`.
* The `StringToFloat` function was failing on the input string `"A"` and returned `0.0` to indicate failure (rather than reporting any kind of error)
* We then converted the `0.0` to integer `0` and converted it to a base-16 string `"0"`
* The comparison to the actual output passed, and then a careless early exit in the comparison loop meant that a full test would pass as soon as one line of output passed according to this "second change" logic.
This change removes the broken code in the test runner since nothing was relying on it, other than the one broken test case we wanted to fix anyway.
* Fix the declarations of byte-address buffer methods for Vulkan
The HLSL `ByteAddressBuffer` and `RWByteAddressBuffer` types have methods `Load` and `Store` that take *byte* offsets from the start of the buffer, but we translate them into GLSL that uses `uint[]` array, so that indexing into that array will be off by a factor of four.
Somehow the code for mutable byte address buffers was written to add 4, 8, and 12 bytes to the base offset of a vector to get to its subsequent components, but I never thought about the implications this would have for the base address itself.
This change includes the following fixes:
* Any place in the translation of a byte-address `Load` or `Store` method that was using the address/offset value has been changed to use `$1 / 4` instead of `$1`.
* The offsets of 4, 8, and 12 have been changed to 1, 2, and 3 since they are now being added to an *index* instead of a byte offset
* The `GetDimensions` methods have introduced a factor of `* 4` to account for the fact that they need to return a byte size and not a count of elements.
With this change the existing `byte-address-buffer` test now produces the desired output under Vulkan.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 58 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang.h | 58 |
2 files changed, 58 insertions, 58 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 98b50e574..541d12112 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -18,26 +18,26 @@ __magic_type(HLSLByteAddressBufferType) __intrinsic_type($(kIROp_HLSLByteAddressBufferType))
struct ByteAddressBuffer
{
- __target_intrinsic(glsl, "$1 = $0._data.length()")
+ __target_intrinsic(glsl, "$1 = $0._data.length() * 4")
void GetDimensions(
out uint dim);
- __target_intrinsic(glsl, "$0._data[$1]")
+ __target_intrinsic(glsl, "$0._data[$1/4]")
uint Load(int location);
uint Load(int location, out uint status);
- __target_intrinsic(glsl, "uvec2($0._data[$1], $0._data[$1+1])")
+ __target_intrinsic(glsl, "uvec2($0._data[$1/4], $0._data[$1/4+1])")
uint2 Load2(int location);
uint2 Load2(int location, out uint status);
- __target_intrinsic(glsl, "uvec3($0._data[$1], $0._data[$1+1], $0._data[$1+2])")
+ __target_intrinsic(glsl, "uvec3($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2])")
uint3 Load3(int location);
uint3 Load3(int location, out uint status);
- __target_intrinsic(glsl, "uvec4($0._data[$1], $0._data[$1+1], $0._data[$1+2], $0._data[$1+3])")
+ __target_intrinsic(glsl, "uvec4($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2], $0._data[$1/4+3])")
uint4 Load4(int location);
uint4 Load4(int location, out uint status);
@@ -109,133 +109,133 @@ struct $(item.name) // Note(tfoley): supports all operations from `ByteAddressBuffer`
// TODO(tfoley): can this be made a sub-type?
- __target_intrinsic(glsl, "$1 = $0._data.length()")
+ __target_intrinsic(glsl, "$1 = $0._data.length() * 4")
void GetDimensions(
out uint dim);
- __target_intrinsic(glsl, "$0._data[$1]")
+ __target_intrinsic(glsl, "$0._data[$1/4]")
uint Load(int location);
uint Load(int location, out uint status);
- __target_intrinsic(glsl, "uvec2($0._data[$1], $0._data[$1+4])")
+ __target_intrinsic(glsl, "uvec2($0._data[$1/4], $0._data[$1/4+1])")
uint2 Load2(int location);
uint2 Load2(int location, out uint status);
- __target_intrinsic(glsl, "uvec3($0._data[$1], $0._data[$1+4], $0._data[$1+8])")
+ __target_intrinsic(glsl, "uvec3($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2])")
uint3 Load3(int location);
uint3 Load3(int location, out uint status);
- __target_intrinsic(glsl, "uvec4($0._data[$1], $0._data[$1+4], $0._data[$1+8], $0._data[$1+12])")
+ __target_intrinsic(glsl, "uvec4($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2], $0._data[$1/4+3])")
uint4 Load4(int location);
uint4 Load4(int location, out uint status);
// Added operations:
- __target_intrinsic(glsl, "($3 = atomicAdd($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicAdd($0._data[$1/4], $2))")
void InterlockedAdd(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicAdd($0._data[$1], $2)")
+ __target_intrinsic(glsl, "atomicAdd($0._data[$1/4], $2)")
void InterlockedAdd(
UINT dest,
UINT value);
- __target_intrinsic(glsl, "($3 = atomicAnd($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicAnd($0._data[$1/4], $2))")
void InterlockedAnd(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicAnd($0._data[$1], $2)")
+ __target_intrinsic(glsl, "atomicAnd($0._data[$1/4], $2)")
void InterlockedAnd(
UINT dest,
UINT value);
- __target_intrinsic(glsl, "($4 = atomicCompSwap($0._data[$1], $2, $3))")
+ __target_intrinsic(glsl, "($4 = atomicCompSwap($0._data[$1/4], $2, $3))")
void InterlockedCompareExchange(
UINT dest,
UINT compare_value,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicCompSwap($0._data[$1], $2, $3)")
+ __target_intrinsic(glsl, "atomicCompSwap($0._data[$1/4], $2, $3)")
void InterlockedCompareStore(
UINT dest,
UINT compare_value,
UINT value);
- __target_intrinsic(glsl, "($3 = atomicExchange($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicExchange($0._data[$1/4], $2))")
void InterlockedExchange(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "($3 = atomicMax($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicMax($0._data[$1/4], $2))")
void InterlockedMax(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicMax($0._data[$1], $2)")
+ __target_intrinsic(glsl, "atomicMax($0._data[$1/4], $2)")
void InterlockedMax(
UINT dest,
UINT value);
- __target_intrinsic(glsl, "($3 = atomicMin($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicMin($0._data[$1/4], $2))")
void InterlockedMin(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicMin($0._data[$1], $2)")
+ __target_intrinsic(glsl, "atomicMin($0._data[$1/4], $2)")
void InterlockedMin(
UINT dest,
UINT value);
- __target_intrinsic(glsl, "($3 = atomicOr($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicOr($0._data[$1/4], $2))")
void InterlockedOr(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicOr($0._data[$1], $2)")
+ __target_intrinsic(glsl, "atomicOr($0._data[$1/4], $2)")
void InterlockedOr(
UINT dest,
UINT value);
- __target_intrinsic(glsl, "($3 = atomicXor($0._data[$1], $2))")
+ __target_intrinsic(glsl, "($3 = atomicXor($0._data[$1/4], $2))")
void InterlockedXor(
UINT dest,
UINT value,
out UINT original_value);
- __target_intrinsic(glsl, "atomicXor($0._data[$1], $2)")
+ __target_intrinsic(glsl, "atomicXor($0._data[$1/4], $2)")
void InterlockedXor(
UINT dest,
UINT value);
- __target_intrinsic(glsl, "$0._data[$1] = $2")
+ __target_intrinsic(glsl, "$0._data[$1/4] = $2")
void Store(
uint address,
uint value);
- __target_intrinsic(glsl, "$0._data[$1] = $2.x, $0._data[$1+4] = $2.y")
+ __target_intrinsic(glsl, "$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y")
void Store2(
uint address,
uint2 value);
- __target_intrinsic(glsl, "$0._data[$1] = $2.x, $0._data[$1+4] = $2.y, $0._data[$1+8] = $2.z")
+ __target_intrinsic(glsl, "$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y, $0._data[$1/4+2] = $2.z")
void Store3(
uint address,
uint3 value);
- __target_intrinsic(glsl, "$0._data[$1] = $2.x, $0._data[$1+4] = $2.y, $0._data[$1+8] = $2.z, $0._data[$1+12] = $2.w")
+ __target_intrinsic(glsl, "$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y, $0._data[$1/4+2] = $2.z, $0._data[$1/4+3] = $2.w")
void Store4(
uint address,
uint4 value);
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h index ea21a0fde..9fb06b4b0 100644 --- a/source/slang/hlsl.meta.slang.h +++ b/source/slang/hlsl.meta.slang.h @@ -24,26 +24,26 @@ SLANG_SPLICE(kIROp_HLSLByteAddressBufferType SLANG_RAW(")\n") SLANG_RAW("struct ByteAddressBuffer\n") SLANG_RAW("{\n") -SLANG_RAW(" __target_intrinsic(glsl, \"$1 = $0._data.length()\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$1 = $0._data.length() * 4\")\n") SLANG_RAW(" void GetDimensions(\n") SLANG_RAW(" out uint dim);\n") SLANG_RAW("\n") -SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1]\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1/4]\")\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._data[$1], $0._data[$1+1])\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"uvec2($0._data[$1/4], $0._data[$1/4+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._data[$1], $0._data[$1+1], $0._data[$1+2])\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"uvec3($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+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._data[$1], $0._data[$1+1], $0._data[$1+2], $0._data[$1+3])\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"uvec4($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2], $0._data[$1/4+3])\")\n") SLANG_RAW(" uint4 Load4(int location);\n") SLANG_RAW("\n") SLANG_RAW(" uint4 Load4(int location, out uint status);\n") @@ -136,133 +136,133 @@ SLANG_RAW("{\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._data.length()\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$1 = $0._data.length() * 4\")\n") SLANG_RAW(" void GetDimensions(\n") SLANG_RAW(" out uint dim);\n") SLANG_RAW("\n") -SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1]\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1/4]\")\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._data[$1], $0._data[$1+4])\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"uvec2($0._data[$1/4], $0._data[$1/4+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._data[$1], $0._data[$1+4], $0._data[$1+8])\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"uvec3($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+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._data[$1], $0._data[$1+4], $0._data[$1+8], $0._data[$1+12])\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"uvec4($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2], $0._data[$1/4+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(" // Added operations:\n") SLANG_RAW("\n") -SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicAdd($0._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicAdd($0._data[$1/4], $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._data[$1], $2)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicAdd($0._data[$1/4], $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._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicAnd($0._data[$1/4], $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._data[$1], $2)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicAnd($0._data[$1/4], $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._data[$1], $2, $3))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($4 = atomicCompSwap($0._data[$1/4], $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("\n") -SLANG_RAW(" __target_intrinsic(glsl, \"atomicCompSwap($0._data[$1], $2, $3)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicCompSwap($0._data[$1/4], $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("\n") -SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicExchange($0._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicExchange($0._data[$1/4], $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("\n") -SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicMax($0._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicMax($0._data[$1/4], $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._data[$1], $2)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicMax($0._data[$1/4], $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._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicMin($0._data[$1/4], $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._data[$1], $2)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicMin($0._data[$1/4], $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._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicOr($0._data[$1/4], $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._data[$1], $2)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicOr($0._data[$1/4], $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._data[$1], $2))\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"($3 = atomicXor($0._data[$1/4], $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._data[$1], $2)\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"atomicXor($0._data[$1/4], $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._data[$1] = $2\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1/4] = $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._data[$1] = $2.x, $0._data[$1+4] = $2.y\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $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._data[$1] = $2.x, $0._data[$1+4] = $2.y, $0._data[$1+8] = $2.z\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y, $0._data[$1/4+2] = $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._data[$1] = $2.x, $0._data[$1+4] = $2.y, $0._data[$1+8] = $2.z, $0._data[$1+12] = $2.w\")\n") +SLANG_RAW(" __target_intrinsic(glsl, \"$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y, $0._data[$1/4+2] = $2.z, $0._data[$1/4+3] = $2.w\")\n") SLANG_RAW(" void Store4(\n") SLANG_RAW(" uint address,\n") SLANG_RAW(" uint4 value);\n") |
