McManning / Scratchpad

Realtime viewport render engine for Blender 2.8+
35 stars 4 forks source link

Blender 2.91 - GL Context Crashes #15

Open McManning opened 3 years ago

McManning commented 3 years ago

Got the following exception - sourced from Mesh.draw() glDrawElements after either copying a mesh or adding a new mesh to the scene while the render engine is active.

# Blender 2.91.0, Commit date: 2020-11-25 08:34, Hash 0f45cab862b8
bpy.context.space_data.context = 'RENDER'  # Property
bpy.context.scene.render.engine = 'foo_renderer'  # Property
bpy.context.space_data.shading.type = 'MATERIAL'  # Property
bpy.ops.transform.translate(value=(-1.0005, -0.840433, 1.15594), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=True, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)  # Operator
Copied 1 selected object(s)  # Info
bpy.ops.view3d.pastebuffer()  # Operator
1 object(s) pasted  # Info

# backtrace
Exception Record:

ExceptionCode         : EXCEPTION_ACCESS_VIOLATION
Exception Address     : 0x00007FFA5607D0E0
Exception Module      : nvoglv64.dll
Exception Flags       : 0x00000000
Exception Parameters  : 0x2
    Parameters[0] : 0x0000000000000000
    Parameters[1] : 0x0000000000000000

Stack trace:
nvoglv64.dll        :0x00007FFA5607D0E0  Symbols not available

Loaded Modules :
0x00007FF75BA20000 2.9.1.0              blender.exe c:\Program Files\Blender Foundation\Blender 2.91\blender.pdb 
0x00007FFAB7660000 10.0.18362.1171      ntdll.dll  
... etc ...

# Python backtrace
  File "C:\Users\cmcma\AppData\Roaming\Blender Foundation\Blender\2.91\scripts\addons\micro.py", line 428 in draw
  File "C:\Users\cmcma\AppData\Roaming\Blender Foundation\Blender\2.91\scripts\addons\micro.py", line 594 in view_draw
McManning commented 3 years ago

Adding a mesh to the scene seems fine - and the render engine picks it up and draws it. But it looks like once you click the scene view it crashes.

So it's probably only happening after a FooRenderEngine.view_update

McManning commented 3 years ago

I'm also noticing gamma differences for the default shader. But I remember Blender changing how this works so I'm going to have to go re-read changes for 2.91 (below would be 2.82 vs 2.91)

2.82 default shader 2.91 default shader

McManning commented 3 years ago

Seeing some issues with the full scratchpad as well - that has better error reporting so it's a little less vague, but it seems like a similar point of failure:

Draw <ScratchpadMesh(name=Cube) at 2111374997768>
Bind VAO(vao_id=13, indices=0, valid=1): <IndexBuffer(ebo_id=178, valid=0) object at 2111375019208> dict_values([])
        Program: 281
        VAO: 13
        VBO: 146
        EBO: 0
Invalid state for glDrawElements. Current bindings:
        Program: 281
        VAO: 13
        VBO: 146
        EBO: 0
        Bound VAO: VAO(vao_id=13, indices=0, valid=1): <IndexBuffer(ebo_id=178, valid=0) object at 2111375019208> dict_values([])
McManning commented 3 years ago

Looks like they added bl_use_gpu_context - but it doesn't seem to do anything useful here.

McManning commented 3 years ago

Alright - think I got this one figured out. Flagging bl_use_gpu_context essentially lets the render engine call their DRW_render_context_enable method here: https://github.com/sobotka/blender/blob/2221389d6e8e799ae1a001e4a3457fa5c3fd90fb/source/blender/render/intern/engine.c#L781-L783 and https://github.com/sobotka/blender/blob/1f41bdc6f37fd091bb5649436f68335b10ade51f/source/blender/draw/intern/draw_manager.c#L3005-L3030

Seems like it'll be needed for these render engines moving forward if I want to do ANYTHING that uses GL context and not just piping it off to an external lib to render and return.

It looks like each render engine is getting its own context now (or maybe did before - I didn't diff this), either way I'm doing a glGenBuffers in the main thread per mesh, so I'm betting those are setup in the wrong context in some way. I don't know for a fact that I can't call glGenBuffers outside of a context, but moving that work into setting up the VAO on first use from within the RenderEngine.view_draw seems to have stopped the access violation issues.

I'm going to play with it some more - also added a lock to read access to the Mesh's vertices/normals/etc buffers - because I did notice it'd be possible for the main thread to re-allocate those while the render thread was uploading. Rare - but still indeterminate behaviour that'd be annoying to debug. Also caching the raw foreach_get call return values in the Python Mesh class alongside the Buffer() wrapped copies. I don't think those would be deallocated out from under me, but I'd rather be safe than sorry.

Changes will also need to be applied to the main Scratchpad addon - since I bet that's why the EBO keeps invalidating there.

McManning commented 3 years ago

Yea I'm going to assume my glGenVertexArrays outside the render engine's context definitely helped cause it. Via https://stackoverflow.com/questions/44812250/is-vertex-array-object-a-part-of-context

McManning commented 3 years ago

I'm not seeing anything context-switching related in 2.82 (assuming I'm looking in the right place) - https://github.com/sobotka/blender/blob/v2.82/source/blender/render/intern/source/external_engine.c#L778

McManning commented 3 years ago

Should be resolved by 0387993

McManning commented 3 years ago

Whoops - resolved for micro.py - not the main Scratchpad project.