vulkan: Split out a function

Split out the function that uploads using a buffer, so that it can be
used with an area to only update parts of the image.

That feature is not used yet, but will be in future commits.
This commit is contained in:
Benjamin Otte 2023-07-14 20:53:54 +02:00
parent 0d5e54986a
commit 68b337d457

View File

@ -32,31 +32,21 @@ gsk_vulkan_upload_op_reserve_descriptor_sets (GskVulkanOp *op,
} }
static GskVulkanOp * static GskVulkanOp *
gsk_vulkan_upload_op_command (GskVulkanOp *op, gsk_vulkan_upload_op_command_with_area (GskVulkanOp *op,
GskVulkanRender *render, GskVulkanRender *render,
VkPipelineLayout pipeline_layout, VkPipelineLayout pipeline_layout,
VkCommandBuffer command_buffer, VkCommandBuffer command_buffer,
GskVulkanImage *image, GskVulkanImage *image,
const cairo_rectangle_int_t *area,
void (* draw_func) (GskVulkanOp *, guchar *, gsize), void (* draw_func) (GskVulkanOp *, guchar *, gsize),
GskVulkanBuffer **buffer) GskVulkanBuffer **buffer)
{ {
gsize stride; gsize stride;
guchar *data; guchar *data;
data = gsk_vulkan_image_try_map (image, &stride); stride = area->width * gdk_memory_format_bytes_per_pixel (gsk_vulkan_image_get_format (image));
if (data)
{
draw_func (op, data, stride);
gsk_vulkan_image_unmap (image);
*buffer = NULL;
}
else
{
stride = gsk_vulkan_image_get_width (image) *
gdk_memory_format_bytes_per_pixel (gsk_vulkan_image_get_format (image));
*buffer = gsk_vulkan_buffer_new_map (gsk_vulkan_render_get_context (render), *buffer = gsk_vulkan_buffer_new_map (gsk_vulkan_render_get_context (render),
gsk_vulkan_image_get_height (image) * stride, area->height * stride,
GSK_VULKAN_WRITE); GSK_VULKAN_WRITE);
data = gsk_vulkan_buffer_map (*buffer); data = gsk_vulkan_buffer_map (*buffer);
@ -108,21 +98,26 @@ gsk_vulkan_upload_op_command (GskVulkanOp *op,
(VkBufferImageCopy[1]) { (VkBufferImageCopy[1]) {
{ {
.bufferOffset = 0, .bufferOffset = 0,
.bufferRowLength = area->width,
.bufferImageHeight = area->height,
.imageSubresource = { .imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0, .mipLevel = 0,
.baseArrayLayer = 0, .baseArrayLayer = 0,
.layerCount = 1 .layerCount = 1
}, },
.imageOffset = { 0, 0, 0 }, .imageOffset = {
.x = area->x,
.y = area->y,
.z = 0
},
.imageExtent = { .imageExtent = {
.width = gsk_vulkan_image_get_width (image), .width = area->width,
.height = gsk_vulkan_image_get_height (image), .height = area->height,
.depth = 1 .depth = 1
} }
} }
}); });
}
vkCmdPipelineBarrier (command_buffer, vkCmdPipelineBarrier (command_buffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
@ -155,6 +150,48 @@ gsk_vulkan_upload_op_command (GskVulkanOp *op,
return op->next; return op->next;
} }
static GskVulkanOp *
gsk_vulkan_upload_op_command (GskVulkanOp *op,
GskVulkanRender *render,
VkPipelineLayout pipeline_layout,
VkCommandBuffer command_buffer,
GskVulkanImage *image,
void (* draw_func) (GskVulkanOp *, guchar *, gsize),
GskVulkanBuffer **buffer)
{
gsize stride;
guchar *data;
data = gsk_vulkan_image_try_map (image, &stride);
if (data)
{
draw_func (op, data, stride);
gsk_vulkan_image_unmap (image);
*buffer = NULL;
gsk_vulkan_image_set_vk_image_layout (image,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_ACCESS_SHADER_READ_BIT);
return op->next;
}
return gsk_vulkan_upload_op_command_with_area (op,
render,
pipeline_layout,
command_buffer,
image,
&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (image),
gsk_vulkan_image_get_height (image),
},
draw_func,
buffer);
}
typedef struct _GskVulkanUploadTextureOp GskVulkanUploadTextureOp; typedef struct _GskVulkanUploadTextureOp GskVulkanUploadTextureOp;
struct _GskVulkanUploadTextureOp struct _GskVulkanUploadTextureOp