Turn vulkan_copy_staging_to_dynamic into macro

This commit is contained in:
twinaphex 2020-12-15 07:20:33 +01:00
parent d70420a12d
commit cdca5d0afc
4 changed files with 69 additions and 81 deletions

View File

@ -318,69 +318,6 @@ uint32_t vulkan_find_memory_type_fallback(
device_reqs, host_reqs_second, 0);
}
/* Dynamic texture type should be set to : VULKAN_TEXTURE_DYNAMIC
* Staging texture type should be set to : VULKAN_TEXTURE_STAGING
*/
void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd,
struct vk_texture *dynamic,
struct vk_texture *staging)
{
VkBufferImageCopy region;
/* We don't have to sync against previous TRANSFER,
* since we observed the completion by fences.
*
* If we have a single texture_optimal, we would need to sync against
* previous transfers to avoid races.
*
* We would also need to optionally maintain extra textures due to
* changes in resolution, so this seems like the sanest and
* simplest solution. */
VULKAN_IMAGE_LAYOUT_TRANSITION(
cmd,
dynamic->image,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
0,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT);
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset.x = 0;
region.imageOffset.y = 0;
region.imageOffset.z = 0;
region.imageExtent.width = dynamic->width;
region.imageExtent.height = dynamic->height;
region.imageExtent.depth = 1;
vkCmdCopyBufferToImage(
cmd,
staging->buffer,
dynamic->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&region);
VULKAN_IMAGE_LAYOUT_TRANSITION(
cmd,
dynamic->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
dynamic->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
#ifdef VULKAN_DEBUG_TEXTURE_ALLOC
static VkImage vk_images[4 * 1024];
static unsigned vk_count;

View File

@ -605,10 +605,62 @@ void vulkan_destroy_texture(
VkDevice device,
struct vk_texture *tex);
void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd,
struct vk_texture *dynamic,
struct vk_texture *staging);
/* Dynamic texture type should be set to : VULKAN_TEXTURE_DYNAMIC
* Staging texture type should be set to : VULKAN_TEXTURE_STAGING
*/
#define VULKAN_COPY_STAGING_TO_DYNAMIC(vk, cmd, dynamic, staging) \
{ \
VkBufferImageCopy region; \
VULKAN_IMAGE_LAYOUT_TRANSITION( \
cmd, \
dynamic->image, \
VK_IMAGE_LAYOUT_UNDEFINED, \
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
0, \
VK_ACCESS_TRANSFER_WRITE_BIT, \
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, \
VK_PIPELINE_STAGE_TRANSFER_BIT); \
region.bufferOffset = 0; \
region.bufferRowLength = 0; \
region.bufferImageHeight = 0; \
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; \
region.imageSubresource.mipLevel = 0; \
region.imageSubresource.baseArrayLayer = 0; \
region.imageSubresource.layerCount = 1; \
region.imageOffset.x = 0; \
region.imageOffset.y = 0; \
region.imageOffset.z = 0; \
region.imageExtent.width = dynamic->width; \
region.imageExtent.height = dynamic->height; \
region.imageExtent.depth = 1; \
vkCmdCopyBufferToImage( \
cmd, \
staging->buffer, \
dynamic->image, \
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
1, \
&region); \
VULKAN_IMAGE_LAYOUT_TRANSITION( \
cmd, \
dynamic->image, \
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, \
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, \
VK_ACCESS_TRANSFER_WRITE_BIT, \
VK_ACCESS_SHADER_READ_BIT, \
VK_PIPELINE_STAGE_TRANSFER_BIT, \
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); \
dynamic->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; \
}
/* We don't have to sync against previous TRANSFER,
* since we observed the completion by fences.
*
* If we have a single texture_optimal, we would need to sync against
* previous transfers to avoid races.
*
* We would also need to optionally maintain extra textures due to
* changes in resolution, so this seems like the sanest and
* simplest solution. */
#define VULKAN_SYNC_TEXTURE_TO_GPU_COND_PTR(vk, tex) \
if ((tex)->need_manual_cache_management && (tex)->memory != VK_NULL_HANDLE) \
VULKAN_SYNC_TEXTURE_TO_GPU(vk->context->device, (tex)->memory) \
@ -617,14 +669,6 @@ void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd,
if ((tex).need_manual_cache_management && (tex).memory != VK_NULL_HANDLE) \
VULKAN_SYNC_TEXTURE_TO_GPU(vk->context->device, (tex).memory) \
#define VULKAN_COPY_STAGING_TO_DYNAMIC_PTR(vk, cmd, dynamic, staging) \
VULKAN_SYNC_TEXTURE_TO_GPU_COND_PTR(vk, staging); \
vulkan_copy_staging_to_dynamic(vk, cmd, dynamic, staging)
#define VULKAN_COPY_STAGING_TO_DYNAMIC_OBJ(vk, cmd, dynamic, staging) \
VULKAN_SYNC_TEXTURE_TO_GPU_COND_PTR(vk, staging); \
vulkan_copy_staging_to_dynamic(vk, cmd, &dynamic, &staging);
/* VBO will be written to here. */
void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad);

View File

@ -1850,8 +1850,9 @@ static bool vulkan_frame(void *data, const void *frame,
/* If we have an optimal texture, copy to that now. */
if (chain->texture_optimal.memory != VK_NULL_HANDLE)
{
vulkan_copy_staging_to_dynamic(vk, vk->cmd,
&chain->texture_optimal, &chain->texture);
struct vk_texture *dynamic = &chain->texture_optimal;
struct vk_texture *staging = &chain->texture;
VULKAN_COPY_STAGING_TO_DYNAMIC(vk, vk->cmd, dynamic, staging);
}
vk->last_valid_index = frame_index;
@ -1964,10 +1965,11 @@ static bool vulkan_frame(void *data, const void *frame,
{
if (vk->menu.dirty[vk->menu.last_index])
{
struct vk_texture *dynamic = optimal;
struct vk_texture *staging = texture;
VULKAN_SYNC_TEXTURE_TO_GPU_COND_PTR(vk, texture);
vulkan_copy_staging_to_dynamic(vk, vk->cmd,
optimal, texture);
VULKAN_COPY_STAGING_TO_DYNAMIC(vk, vk->cmd,
dynamic, staging);
vk->menu.dirty[vk->menu.last_index] = false;
}
}

View File

@ -294,6 +294,8 @@ static void vulkan_raster_font_flush(vulkan_raster_t *font)
VkSubmitInfo submit_info;
VkCommandBufferAllocateInfo cmd_info;
VkCommandBufferBeginInfo begin_info;
struct vk_texture *dynamic_tex = NULL;
struct vk_texture *staging_tex = NULL;
cmd_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmd_info.pNext = NULL;
@ -310,8 +312,11 @@ static void vulkan_raster_font_flush(vulkan_raster_t *font)
VULKAN_SYNC_TEXTURE_TO_GPU_COND_OBJ(font->vk, font->texture);
vulkan_copy_staging_to_dynamic(font->vk, staging,
&font->texture_optimal, &font->texture);
dynamic_tex = &font->texture_optimal;
staging_tex = &font->texture;
VULKAN_COPY_STAGING_TO_DYNAMIC(font->vk, staging,
dynamic_tex, staging_tex);
vkEndCommandBuffer(staging);