diff --git a/include/render/vulkan.h b/include/render/vulkan.h index fe29fd5b..90a9c4e7 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -374,6 +374,12 @@ bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer, struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb); bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture); +bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer, + VkFormat src_format, VkImage src_image, + uint32_t drm_format, uint32_t stride, + uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y, + uint32_t dst_x, uint32_t dst_y, void *data); + // State (e.g. image texture) associated with a surface. struct wlr_vk_texture { struct wlr_texture wlr_texture; diff --git a/render/vulkan/pixel_format.c b/render/vulkan/pixel_format.c index ced6eb24..67f5a893 100644 --- a/render/vulkan/pixel_format.c +++ b/render/vulkan/pixel_format.c @@ -230,13 +230,14 @@ const struct wlr_vk_format *vulkan_get_format_from_drm(uint32_t drm_format) { } const VkImageUsageFlags vulkan_render_usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; const VkImageUsageFlags vulkan_shm_tex_usage = VK_IMAGE_USAGE_SAMPLED_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT; + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT; const VkImageUsageFlags vulkan_dma_tex_usage = - VK_IMAGE_USAGE_SAMPLED_BIT; + VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT; static const VkFormatFeatureFlags render_features = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index 29fa9b59..a116b0e5 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -1116,14 +1116,25 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) { free(renderer); } -static bool vulkan_read_pixels(struct wlr_renderer *wlr_renderer, +static bool vulkan_read_pixels_legacy(struct wlr_renderer *wlr_renderer, uint32_t drm_format, uint32_t stride, uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, void *data) { struct wlr_vk_renderer *vk_renderer = vulkan_get_renderer(wlr_renderer); - VkDevice dev = vk_renderer->dev->dev; + VkFormat src_format = vk_renderer->current_render_buffer->render_setup->render_format->vk; VkImage src_image = vk_renderer->current_render_buffer->image; + return vulkan_read_pixels(vk_renderer, src_format, src_image, drm_format, + stride, width, height, src_x, src_y, dst_x, dst_y, data); +} + +bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer, + VkFormat src_format, VkImage src_image, + uint32_t drm_format, uint32_t stride, + uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y, + uint32_t dst_x, uint32_t dst_y, void *data) { + VkDevice dev = vk_renderer->dev->dev; + const struct wlr_pixel_format_info *pixel_format_info = drm_get_pixel_format_info(drm_format); if (!pixel_format_info) { wlr_log(WLR_ERROR, "vulkan_read_pixels: could not find pixel format info " @@ -1141,7 +1152,6 @@ static bool vulkan_read_pixels(struct wlr_renderer *wlr_renderer, return false; } VkFormat dst_format = wlr_vk_format->vk; - VkFormat src_format = vk_renderer->current_render_buffer->render_setup->render_format->vk; VkFormatProperties dst_format_props = {0}, src_format_props = {0}; vkGetPhysicalDeviceFormatProperties(vk_renderer->dev->phdev, dst_format, &dst_format_props); vkGetPhysicalDeviceFormatProperties(vk_renderer->dev->phdev, src_format, &src_format_props); @@ -1387,7 +1397,7 @@ static const struct wlr_renderer_impl renderer_impl = { .get_dmabuf_texture_formats = vulkan_get_dmabuf_texture_formats, .get_render_formats = vulkan_get_render_formats, .preferred_read_format = vulkan_preferred_read_format, - .read_pixels = vulkan_read_pixels, + .read_pixels = vulkan_read_pixels_legacy, .destroy = vulkan_destroy, .get_drm_fd = vulkan_get_drm_fd, .get_render_buffer_caps = vulkan_get_render_buffer_caps, diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c index 65ea22ba..16c48356 100644 --- a/render/vulkan/texture.c +++ b/render/vulkan/texture.c @@ -249,8 +249,22 @@ static void vulkan_texture_unref(struct wlr_texture *wlr_texture) { } } +static bool vulkan_texture_read_pixels(struct wlr_texture *wlr_texture, + const struct wlr_texture_read_pixels_options *options) { + struct wlr_vk_texture *texture = vulkan_get_texture(wlr_texture); + + struct wlr_box src; + wlr_texture_read_pixels_options_get_src_box(options, wlr_texture, &src); + + void *p = wlr_texture_read_pixel_options_get_data(options); + + return vulkan_read_pixels(texture->renderer, texture->format->vk, texture->image, + options->format, options->stride, src.width, src.height, src.x, src.y, 0, 0, p); +} + static const struct wlr_texture_impl texture_impl = { .update_from_buffer = vulkan_texture_update_from_buffer, + .read_pixels = vulkan_texture_read_pixels, .destroy = vulkan_texture_unref, };