diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2025-05-06 10:51:07 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-06 08:51:07 -0700 |
| commit | 10376faffee1ab51b2d23c311212b5724c3c6ac6 (patch) | |
| tree | 52deee8642f55a85eb43ceaace2234df67439253 | |
| parent | b0187cdb13ebbf1eaaf101cbfe8860a73280d644 (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.slang | 78 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-extract-value-from-type.cpp | 19 | ||||
| -rw-r--r-- | tests/glsl/interger_pack.slang | 77 |
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 +} |
