SHADERed icon indicating copy to clipboard operation
SHADERed copied to clipboard

All uses of multiple Texture2D arguments inside a HLSL function alias the first Texture2D in the argument list

Open huawei-ahcox opened this issue 4 years ago • 3 comments

I was trying to pass two textures into a function in HSL but accesses to the second texture were pulling texels out of the first texture in the function's argument list. I managed to reproduce it in the deferred shading example. For the repro I just moved a block of code from the example's processing pixel shader into a function and called it from the point that the code was taken from. Screenshot and a zip of the repro project attached:

repro DeferredRendering_hlsl_texture_arguments_repro.zip

huawei-ahcox avatar Feb 10 '21 23:02 huawei-ahcox

Maybe this is a Glslang issue. I note this on their readme:

HLSL -> AST Front End

An HLSL front-end for translation of an approximation of HLSL to glslang's AST form.

Status: Partially complete. Semantics are not reference quality and input is not validated. This is in contrast to the DXC project, which receives a much larger investment and attempts to have definitive/reference-level semantics.

huawei-ahcox avatar Feb 11 '21 00:02 huawei-ahcox

Just checked; it's not a glslang/spirv-cross issue (I think).

glslang and spirv-cross generate this correct GLSL code:

#version 430

struct PSInput
{
    vec2 UV;
};

uniform     vec3 lightPos;

layout(binding = 0) uniform sampler2D _136;
uniform sampler2D _141;
uniform sampler2D _146;

layout(location = 0) in vec2 outputVS0;
layout(location = 0) out vec4 outputPS0;

vec4 called(vec2 UV, vec3 pos, sampler2D SPIRV_Cross_CombinednormalTexsmp, sampler2D SPIRV_Cross_CombineddiffuseTexsmp)
{
    vec4 n = texture(SPIRV_Cross_CombinednormalTexsmp, UV);
    vec3 normal = normalize(n.xyz);
    vec3 toLight = normalize(lightPos - pos);
    float diffuse = clamp(dot(normal, toLight), 0.0, 1.0);
    vec4 ret = texture(SPIRV_Cross_CombineddiffuseTexsmp, UV) * diffuse;
    ret.w = 1.0;
    return ret;
}

vec4 _main(inout PSInput pin)
{
    pin.UV.y = 1.0 - pin.UV.y;
    vec4 pos = texture(_136, pin.UV);
    float clip_val = 1.0;
    if (pos.w == 0.0)
    {
        clip_val = -1.0;
    }
    if (clip_val < 0.0)
    {
        discard;
    }
    vec2 param = pin.UV;
    vec3 param_1 = vec3(pos.xyz);
    return called(param, param_1, _141, _146);
}

void main()
{
    PSInput pin;
    pin.UV = outputVS0;
    PSInput param = pin;
    vec4 _134 = _main(param);
    outputPS0 = _134;
}

Using that code directly produces this result: image

Which means that the cause of the problem is most likely SHADERed. I currently have no idea what causes this issue though.

dfranx avatar Feb 12 '21 16:02 dfranx

I guess it will shake itself out at some point. Could be worth having a test for this when SHADERed gets an acceptance testing (golden image) suite. I personally have a workaround for now (global variables: yay).

huawei-ahcox avatar Feb 12 '21 18:02 huawei-ahcox