mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-14 08:22:25 -04:00
Merge branch 'vk-shm-upload' into 'master'
Draft: render/vulkan: Delay shm texture updates till render See merge request wlroots/wlroots!4734
This commit is contained in:
commit
7283d62058
3 changed files with 51 additions and 15 deletions
|
|
@ -11,6 +11,7 @@
|
|||
#include <wlr/render/interface.h>
|
||||
#include <wlr/util/addon.h>
|
||||
#include "util/rect_union.h"
|
||||
#include <pixman.h>
|
||||
|
||||
struct wlr_vk_descriptor_pool;
|
||||
struct wlr_vk_texture;
|
||||
|
|
@ -469,6 +470,9 @@ struct wlr_vk_texture {
|
|||
struct wlr_addon buffer_addon;
|
||||
|
||||
struct wl_list views; // struct wlr_vk_texture_ds.link
|
||||
|
||||
// For SHM buffers
|
||||
pixman_region32_t invalidated;
|
||||
};
|
||||
|
||||
struct wlr_vk_texture *vulkan_get_texture(struct wlr_texture *wlr_texture);
|
||||
|
|
@ -479,6 +483,7 @@ VkImage vulkan_import_dmabuf(struct wlr_vk_renderer *renderer,
|
|||
struct wlr_texture *vulkan_texture_from_buffer(
|
||||
struct wlr_renderer *wlr_renderer, struct wlr_buffer *buffer);
|
||||
void vulkan_texture_destroy(struct wlr_vk_texture *texture);
|
||||
void vulkan_texture_update(struct wlr_vk_texture *texture);
|
||||
|
||||
struct wlr_vk_descriptor_pool {
|
||||
VkDescriptorPool pool;
|
||||
|
|
|
|||
|
|
@ -703,6 +703,8 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
|
|||
wl_list_insert(&renderer->foreign_textures, &texture->foreign_link);
|
||||
}
|
||||
|
||||
vulkan_texture_update(texture);
|
||||
|
||||
struct wlr_fbox src_box;
|
||||
wlr_render_texture_options_get_src_box(options, &src_box);
|
||||
struct wlr_box dst_box;
|
||||
|
|
|
|||
|
|
@ -153,6 +153,26 @@ static bool write_pixels(struct wlr_vk_texture *texture,
|
|||
return true;
|
||||
}
|
||||
|
||||
void vulkan_texture_update(struct wlr_vk_texture *texture) {
|
||||
if (pixman_region32_empty(&texture->invalidated)) {
|
||||
return;
|
||||
}
|
||||
|
||||
void *data;
|
||||
uint32_t format;
|
||||
size_t stride;
|
||||
if (wlr_buffer_begin_data_ptr_access(texture->buffer,
|
||||
WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) {
|
||||
write_pixels(texture, stride, &texture->invalidated, data, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
wlr_buffer_end_data_ptr_access(texture->buffer);
|
||||
}
|
||||
|
||||
pixman_region32_clear(&texture->invalidated);
|
||||
wlr_buffer_unlock(texture->buffer);
|
||||
texture->buffer = NULL;
|
||||
}
|
||||
|
||||
static bool vulkan_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
||||
struct wlr_buffer *buffer, const pixman_region32_t *damage) {
|
||||
struct wlr_vk_texture *texture = vulkan_get_texture(wlr_texture);
|
||||
|
|
@ -172,8 +192,12 @@ static bool vulkan_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ok = write_pixels(texture, stride, damage, data, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
if (texture->buffer) {
|
||||
wlr_buffer_unlock(texture->buffer);
|
||||
}
|
||||
|
||||
texture->buffer = wlr_buffer_lock(buffer);
|
||||
pixman_region32_union(&texture->invalidated, &texture->invalidated, damage);
|
||||
|
||||
out:
|
||||
wlr_buffer_end_data_ptr_access(buffer);
|
||||
|
|
@ -198,6 +222,7 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) {
|
|||
}
|
||||
|
||||
wl_list_remove(&texture->link);
|
||||
pixman_region32_fini(&texture->invalidated);
|
||||
|
||||
VkDevice dev = texture->renderer->dev->dev;
|
||||
|
||||
|
|
@ -219,13 +244,18 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) {
|
|||
|
||||
static void vulkan_texture_unref(struct wlr_texture *wlr_texture) {
|
||||
struct wlr_vk_texture *texture = vulkan_get_texture(wlr_texture);
|
||||
if (texture->buffer != NULL) {
|
||||
// Keep the texture around, in case the buffer is re-used later. We're
|
||||
// still listening to the buffer's destroy event.
|
||||
if (texture->buffer) {
|
||||
wlr_buffer_unlock(texture->buffer);
|
||||
} else {
|
||||
vulkan_texture_destroy(texture);
|
||||
if (texture->dmabuf_imported) {
|
||||
// Keep the texture around, in case the buffer is re-used later. We're
|
||||
// still listening to the buffer's destroy event.
|
||||
return;
|
||||
}
|
||||
// The buffer is temporary and has no add-on, clear it before destroy
|
||||
texture->buffer = NULL;
|
||||
}
|
||||
|
||||
vulkan_texture_destroy(texture);
|
||||
}
|
||||
|
||||
static bool vulkan_texture_read_pixels(struct wlr_texture *wlr_texture,
|
||||
|
|
@ -265,6 +295,7 @@ static struct wlr_vk_texture *vulkan_texture_create(
|
|||
texture->renderer = renderer;
|
||||
wl_list_insert(&renderer->textures, &texture->link);
|
||||
wl_list_init(&texture->views);
|
||||
pixman_region32_init(&texture->invalidated);
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
|
@ -370,9 +401,11 @@ static void texture_set_format(struct wlr_vk_texture *texture,
|
|||
|
||||
static struct wlr_texture *vulkan_texture_from_pixels(
|
||||
struct wlr_vk_renderer *renderer, uint32_t drm_fmt, uint32_t stride,
|
||||
uint32_t width, uint32_t height, const void *data) {
|
||||
struct wlr_buffer *buffer) {
|
||||
VkResult res;
|
||||
VkDevice dev = renderer->dev->dev;
|
||||
int32_t width = buffer->width;
|
||||
int32_t height = buffer->height;
|
||||
|
||||
const struct wlr_vk_format_props *fmt =
|
||||
vulkan_format_props_from_drm(renderer->dev, drm_fmt);
|
||||
|
|
@ -459,12 +492,8 @@ static struct wlr_texture *vulkan_texture_from_pixels(
|
|||
goto error;
|
||||
}
|
||||
|
||||
pixman_region32_t region;
|
||||
pixman_region32_init_rect(®ion, 0, 0, width, height);
|
||||
if (!write_pixels(texture, stride, ®ion, data, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0)) {
|
||||
goto error;
|
||||
}
|
||||
pixman_region32_init_rect(&texture->invalidated, 0, 0, width, height);
|
||||
texture->buffer = wlr_buffer_lock(buffer);
|
||||
|
||||
return &texture->wlr_texture;
|
||||
|
||||
|
|
@ -815,7 +844,7 @@ struct wlr_texture *vulkan_texture_from_buffer(struct wlr_renderer *wlr_renderer
|
|||
} else if (wlr_buffer_begin_data_ptr_access(buffer,
|
||||
WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) {
|
||||
struct wlr_texture *tex = vulkan_texture_from_pixels(renderer,
|
||||
format, stride, buffer->width, buffer->height, data);
|
||||
format, stride, buffer);
|
||||
wlr_buffer_end_data_ptr_access(buffer);
|
||||
return tex;
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue