Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLSL/MSL: Passing samplers and textures to functions results in global sampler and unused parameters #2358

Open
Ravbug opened this issue Aug 4, 2024 · 2 comments
Labels
question Further progress depends on answer from issue creator.

Comments

@Ravbug
Copy link
Contributor

Ravbug commented Aug 4, 2024

The following GLSL function:

float pcfForShadow(vec3 pixelWorldPos, mat4 lightViewProj, sampler shadowSampler, texture2D t_depthshadow){
	vec4 sampledPos = vec4(pixelWorldPos,1);
	sampledPos = lightViewProj * sampledPos;    // where is this on the light
	sampledPos /= sampledPos.w; // perspective divide
	sampledPos.xy = sampledPos.xy * 0.5 + 0.5;    // transform to [0,1] 
	sampledPos.y = 1 - sampledPos.y;

    return texture(sampler2DShadow(t_depthshadow,shadowSampler), sampledPos.xyz, 0).x;
}

Becomes this when compiled to SPIRV via glslang 14.3.0 and converted to HLSL:

Texture2D<float4> t_depthshadowshadowSampler;
SamplerComparisonState _t_depthshadowshadowSampler_sampler;

float pcfForShadow(float3 pixelWorldPos, float4x4 lightViewProj, SamplerState shadowSampler_1, Texture2D<float4> t_depthshadow)
{
    float4 sampledPos = float4(pixelWorldPos, 1.0f);
    sampledPos = mul(sampledPos, lightViewProj);
    sampledPos /= sampledPos.w.xxxx;
    float4 _854 = sampledPos;
    float2 _860 = (_854.xy * 0.5f) + 0.5f.xx;
    sampledPos.x = _860.x;
    sampledPos.y = _860.y;
    sampledPos.y = 1.0f - sampledPos.y;
    return t_depthshadowshadowSampler.SampleCmp(_t_depthshadowshadowSampler_sampler, sampledPos.xyz.xy, sampledPos.xyz.z);
}

The parameters shadowSampler_1 and t_depthshadow are unused in the HLSL function body and instead the globals t_depthshadowshadowSampler and _t_depthshadowshadowSampler_sampler are created. They are not initialized anywhere in the generated HLSL.

The desired behavior is for the generated function to use the sampler and texture arguments passed in.

@Ravbug Ravbug changed the title HLSL: Passing samplers and textures to functions results in global sampler and unused parameters HLSL/MSL: Passing samplers and textures to functions results in global sampler and unused parameters Aug 4, 2024
@HansKristian-Work
Copy link
Contributor

I cannot reproduce this.

GLSL:

#version 450

layout(location = 0) out float FragColor;
layout(set = 0, binding = 0) uniform texture2D depthShadow;
layout(set = 0, binding = 1) uniform sampler depthSampler;


float pcfForShadow(vec3 pixelWorldPos, mat4 lightViewProj, sampler shadowSampler, texture2D t_depthshadow){
	vec4 sampledPos = vec4(pixelWorldPos,1);
	sampledPos = lightViewProj * sampledPos;    // where is this on the light
	sampledPos /= sampledPos.w; // perspective divide
	sampledPos.xy = sampledPos.xy * 0.5 + 0.5;    // transform to [0,1] 
	sampledPos.y = 1 - sampledPos.y;

    return texture(sampler2DShadow(t_depthshadow,shadowSampler), sampledPos.xyz, 0).x;
}

void main()
{
	FragColor = pcfForShadow(vec3(0.0), mat4(1.0), depthSampler, depthShadow);
}

SPIR-V:

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 84
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %FragColor
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpName %main "main"
               OpName %pcfForShadow_vf3_mf44_p1_t21_ "pcfForShadow(vf3;mf44;p1;t21;"
               OpName %pixelWorldPos "pixelWorldPos"
               OpName %lightViewProj "lightViewProj"
               OpName %shadowSampler "shadowSampler"
               OpName %t_depthshadow "t_depthshadow"
               OpName %sampledPos "sampledPos"
               OpName %FragColor "FragColor"
               OpName %depthSampler "depthSampler"
               OpName %depthShadow "depthShadow"
               OpName %param "param"
               OpName %param_0 "param"
               OpDecorate %FragColor Location 0
               OpDecorate %depthSampler DescriptorSet 0
               OpDecorate %depthSampler Binding 1
               OpDecorate %depthShadow DescriptorSet 0
               OpDecorate %depthShadow Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v3float = OpTypeVector %float 3
