summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2024-04-25 16:14:08 -0700
committerGitHub <noreply@github.com>2024-04-25 16:14:08 -0700
commitbc7231bbcf32819bed37012db3f01b34b5dd856a (patch)
tree03d0c2f1f813b3e0c88e309add0e3c104ce97648
parented0681164d78591148781d08934676bfec63f9da (diff)
Fix unpackUnorm4x8 and unpackSnorm4x8 (#4033)
Fixes #4031 Each component of unpackU/Snorm4x8 had to be masked for 8bits.
-rw-r--r--source/slang/glsl.meta.slang26
-rw-r--r--tests/bugs/gh-4031.slang54
2 files changed, 74 insertions, 6 deletions
diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang
index b4e5cf7ab..508156b8c 100644
--- a/source/slang/glsl.meta.slang
+++ b/source/slang/glsl.meta.slang
@@ -633,28 +633,34 @@ uint packSnorm1x8(float c)
[ForceInline]
float unpackUnorm1x16(uint p)
{
- return float(p) / 65535.0;
+ const uint wordMask = 0xffff;
+ return float(p & wordMask) / 65535.0;
}
[__readNone]
[ForceInline]
float unpackSnorm1x16(uint p)
{
- return clamp((float(p) - 32767.0) / 32767.0, -1.0, 1.0);
+ const uint wordMask = 0xffff;
+ return clamp((float(p & wordMask) - 32767.0) / 32767.0, -1.0, 1.0);
}
+__target_intrinsic(glsl)
[__readNone]
[ForceInline]
float unpackUnorm1x8(uint p)
{
- return float(p) / 255.0;
+ const uint byteMask = 0xff;
+ return float(p & byteMask) / 255.0;
}
+__target_intrinsic(glsl)
[__readNone]
[ForceInline]
float unpackSnorm1x8(uint p)
{
- return clamp((float(p) - 127.0) / 127.0, -1.0, 1.0);
+ const uint byteMask = 0xff;
+ return clamp((float(p & byteMask) - 127.0) / 127.0, -1.0, 1.0);
}
[__readNone]
@@ -733,7 +739,11 @@ __target_intrinsic(glsl)
[require(cpp_cuda_glsl_hlsl_spirv, shader5_sm_4_0)]
public vec4 unpackUnorm4x8(highp uint p)
{
- return vec4(unpackUnorm1x8(p & uint(0xffff)), unpackUnorm1x8(p >> uint(8)), unpackUnorm1x8(p >> uint(16)), unpackUnorm1x8(p >> uint(24)));
+ return vec4(
+ unpackUnorm1x8(p),
+ unpackUnorm1x8(p >> 8),
+ unpackUnorm1x8(p >> 16),
+ unpackUnorm1x8(p >> 24));
}
__target_intrinsic(glsl)
@@ -742,7 +752,11 @@ __target_intrinsic(glsl)
[require(cpp_cuda_glsl_hlsl_spirv, shader5_sm_4_0)]
public vec4 unpackSnorm4x8(highp uint p)
{
- return vec4(unpackSnorm1x8(p & uint(0xffff)), unpackSnorm1x8(p >> uint(8)), unpackSnorm1x8(p >> uint(16)), unpackSnorm1x8(p >> uint(24)));
+ return vec4(
+ unpackSnorm1x8(p),
+ unpackSnorm1x8(p >> 8),
+ unpackSnorm1x8(p >> 16),
+ unpackSnorm1x8(p >> 24));
}
__target_intrinsic(glsl)
diff --git a/tests/bugs/gh-4031.slang b/tests/bugs/gh-4031.slang
new file mode 100644
index 000000000..015eeefc6
--- /dev/null
+++ b/tests/bugs/gh-4031.slang
@@ -0,0 +1,54 @@
+//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUF):-dx12 -compute -entry computeMain -allow-glsl -profile cs_6_6 -use-dxil -shaderobj -output-using-type
+//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -output-using-type
+//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -output-using-type -emit-spirv-directly
+
+//TEST_INPUT: ubuffer(data=[0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+bool Test_unpackUnorm4x8()
+{
+ vector<float,4> val;
+ val[0] = 1.f / 1.f;
+ val[1] = 1.f / 2.f;
+ val[2] = 1.f / 4.f;
+ val[3] = 1.f / 8.f;
+
+ const uint32_t packed = packUnorm4x8(val);
+ const vector<float,4> unpacked = unpackUnorm4x8(packed);
+
+ return true
+ && int(unpacked[0] * 1.f) == 1
+ && int(unpacked[1] * 2.f) == 1
+ && int(unpacked[2] * 4.f) == 1
+ && int(unpacked[3] * 8.f) == 1
+ ;
+}
+
+bool Test_unpackSnorm4x8()
+{
+ vector<float,4> val;
+ val[0] = 1.f / 1.f;
+ val[1] = 1.f / 2.f;
+ val[2] = 1.f / 4.f;
+ val[3] = 1.f / 8.f;
+
+ const uint32_t packed = packSnorm4x8(val);
+ const vector<float,4> unpacked = unpackSnorm4x8(packed);
+
+ return true
+ && int(unpacked[0] * 1.f) == 1
+ && int(unpacked[1] * 2.f) == 1
+ && int(unpacked[2] * 4.f) == 1
+ && int(unpacked[3] * 8.f) == 1
+ ;
+}
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ //BUF:1
+ outputBuffer[0] = int(true
+ && Test_unpackUnorm4x8()
+ && Test_unpackSnorm4x8()
+ );
+}