-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
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
D3D12 implementation #301
D3D12 implementation #301
Conversation
Thanks! Looks like a really tedious API to work with. |
Happy to contribute! :) I don't think any licence is necessary, it can follow the rest of the code. |
Oh and also I forgot to implement changing texture id's between draw calls. |
This D3D12 example doesn't work on my machine (Win 10 Pro, i7-4790K, GTX 970). Debug output shows error:
This happens if you build 64-bit code. Then this initialization is wrong:
{0,0} initializes DescriptorTable member of rootParameter[1], but it should initialize Constants member. Why this works on 32-bit code? Because DescriptorTable and Constants are in union. And in 32-bit code members of these structures align on each just fine. But in 64-bit code there is 32-bit padding after first member DescriptorTable. So second 0 doesn't initialize second member of Constants structure correctly and everything fails later. Oh and dxgidll variable is not used - you are linking with dxgi.lib file. I would suggest to do same thing with d3d12.dll file and its functions. |
Sorry for the late response, just saw this, thanks for the info, those dang unions! |
Is there a reason this hasn't been merged? I ask because I wish to use it and just wanted to make sure there were no known issues I should be aware of beforehand. Thanks so much for contributing this, it's a massive help. |
Hasn't been merged because 1/ I didn't have time to look, 2/ comment above suggest there are issues 3/ frankly I am not super convinced of the value of a DX12 example. DX12 is rather complex and anybody using that would have their own high-level layer/engine over it, at which point it would be preferable to just call your own functions and not native DX12 ones. The additions of examples may be noise more than anything, it is preferable to look at the simplest OpenGL example and adapt that to your own renderer architecture rather than use the raw render API. |
So as per you and Julian interventions in others I understand why this may be of use as is. (The reason I'm a bit slow and reluctant to add new examples is that even minimal, they all requires some amount of maintenance/sync at some point). |
Ah yes, I misread the comments sorry. I thought the flickering issue was resolved but it is not. I made a (very short, due to my awful upload speed) video which shows it. https://youtu.be/DNBiMhEWb9A I was able to work around it by removing the DXGI_PRESENT_RESTART flag (simply passing 0 instead) on the call to Present on line 511 of main.cpp, however that dropped the FPS down to double my refresh rate, instead of what it was before which was about 8x. |
Yes, thank you for the video, maybe it will help identify the problem. Unfortunately I haven't found a workaround either except for rendering with vsync. There is a fence before Present() which should prevent this behavior, so I am very curious why this happens. |
Any reason why you shared a single CommandBuffer between RenderDrawLists and the main loop? It sounds simpler if the render target and the commandAllocator are the only things shared and the hypothetical game code can then use an independent set of commandbuffers. |
|
||
uint64_t readCursor = 64; // Our constant buffer takes 64 bytes - one mat4x4 | ||
|
||
for (int n = 0; n < _draw_data->CmdListsCount; n++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This for loop can be merged with the previous one. So you copy the render data in parallel with filling the command buffer.
also you never unmapped g_uploadBuffer
g_uploadBuffer is on D3D12_HEAP_TYPE_UPLOAD heap. Resources on upload heap can be permanently mapped. No need to call unmap. This is in the docs: https://msdn.microsoft.com/en-us/library/windows/desktop/dn788712.aspx#Advanced_Usage_Models |
I think you can stop the flickering if you have proper buffering There microsoft has a created a CommandAllocator per frame in the swapchain and only resets the allocator when it's time to render to the frame it's connected to. In addition you'll need to round robin buffer the upload heap. |
Why is the root signature created and set in main.cpp instead of imgui_impl_dx12.cpp? Also, commandList->SetGraphicsRootDescriptorTable(0, ...); needs to be set per-draw in ImGui_ImplDX12_RenderDrawLists() in order to support more than one texture (not once for the entire GUI). This doesn't happen in the example app but is necessary in general. This implementation will only support rendering one frame at a time, as you need to version your geometry data in order to support multiple concurrent frames in flight. main.cpp indeed waits for each render to complete before starting the next frame, but this is a pretty bad constraint for performance and probably isn't appropriate for all imgui users. IMO, it would be nice if the imgui_impl_dx12.h API matched the other API implementations more-closely to help integrate it with existing imgui applications (e.g. _Init, _Shutdown, _NewFrame, _InvalidateDeviceObjects, etc). |
Is there still interest in merging this in? |
@sherief I wouldn't mind merging a DX12 sample but it looks like this one has several pending questions/issues to be looked at. The PR code is maybe usable locally (I don't know) but isn't mergable quality. If someone knowledgeable of DX12 want to have a serious look at some of the things discussed. They may also do line-by-line compare of the code with the DX11 version to be more strict about coding-style and mirroring other examples structures. |
FWIW, I also have a DX12 implementation that I wrote because I didn't notice that this pull request existed yet: https://github.com/jdm3/imgui It may serve as an interesting comparison to the above. |
You should compile as 64-bit code (amd64). Example code assumes void* can store UINT64 type (ptr member of D3D12_GPU_DESCRIPTOR_HANDLE structure). |
should be called before drawing so we set the font texture. And the back buffer format should be changeable, for example I am using RGB and not BGR as you are. here Edit: I am not sure about setting the texture like that thought. |
Hi Guys, I put this version into my project and noticed when i call to render the ImGui it makes my screen brighter overall. Would there be any reason for this to happen? |
I assume you mean the window IMGUI is rendering is brighter and not the whole screen right? Also, is this brighter than a different backend like D3D11? Check to make sure you are using the same rendertarget/swapchain formats (in particular, SRGB vs. RGB). |
@ChillyFlashER: The font texture's SRV is created in ImGui_ImplDX12_CreateFontsTexture(). @ChillyFlashER: Is there IMGUI API for changing the backbuffer format? I believe the expectation is that you just change the backend to your desired the swapchain format. |
@onatto @jdm3 Thanks, this is merged now! Better late than never :) I'm currently working on another branch where the examples/ files are being redesigned so we can easily separate the platform (win32/glfw etc.) from the renderer (dx12/vulkan) so I wanted this in the master branch. The 32-bit ImTextureId is still an open problem, will look at that soon. |
That definitely sounds like a lower-touch option. imgui_impl_dx12.cpp already has storage for the D3D12_GPU_DESCRIPTOR_HANDLE so it would just be a matter of storing &g_hFontSrvGpuDescHandle into the TexID instead of g_FontSrvGpuDescHandle and then dereferencing it for SetGraphicsRootDescriptorTable(...). |
We don’t really care about the font texture, the question is will it be sufficiently practical for user displaying their own texture to pass a pointer there (aka their descriptor can’t be on the stack etc and must have a lifetime of one frame).
|
Ah, ok, my typical imgui usage is more basic than that I guess :) IMO 64-bit TextureId is a more-ideal solution, but requiring the user to maintain storage and taking a pointer to that is a reasonable, easier change. Freeing the memory too early is a risk, and would be hard to debug, but hopefully clear usage documentation is enough to prevent that. Vulkan/D3D12 users need to be pretty aware of these parallel execution and lifetime issues anyway, so it shouldn't be too painful to add descriptor handles into whatever their "in-flight" data structure is. |
My recommendation is to keep it as void* but consider adding a frame allocator to ImGui (maybe on the draw list?). Most larger projects will already have one, but for smaller things I've run into it a few times. E.g. passing data to a draw list callback. If someone had a descriptor on the stack and knew that it would be valid for the frame, they could use the ImGui frame allocator as a convenience. |
a frame allocator that clears on newFrame sounds like a good idea, preallocate some memory for it (configurable) and you can allocate some more when the allocation gets too big, though will you add running destructors on clear to that? Unless it's clearly documented that it's a flat clear I can foresee a lot of leaks because someone thought destructors of pushed types would also run. |
Thanks for your feedback all. It feels like we can keep the I have pushed an experimental Viewport branch (#1542) which includes two things:
The branch is at: The reason I'm posting here is that both the DX12 and Vulkan renderer in this branch don't have support for the "viewport renderer" api yet. In: From Line 640 I have pushed an empty skeleton of what would be needed to support it in DX12, there are basically 5~6 functions to fill.
I left commented out code based on the DX11 renderer to make it clearer what is expected here. I may try to look at it at some point later, but if someone knows DX12 and is excited by this you may want to see how to add the missing code for DX12 and Vulkan and see if the current API hold or how we should improve it. |
…rom ImGui_ImplDX12_NewFrame() to ImGui_ImplDX12_RenderDrawData() which makes a lots more sense. (#301)
This is probably obvious to some of you :) But I'll add this info here in case someone looking for this in the future. #define ImTextureID D3D12_GPU_DESCRIPTOR_HANDLE * Then remove the and it should compile perfectly fine. There are few other issues with imgui-dx12-example, when resizing the back-buffer of the main-window. it kind of squeezing the fonts and the imgui windows until the mouse is released. Also multi-view support still not available. Other than that, it's quiet usable :) |
I'm actually experiencing these problems right now (I'm using ResizeBuffers on my swap chain rather than re-creating the swap chain itself on every resize like how the example is doing it). How do people get around this? I'm not super up-to-date on all the stuff available within ImGui; is there something quick and easy to 1. tell ImGui it needs to auto-resize the widgets to fit the new client width/height 2. update the hot zones for widgets? |
…ect files and comments. (#301)
Closing this old issue :)
This is a general issue with many/most windows application, the way the Win32 API works is that during a resize it goes into a modal loop inside Windows code and the application cannot react, so your notice most back-ends are doing that. There are several ways to fix it, e.g. using a WM_TIMER, and it's well documented on the internet but right now out of the scope of your examples application to avoid dragging in noise into the application. Resizing programmatically (e.g. via dear imgui decorations in a multi-viewport context) doesn't suffer from it and should be totally smooth.
This has been added since. |
Includes my merged PRs and everything in my dev branch. Haven't tested with it yet. Changelog: Test case for clip rect HACK: more recent Windows SDK and VS2017; disable graph Set size to amount of space required Merge pull request ocornut#349 from maksw2/master Merge pull request ocornut#347 from mgerhardy/341 Merge pull request ocornut#348 from mgerhardy/fixed-warning Merge pull request ocornut#346 from mgerhardy/280 Merge pull request ocornut#345 from mgerhardy/322 Merge pull request ocornut#344 from rherilier/fix-gcc-warnings Merge pull request ocornut#336 from rherilier/add-isusingviewmanipulate Merge pull request ocornut#335 from RedSkittleFox/alternative_window Merge pull request ocornut#334 from ocornut/fix-beginchildframe dear imgui update and small fixes Merge pull request ocornut#316 from Batres3/2DSupport Merge pull request ocornut#326 from Sayama3/use-push-pop-id Merge pull request ocornut#328 from georgeto/master Merge pull request ocornut#330 from maritim/master Merge pull request ocornut#331 from GiovanyH/patch-1 Merge pull request ocornut#318 from dougbinks/imgui_math_operators Merge pull request ocornut#312 from kimidaisuki22/master div 0 fixed Merge pull request ocornut#301 from ZingBallyhoo/using-any Merge pull request ocornut#300 from Clog41200/Configurable-limits Merge pull request ocornut#298 from xDUDSSx/fix/rotation_circles Merge pull request ocornut#297 from xDUDSSx/fix/vertical-aspect-scaling Merge pull request ocornut#289 from ComputationalBiomechanicsLab/fix_isusing-ignores-setid Merge pull request ocornut#291 from ocornut/fix_math_operators_include Merge pull request ocornut#282 from MohitSethi99/master Merge pull request ocornut#276 from pthom/virtual_destructors Merge pull request ocornut#271 from idbrii/clip-parent Merge pull request ocornut#270 from idbrii/btn-behaviour Merge pull request ocornut#265 from mgerhardy/pr/fix-minor-formatting Merge pull request ocornut#264 from mgerhardy/pr/div0 Merge pull request ocornut#269 from peter1745/hatched-line-thickness-enhancement Merge pull request ocornut#259 from miyanyan/master Merge branch 'master' of https://github.com/CedricGuillemet/ImGuizmo update dear imgui Merge pull request ocornut#256 from Aidiakapi/patch-1 Merge pull request ocornut#252 from aaronkirkham/master Merge pull request ocornut#249 from rokups/rk/mouse-capture Merge pull request ocornut#246 from mgerhardy/pr/viewmanipulate removed commented code fix click view cube Merge pull request ocornut#231 from mgerhardy/master Merge pull request ocornut#230 from mgerhardy/master Merge pull request ocornut#228 from longod/master Merge pull request ocornut#227 from madeso/master AddBezierCubic Merge pull request ocornut#226 from sherief/master revert culling test commit Merge pull request ocornut#203 from rokups/rk/misc-fixes Merge pull request ocornut#212 from zhaijialong/fix-behind-camera-cull Merge pull request ocornut#209 from VictorFouquet/fix_normalize scale is always local Merge pull request ocornut#202 from pezy/master imguizmo namespace Merge pull request ocornut#194 from JonathanHiggs/vcpkg-example 1.84 WIP Merge pull request ocornut#197 from idbrii/seq-btn-color Merge pull request ocornut#196 from idbrii/seq-big-handles
I have some flickering errors for the first frames or so but it's working.