godot icon indicating copy to clipboard operation
godot copied to clipboard

Instancing MultiMesh with local to scene flag set throws Vulkan buffer argument error

Open SdgGames opened this issue 1 year ago • 2 comments

Godot version

v4.0.beta4.official [e6751549c]

System information

Windows Server 2022, Nvidia 4080 Ti, Vulkan

Issue description

I made Minecraft using chunks made of of MultiMeshInstance3Ds. Each time a new chunk is instanced, there are errors thrown. It turns out, the "Local To Scene" flag in the MultiMesh resource was causing the error. This project was a convert from Godot 3.5.1. The issue was not present in that version, it appeared after upgrading.

Error output from reproduction project below.

E 0:00:00:0780   _ready: Buffer argument is not a valid buffer of any type.
  <C++ Error>    Method/function failed. Returning: ERR_INVALID_PARAMETER
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:6311 @ buffer_update()
  <Stack Trace>  Game.gd:7 @ _ready()

Despite printing an error, everything does seem to be working, I can use the multimesh that is created.

Steps to reproduce

Create a MultiMeshInstance3D with a MultiMesh and Mesh resource. Set the Local To Scene flag as shown below:

multi

Save the scene. Load the scene resource from another scene, then call multiMeshScene.instantiate()

A rendering error will be thrown.

Minimal reproduction project

Multimesh.zip

SdgGames avatar Nov 13 '22 04:11 SdgGames

Still present in v4.0.beta.custom_build [2a04b18d3]

E 0:00:01:0175   _ready: Buffer argument is not a valid buffer of any type.
  <C++ Error>    Method/function failed. Returning: ERR_INVALID_PARAMETER
  <C++ Source>   drivers\vulkan\rendering_device_vulkan.cpp:5856 @ RenderingDeviceVulkan::buffer_update()
  <Stack Trace>  Game.gd:7 @ _ready()

Lippanon avatar Dec 20 '22 21:12 Lippanon

Still present in v4.0.rc5.official [6296b4600] // Edit: 4.0.stable as well

E 0:00:01:0109   Load.gd:36 @ _process(): Buffer argument is not a valid buffer of any type.
  <C++ Error>    Method/function failed. Returning: ERR_INVALID_PARAMETER
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:5857 @ buffer_update()
  <Stack Trace>  Load.gd:36 @ _process()

Swarkin avatar Feb 25 '23 15:02 Swarkin

v4.0.stable.mono.official [92bee43ad] I see the same issue, and it doesn't seem to matter if it's created from a saved tscn/tres file and/or duplicated afterwards. Even if I create the MultiMesh resource and node 'manually' from code this error pops up whenever it's added to the scene.

rmvermeulen avatar Mar 15 '23 21:03 rmvermeulen

I get this same error message in v4.0.1.stable.official when duplicating a multimesh with an instance count of 0, as well as a second when the multimesh is set as 'local to scene' (but only when the multimesh has instancecount of 0).

[this error only shows upo when 'local to scene' is set AND instance count is 0]

E 0:00:00:0761   buffer_update: Buffer argument is not a valid buffer of any type.
  <C++ Error>    Method/function failed. Returning: ERR_INVALID_PARAMETER
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:5857 @ buffer_update()

[when instance count is set to 0]

E 0:00:00:0769   Test_Multimesh_Buffer_Error.gd:6 @ _ready(): Buffer argument is not a valid buffer of any type.
  <C++ Error>    Method/function failed. Returning: ERR_INVALID_PARAMETER
  <C++ Source>   drivers/vulkan/rendering_device_vulkan.cpp:5857 @ buffer_update()
  <Stack Trace>  Test_Multimesh_Buffer_Error.gd:6 @ _ready()

It's easy enough to work around by making sure instance count is above 0, but there shouold probably be a check before vulcan tries to update a non existant buffer. I tried digging to work out where this check could be but made no headway.

Will happily make this a new issue if folk think it requires it.

SamsPepper1 avatar Mar 27 '23 14:03 SamsPepper1

In my case, I need to instance hundreds of local to scene MultiMeshes and this really slows down the engine (150+ instances, and I have to wait up to 15-20 seconds for the engine to throw an error for each of them). After that, everything works fine.

If you can raise an issue for them, it would be much appreciated @SamsPepper1

ironstrasza avatar Mar 28 '23 19:03 ironstrasza

Just saying, while the error is annoying in Vulkan, it crashes the whole program when using the OpenGL ES Compatibility renderer. It happens whether duplicating in code or using local_to_scene, so the only option is to create a new MultiMesh in code.

ERROR: GL ERROR: Source: OpenGL Type: Error     ID: 1282        Severity: High  Message: GL_INVALID_OPERATION error generated. Target buffer must be bound.
   at: _gl_debug_print (drivers/gles3/rasterizer_gles3.cpp:168)

caimantilla avatar Jun 14 '23 19:06 caimantilla

I am just running into error this in 4.1.1. My multimeshes are working correctly but each one gets this error on creation.

I am setting the instance count with gdscript and in general there is a lot of weirdness with using a multimesh from an instanced scene. But they do render correctly so far. Every time I change something in the scene with the multimesh, I have to add in back to the master scene, otherwise the changes don't update.

fracteed avatar Aug 27 '23 03:08 fracteed

@SamsPepper1 I had also tried this tactic, but had even more issues with it. I have it on a value above 0 and then in the ready method try to change the instance count and get the error "Condition instance_count > 0 is true". It also doesn't increase the instance count correctly, so the buffer size is incorrect.

I seem to only be able to dynamically change the instance count in ready if it is on zero to start with. Note, that 3.x didn't exhibit these issues.

fracteed avatar Aug 27 '23 04:08 fracteed

Still present in 4.2 rc2 official

image

And yes, the project silently crashes when it's in compatibility mode. This issue should be given more attention than what it's getting

EDIT: The easiest way I found to overcome this problem is to not store the multimesh but only the mesh itself. Then you can do something like this:

var multimesh_mesh_inst : Mesh = preload("YOUR MESH PATH")

func _ready() -> void:
  #Setup multimesh
  var multimesh : Multimesh = MultiMesh.new()
  multimesh.transform_format = MultiMesh.TRANSFORM_3D
  multimesh.use_colors = true
  multimesh.instance_count = 0
  multimesh.mesh = multimesh_mesh_inst
  
  #Setup MultimeshInstance
  var multiMeshInstance : MultiMeshInstance3D = MultiMeshInstance3D.new()
  multiMeshInstance.multimesh = multimesh
  add_child.call_deferred(multiMeshInstance)

NatGazer avatar Nov 29 '23 18:11 NatGazer