render/vulkan: Implement texture_read_pixels

This commit is contained in:
Alexander Orzechowski 2023-11-30 19:56:54 -05:00
parent e7055b4840
commit 09f16b2a9c
4 changed files with 39 additions and 8 deletions

View file

@ -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;

View file

@ -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 |

View file

@ -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,

View file

@ -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,
};