-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Add glfw wgpu desktop and multiviewport support #7132
Conversation
Changed ImGui_ImplWGPU_Init function by adding instance Added Safe release for WGPU structures (SwapChain/Surface) Added ImGui_ImplWGPUH_Window struct required for each window Check for required empty instance when using multiveiwport
Added backend flags and checks Added platform init function Added platform shutdown function Hooked render functions CreateWindow, DestroyWindow, SetWindowSize, RenderWindow, SwapBuffers
Fixed missing Instance Fixed null check and moved it when using it
Fix emscripten build in unused area
Added cmake lists to compile dawn along with the example Added cmake presets (for anyone one using cmake 3.19+) to configure easier
Split emscripten only sections off Added callbacks for getting device & adapter Added multi viewport code Added swapchain creation function Added temporary canvas resize on creation until ocornut#6751 is merged in (Refreshing will resize the canvas)
Removed hardcoded dawn location
Removed temp resize code Split the main function up to show init fuctions
Removed temp code in index
Hello, Very interested in getting even-basic desktop support in. Could you squash/rebase this and try to separate it into two commits?
Feedback:
|
…compatible Desktop examples, as aiming to make this suppot desktop eventually. Also aimed at reducing diff for #7132 tho this will lead in conflict.
FYI i have pushed some WebGPU related changes which will conflict with this (but ultimately simplify the diff).
To proceed I suggest that:
|
I'm working with the But a couple of notes from reading through this:
|
@ocornut sorry for disappearing, just have a contract close to completion, that I need to take care of. I will sort those changes within the coming week or 2. Surface creation is still something I am having issues with cross platform. That will require a bit of work to figure out. @waywardmonkeys Awesome to hear about the cmake stuff and conflicts with swapchain. I had no idea that was coming. I will have to read up on it. The mix between the C and C++ was to get around surface creation stuff for half of it and getting the device and adapter callbacks. I have kept the implementation of webgpu as the C api only to keep it more inline, but the example has the C and C++ stuff. Tho it still has swapchain stuff in the dawn implementation that i used. So we will need to convert that. What would the best approach be for aligning this? Pre processor for wgpu-native and dawn for how to use swapchain? But that would break when dawn changes it. My guess will be make it the way wgpu-native uses it and maybe release it once dawn releases that change. I will try sort out some stuff today around the merge from docking, feel free to sort out the swapchain/surface reconciliation issue any help there is much appreciated :D |
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.
@@ -72,8 +74,22 @@ struct Uniforms | |||
float Gamma; | |||
}; | |||
|
|||
// Forward declarations for multi-viewport support | |||
static void ImGui_ImplWGPU_InitPlatformInterface(); |
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.
@ocornut, maybe it's worth renaming everything from WGPU to WebGPU? "wgpu" is a name of the Rust implementation and I see "WebGPU" being used everywhere (except for C API, which I find unfortunate).
Otherwise people might think that this backend can only be used with wgpu and not with Dawn.
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.
I had chosen to go with WGPU purely based on how the C API was naming things, so yeah WebGPU is fine to go with as well.
backends/imgui_impl_wgpu.cpp
Outdated
ImGui_ImplWGPU_ViewportData() { } | ||
~ImGui_ImplWGPU_ViewportData() { } |
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.
These constructor and destructors are unnecessary and can be removed.
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.
That was a hang over of when I did have objects in there, yup should have been deleted
color_attachments.view = wgpuSwapChainGetCurrentTextureView(vd->Window.swapChain); | ||
color_attachments.loadOp = WGPULoadOp_Clear; | ||
color_attachments.storeOp = WGPUStoreOp_Store; | ||
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; |
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.
Doesn't work without this:
color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
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.
I think this is a new requirement imposed in a version of dawn that I had yet to work with, If that is required then putting it in should be done.
backends/imgui_impl_wgpu.h
Outdated
@@ -22,7 +22,7 @@ | |||
|
|||
#include <webgpu/webgpu.h> | |||
|
|||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined); | |||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined, WGPUInstance instance = nullptr); |
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.
Probably needs a comment which will explain why "instance" is optional here (so that people don't need to read the implementation to know that).
backends/imgui_impl_wgpu.h
Outdated
@@ -31,4 +31,17 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURen | |||
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects(); | |||
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(); | |||
|
|||
// Helper structure to hold the data needed by one rendering context into one OS window | |||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.) |
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.
If it's not meant to be used by other people, then maybe let's move it into the example's main.cpp?
Actually, it would be pretty handy since you'll be able to use Dawn's webgpu_glfw.h
+ CreateSurfaceForWindow
function that they provide.
@@ -216,22 +283,28 @@ static void MainLoopStep(void* window) | |||
color_attachments.storeOp = WGPUStoreOp_Store; | |||
color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; | |||
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain); | |||
|
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 is needed here too:
color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
static int wgpu_swap_chain_height = 0; | ||
static wgpu::Instance wgpu_instance = nullptr; | ||
static wgpu::Surface wgpu_surface = nullptr; | ||
static wgpu::Device wgpu_device = nullptr; |
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.
As others have said, there's no need to use C++ wrappers here since they don't simplify much in this example.
{ | ||
// Async Get Instance, Adapter and device | ||
// Init and run everything once these have been obtained. | ||
InitWGPU([](wgpu::Device device) { |
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 type of code is pretty hard to follow. Would be a bit easier to understand this, imo (note that wgpu_instance should be changed to a C type too):
int main(int, char**)
{
wgpu_instance = wgpuCreateInstance(nullptr);
WGPUAdapter adapter = requestAdapter(wgpu_instance);
wgpu_device = requestDevice(adapter);
SetupAndRun();
return 0;
}
static WGPUAdapter requestAdapter(WGPUInstance instance)
{
auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status,
WGPUAdapter adapter,
char const* message,
void* pUserData) {
if (status == WGPURequestAdapterStatus_Success) {
*static_cast<WGPUAdapter*>(pUserData) = adapter;
}
else {
printf("Could not get WebGPU adapter: %s\n", message);
}
};
WGPUAdapter adapter;
wgpuInstanceRequestAdapter(instance, nullptr, onAdapterRequestEnded, (void*)&adapter);
return adapter;
}
static WGPUDevice requestDevice(WGPUAdapter& adapter)
{
auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status,
WGPUDevice device,
char const* message,
void* pUserData) {
if (status == WGPURequestDeviceStatus_Success) {
*static_cast<WGPUDevice*>(pUserData) = device;
}
else {
printf("Could not get WebGPU device: %s\n", message);
}
};
WGPUDevice device;
wgpuAdapterRequestDevice(adapter, nullptr, onDeviceRequestEnded, (void*)&device);
return device;
}
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.
Yup that looks way better
//-------------------------------------------------------------------------------------------------------- | ||
|
||
|
||
static void ImGui_ImplWGPU_CreateWindow(ImGuiViewport* viewport) |
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 should probably be moved out of the backend and user should provide this instead - there's no easy way to handle this for every platform/WebGPU impl.
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.
100% this is the main thing I was struggling with trying to fix, would it be just a callback that a user would need to assign to ?
backends/imgui_impl_wgpu.cpp
Outdated
@@ -38,6 +39,7 @@ | |||
#include "imgui_impl_wgpu.h" | |||
#include <limits.h> | |||
#include <webgpu/webgpu.h> | |||
#include <memory> |
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.
Can be removed if ImGui_ImplWGPU_CreateWindow
is not included in the backend.
@Zelif If you're currently busy with other work, I can do this myself and credit your contributions. (P.S. I would also make some of the changes I've proposed myself, especially about C API usage and taming the callbacks in main.cpp) |
…ze and contents size are submitted by API. (ocornut#7252)
@eliasdaler The changes with swapchain I have yet to read up on and unsure if they have made their way to Dawn yet. I never got around to testing wgpu-native with it either. What is the best way to move forward ? Do I add you or anyone else to my fork or did we want to move this to a new PR with someone else in control. I'm fine with anything wish I had time to sort it out. |
Extracted from 2023/12/29 post. WIP add PathFillConcave(), AddConcavePolyFilled() * remove use of 'auto' * IsConvex -> ImPathIsConvex * Triangulator -> ImTriangulator * ImTriangulator: split declaration from definition, ImTriangulator can be put in the header if necessary * ImTriangulator: Add node list flip to reverse winding order and handle degenerate cases * ImTriangulator: Remove _HeapStorage, always require scratch buffer to be provided * ImTriangulator: Use ImTriangleContainsPoint * AddConcavePolyFilled: Clone AddConvexPolyFilled and use triangulator * AddConcavePolyFilled: Remove ImDrawListEx_AddPolyFilled_xxx * AddConcavePolyFilled: Use _Data->TempBuffer in triangulator * AddConcavePolyFilled:
…ornut#760) - Simplify and compact some code. Shallow tweaks. - Add comments. - Add concave shape demo. - Remove coarse culling. - Remove nested types to match coding style and for consistent type nams when translated to other languages. - Merged ClassifyNode() and ReclassifyNode(). - Extracted ImTriangleIsClockwise(). - Hold copy of points inside nodes instead of pointing to them.
No problem, life happens, don't feel bad about it. I've abandoned quite a few PRs in my life myself and it's okay. :) I'll start a new PR from my fork sometime later. |
@eliasdaler The only difference that was being done was the instance, adapter and was being captured in the html. (this was being swapped over in another pull request here: #7151 Seems the depth stencil issue has already been resolved via: |
…e closer to each others + better packed ImGuiNavItemData
…ure so other fields layout are not affected by it (ocornut#7534) This is essentially a misleading grace feature allowing a build mistake to be made, as we technically are more flexible now. BUT if we reintroduce a need we may more harshly move it to the top of the structure to detect issues.
# Conflicts: # backends/imgui_impl_vulkan.cpp # backends/imgui_impl_win32.cpp
…s stored outside the scope". Technically not used outside that scope, but best to play nice.
…dows. Clarify why we don't need to store alpha. (ocornut#7535, ocornut#2771) Amend ebbb98d
…indow::Pipeline (ocornut#6325, ocornut#6305, ocornut#7398, ocornut#3459, ocornut#3253, ocornut#3522) As this is currently unused and misleading. Next commit will add a separate pipeline for secondary viewport.
…cornut#6325, ocornut#6305, ocornut#7398, ocornut#3459, ocornut#3253, ocornut#3522) Edited from original commit: moved ImGui_ImplVulkan_CreatePipeline() call from ImGui_ImplVulkanH_CreateOrResizeWindow() to ImGui_ImplVulkan_CreateWindow().
…d header bg and text colors per column. (ocornut#6917)
…Var_TableAngledHeadersTextAlign. (ocornut#6917)
No functional changes.
…cornut#6861, ocornut#2884, followed by rename 94da584) Since negative windows can never be visibile in master it didn't show as a difference.
# Conflicts: # imgui.cpp # imgui.h
…y one when window is located on a monitor with negative coordinates. (ocornut#6861, ocornut#2884)
- Added instance to init model - Added Present mode for any new window to adhere by - Added Multiviewport render and update code - Changed Texture format and Present mode to select the first available mode for capabilities (some surface creation such as laptops might not support FiFo)
Added cmake lists to compile dawn along with the example Added cmake presets (for anyone one using cmake 3.19+) to configure easier
Split emscripten only sections off Added callbacks for getting device & adapter Added multi viewport code Added swapchain creation function Added temporary canvas resize on creation until ocornut#6751 is merged in (Refreshing will resize the canvas)
Removed hardcoded dawn location
Removed temp resize code Split the main function up to show init fuctions
Removed temp code in index
…into Add-glfw-wgpu-example
Welp I messed that up(I will have to fix the history of this PR or start another?), This still has the issue of surface creation which @eliasdaler said to change to a callback that a user creates. I am unsure how to structure this, but should hopefully help. EDIT: I started another PR that focuses on just the multiviewport stuff #7557 |
Adding Multi viewport to the desktop version of WGPU
When using dawn/wgpu-native have the multi viewport enabled and rendering (fixes: #7110 )
Items required to get the wgpu backend working:
color_attachments.view = wgpuSwapChainGetCurrentTextureView(vd->Window.swapChain);
)Create window is the major area that still needs work due to surface creation being platform dependent. I was looking at the way vulkan handles it and there is a special function inside the glfw/sdl/etc backends (
CreateVkSurface
) I assume this is the approach that would be required going forward?Example changes
Example now works on desktop and all emscripten stuff is behind preprocessor directives.
Added CMakeLists.txt and a CMakePresets.json, the latter doesn't have to be used but is handy (only works with CMake 3.19+), adding the location to a clone of the dawn repo is required in
CMakeLists.txt:30
. I am yet to test out wgpu-native vs dawn as of yet. Or if there is anywhere that has static builds to link against for dawn that could be included. (I am unsure how you would want this included)The make file will need to be updated but I do not know my way around them, and as I only know how to get dawn working with CMake that is what I used.
Firefox/WGPU-Native
Google/Dawn
Video of it working:
https://github.com/ocornut/imgui/assets/666945/875315c9-5b61-42b6-b8ed-a31bc8179050
Hopefully this helps :D