%_ptr_Function_v3float = OpTypePointer Function %v3float
    %v4float = OpTypeVector %float 4
%mat4v4float = OpTypeMatrix %v4float 4
%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
         %12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
         %14 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
         %16 = OpTypeFunction %float %_ptr_Function_v3float %_ptr_Function_mat4v4float %_ptr_UniformConstant_12 %_ptr_UniformConstant_14
%_ptr_Function_v4float = OpTypePointer Function %v4float
    %float_1 = OpConstant %float 1
       %uint = OpTypeInt 32 0
     %uint_3 = OpConstant %uint 3
%_ptr_Function_float = OpTypePointer Function %float
    %v2float = OpTypeVector %float 2
  %float_0_5 = OpConstant %float 0.5
     %uint_0 = OpConstant %uint 0
     %uint_1 = OpConstant %uint 1
         %61 = OpTypeImage %float 2D 1 0 0 1 Unknown
         %62 = OpTypeSampledImage %61
    %float_0 = OpConstant %float 0
%_ptr_Output_float = OpTypePointer Output %float
  %FragColor = OpVariable %_ptr_Output_float Output
         %73 = OpConstantComposite %v3float %float_0 %float_0 %float_0
         %74 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_0
         %75 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_0
         %76 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_0
         %77 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
         %78 = OpConstantComposite %mat4v4float %74 %75 %76 %77
%depthSampler = OpVariable %_ptr_UniformConstant_12 UniformConstant
%depthShadow = OpVariable %_ptr_UniformConstant_14 UniformConstant
       %main = OpFunction %void None %3
          %5 = OpLabel
      %param = OpVariable %_ptr_Function_v3float Function
    %param_0 = OpVariable %_ptr_Function_mat4v4float Function
               OpStore %param %73
               OpStore %param_0 %78
         %83 = OpFunctionCall %float %pcfForShadow_vf3_mf44_p1_t21_ %param %param_0 %depthSampler %depthShadow
               OpStore %FragColor %83
               OpReturn
               OpFunctionEnd
%pcfForShadow_vf3_mf44_p1_t21_ = OpFunction %float None %16
%pixelWorldPos = OpFunctionParameter %_ptr_Function_v3float
%lightViewProj = OpFunctionParameter %_ptr_Function_mat4v4float
%shadowSampler = OpFunctionParameter %_ptr_UniformConstant_12
%t_depthshadow = OpFunctionParameter %_ptr_UniformConstant_14
         %22 = OpLabel
 %sampledPos = OpVariable %_ptr_Function_v4float Function
         %25 = OpLoad %v3float %pixelWorldPos
         %27 = OpCompositeExtract %float %25 0
         %28 = OpCompositeExtract %float %25 1
         %29 = OpCompositeExtract %float %25 2
         %30 = OpCompositeConstruct %v4float %27 %28 %29 %float_1
               OpStore %sampledPos %30
         %31 = OpLoad %mat4v4float %lightViewProj
         %32 = OpLoad %v4float %sampledPos
         %33 = OpMatrixTimesVector %v4float %31 %32
               OpStore %sampledPos %33
         %37 = OpAccessChain %_ptr_Function_float %sampledPos %uint_3
         %38 = OpLoad %float %37
         %39 = OpLoad %v4float %sampledPos
         %40 = OpCompositeConstruct %v4float %38 %38 %38 %38
         %41 = OpFDiv %v4float %39 %40
               OpStore %sampledPos %41
         %43 = OpLoad %v4float %sampledPos
         %44 = OpVectorShuffle %v2float %43 %43 0 1
         %46 = OpVectorTimesScalar %v2float %44 %float_0_5
         %47 = OpCompositeConstruct %v2float %float_0_5 %float_0_5
         %48 = OpFAdd %v2float %46 %47
         %50 = OpAccessChain %_ptr_Function_float %sampledPos %uint_0
         %51 = OpCompositeExtract %float %48 0
               OpStore %50 %51
         %53 = OpAccessChain %_ptr_Function_float %sampledPos %uint_1
         %54 = OpCompositeExtract %float %48 1
               OpStore %53 %54
         %55 = OpAccessChain %_ptr_Function_float %sampledPos %uint_1
         %56 = OpLoad %float %55
         %57 = OpFSub %float %float_1 %56
         %58 = OpAccessChain %_ptr_Function_float %sampledPos %uint_1
               OpStore %58 %57
         %59 = OpLoad %14 %t_depthshadow
         %60 = OpLoad %12 %shadowSampler
         %63 = OpSampledImage %62 %59 %60
         %64 = OpLoad %v4float %sampledPos
         %65 = OpVectorShuffle %v3float %64 %64 0 1 2
         %67 = OpCompositeExtract %float %65 2
         %68 = OpImageSampleDrefImplicitLod %float %63 %65 %67 Bias %float_0
               OpReturnValue %68
               OpFunctionEnd

