summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2025-05-06 10:51:07 -0500
committerGitHub <noreply@github.com>2025-05-06 08:51:07 -0700
commit10376faffee1ab51b2d23c311212b5724c3c6ac6 (patch)
tree52deee8642f55a85eb43ceaace2234df67439253
parentb0187cdb13ebbf1eaaf101cbfe8860a73280d644 (diff)
Add interger pack/unpack intrinsic to glsl (#6997)
* Add interger pack/unpack intrinsic to glsl Add unpack8, unpack16 and pack32 intrinsics to glsl. * add unit test * fix lowering logic for 'bitcast' * format
-rw-r--r--source/slang/glsl.meta.slang78
-rw-r--r--source/slang/hlsl.meta.slang4
-rw-r--r--source/slang/slang-ir-extract-value-from-type.cpp19
-rw-r--r--tests/glsl/interger_pack.slang77
4 files changed, 175 insertions, 3 deletions
diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang
index 0ea7d1c89..00ad88add 100644
--- a/source/slang/glsl.meta.slang
+++ b/source/slang/glsl.meta.slang
@@ -17,6 +17,10 @@
// Section 4.1. 'asic Types'
//
+public typealias f16vec2 = half2;
+public typealias f16vec3 = half3;
+public typealias f16vec4 = half4;
+
public typealias vec2 = vector<float, 2>;
public typealias vec3 = vector<float, 3>;
public typealias vec4 = vector<float, 4>;
@@ -93,6 +97,10 @@ public typealias dmat4x2 = matrix<double, 4, 2>;
public typealias dmat4x3 = matrix<double, 4, 3>;
public typealias dmat4x4 = matrix<double, 4, 4>;
+public typealias f16mat2x2 = matrix<half, 2, 2>;
+public typealias f16mat2x3 = matrix<half, 2, 3>;
+public typealias f16mat2x4 = matrix<half, 2, 4>;
+
public out float4 gl_Position : SV_Position;
public out float gl_PointSize : SV_PointSize;
@@ -724,6 +732,76 @@ public uvec2 unpackDouble2x32(double v)
}
}
+/// Unpack a 32-bit unsigned integer into 4 8-bit unsigned integers.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public u8vec4 unpack8(uint32_t u);
+
+/// Unpack a 32-bit signed integer into 4 8-bit signed integers.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public i8vec4 unpack8(int32_t u);
+
+/// Unpack a 16-bit unsigned integer into 2 8-bit unsigned integers.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public u8vec2 unpack8(uint16_t u);
+
+/// Unpack a 16-bit signed integer into 2 8-bit signed integers.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public i8vec2 unpack8(int16_t u);
+
+/// Unpack a 32-bit unsigned integer into 2 16-bit unsigned integers.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public u16vec2 unpack16(uint32_t u);
+
+/// Unpack a 32-bit signed integer into 2 16-bit signed integers.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public i16vec2 unpack16(int32_t u);
+
+/// Pack 2 16-bit unsigned integers into a 32-bit unsigned integer.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public uint32_t pack32(u16vec2 v);
+
+/// Pack 2 16-bit signed integers into a 32-bit signed integer.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public int32_t pack32(i16vec2 v);
+
+/// Pack 4 8-bit unsigned integers into a 32-bit unsigned integer.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public uint32_t pack32(u8vec4 v);
+
+/// Pack 4 8-bit signed integers into a 32-bit signed integer.
+[__readNone]
+[ForceInline]
+[require(cpp_cuda_glsl_hlsl_spirv, pack_vector)]
+__intrinsic_op($(kIROp_BitCast))
+public int32_t pack32(i8vec4 v);
+
//
// Section 8.5. Geometric Functions
//
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 07160ae9d..99eba0a42 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -25598,14 +25598,14 @@ int32_t2 __unpackInt2x16ToInt32(uint packedValue)
[ForceInline]
uint __packUint2x16(uint32_t2 unpackedValue)
{
- return unpackedValue.x | (unpackedValue.y << 16U);
+ return (unpackedValue.x & 0xFFFF) | (unpackedValue.y << 16U);
}
[__readNone]
[ForceInline]
uint __packInt2x16(int32_t2 unpackedValue)
{
- return uint(unpackedValue.x | (unpackedValue.y << 16U));
+ return uint((unpackedValue.x & 0xFFFF) | (unpackedValue.y << 16U));
}
//@public:
diff --git a/source/slang/slang-ir-extract-value-from-type.cpp b/source/slang/slang-ir-extract-value-from-type.cpp
index acb17068f..621532a38 100644
--- a/source/slang/slang-ir-extract-value-from-type.cpp
+++ b/source/slang/slang-ir-extract-value-from-type.cpp
@@ -274,6 +274,23 @@ IRInst* extractMultiByteValueAtOffset(
src,
firstHalfSize,
offset);
+ switch (firstHalfSize)
+ {
+ case 1:
+ firstHalf =
+ builder.emitBitAnd(uintType, firstHalf, builder.getIntValue(uintType, 0xFF));
+ break;
+ case 2:
+ firstHalf =
+ builder.emitBitAnd(uintType, firstHalf, builder.getIntValue(uintType, 0xFFFF));
+ break;
+ case 3:
+ firstHalf =
+ builder.emitBitAnd(uintType, firstHalf, builder.getIntValue(uintType, 0xFFFFFF));
+ break;
+ default:
+ break;
+ }
auto restSize = size - firstHalfSize;
auto secondHalf = extractMultiByteValueAtOffset(
builder,
@@ -284,7 +301,7 @@ IRInst* extractMultiByteValueAtOffset(
restSize,
offset + firstHalfSize);
uint32_t shift = firstHalfSize * 8;
- resultValue = builder.emitAdd(
+ resultValue = builder.emitBitOr(
builder.getUIntType(),
firstHalf,
builder.emitShl(
diff --git a/tests/glsl/interger_pack.slang b/tests/glsl/interger_pack.slang
new file mode 100644
index 000000000..7bf414c4d
--- /dev/null
+++ b/tests/glsl/interger_pack.slang
@@ -0,0 +1,77 @@
+//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl
+//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -emit-spirv-via-glsl
+
+#version 450
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
+layout(scalar) buffer MyBlockName2
+{
+ uvec4 a;
+ ivec4 b;
+
+ uvec2 c;
+ ivec2 d;
+
+ uvec2 e;
+ ivec2 f;
+
+ uint32_t g;
+ int32_t h;
+
+ uint32_t i;
+ int32_t j;
+} outputBuffer;
+
+layout(local_size_x = 1) in;
+void computeMain()
+{
+ uint32_t a = 0xF2845678;
+ outputBuffer.a = unpack8(a);
+ // BUF: 78
+ // BUF-NEXT: 56
+ // BUF-NEXT: 84
+ // BUF-NEXT: F2
+
+ int32_t b = 0xF2845678;
+ outputBuffer.b = unpack8(b);
+ // BUF: 78
+ // BUF-NEXT: 56
+ // BUF-NEXT: FFFFFF84
+ // BUF-NEXT: FFFFFFF2
+
+ uint16_t c = 0xF256;
+ outputBuffer.c = unpack8(c);
+ // BUF-NEXT: 56
+ // BUF-NEXT: F2
+
+ int16_t d = 0xF256;
+ outputBuffer.d = unpack8(d);
+ // BUF-NEXT: 56
+ // BUF-NEXT: FFFFFFF2
+
+ uint32_t e = 0xF2845678;
+ outputBuffer.e = unpack16(e);
+ // BUF-NEXT: 5678
+ // BUF-NEXT: F284
+
+ int32_t f = 0xF2845678;
+ outputBuffer.f = unpack16(f);
+ // BUF-NEXT: 5678
+ // BUF-NEXT: FFFFF284
+
+ u16vec2 g = {0xF256, 0x1234};
+ outputBuffer.g = pack32(g);
+ // BUF-NEXT: 1234F256
+
+ i16vec2 h = {0xF256, 0x1234};
+ outputBuffer.h = pack32(h);
+ // BUF-NEXT: 1234F256
+
+ u8vec4 i = {0xF2, 0x56, 0x12, 0x34};
+ outputBuffer.i = pack32(i);
+ // BUF-NEXT: 341256F2
+
+ i8vec4 j = {0x82, 0x56, 0x12, 0x80};
+ outputBuffer.j = pack32(j);
+ // BUF-NEXT: 80125682
+}