Open Xottab-DUTY opened 6 years ago
The moment has arrived!
The first way is to use glslang to compile to HLSL to SPIR-V and then use SPIRV-Cross to convert SPIR-V to GLSL.
The second way -that might work- is to use SPIR-V directly if your driver supports the GL_ARB_gl_spirv extension.
You can experiment with all the compilers and cross compilers here: http://shader-playground.timjones.io/d1af9d9a29f86e412b1b23e68a7e3998
Are you sure that SPIR-V compiled for Vulkan would work for OpenGL? The same question goes for GLSL output from SPIR-V Cross. Will it work with OpenGL?
P.S. anyway, the moment has not arrived. You can't directly compile HLSL to OpenGL SPIR-V. I've tried to do this and got this:
ERROR: HLSL currently only supported when requesting SPIR-V for Vulkan.
OpenGL is a different execution environment that supports different features than the Vulkan execution environment.
It is probably not too difficult to plumb HLSL -> glslang -> SPIR-V-for-OpenGL, if we have good understanding of ecosystem need for it.
Can't wait to see it working. =)
@johnkslang, any progress on this? At least a little bit?
Silly question, but why don’t you just use mojoshader to convert from HLSL to GLSL?
https://hg.icculus.org/icculus/mojoshader/file/tip/mojoshader.h
That is supposed to work for Shader Model 1.0 through 3.0. For 4.0 and 5.0, you can probably reuse the DXVK shader compiler code:
https://github.com/doitsujin/dxvk/tree/master/src/dxbc
It converts directly from DXBC to SPIR-V.
@ryao, thank you! I didn't heard about these, I'll try.
When I use glslangValidator version 7.11.3113 and I try to compile Hlsl into opengl spirv it compiles without any warning or error. With line: glslangValidator -e main -G -D "file.frag" -o "file.spv" But the moment I try to use the compiled shaders I get a read access violation in nvogl.dll. If I compile it to vulkan spirv, cross compile it back to glsl than compile again to opengl spirv I don't get this read acces violation (So for now this is the method I will be using). I was wondering if the read access violation is a problem on my end or if compiling hlsl into opengl spirv isn't fully supported yet and I just have to wait longer?
Is this still an issue or it was implemented?
seems like it crashes only if texture sampling is used. A simple hello-world fragment HLSL shader displaying uv coordinates did work.
seems like it crashes only if texture sampling is used. A simple hello-world fragment HLSL shader displaying uv coordinates did work.
I fully support it, I have the same problem, the semantics of samplers for opengle is not respected, if you look at the spirv-cross reflect, we will see that the code with the samplers is compiled into this
"separate_images" : [
{
"type" : "texture2D",
"name" : "screenTexture",
"set" : 0,
"binding" : 0
}
],
"separate_samplers" : [
{
"type" : "sampler",
"name" : "linearSampler",
"set" : 0,
"binding" : 0
}
]
which, as far as I understand, makes the video card break when trying to execute such code
but the exit from glsl to spirv should contain only this
"textures" : [
{
"type" : "sampler2D",
"name" : "tex",
"location" : 0,
"set" : 0,
"binding" : 0
}
]
Why don't you generate semantically correct code for opengl from hlsl?
after all, this is quite possible, for example, if there are 2 identical textures and one sampler for them, then in the code it will be just 2 samplers, this is already a problem with the opengle application in order to bind the same sampler to 2 different texture slots, although this is not problem.
On the other hand, if there are 2 textures and two different samplers, then this is also not a problem, it would be just 2 different sampler2d uniforms in the glsl code, here, too, the opengl application itself will bind 2 different samplers to 2 different texture slots.
why can't you implement similar behavior in code generator?
it would be absolutely stupid to force users to make such a large chain of calls glslangvalidator (hlsl) -> spirv-cross (spirv) -> glslangvalidator (glsl) -> semantic correct spirv
PS: probably this instructions break execution of shader
%80 = OpLoad %20 %screenTexture
%81 = OpLoad %24 %linearSampler
%82 = OpSampledImage %28 %80 %81
code that do sampling generated from glsl
%main = OpFunction %void None %3
%5 = OpLabel
%14 = OpLoad %11 %tex
%18 = OpLoad %v2float %tc
%19 = OpImageSampleImplicitLod %v4float %14 %18
OpStore %fragColor %19
OpReturn
OpFunctionEnd
from hlsl with separate texture and sampler
%main = OpFunction %void None %3
%5 = OpLabel
%51 = OpLoad %v2float %stage_input_IN_tc
OpStore %IN_tc %51
%80 = OpLoad %20 %screenTexture
%81 = OpLoad %24 %linearSampler
%82 = OpSampledImage %28 %80 %81
%83 = OpLoad %v2float %IN_tc
%84 = OpImageSampleImplicitLod %v4float %82 %83
OpStore %_entryPointOutput %84
%76 = OpLoad %v4float %_entryPointOutput
OpStore %_entryPointOutput__entryPointOutput %76
OpReturn
OpFunctionEnd
maybe it is possible to set up the pipeline in the opengl so that this shader works correctly? then no problem, but it seems to me this execution model is specific for the vulkan environment
I will take a look...
It appears to me that -G was not intended to work with -D, that is, with HLSL source. As such I will create an issue to fix the documentation and give an error message for this to avoid future confusion.
I think the status of this issue stands: it is a request for an enhancement. As such, and since there is a workaround with spirv-cross, I likely will not be able to find time to implement this in the foreseeable future.
If someone wishes to implement it, I would highly recommend posting an implementation plan here first and gets my approval. Specifically, it is not clear I would approve a design that pulls spirv-cross into this project.
So, if I understand it correctly, the only way to use HLSL shaders in an OpenGL game is to first convert them to SPIRV with Glslang and then to GLSL with SPIRV-Cross? Directly using the SPIRV doesn't work, even in GL 4.6?
So, if I understand it correctly, the only way to use HLSL shaders in an OpenGL game is to first convert them to SPIRV with Glslang and then to GLSL with SPIRV-Cross? Directly using the SPIRV doesn't work, even in GL 4.6?
It should be possible if you're willing to chain-compile HLSL -> SPIR-V for Vulkan -> GLSL -> SPIR-V for OpenGL 4.6
Unfortunately, yes, the currently supported option is to use that cross-compilation pipeline. The issue is that OpenGL SPIR-V supports slightly different features compared to Vulkan SPIR-V. You can see the differences listed in the spec here: https://registry.khronos.org/OpenGL/extensions/ARB/ARB_gl_spirv.txt
Sadly, but you can't currently use glslang to compile HLSL shaders for OpenGL right now.
Waiting forward for the moment when this will be finally available..