hlsl -> spirv -> glsl compilation lost texture binding points
Hochheilige opened this issue · 2 comments
Hello!
I decided to write shaders in hlsl to use it with my OpenGl render. My fragment shader has following textures and sampler
Texture2D<float4> diffuse_map : register(t0, space0);
Texture2D<float4> specular_map : register(t1, space0);
SamplerState samplerState : register(s0, space0);
Using dxc I compile this shader to spirv and want to generate OpenGL readable glsl code using spirv_cross. But for some reason finall glsl code lost the binding points and a space (but this is not so important for ogl). So after generating glsl I have something like this:
uniform Sampler2D _113;
uniform Sampler2D _115;
I use dxc and spirv_cross from my c++ code to compile shaders at runtime and have an ability to recompile it. For dxc I pass only -spirv argument, for spirv_cross I do something like this:
spirv_cross::CompilerGLSL glsl_compiler(spirv);
spirv_cross::CompilerGLSL::Options options;
options.version = 450;
options.es = false;
glsl_compiler.set_common_options(options);
glsl_compiler.build_combined_image_samplers();
std::string glsl_code = glsl_compiler.compile();
And as far as I understand build_combined_image_samplers generates this two uniforms from my textures and sampler, but why there is no bindings points at final output and is it possible to generate bindings?
why there is no bindings points at final output?
Normally, that happens because OpenGL below 4.2 requires the GL_ARB_explicit_uniform_location
and GL_ARB_shading_language_420pack
extensions for that. But, you're setting version
to 450 explicitly, and enable_420pack_extension
is true
by default, so that can't be it.
In this case, I'd say it's because those uniform
s are generated by SPIRV-Cross, but SPIRV-Cross didn't copy the DecorationBinding
from the original uniform
s. And how could it? The original image and sampler uniform
s each have a different binding; which one should it copy? What about in the case where multiple images are used with multiple samplers? What if the image and sampler are from different descriptor sets (Vulkan)/register spaces (D3D12/HLSL)?
is it possible to generate bindings?
Yes, but it's somewhat involved. It entails finding the generated uniform
s after build_combined_image_samplers()
has been called, and explicitly setting DecorationBinding
on them. The Compiler::get_shader_resources()
and Compiler::set_decoration()
methods will facilitate this. This should happen, of course, before compile()
is called.
I see. Thank you.
Your solution works for me. I used set_decoration
and successfully add bindings to my samplers.