pkdawson / imgui-godot

Dear ImGui plugin for Godot 4
MIT License
318 stars 18 forks source link

Error (-3) creating shader module for stage: Vertex #40

Closed byte-arcane closed 4 months ago

byte-arcane commented 9 months ago

I get this error on my laptop (Radeon RX Vega 10 graphics). Here's the callstack (none is my code). I get this with any simple ImGui.Begin("blah")/ImGui.End() in a single node's _Process function (I'm using the 4.1.2 dotnet)

E 0:00:02:0871   Godot.NativeInterop.NativeFuncs.generated.cs:345 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* ): Error (-3) creating shader module for stage: Vertex
  <C++ Error>    Method/function failed. Returning: RID()
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:5131 @ shader_create_from_bytecode()
  <Stack Trace>  Godot.NativeInterop.NativeFuncs.generated.cs:345 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* )
                 NativeCalls.cs:7393 @ Godot.Rid Godot.NativeCalls.godot_icall_2_814(IntPtr , IntPtr , IntPtr , System.String )
                 RenderingDevice.cs:2381 @ Godot.Rid Godot.RenderingDevice.ShaderCreateFromSpirV(Godot.RDShaderSpirV , System.String )
                 RdRenderer.cs:56 @ ImGuiGodot.Internal.RdRenderer..ctor()
                 ImGuiGD.cs:79 @ void ImGuiGodot.ImGuiGD.Init(Godot.Window , Godot.Rid , System.Nullable`1[System.Single] , ImGuiGodot.RendererType )
                 ImGuiLayer.cs:83 @ void ImGuiGodot.ImGuiLayer._EnterTree()
                 Node.cs:2057 @ Boolean Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 CanvasLayer.cs:379 @ Boolean Godot.CanvasLayer.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 ImGuiGodot.ImGuiLayer_ScriptMethods.generated.cs:82 @ Boolean ImGuiGodot.ImGuiLayer.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(IntPtr , Godot.NativeInterop.godot_string_name* , Godot.NativeInterop.godot_variant** , Int32 , Godot.NativeInterop.godot_variant_call_error* , Godot.NativeInterop.godot_variant* )
pkdawson commented 9 months ago

Hm. I've seen other Godot issues where laptops have both an integrated GPU and a dedicated GPU and that causes problems; I wonder if it's trying to compile the shader on the integrated GPU. I'll have to look at that bit of engine code.

There is an easy workaround: open res://addons/imgui-godot/ImGuiLayer.tscn, go to the ImGuiLayer node, and create a Config resource if you don't already have one. Set the Renderer to Canvas. It's less efficient, but it should work fine.

byte-arcane commented 9 months ago

Sounds great! But how would that section look like in the .tscn file? Apologies, I'm unfamiliar with how I'd do such an edit. These are the contents:

[gd_scene load_steps=2 format=3 uid="uid://7nffahig8gu8"]

[ext_resource type="Script" path="res://addons/imgui-godot/ImGuiGodot/ImGuiLayer.cs" id="1_ag3g6"]

[node name="ImGuiLayer" type="CanvasLayer"]
process_mode = 3
process_priority = 2147483647
layer = 128
script = ExtResource("1_ag3g6")
pkdawson commented 9 months ago

Sorry, I meant open the .tscn file in the Godot editor. That will open the scene with the ImGuiLayer node, which you can modify in the GUI.

Alternatively, here's an ImGuiLayer.tscn file with a configuration resource:

[gd_scene load_steps=4 format=3 uid="uid://7nffahig8gu8"]

[ext_resource type="Script" path="res://addons/imgui-godot/ImGuiGodot/ImGuiLayer.cs" id="1_ag3g6"]
[ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiConfig.gd" id="2_q1xxp"]

[sub_resource type="Resource" id="Resource_eqt6v"]
script = ExtResource("2_q1xxp")
Fonts = Array[Resource("res://addons/imgui-godot/scripts/ImGuiFont.gd")]([])
MergeFonts = true
AddDefaultFont = true
Scale = 1.0
ScaleToDpi = true
IniFilename = "user://imgui.ini"
Renderer = "Canvas"
Layer = 128

[node name="ImGuiLayer" type="CanvasLayer"]
process_mode = 3
process_priority = 2147483647
layer = 128
script = ExtResource("1_ag3g6")
Config = SubResource("Resource_eqt6v")
byte-arcane commented 9 months ago

Awesome, many thanks. Confirming that the workaround works! (and thanks for the ultra quick responses)

pkdawson commented 8 months ago

I saw you mention that you're using RenderingDevice in your own game (which looks really cool; 2D procedural world gen is very much my area of interest), so I assume you're calling ShaderCompileSpirVFromSource in your own code, and that works?

I'd appreciate it if you could test the latest commit (without any custom configuration), and send me the output.

https://github.com/pkdawson/imgui-godot/archive/0932c2d84287753e2482bbc0f42cff09e6434dcd.zip

If loading the precompiled SPIR-V fails, it will try to compile the shader from source, and if that fails it will fall back to the canvas renderer.

The SPIR-V bytecode should be universal, it compiles identically for me on Windows/NVIDIA and Mac/M1, so I'm not sure what's going on. If you're doing something different to load RenderingDevice shaders, I'd be very interested to know.

pkdawson commented 8 months ago

OK I found the compute shader docs which suggest using an RDShaderFile (.glsl). That way the engine takes care of caching the SPIR-V.

I'm guessing that's how you write shaders for your game? If so, I'll just switch to that, and hopefully the issue will be fixed.

byte-arcane commented 8 months ago

2D procedural world gen is very much my area of interest

Awesome! Procgen is fantastic, share if you have anything! :D

I am indeed using the ShaderCreateFromSpirV. I'm not even using RDShaderFiles because I had troubles with includes and caching, I'm doing it fully DIY (including resolving includes) and using ShaderCreateFromSpirV

I'd appreciate it if you could test the latest commit (without any custom configuration), and send me the output.

Got this error code again:

E 0:00:02:0544   Godot.NativeInterop.NativeFuncs.generated.cs:345 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* ): Error (-3) creating shader module for stage: Vertex
  <C++ Error>    Method/function failed. Returning: RID()
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:5131 @ shader_create_from_bytecode()
  <Stack Trace>  Godot.NativeInterop.NativeFuncs.generated.cs:345 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* )
                 NativeCalls.cs:7393 @ Godot.Rid Godot.NativeCalls.godot_icall_2_814(IntPtr , IntPtr , IntPtr , System.String )
                 RenderingDevice.cs:2381 @ Godot.Rid Godot.RenderingDevice.ShaderCreateFromSpirV(Godot.RDShaderSpirV , System.String )
                 RdRenderer.cs:56 @ ImGuiGodot.Internal.RdRenderer..ctor()
                 ImGuiGD.cs:79 @ void ImGuiGodot.ImGuiGD.Init(Godot.Window , Godot.Rid , System.Nullable`1[System.Single] , ImGuiGodot.RendererType )
                 ImGuiLayer.cs:83 @ void ImGuiGodot.ImGuiLayer._EnterTree()
                 Node.cs:2057 @ Boolean Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 CanvasLayer.cs:379 @ Boolean Godot.CanvasLayer.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 ImGuiGodot.ImGuiLayer_ScriptMethods.generated.cs:82 @ Boolean ImGuiGodot.ImGuiLayer.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(IntPtr , Godot.NativeInterop.godot_string_name* , Godot.NativeInterop.godot_variant** , Int32 , Godot.NativeInterop.godot_variant_call_error* , Godot.NativeInterop.godot_variant* )

I just deleted the content from the addons folder, replaced with your new code, restarted Godot and re-ran it. Is there a different way to force-reload a plugin?

pkdawson commented 8 months ago

OK great, if that's the only error message, it means that compiling the shader from source worked. I expect the latest release (v4.0.6) will fix this issue.

I just deleted the content from the addons folder, replaced with your new code, restarted Godot and re-ran it.

Yeah that's the correct way to upgrade.

Thanks for your help!

byte-arcane commented 8 months ago

Sounds fantastic, thanks! Edit: I've tried 4.0.6 but still no luck!

byte-arcane commented 4 months ago

As of 4.1.0, this seems now fixed!