Skip to content
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

Update wgpu backend to emscripten 2.0.20 and chrome canary 92 #4116

Closed
wants to merge 13 commits into from

Conversation

bfierz
Copy link
Contributor

@bfierz bfierz commented May 8, 2021

This changeset introduces some implementation simplifications proposed by @Kangz here and updates the code to be compatible with Emscripten 2.0.20 as described here.

The major changes are:

  • Make use of automatic bind group generation instead of explicitly creating them
  • Update the API to the latest WebGPU changes as outlined here

@@ -331,7 +329,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// Create and grow vertex/index buffers if needed
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
{
SafeRelease(fr->VertexBuffer);
if (fr->VertexBuffer)
wgpuBufferDestroy(fr->VertexBuffer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need to call SafeRelease here and for the index buffer. Destroy only destroy the data internal to the buffer but the CPU-side state tracking isn't freed. This is to allow to reclaim GPU memory faster.

@@ -419,9 +417,11 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
}
else
{
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)pcmd->TextureId);
WGPUBindGroupLayout bg_layout = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Maybe this bindgroup could be stored so we don't re-query it all the time. There is little cost to doing that in native, but in WASM you will get a new JS object everytime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bind group is stored in g_resources. Only the layout is created and released once a new bind group is created. I assumed, that the bind group would store a reference to the layout internally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the bindgroup stores a reference to the layout internally, This was just to avoid the creation of new JS object for the layout for every texture used here. We could just store to a global variable at [1]. But this is a nit: so it's ok to skip.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems I've misunderstood you. Your suggestion makes perfect sense, consider it changed 👍

@@ -455,7 +455,10 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
tex_desc.dimension = WGPUTextureDimension_2D;
tex_desc.size.width = width;
tex_desc.size.height = height;
tex_desc.size.depthOrArrayLayers = 1;
#if !defined(__EMSCRIPTEN__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Dawn in native should understand depthOrArrayLayers too so this ifdef might not be necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually a work-around for an issue I've encountered in Dawn (latest commit 30.4.). The validator checks for depth != 0, which triggers an error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing it out. I had another look at the code. It seems like dawn is trying to fix 'wrong' settings in the wrong way:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/src/dawn_native/Texture.cpp;drc=2dd2d67dbcbbf0a241fd13d4fccbc049ee39bfd4;l=251

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's because it is assuming there is the C++ structure defaulting happening. https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/src/include/dawn/webgpu_cpp.h;drc=d3d0337463160599bde3ef97db67071148652b9c;l=1203

Keeping as is sounds good, but soon (as in this week) Dawn will remove depth since we're past the deprecation period.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the default initialization in the cpp header explains a lot. I am going to convert the implementation eventually to use the cpp version.

I am going to remove depth in this case, as Dawn users will probably stay at head anyways (this implementation anyway already uses most of the latest changes().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok sounds good!

WGPUTextureDataLayout layout = {};
layout.offset = 0;
layout.bytesPerRow = width * size_pp;
layout.rowsPerImage = height;
WGPUExtent3D size = { static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1 };
#if !defined(__EMSCRIPTEN__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not setting depth here leads to wgpuQueueWriteTexture not being executed properly (no texture data written), however, not error message is produced.

Copy link
Contributor

@Kangz Kangz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, with some small comments. Thanks for doing the update!


ImGui_ImplWGPU_CreateFontsTexture();
ImGui_ImplWGPU_CreateUniformBuffer();

// Create resource bind group
WGPUBindGroupLayout bg_layouts[2];
bg_layouts[0] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 0);
bg_layouts[1] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[1]

@@ -419,9 +417,11 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
}
else
{
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)pcmd->TextureId);
WGPUBindGroupLayout bg_layout = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the bindgroup stores a reference to the layout internally, This was just to avoid the creation of new JS object for the layout for every texture used here. We could just store to a global variable at [1]. But this is a nit: so it's ok to skip.

@bfierz bfierz force-pushed the feature/update-wgpu-emsdk-2.0.20 branch from 71f3005 to 03de8ae Compare May 9, 2021 18:55
@bfierz
Copy link
Contributor Author

bfierz commented May 9, 2021

Updated the PR with all the suggestions from @Kangz. Thanks for the review.

@Kangz
Copy link
Contributor

Kangz commented May 9, 2021

LGTM no additional comments from the WebGPU side

ocornut pushed a commit that referenced this pull request May 16, 2021
@ocornut
Copy link
Owner

ocornut commented May 16, 2021

All merged now (as 83bdfef) thank you both very much!

@ocornut ocornut closed this May 16, 2021
@ocornut ocornut added the web label Jul 8, 2021
ocornut pushed a commit that referenced this pull request Jan 25, 2023
kjblanchard pushed a commit to kjblanchard/imgui that referenced this pull request May 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants