summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-10-30 14:07:38 -0700
committerGitHub <noreply@github.com>2024-10-30 14:07:38 -0700
commit28f20f458c4f7f587556a1738d63b70e87c2b148 (patch)
treea3d4fbd77be026979fd5f9802dcbe01404e20396 /source
parentfeec3cf4354524e2badb3e3165fdf2a17c24597e (diff)
Write only texture types. (#5454)
* Add support for write-only textures. * Fix capabilities. * Fix implementation. * Fix. * format code --------- Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com> Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/hlsl.meta.slang213
-rw-r--r--source/slang/slang-ast-type.cpp1
-rw-r--r--source/slang/slang-capabilities.capdef4
-rw-r--r--source/slang/slang-core-module-textures.cpp3
-rw-r--r--source/slang/slang-emit-cpp.cpp1
-rw-r--r--source/slang/slang-emit-cuda.cpp2
-rw-r--r--source/slang/slang-emit-glsl.cpp2
-rw-r--r--source/slang/slang-emit-hlsl.cpp2
-rw-r--r--source/slang/slang-emit-metal.cpp2
-rw-r--r--source/slang/slang-emit-spirv.cpp1
-rw-r--r--source/slang/slang-emit-wgsl.cpp6
-rw-r--r--source/slang/slang-ir-specialize-resources.cpp1
-rw-r--r--source/slang/slang-ir.h5
-rw-r--r--source/slang/slang-type-system-shared.h5
-rw-r--r--source/slang/slang.cpp4
15 files changed, 150 insertions, 102 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index dad634934..747446bbd 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -950,7 +950,7 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
[__readNone]
[ForceInline]
__glsl_extension(GL_ARB_sparse_texture_clamp)
- [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0_fragment)]
+ [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_clamp_fragment)]
T Sample(vector<float, Shape.dimensions+isArray> location, vector<int, Shape.planeDimensions> offset, float clamp)
{
__requireComputeDerivative();
@@ -1251,7 +1251,7 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
[__readNone]
[ForceInline]
__glsl_extension(GL_ARB_sparse_texture_clamp)
- [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_0)]
+ [require(cpp_glsl_hlsl_metal_spirv, texture_sm_4_1_clamp_fragment)]
T SampleGrad(vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY, constexpr vector<int, Shape.dimensions> offset, float lodClamp)
{
__target_switch
@@ -3444,6 +3444,10 @@ ${{{{
__generic<T, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let isShadow:int, let format:int>
extension _Texture<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,format>
{
+ ${{{{
+ if (access != kCoreModule_ResourceAccessWriteOnly)
+ {
+ }}}}
[__readNone]
[ForceInline]
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1)]
@@ -3610,6 +3614,9 @@ extension _Texture<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,format>
}
}
+ ${{{{
+ } // if (access != kCoreModule_ResourceAccessWriteOnly)
+ }}}}
[require(glsl, texture_sm_4_1)]
void __glslImageStore(vector<int, Shape.dimensions+isArray> location, T value)
{
@@ -3624,6 +3631,105 @@ extension _Texture<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,format>
__intrinsic_op($(kIROp_ImageStore))
static void __metalImageStore(This val, vector<uint, Shape.dimensions+isArray> location, T value);
+ [ForceInline]
+ void Store(vector<uint, Shape.dimensions+isArray> location, T newValue)
+ {
+ __target_switch
+ {
+ case cpp:
+ case hlsl:
+ __intrinsic_asm ".operator[]";
+ case glsl:
+ __glslImageStore(location, newValue);
+ case cuda:
+ if (isArray != 0)
+ {
+ switch(Shape.flavor)
+ {
+ case $(SLANG_TEXTURE_1D):
+ __intrinsic_asm "surf1DLayeredwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, SLANG_CUDA_BOUNDARY_MODE)";
+ case $(SLANG_TEXTURE_2D):
+ __intrinsic_asm "surf2DLayeredwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, ($1).z, SLANG_CUDA_BOUNDARY_MODE)";
+ case $(SLANG_TEXTURE_3D):
+ __intrinsic_asm "surf3DLayeredwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, ($1).z, ($1).w, SLANG_CUDA_BOUNDARY_MODE)";
+ default:
+ __intrinsic_asm "<invalid intrinsic>";
+ }
+ }
+ else
+ {
+ switch(Shape.flavor)
+ {
+ case $(SLANG_TEXTURE_1D):
+ __intrinsic_asm "surf1Dwrite$C<$T0>($2, $0, ($1) * $E, SLANG_CUDA_BOUNDARY_MODE)";
+ case $(SLANG_TEXTURE_2D):
+ __intrinsic_asm "surf2Dwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, SLANG_CUDA_BOUNDARY_MODE)";
+ case $(SLANG_TEXTURE_3D):
+ __intrinsic_asm "surf3Dwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, ($1).z, SLANG_CUDA_BOUNDARY_MODE)";
+ default:
+ __intrinsic_asm "<invalid intrinsic>";
+ }
+ }
+ case spirv:
+ return spirv_asm
+ {
+ OpImageWrite $this $location __convertTexel(newValue);
+ };
+ case metal:
+ if (isArray != 0)
+ {
+ // last arg will be replaced with the split off array index
+ __metalImageStoreArray(this, __vectorReshape<Shape.dimensions>(location), newValue, location[Shape.dimensions + isArray - 1]);
+ }
+ else
+ {
+ __metalImageStore(this, location, newValue);
+ }
+ case wgsl:
+ static_assert(Shape.flavor == $(SLANG_TEXTURE_1D)
+ || Shape.flavor == $(SLANG_TEXTURE_2D)
+ || Shape.flavor == $(SLANG_TEXTURE_3D)
+ , "WGSL doesn't supports textureStore for Cube texture.");
+ static_assert(isArray == 0 || Shape.flavor == $(SLANG_TEXTURE_2D)
+ , "WGSL supports textureStore for texture_store_2d_array but not for array of 1D, 3D or Cube.");
+
+ // WGSL requires the value type to be always `vec4`
+ if (isArray == 1)
+ {
+ if (T is int32_t || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<i32>($V2)";
+ if (T is int32_t2 || T is int16_t2 || T is int8_t2) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<i32>($2, 0, 1))";
+ if (T is int32_t3 || T is int16_t3 || T is int8_t3) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<i32>($2, 1))";
+ if (T is uint32_t || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<u32>($2, 0, 0, 1))";
+ if (T is uint32_t2 || T is uint16_t2 || T is uint8_t2) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<u32>($2, 0, 1))";
+ if (T is uint32_t3 || T is uint16_t3 || T is uint8_t3) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<u32>($2, 1))";
+ if (T is half) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f16>($2, 0, 0, 1))";
+ if (T is half2) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f16>($2, 0, 1))";
+ if (T is half3) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f16>($2, 1))";
+ if (T is float) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f32>($2, 0, 0, 1))";
+ if (T is float2) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f32>($2, 0, 1))";
+ if (T is float3) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f32>($2, 1))";
+ __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), $2)";
+ }
+ if (T is int32_t || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, $1, vec4<i32>($2, 0, 0, 1))";
+ if (T is int32_t2 || T is int16_t2 || T is int8_t2) __intrinsic_asm "textureStore($0, $1, vec4<i32>($2, 0, 1))";
+ if (T is int32_t3 || T is int16_t3 || T is int8_t3) __intrinsic_asm "textureStore($0, $1, vec4<i32>($2, 1))";
+ if (T is uint32_t || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, $1, vec4<u32>($2, 0, 0, 1))";
+ if (T is uint32_t2 || T is uint16_t2 || T is uint8_t2) __intrinsic_asm "textureStore($0, $1, vec4<u32>($2, 0, 1))";
+ if (T is uint32_t3 || T is uint16_t3 || T is uint8_t3) __intrinsic_asm "textureStore($0, $1, vec4<u32>($2, 1))";
+ if (T is half) __intrinsic_asm "textureStore($0, $1, vec4<f16>($2, 0, 0, 1))";
+ if (T is half2) __intrinsic_asm "textureStore($0, $1, vec4<f16>($2, 0, 1))";
+ if (T is half3) __intrinsic_asm "textureStore($0, $1, vec4<f16>($2, 1))";
+ if (T is float) __intrinsic_asm "textureStore($0, $1, vec4<f32>($2, 0, 0, 1))";
+ if (T is float2) __intrinsic_asm "textureStore($0, $1, vec4<f32>($2, 0, 1))";
+ if (T is float3) __intrinsic_asm "textureStore($0, $1, vec4<f32>($2, 1))";
+ __intrinsic_asm "textureStore($0, $1, $2)";
+ }
+ }
+
+ ${{{{
+ if (access != kCoreModule_ResourceAccessWriteOnly)
+ {
+ }}}}
__subscript(vector<uint, Shape.dimensions+isArray> location) -> T
{
[__readNone]
@@ -3650,96 +3756,7 @@ extension _Texture<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,format>
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_1)]
set(T newValue)
{
- __target_switch
- {
- case cpp:
- case hlsl:
- __intrinsic_asm ".operator[]";
- case glsl:
- __glslImageStore(location, newValue);
- case cuda:
- if (isArray != 0)
- {
- switch(Shape.flavor)
- {
- case $(SLANG_TEXTURE_1D):
- __intrinsic_asm "surf1DLayeredwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, SLANG_CUDA_BOUNDARY_MODE)";
- case $(SLANG_TEXTURE_2D):
- __intrinsic_asm "surf2DLayeredwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, ($1).z, SLANG_CUDA_BOUNDARY_MODE)";
- case $(SLANG_TEXTURE_3D):
- __intrinsic_asm "surf3DLayeredwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, ($1).z, ($1).w, SLANG_CUDA_BOUNDARY_MODE)";
- default:
- __intrinsic_asm "<invalid intrinsic>";
- }
- }
- else
- {
- switch(Shape.flavor)
- {
- case $(SLANG_TEXTURE_1D):
- __intrinsic_asm "surf1Dwrite$C<$T0>($2, $0, ($1) * $E, SLANG_CUDA_BOUNDARY_MODE)";
- case $(SLANG_TEXTURE_2D):
- __intrinsic_asm "surf2Dwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, SLANG_CUDA_BOUNDARY_MODE)";
- case $(SLANG_TEXTURE_3D):
- __intrinsic_asm "surf3Dwrite$C<$T0>($2, $0, ($1).x * $E, ($1).y, ($1).z, SLANG_CUDA_BOUNDARY_MODE)";
- default:
- __intrinsic_asm "<invalid intrinsic>";
- }
- }
- case spirv:
- return spirv_asm
- {
- OpImageWrite $this $location __convertTexel(newValue);
- };
- case metal:
- if (isArray != 0)
- {
- // last arg will be replaced with the split off array index
- __metalImageStoreArray(this, __vectorReshape<Shape.dimensions>(location), newValue, location[Shape.dimensions + isArray - 1]);
- }
- else
- {
- __metalImageStore(this, location, newValue);
- }
- case wgsl:
- static_assert(Shape.flavor == $(SLANG_TEXTURE_1D)
- || Shape.flavor == $(SLANG_TEXTURE_2D)
- || Shape.flavor == $(SLANG_TEXTURE_3D)
- , "WGSL doesn't supports textureStore for Cube texture.");
- static_assert(isArray == 0 || Shape.flavor == $(SLANG_TEXTURE_2D)
- , "WGSL supports textureStore for texture_store_2d_array but not for array of 1D, 3D or Cube.");
-
- // WGSL requires the value type to be always `vec4`
- if (isArray == 1)
- {
- if (T is int32_t || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<i32>($2, 0, 0, 1))";
- if (T is int32_t2 || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<i32>($2, 0, 1))";
- if (T is int32_t3 || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<i32>($2, 1))";
- if (T is uint32_t || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<u32>($2, 0, 0, 1))";
- if (T is uint32_t2 || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<u32>($2, 0, 1))";
- if (T is uint32_t3 || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<u32>($2, 1))";
- if (T is half) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f16>($2, 0, 0, 1))";
- if (T is half2) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f16>($2, 0, 1))";
- if (T is half3) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f16>($2, 1))";
- if (T is float) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f32>($2, 0, 0, 1))";
- if (T is float2) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f32>($2, 0, 1))";
- if (T is float3) __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), vec4<f32>($2, 1))";
- __intrinsic_asm "textureStore($0, ($1).xy, i32(($1).z), $2)";
- }
- if (T is int32_t || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, $1, vec4<i32>($2, 0, 0, 1))";
- if (T is int32_t2 || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, $1, vec4<i32>($2, 0, 1))";
- if (T is int32_t3 || T is int16_t || T is int8_t) __intrinsic_asm "textureStore($0, $1, vec4<i32>($2, 1))";
- if (T is uint32_t || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, $1, vec4<u32>($2, 0, 0, 1))";
- if (T is uint32_t2 || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, $1, vec4<u32>($2, 0, 1))";
- if (T is uint32_t3 || T is uint16_t || T is uint8_t) __intrinsic_asm "textureStore($0, $1, vec4<u32>($2, 1))";
- if (T is half) __intrinsic_asm "textureStore($0, $1, vec4<f16>($2, 0, 0, 1))";
- if (T is half2) __intrinsic_asm "textureStore($0, $1, vec4<f16>($2, 0, 1))";
- if (T is half3) __intrinsic_asm "textureStore($0, $1, vec4<f16>($2, 1))";
- if (T is float) __intrinsic_asm "textureStore($0, $1, vec4<f32>($2, 0, 0, 1))";
- if (T is float2) __intrinsic_asm "textureStore($0, $1, vec4<f32>($2, 0, 1))";
- if (T is float3) __intrinsic_asm "textureStore($0, $1, vec4<f32>($2, 1))";
- __intrinsic_asm "textureStore($0, $1, $2)";
- }
+ Store(location, newValue);
}
// If a 'Texture[location]' is referred to by a '__ref', call 'kIROp_ImageSubscript(location)'.
@@ -3747,6 +3764,10 @@ extension _Texture<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,format>
__intrinsic_op($(kIROp_ImageSubscript))
ref;
}
+ ${{{{
+ } // if (access != kCoreModule_ResourceAccessWriteOnly)
+ }}}}
+
}
${{{{
@@ -3978,7 +3999,8 @@ extension _Texture<T, Shape, isArray, 1 /*isMS*/, 0 /*sampleCount*/, 0 /*access*
// T, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let access:int, let isShadow:int, let isCombined:int, let format:int
${{{{
const char* shapeTypeNames[] = {"1D", "2D", "3D", "Cube"};
- const char* accessPrefix[] = {"", "RW", "RasterizerOrdered", "Feedback"};
+ const char* accessPrefix[] = {"", "RW", "W", "RasterizerOrdered", "Feedback"};
+ const char* accessDocumentation[] = {"read-only", "read-write", "write-only", "rasterizer-ordered", "feedback"};
const char* arrayPostFix[] = {"", "Array"};
const char* msPostFix[] = {"", "MS"};
for (int shape = 0; shape < 4; shape++)
@@ -4013,6 +4035,11 @@ ${{{{
const char* textureTypeName = isCombined ? "Sampler" : "Texture";
}}}}
/// @category texture_types
+/// Represents a handle to a $(accessDocumentation[access])$(isMS?", multisampled": "") $(shapeTypeNames[shape]) $(isCombined?"combined texture-sampler": "texture")$(isArray?" array":"").
+/// @param T The texel type of the texture.
+/// @param sampleCount The number of samples in the texture, when the texture is multisampled.
+/// @param format The storage format of the texture.
+/// @see Please refer to `_Texture` for more information about texture types.
typealias $(accessPrefix[access])$(textureTypeName)$(shapeTypeNames[shape])$(msPostFix[isMS])$(arrayPostFix[isArray])<T=float4, let sampleCount:int=0, let format:int=0> = _Texture<T, __Shape$(shapeTypeNames[shape]), $(isArray), $(isMS), sampleCount, $(access), 0, $(isCombined), format>;
${{{{
}
diff --git a/source/slang/slang-ast-type.cpp b/source/slang/slang-ast-type.cpp
index 529cbb1be..8c7561e8d 100644
--- a/source/slang/slang-ast-type.cpp
+++ b/source/slang/slang-ast-type.cpp
@@ -1132,6 +1132,7 @@ SlangResourceAccess ResourceType::getAccess()
{
case kCoreModule_ResourceAccessReadOnly: return SLANG_RESOURCE_ACCESS_READ;
case kCoreModule_ResourceAccessReadWrite: return SLANG_RESOURCE_ACCESS_READ_WRITE;
+ case kCoreModule_ResourceAccessWriteOnly: return SLANG_RESOURCE_ACCESS_WRITE;
case kCoreModule_ResourceAccessRasterizerOrdered:
return SLANG_RESOURCE_ACCESS_RASTER_ORDERED;
case kCoreModule_ResourceAccessFeedback: return SLANG_RESOURCE_ACCESS_FEEDBACK;
diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef
index ed286eb86..3ea991eb4 100644
--- a/source/slang/slang-capabilities.capdef
+++ b/source/slang/slang-capabilities.capdef
@@ -1757,11 +1757,11 @@ alias getattributeatvertex = fragment + _sm_6_1 | fragment + GL_EXT_fragment_sha
alias memorybarrier = sm_5_0_version;
/// Capabilities required to use sm_4_0 texture operations
/// [Compound]
-alias texture_sm_4_0 = sm_4_0_version | GL_ARB_sparse_texture_clamp + GL_EXT_texture_query_lod
+alias texture_sm_4_0 = sm_4_0_version
;
/// Capabilities required to use sm_4_1 texture operations
/// [Compound]
-alias texture_sm_4_1 = sm_4_1_version | GL_ARB_sparse_texture_clamp + GL_EXT_texture_query_lod
+alias texture_sm_4_1 = sm_4_1_version
;
/// Capabilities required to use sm_4_1 samplerless texture operations
/// [Compound]
diff --git a/source/slang/slang-core-module-textures.cpp b/source/slang/slang-core-module-textures.cpp
index 568c6f37d..8198fa1db 100644
--- a/source/slang/slang-core-module-textures.cpp
+++ b/source/slang/slang-core-module-textures.cpp
@@ -102,7 +102,8 @@ void TextureTypeInfo::writeFuncBody(
if (spirvDefault.getLength() && spirvCombined.getLength())
{
sb << i << "case spirv:\n";
- sb << i << "if (access == " << kCoreModule_ResourceAccessReadWrite << ")\n";
+ sb << i << "if (access == " << kCoreModule_ResourceAccessReadWrite
+ << " || access == " << kCoreModule_ResourceAccessWriteOnly << ")\n";
sb << i << "return spirv_asm\n";
{
BraceScope spirvRWScope{i, sb, ";\n"};
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 63c7dd9a4..04d513e7a 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -130,6 +130,7 @@ SlangResult CPPSourceEmitter::_calcCPPTextureTypeName(
switch (texType->getAccess())
{
case SLANG_RESOURCE_ACCESS_READ: break;
+ case SLANG_RESOURCE_ACCESS_WRITE: outName << "RW"; break;
case SLANG_RESOURCE_ACCESS_READ_WRITE: outName << "RW"; break;
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED: outName << "RasterizerOrdered"; break;
case SLANG_RESOURCE_ACCESS_APPEND: outName << "Append"; break;
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index 2bccb59a7..4caddbc11 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -130,6 +130,8 @@ SlangResult CUDASourceEmitter::_calcCUDATextureTypeName(
return SLANG_OK;
}
case SLANG_RESOURCE_ACCESS_READ_WRITE:
+ case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
+ case SLANG_RESOURCE_ACCESS_WRITE:
{
outName << "CUsurfObject";
return SLANG_OK;
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 3203d74e1..bd8987d03 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -1500,6 +1500,7 @@ void GLSLSourceEmitter::emitImageFormatModifierImpl(IRInst* varDecl, IRType* var
{
switch (resourceType->getAccess())
{
+ case SLANG_RESOURCE_ACCESS_WRITE:
case SLANG_RESOURCE_ACCESS_READ_WRITE:
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
{
@@ -2939,6 +2940,7 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type)
}
switch (texType->getAccess())
{
+ case SLANG_RESOURCE_ACCESS_WRITE:
case SLANG_RESOURCE_ACCESS_READ_WRITE:
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
_emitGLSLTextureOrTextureSamplerType(texType, "image");
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 0b4ceed92..49ccc3c65 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -278,6 +278,8 @@ void HLSLSourceEmitter::_emitHLSLTextureType(IRTextureTypeBase* texType)
case SLANG_RESOURCE_ACCESS_READ_WRITE: m_writer->emit("RW"); break;
+ case SLANG_RESOURCE_ACCESS_WRITE: m_writer->emit("RW"); break;
+
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED: m_writer->emit("RasterizerOrdered"); break;
case SLANG_RESOURCE_ACCESS_APPEND: m_writer->emit("Append"); break;
diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp
index ded0e05c2..b4d682e86 100644
--- a/source/slang/slang-emit-metal.cpp
+++ b/source/slang/slang-emit-metal.cpp
@@ -125,6 +125,8 @@ void MetalSourceEmitter::_emitHLSLTextureType(IRTextureTypeBase* texType)
{
case SLANG_RESOURCE_ACCESS_READ: m_writer->emit("access::sample"); break;
+ case SLANG_RESOURCE_ACCESS_WRITE: m_writer->emit("access::write"); break;
+
case SLANG_RESOURCE_ACCESS_READ_WRITE:
case SLANG_RESOURCE_ACCESS_APPEND:
case SLANG_RESOURCE_ACCESS_CONSUME:
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 954caf24b..30c03e98c 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -2068,6 +2068,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
{
case SlangResourceAccess::SLANG_RESOURCE_ACCESS_READ_WRITE:
case SlangResourceAccess::SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
+ case SlangResourceAccess::SLANG_RESOURCE_ACCESS_WRITE:
sampled = ImageOpConstants::readWriteImage;
break;
case SlangResourceAccess::SLANG_RESOURCE_ACCESS_NONE:
diff --git a/source/slang/slang-emit-wgsl.cpp b/source/slang/slang-emit-wgsl.cpp
index ba89222cd..4aca03a61 100644
--- a/source/slang/slang-emit-wgsl.cpp
+++ b/source/slang/slang-emit-wgsl.cpp
@@ -405,6 +405,7 @@ void WGSLSourceEmitter::emitSimpleTypeImpl(IRType* type)
{
switch (texType->getAccess())
{
+ case SLANG_RESOURCE_ACCESS_WRITE:
case SLANG_RESOURCE_ACCESS_READ_WRITE: m_writer->emit("texture_storage"); break;
default: m_writer->emit("texture"); break;
}
@@ -442,7 +443,10 @@ void WGSLSourceEmitter::emitSimpleTypeImpl(IRType* type)
m_writer->emit(getWgslImageFormat(texType));
m_writer->emit(", read_write");
break;
-
+ case SLANG_RESOURCE_ACCESS_WRITE:
+ m_writer->emit(getWgslImageFormat(texType));
+ m_writer->emit(", write");
+ break;
default:
if (auto vecElemType = as<IRVectorType>(elemType))
emitSimpleType(vecElemType->getElementType());
diff --git a/source/slang/slang-ir-specialize-resources.cpp b/source/slang/slang-ir-specialize-resources.cpp
index c69e33225..2230ec857 100644
--- a/source/slang/slang-ir-specialize-resources.cpp
+++ b/source/slang/slang-ir-specialize-resources.cpp
@@ -1315,6 +1315,7 @@ bool isIllegalGLSLParameterType(IRType* type)
switch (texType->getAccess())
{
case SLANG_RESOURCE_ACCESS_READ_WRITE:
+ case SLANG_RESOURCE_ACCESS_WRITE:
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED: return true;
default: break;
}
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 3585a379d..0a31232f5 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1437,8 +1437,9 @@ struct IRResourceTypeBase : IRType
case kCoreModule_ResourceAccessReadWrite: return SLANG_RESOURCE_ACCESS_READ_WRITE;
case kCoreModule_ResourceAccessRasterizerOrdered:
return SLANG_RESOURCE_ACCESS_RASTER_ORDERED;
- case kCoreModule_ResourceAccessFeedback: return SLANG_RESOURCE_ACCESS_FEEDBACK;
- default: break;
+ case kCoreModule_ResourceAccessFeedback: return SLANG_RESOURCE_ACCESS_FEEDBACK;
+ case kCoreModule_ResourceAccessWriteOnly: return SLANG_RESOURCE_ACCESS_WRITE;
+ default: break;
}
}
return SLANG_RESOURCE_ACCESS_UNKNOWN;
diff --git a/source/slang/slang-type-system-shared.h b/source/slang/slang-type-system-shared.h
index e6cc5b578..73370a4e6 100644
--- a/source/slang/slang-type-system-shared.h
+++ b/source/slang/slang-type-system-shared.h
@@ -41,8 +41,9 @@ enum class SamplerStateFlavor : uint8_t
const int kCoreModule_ResourceAccessReadOnly = 0;
const int kCoreModule_ResourceAccessReadWrite = 1;
-const int kCoreModule_ResourceAccessRasterizerOrdered = 2;
-const int kCoreModule_ResourceAccessFeedback = 3;
+const int kCoreModule_ResourceAccessWriteOnly = 2;
+const int kCoreModule_ResourceAccessRasterizerOrdered = 3;
+const int kCoreModule_ResourceAccessFeedback = 4;
const int kCoreModule_ShapeIndex1D = 0;
const int kCoreModule_ShapeIndex2D = 1;
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 01efcb11b..d6e57e6f3 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1984,7 +1984,9 @@ CapabilitySet TargetRequest::getTargetCaps()
case CodeGenTarget::MetalLib:
case CodeGenTarget::MetalLibAssembly: atoms.add(CapabilityName::metal); break;
- case CodeGenTarget::WGSL: atoms.add(CapabilityName::wgsl); break;
+ case CodeGenTarget::WGSLSPIRV:
+ case CodeGenTarget::WGSLSPIRVAssembly:
+ case CodeGenTarget::WGSL: atoms.add(CapabilityName::wgsl); break;
default: break;
}