DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

[SPIR-V] Sampled image type requires an image type with "Sampled" operand set to 0 or 1

Open StarsX opened this issue 3 years ago • 2 comments

This issue is compute shader only in my case. In pixel (fragment) shader code, I wrote: const float4 baseColor = BaseColor[input.Pos.xy]; It's OK.

But in compute shader code, I wrote: const float4 baseColor = BaseColor[DTid]; It reports a compilation error:

fatal error: generated SPIR-V is invalid: [VUID-StandaloneSpirv-OpTypeImage-04657] Sampled image type requires an image type with "Sampled" operand set to 0 or 1
  %31 = OpTypeSampledImage %type_2d_image_0

Full reproducible code:

[[vk::combinedImageSampler]] SamplerState Sampler : register (s0);
[[vk::combinedImageSampler]] Texture2D BaseColor : register (t0);
[[vk::combinedImageSampler]] SamplerState Sampler1 : register (s1);
[[vk::combinedImageSampler]] Texture2D BaseColor1 : register (t1);

RWTexture2D<float4> OutBuffer : register (u0);

[numthreads(8, 8, 1)]
void main(uint2 DTid : SV_DispatchThreadID)
{
    float2 texSize;
    BaseColor.GetDimensions(texSize.x, texSize.y);
    
    const float2 uv = (DTid + 0.5) / texSize;
	const float4 baseColor = BaseColor1[DTid];
    
    OutBuffer[DTid] = baseColor.w > 0.0 ? baseColor : 0.0;
}
fatal error: generated SPIR-V is invalid: [VUID-StandaloneSpirv-OpTypeImage-04657] Sampled image type requires an image type with "Sampled" operand set to 0 or 1
  %22 = OpTypeSampledImage %type_2d_image_0

Another trial:

[[vk::combinedImageSampler]] SamplerState Sampler : register (s0);
[[vk::combinedImageSampler]] Texture2D BaseColor : register (t0);

RWTexture2D<float4> OutBuffer : register (u0);

[numthreads(8, 8, 1)]
void main(uint2 DTid : SV_DispatchThreadID)
{
    float2 texSize;
    BaseColor.GetDimensions(texSize.x, texSize.y);
    
    const float2 uv = (DTid + 0.5) / texSize;
	const float4 baseColor = BaseColor.SampleLevel(Sampler, uv, 0.0);
    
    OutBuffer[DTid] = baseColor.w > 0.0 ? baseColor : 0.0;
}
fatal error: failed to legalize SPIR-V: 
note: please file a bug report on https://github.com/Microsoft/DirectXShaderCompiler/issues with source code if possible

It seems that the cause is the confliction of u0 and (t0, s0). DXC regards OutBuffer in u0 as the sampled image by mistake. Besides, glslang is good for the similar use cases, but I use DX9-style Sampler2D instead of [[vk::combinedImageSampler]] with glslang. However, glslang does not support [[vk::combinedImageSampler]], so it has no way to realize a texture combined with SamplerComparisonState by DX9 style.

StarsX avatar Nov 23 '22 07:11 StarsX

Completed the reproducible code and root-cause analysis.

StarsX avatar Nov 30 '22 07:11 StarsX

The spirv-opt pass that combines the sampler and the image into a combined image sampler, is modifying the RWTexture2D as well.

The source

[[vk::combinedImageSampler]] SamplerState Sampler : register (s0);
[[vk::combinedImageSampler]] Texture2D BaseColor : register (t0);

RWTexture2D<float4> OutBuffer : register (u0);

[numthreads(8, 8, 1)]
void main(uint2 DTid : SV_DispatchThreadID)
{
    OutBuffer[DTid] = float4(0.0, 1.0, 2.0, 3.0);
}

The spir-v that does the type of %OutBuffer is

%type_2d_image_0 = OpTypeImage %float 2D 2 0 0 2 Rgba32f
%_ptr_UniformConstant_type_2d_image_0 = OpTypePointer UniformConstant %type_2d_image_0
  %OutBuffer = OpVariable %_ptr_UniformConstant_type_2d_image_0 UniformConstant

After legalization

%type_2d_image = OpTypeImage %float 2D 2 0 0 2 Rgba32f
         %19 = OpTypeSampledImage %type_2d_image  ;  <---- This causes the validation error
%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
  %OutBuffer = OpVariable %_ptr_UniformConstant_19 UniformConstant

Note that is the vk::combinedImageSampler attribute is removed, this change does not happen.

s-perron avatar Jul 21 '23 20:07 s-perron