HLSL with --shader-model 50

SamplerComparisonState depthSampler : register(s1);
Texture2D<float4> depthShadow : register(t0);

static float FragColor;

struct SPIRV_Cross_Output
{
    float FragColor : SV_Target0;
};

float pcfForShadow(float3 pixelWorldPos, float4x4 lightViewProj, SamplerComparisonState shadowSampler, Texture2D<float4> t_depthshadow)
{
    float4 sampledPos = float4(pixelWorldPos, 1.0f);
    sampledPos = mul(sampledPos, lightViewProj);
    sampledPos /= sampledPos.w.xxxx;
    float4 _43 = sampledPos;
    float2 _48 = (_43.xy * 0.5f) + 0.5f.xx;
    sampledPos.x = _48.x;
    sampledPos.y = _48.y;
    sampledPos.y = 1.0f - sampledPos.y;
    return t_depthshadow.SampleCmp(shadowSampler, sampledPos.xyz.xy, sampledPos.xyz.z);
}

void frag_main()
{
    float3 param = 0.0f.xxx;
    float4x4 param_1 = float4x4(float4(1.0f, 0.0f, 0.0f, 0.0f), float4(0.0f, 1.0f, 0.0f, 0.0f), float4(0.0f, 0.0f, 1.0f, 0.0f), float4(0.0f, 0.0f, 0.0f, 1.0f));
    FragColor = pcfForShadow(param, param_1, depthSampler, depthShadow);
}

SPIRV_Cross_Output main()
{
    frag_main();
    SPIRV_Cross_Output stage_output;
    stage_output.FragColor = FragColor;
    return stage_output;
}

MSL:

#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct main0_out
{
    float FragColor [[color(0)]];
};

static inline __attribute__((always_inline))
float pcfForShadow(thread const float3& pixelWorldPos, thread const float4x4& lightViewProj, sampler shadowSampler, depth2d<float> t_depthshadow)
{
    float4 sampledPos = float4(pixelWorldPos, 1.0);
    sampledPos = lightViewProj * sampledPos;
    sampledPos /= float4(sampledPos.w);
    float4 _43 = sampledPos;
    float2 _48 = (_43.xy * 0.5) + float2(0.5);
    sampledPos.x = _48.x;
    sampledPos.y = _48.y;
    sampledPos.y = 1.0 - sampledPos.y;
    return t_depthshadow.sample_compare(shadowSampler, sampledPos.xyz.xy, sampledPos.xyz.z);
}

fragment main0_out main0(depth2d<float> depthShadow [[texture(0)]], sampler depthSampler [[sampler(0)]])
{
    main0_out out = {};
    float3 param = float3(0.0);
    float4x4 param_1 = float4x4(float4(1.0, 0.0, 0.0, 0.0), float4(0.0, 1.0, 0.0, 0.0), float4(0.0, 0.0, 1.0, 0.0), float4(0.0, 0.0, 0.0, 1.0));
    out.FragColor = pcfForShadow(param, param_1, depthSampler, depthShadow);
    return out;
}

@HansKristian-Work HansKristian-Work added the question Further progress depends on answer from issue creator. label Aug 20, 2024
@Ravbug
Copy link
Contributor Author

Ravbug commented Aug 30, 2024

Apologies for the late response. Here is my full shader and the intermediate SPIR-V that glslang generated. Does this reproduce for you? I updated to the latest glslang ToT and it's still happening. On my older glslang version the issue does not occur (same spirv-cross version).

full_shader.frag.txt
full_shader.spv.txt

I am using the glslang and spirv-cross C++ APIs to perform the conversions. I used spvBinaryToText to get the textual SPIR-V representation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further progress depends on answer from issue creator.
Projects
None yet
Development

No branches or pull requests

2 participants