-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reset dx12 render state after returning from a user callback. #2037
Conversation
Hello Chris, This would unfortunately be a breaking change for people who rely on callbacks to change their render state. #1639 was proposing a similar thing for OpenGL, see comments and particularly #1639 (comment). I think we should standardize dummy callback value for that purpose, e.g. something like:
(And possibly finer grained variations later.) It would be up to the user to push this callback to request restoration of graphics state. The work required would be to implement that for all/most current renderers, which would require a bit of code refactoring. -Omar |
83309fa
to
e3ee052
Compare
I kept it as a local solution, but manually triggered, so I don't risk breaking all other renderers. The pattern will need to be replicated in each one if support is desired. |
e3ee052
to
3cd56f5
Compare
3cd56f5
to
8864e23
Compare
8864e23
to
2ab7b9c
Compare
…r a user callback. It can be called directly or bound as a callback. Add optional descriptor heap parameter to render function so it can be reset along with the rest of the render state.
2ab7b9c
to
2990b1a
Compare
I updated it to match the comment in #2452 so you can simply write: I also added an optional descriptor heap to the render function so it will also be reset. I was already doing this manually. |
Thanks! I would keep using a hardcoded-value-casted-into-pointer (defined in imgui.h) in order to allow any user code to use them without having to include binding headers. It also allow the rendering those to be performing those actions locally with less cruft (no setting of globals). Among related tasks:
(Edited with a third point) |
Another issue with the PR constructed as is, is that if a user callback is the first element of the list draw, it will be executed without having the GPU state setup. Likewise for a CustomCallback/ResetState/CustomCallback sequence. The main problem here is to find the most elegant, most consistent and least confusing way to handle that for every rendering back-ends. And we have to be particularly considerate that those rendering functions are de-facto documentations for a lot of users. The cleanest way may actually be to move that init code into a function?
[...]
|
Pushed a test: Seems fairly clean and not adding too much extra cognitive load to the casual reader? I think we ought to answer this question: Ping @bear24rw, @xor2k (sorry for resurrecting #1639 so late!) |
Thanks for feature branch. The only suggestion I have is to move the check for ImDrawCallback_ResetGpuState inside the check to see if UserCallback is valid, just to get rid of the extra if on each iteration (even though I added one in my version...) What are you thoughts about adding the HeapDescriptor to the DX12 Render call so it can be reset by default without extra user code? I was interleaving ImGui rendering with my own rendering to reduce the number of offscreen buffers which meant switching to my own HeapDescriptors. |
You're right I'll do that, mostly to keep all that code in a single block and not give too much importance of the callback paths (as for the casual user callbacks are not relevant).
I would need more details, and probably need a crash course about what a HeapDescriptor is and how they are used or can be used. Similar topics have been brushed in the past for DX12/Vulkan issues rarely with enough details to allow me to take good enough decision (both DX12/Vulkan still have unsorted issues regarding how |
Now that I'm reading it more it looks like I set things up wrong by isolating ImGui resources into their own static heap. Everyone seems to agree that rebinding Heaps is very costly so I will still need some mechanism to ensure that ImGui's font resources are available on the global heap so I don't need to rebind it. |
You may want to investigate how would using |
Looking at that was part of what made me start to rethink the whole process. I feel like I would need a hook to replace: ctx->SetGraphicsRootDescriptorTable(1, (D3D12_GPU_DESCRIPTOR_HANDLE)&pcmd->TextureId); with my own method of binding resources. Generally the texture is held in a cpu only heap and needs to be copied to the currently active gpu heap before being set, but that gpu heap is controlled by the application, not by ImGui. |
Also see the end of #301 (and #914, #2251) What I would like to determine is if we could provide a renderer-agnostic hook (e.g. an optional function pointer in ImGuiIO) or if it is best hooked at the renderer level. The later would require a little more cruft but would make it easier for each renderer to pass on local information that may be useful to the "texture" change. e.g. in DX12's command-list. |
I pushed a change to address the issue. https://github.com/kudaba/imgui/tree/features/drawcallback_reset_render_state My main concern was making it so whatever ImTextureID is being used for is consistent for all calls. This meant that the Font texture has to be created and set by the user when using a callback to set textures during rendering. |
I think from the moment you specify a set_texture_function we can leave it to the user to call PS: It would be good is you made sure your editor supported EditorConfig so make your patches use 4-spaces instead of tabs. |
I'll get another version uploaded tomorrow with a global set texture function. I'll put some assertions in there to make sure that the user is setting the texture function and font texture ID before calling dx12 init to make sure they are in sync and to prevent the dx12 init from creating its own texture. I can go ahead and update all the example renderers to use the new texture resolution method, but I'm not currently setup to be able to test anything beyond dx12 at the moment. PS: I'm using Visual Studio 2017 which does support it, but apparently has some holes in it's implementation. I'll make sure the next change doesn't have this problem. |
Don't worry about this. The important part is nailing the design, once I'm happy with a solution I can apply it to other back-ends (and it is definitively more important for DX12 and Vulkan than many other back-ends). |
The branch is updated. One thing I couldn't decide on was if I should be more strict about setting both the font texture and texture set functions consistently. I was thinking of adding asserts to make sure they were both set or both unset during initialization but felt that might be too restrictive so I left it up to the user. |
@kudaba I may start backporting some of the ImGuiPlatformIO stuff from the |
Branch has been merged in now. |
@kudaba |
I'll try to get a fresh pr up for the texture set callback sometime this week. Thanks for getting this in. |
This change allows for rendering my 3d scene interleaved with imgui rendering so I don't need to render to an offscreen buffer.