使用HLSL->SPIR-V->OpenGL时着色器的入口点无效

dced5bon  于 2023-04-20  发布在  其他
关注(0)|答案(1)|浏览(164)

我正在尝试实现一个系统,以便我可以在我的OpenGL应用程序中使用HLSL,因为它可以编译为SPIR-V,SPIR-V可以转换为与DirectX一起工作的东西。
但是,我在专门化着色器时收到一个错误:

glSpecializeShaderARB("vert" is not a valid entry point for shader)

我使用shaderc.net,并通过它编译到SPIR-V,然后按照标准程序,我将SPIR-V源代码附加到着色器对象。

ShaderHandle shaderHandle = GL.CreateShader(source.GLShaderType);
GL.ShaderBinary(Utility.Wrap(shaderHandle), ShaderBinaryFormat.ShaderBinaryFormatSpirV, result.CodePointer, (int)result.CodeLength);
GL.SpecializeShader(shaderHandle, source.EntryPoint, 0, Array.Empty<uint>(), Array.Empty<uint>());

result变量只是shaderc的编译结果,Utility.Wrap是我用来简单地将单个变量转换为ReadOnlySpan的工具。
我将补充说明我正在使用OpenTK进行OpenGL绑定。
我尝试了各种各样的着色器源。这一个实际上反编译成RenderDoc中似乎有效的GLSL:

struct VERTEX_DATA
{
    float3 pos;
};

float4 vert(VERTEX_DATA vertex) : SV_POSITION
{
    return float4(vertex.pos, 0);
}

下面是RenderDoc反编译器的输出

#version 450

layout(location = 0) in vec3 vertex_pos;

void main()
{
    gl_Position = vec4(vertex_pos, 0.0);
}

这看起来像是有效的GLSL,但它会导致我指定的错误。
编辑:有一个反汇编的请求。这是RenderDoc SPIR-V反汇编

; SPIR-V
; Version: 1.0
; Generator: Google Shaderc over Glslang; 11
; Bound: 47
; Schema: 0
               OpCapability Shader
          %2 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %vert "vert" %vertex_pos %_entryPointOutput
          %1 = OpString "test.hlsl"
               OpSource HLSL 500 %1 "// OpModuleProcessed entry-point vert
// OpModuleProcessed client opengl100
// OpModuleProcessed target-env opengl
// OpModuleProcessed hlsl-offsets
#line 1
struct VERTEX_DATA
{
    float3 pos;
};

float4 vert(VERTEX_DATA vertex) : SV_POSITION
{
    return float4(vertex.pos, 0);
}"
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpSourceExtension "GL_GOOGLE_include_directive"
               OpName %vert "vert"
               OpName %vertex_pos "vertex.pos"
               OpName %_entryPointOutput "@entryPointOutput"
               OpDecorate %vertex_pos Location 0
               OpDecorate %_entryPointOutput BuiltIn Position
       %void = OpTypeVoid
          %4 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v3float = OpTypeVector %float 3
    %v4float = OpTypeVector %float 4
    %float_0 = OpConstant %float 0
%_ptr_Input_v3float = OpTypePointer Input %v3float
 %vertex_pos = OpVariable %_ptr_Input_v3float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
               OpLine %1 7 1
       %vert = OpFunction %void None %4
               OpNoLine
          %6 = OpLabel
               OpLine %1 7 0
         %31 = OpLoad %v3float %vertex_pos
               OpLine %1 8 0
         %43 = OpCompositeExtract %float %31 0
         %44 = OpCompositeExtract %float %31 1
         %45 = OpCompositeExtract %float %31 2
         %46 = OpCompositeConstruct %v4float %43 %44 %45 %float_0
               OpLine %1 7 0
               OpStore %_entryPointOutput %46
               OpReturn
               OpFunctionEnd
ia2d9nvy

ia2d9nvy1#

我设法解决了这个问题,简单地不使用shaderc.net。无论出于什么原因(我不知道),它似乎不能正常工作。然而,一旦我切换到Vortice.ShaderCompiler,这几乎只是一个插槽的替代品,一些不同的命名约定,仅此而已,它突然完美地工作了。
所以,我想答案是:
不要使用shaderc.net,它已经坏了,3年没有维护了,使用最新的东西代替,有一些不错的替代品。

相关问题