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 validation error when a Texture2D is inside a cbuffer #2754

Open
Ace17 opened this issue Sep 14, 2021 · 5 comments
Open

HLSL validation error when a Texture2D is inside a cbuffer #2754

Ace17 opened this issue Sep 14, 2021 · 5 comments
Assignees

Comments

@Ace17
Copy link

Ace17 commented Sep 14, 2021

Here's a minimal example that triggers the error.
Do you think it's legit ? This code is accepted by fxc.exe.

// input.frag.hlsl (updated)
cbuffer MyCBuffer
{
    Texture2D myTexture;
    SamplerState mySampler;
}

float4 main(float4 parFragIn : SV_POSITION) : SV_TARGET
{
    return myTexture.SampleLevel(mySampler, float2(0, 0), 0).rgba;
}
% glslangValidator -V100 --spirv-val -S frag -D --target-env vulkan1.0 input.frag.hlsl -e main
input.frag.hlsl
error: SPIRV-Tools Validation Errors
error: In Vulkan, OpTypeStruct must not contain an opaque type.
  %MyCBuffer = OpTypeStruct %13 %14

% glslangValidator --version
Glslang Version: 10:11.0.0
ESSL Version: OpenGL ES GLSL 3.20 glslang Khronos. 11.0.0
GLSL Version: 4.60 glslang Khronos. 11.0.0
SPIR-V Version 0x00010500, Revision 4
GLSL.std.450 Version 100, Revision 1
Khronos Tool ID 8
SPIR-V Generator Version 10
GL_KHR_vulkan_glsl version 100
ARB_GL_gl_spirv version 100

@greg-lunarg
Copy link
Contributor

Can you please supply the fxc command line?

@Ace17
Copy link
Author

Ace17 commented Sep 14, 2021

Here you can see the shader getting compiled by fxc.exe ( I don't know the exact command line ) :

http://shader-playground.timjones.io/8cf11c21f20657d1000d16207292af25

Please note that I slightly updated the source code in my first post, as I had posted a too-much-stripped-down version ; sorry for the inconvenience!

@greg-lunarg
Copy link
Contributor

FWIW, the following shader yields identical byte code from fxc:

Texture2D myTexture;
SamplerState mySampler;

float4 main(float4 parFragIn : SV_POSITION) : SV_TARGET
{
    return myTexture.SampleLevel(mySampler, float2(0, 0), 0).rgba;
}

In other words, identical results are obtained if the cbuffer syntax is thrown away. That is the basic approach I am going to take for the solution: to effectively throw away the cbuffer syntax in this situation. I will completely handle the solution in glslang and not pass the responsibility off to the legalization passes in spirv-opt.

@greg-lunarg
Copy link
Contributor

A slightly different way of looking at it is to treat the opaque definitions as if they occurred outside of the cbuffer. Any non-opaque members will be treated as if they appeared in the cbuffer without the opaque members.

@Ace17
Copy link
Author

Ace17 commented Mar 7, 2022

In other words, identical results are obtained if the cbuffer syntax is thrown away.

What if the cbuffer specifies a register? e.g:

cbuffer Material : register(b2)
{
float2 uni1;
float uni2;
float uni3;
}

Currently, the b2 correctly gets mapped to SPIRV-code descriptor set binding number ("binding = 2"), as you can see below (this is the output of spirv-cross with, as input, the .spv bytecode obtained from glslang when fed with the above HLSL code):

layout(set = 0, binding = 2, std140) uniform _192_194
{
    vec2 _m0;
    float _m1;
    float _m2;
} _194;

If you throw away the cbuffer syntax, it seems you are going to lose this information.
Am I missing something here ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants