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

Present with damage region (VkPresentRegionKHR) #682

Closed
valpackett opened this issue May 28, 2020 · 12 comments
Closed

Present with damage region (VkPresentRegionKHR) #682

valpackett opened this issue May 28, 2020 · 12 comments
Labels
area: wsi Issues with swapchain management or windowing help required We need community help to make this happen. type: enhancement New feature or request

Comments

@valpackett
Copy link
Contributor

Is your feature request related to a problem? Please describe.

Looks like there is no way to pass the VkPresentRegion (and equivalents on other platforms) when presenting a frame.

The thing the Vulkan WSI-side code gets as the last arg here:

static VkResult
wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
                               uint32_t image_index,
                               const VkPresentRegionKHR *damage)

Describe the solution you'd like

Some way to do that. I can't find anything like that in the WebGPU spec :(
Are custom extensions allowed in wgpu?

Additional context

Damage tracking allows applications to only render changed parts between frames, saving power. In this case, I'm only talking about the compositor-side thing, where applications tell the compositor which regions of the window have changed so the compositor can only update them. This is called EGL_KHR_swap_buffers_with_damage in the GL world.

@kvark
Copy link
Member

kvark commented May 29, 2020

Thank you for filing! It's great to see a well made issue 👍

I think damage tracking is only feasible if you have full control over your swapchain. I.e. if you rendered to swapchain frame X before, and you render to it again, you know which parts you can rely on being preserved.

In WebGPU, every frame is a new frame. So I don't think with the current swapchain model the partial present is an option. An issue on https://github.com/webgpu-native/webgpu-headers would help to kick off the discussion. cc @Kangz

@Kangz
Copy link

Kangz commented May 29, 2020

We'll certainly need more and more presentation extensions. In a way we can do whatever we want for now, as long as the "core" API can be translated to GPUSwapChain, then coalesce APIs later.

@valpackett
Copy link
Contributor Author

you know which parts you can rely on being preserved

Here, I'm not talking about preserving buffers in the webgpu application, just about the damage hint to the windowing system so the system compositor would preserve parts of the whole monitor output's buffer. Again:

In this case, I'm only talking about the compositor-side thing, where applications tell the compositor which regions of the window have changed so the compositor can only update them. This is called EGL_KHR_swap_buffers_with_damage in the GL world.

This works just fine with every frame being a new frame, in fact Firefox's legacy GL compositor always renders a full frame and I have added SwapBuffersWithDamage to it.

@kvark
Copy link
Member

kvark commented Jun 1, 2020

@myfreeweb the damage region needs to be specified relative to something. We could accept it relative to the previous frame, an internally accumulate the regions between frames of the swapchain. Is this close to what you are thinking?

@valpackett
Copy link
Contributor Author

Why would there be a need to accumulate anything? o_0 It already is defined as

rectangle of the given image that has changed since the last image was presented to the given swapchain

https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPresentRegionKHR.html

It's just straightforward data passing, nothing clever is required.

@kvark
Copy link
Member

kvark commented Jun 1, 2020

o_0 It already is defined as

If I read it correctly, the spec specifically describes what regions of a particular VkImage are dirty:

VkPresentRegionKHR - Structure containing rectangular region changed by vkQueuePresentKHR for a given VkImage

WebGPU doesn't expose the fact that a swapchain contains multiple images that are recycled. User always gets a new image (from their perspective). So wgpu would internally acquire images from the swapchain.

Let's consider this example:

  • first frame is acquired image 1 (of the Vulkan swapchain)
  • next frame is image 2, presented with dirty rect A
  • next frame is image 0 presented with dirty rect B
  • next frame is image 1, presented with dirty rect C

If webgpu-native specifies the dirty rect relative to the previous frame, then the damage regions we pass to the last Vulkan present (internally) would have to include all of A | B | C.

@valpackett
Copy link
Contributor Author

Nah, you really have to read the pRectangles member description carefully:

rectangle of the given image [yes, as in the struct description] that has changed since the last image [any image — does not say this one!] was presented to the given swapchain

This is a convoluted way of saying "relative to the previous frame".

And so, Wayland WSI code in Mesa literally just turns this into wl_surface_damage_buffer:

      for (unsigned i = 0; i < damage->rectangleCount; i++) {
         const VkRectLayerKHR *rect = &damage->pRectangles[i];
         assert(rect->layer == 0);
         wl_surface_damage_buffer(chain->surface,
                                  rect->offset.x, rect->offset.y,
                                  rect->extent.width, rect->extent.height);
      }

Wayland also doesn't care about VkImages, this is also just "damage since the last frame".

@kvark
Copy link
Member

kvark commented Jun 1, 2020

Ok, that's good to know! I find Vulkan spec wording to be confusing here.

@cwfitzgerald
Copy link
Member

Note that currently wgpu doesn't allow you to write to a swapchain image without clearing it first, so if things like iced want to take full advantage of it, we would have to allow that somehow.

@valpackett
Copy link
Contributor Author

@cwfitzgerald yeah, that's kind of an orthogonal issue. "telling the compositor what changed" and "not redrawing stuff on buffers" do not depend on each other, they just use the same data (damage tracking)

@cwfitzgerald
Copy link
Member

Ah yes, you're right. I somehow thought you had to do one to do the other, 'pologizes

kvark added a commit to kvark/wgpu that referenced this issue Jun 3, 2021
682: Expose adapter.get_info() everywhere r=grovesNL a=kvark



Co-authored-by: Dzmitry Malyshau <kvark@fastmail.com>
@cwfitzgerald cwfitzgerald added help required We need community help to make this happen. area: wsi Issues with swapchain management or windowing labels Jun 5, 2022
@cwfitzgerald
Copy link
Member

Superceeded by 2869

@cwfitzgerald cwfitzgerald closed this as not planned Won't fix, can't repro, duplicate, stale Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: wsi Issues with swapchain management or windowing help required We need community help to make this happen. type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants