summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/core.meta.slang43
-rw-r--r--source/slang/core.meta.slang.h43
-rw-r--r--tests/hlsl/simple/rw-texture.hlsl34
3 files changed, 112 insertions, 8 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index e7c424c33..14254e99e 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -671,7 +671,17 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
if( kBaseTextureTypes[tt].coordCount + isArray < 4 )
{
- int loadCoordCount = kBaseTextureTypes[tt].coordCount + isArray + (isMultisample?0:1);
+ // The `Load()` operation on an ordinary `Texture2D` takes
+ // an `int3` for the location, where `.xy` holds the texel
+ // coordinates, and `.z` holds the mip level to use.
+ //
+ // The third coordinate for mip level is absent in
+ // `Texure2DMS.Load()` and `RWTexture2D.Load`. This pattern
+ // is repreated for all the other texture shapes.
+ //
+ bool needsMipLevel = !isMultisample && (access == SLANG_RESOURCE_ACCESS_READ);
+
+ int loadCoordCount = kBaseTextureTypes[tt].coordCount + isArray + (needsMipLevel?1:0);
// When translating to GLSL, we need to break apart the `location` argument.
//
@@ -679,6 +689,13 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
static const char* kGLSLLoadCoordsSwizzle[] = { "", "", "x", "xy", "xyz", "xyzw" };
static const char* kGLSLLoadLODSwizzle[] = { "", "", "y", "z", "w", "error" };
+ // TODO: The GLSL translations here only handle the read-only texture
+ // cases (stuff that lowers to `texture*` in GLSL) and not the stuff
+ // that lowers to `image*`.
+ //
+ // At some point it may make sense to separate the read-only and
+ // `RW`/`RasterizerOrdered` cases here rather than try to share code.
+
if (isMultisample)
{
sb << "__glsl_extension(GL_EXT_samplerless_texture_functions)";
@@ -687,7 +704,16 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
else
{
sb << "__glsl_extension(GL_EXT_samplerless_texture_functions)";
- sb << "__target_intrinsic(glsl, \"texelFetch($0, ($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount] << ")\")\n";
+ sb << "__target_intrinsic(glsl, \"texelFetch($0, ";
+ if( needsMipLevel )
+ {
+ sb << "($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount];
+ }
+ else
+ {
+ sb << "$1, 0";
+ }
+ sb << ")\")\n";
}
sb << "T Load(";
sb << "int" << loadCoordCount << " location";
@@ -705,7 +731,16 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
else
{
sb << "__glsl_extension(GL_EXT_samplerless_texture_functions)";
- sb << "__target_intrinsic(glsl, \"texelFetch($0, ($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount] << ", $2)\")\n";
+ sb << "__target_intrinsic(glsl, \"texelFetch($0, ";
+ if( needsMipLevel )
+ {
+ sb << "($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount];
+ }
+ else
+ {
+ sb << "$1, 0";
+ }
+ sb << ", $2)\")\n";
}
sb << "T Load(";
sb << "int" << loadCoordCount << " location";
@@ -713,7 +748,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
{
sb << ", int sampleIndex";
}
- sb << ", constexpr int" << loadCoordCount << " offset";
+ sb << ", constexpr int" << kBaseTextureTypes[tt].coordCount << " offset";
sb << ");\n";
diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h
index addc3856f..9a2033384 100644
--- a/source/slang/core.meta.slang.h
+++ b/source/slang/core.meta.slang.h
@@ -686,7 +686,17 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
if( kBaseTextureTypes[tt].coordCount + isArray < 4 )
{
- int loadCoordCount = kBaseTextureTypes[tt].coordCount + isArray + (isMultisample?0:1);
+ // The `Load()` operation on an ordinary `Texture2D` takes
+ // an `int3` for the location, where `.xy` holds the texel
+ // coordinates, and `.z` holds the mip level to use.
+ //
+ // The third coordinate for mip level is absent in
+ // `Texure2DMS.Load()` and `RWTexture2D.Load`. This pattern
+ // is repreated for all the other texture shapes.
+ //
+ bool needsMipLevel = !isMultisample && (access == SLANG_RESOURCE_ACCESS_READ);
+
+ int loadCoordCount = kBaseTextureTypes[tt].coordCount + isArray + (needsMipLevel?1:0);
// When translating to GLSL, we need to break apart the `location` argument.
//
@@ -694,6 +704,13 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
static const char* kGLSLLoadCoordsSwizzle[] = { "", "", "x", "xy", "xyz", "xyzw" };
static const char* kGLSLLoadLODSwizzle[] = { "", "", "y", "z", "w", "error" };
+ // TODO: The GLSL translations here only handle the read-only texture
+ // cases (stuff that lowers to `texture*` in GLSL) and not the stuff
+ // that lowers to `image*`.
+ //
+ // At some point it may make sense to separate the read-only and
+ // `RW`/`RasterizerOrdered` cases here rather than try to share code.
+
if (isMultisample)
{
sb << "__glsl_extension(GL_EXT_samplerless_texture_functions)";
@@ -702,7 +719,16 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
else
{
sb << "__glsl_extension(GL_EXT_samplerless_texture_functions)";
- sb << "__target_intrinsic(glsl, \"texelFetch($0, ($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount] << ")\")\n";
+ sb << "__target_intrinsic(glsl, \"texelFetch($0, ";
+ if( needsMipLevel )
+ {
+ sb << "($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount];
+ }
+ else
+ {
+ sb << "$1, 0";
+ }
+ sb << ")\")\n";
}
sb << "T Load(";
sb << "int" << loadCoordCount << " location";
@@ -720,7 +746,16 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
else
{
sb << "__glsl_extension(GL_EXT_samplerless_texture_functions)";
- sb << "__target_intrinsic(glsl, \"texelFetch($0, ($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount] << ", $2)\")\n";
+ sb << "__target_intrinsic(glsl, \"texelFetch($0, ";
+ if( needsMipLevel )
+ {
+ sb << "($1)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($1)." << kGLSLLoadLODSwizzle[loadCoordCount];
+ }
+ else
+ {
+ sb << "$1, 0";
+ }
+ sb << ", $2)\")\n";
}
sb << "T Load(";
sb << "int" << loadCoordCount << " location";
@@ -728,7 +763,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
{
sb << ", int sampleIndex";
}
- sb << ", constexpr int" << loadCoordCount << " offset";
+ sb << ", constexpr int" << kBaseTextureTypes[tt].coordCount << " offset";
sb << ");\n";
diff --git a/tests/hlsl/simple/rw-texture.hlsl b/tests/hlsl/simple/rw-texture.hlsl
new file mode 100644
index 000000000..26916b474
--- /dev/null
+++ b/tests/hlsl/simple/rw-texture.hlsl
@@ -0,0 +1,34 @@
+// rw-texture.hlsl
+
+//TEST:COMPARE_HLSL:-no-mangle -profile ps_5_0 -entry main
+
+// Ensure that we implement the `Load` operations on
+// `RWTexture*` types with the correct signature.
+
+#ifndef __SLANG__
+#define C C_0
+#define SV_Target SV_TARGET
+#define u2 u2_0
+#define u3 u3_0
+#define t2 t2_0
+#define t2a t2a_0
+#define t3 t3_0
+#endif
+
+
+cbuffer C : register(b0)
+{
+ uint2 u2;
+ uint3 u3;
+};
+
+RWTexture2D<float4> t2 : register(u1);
+RWTexture2DArray<float4> t2a : register(u2);
+RWTexture3D<float4> t3 : register(u3);
+
+float4 main() : SV_Target
+{
+ return t2.Load(u2)
+ + t2a.Load(u3)
+ + t3.Load(u3);
+}