From dc79a8a935cfb3d2fffe2705a379b7fa82f70892 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 21 Jan 2021 17:13:17 +0900 Subject: [PATCH] [vulkan] Clear scrap image on creation And fix the transitions in ScrapFlush. --- include/QF/Vulkan/barrier.h | 1 + include/QF/Vulkan/scrap.h | 2 +- libs/video/renderer/vulkan/barrier.c | 12 ++++++++ libs/video/renderer/vulkan/scrap.c | 35 +++++++++++++++++++++--- libs/video/renderer/vulkan/vulkan_bsp.c | 2 +- libs/video/renderer/vulkan/vulkan_draw.c | 2 +- 6 files changed, 47 insertions(+), 7 deletions(-) diff --git a/include/QF/Vulkan/barrier.h b/include/QF/Vulkan/barrier.h index 12cea49ab..56438aeba 100644 --- a/include/QF/Vulkan/barrier.h +++ b/include/QF/Vulkan/barrier.h @@ -11,6 +11,7 @@ typedef struct { enum { qfv_LT_Undefined_to_TransferDst, qfv_LT_TransferDst_to_ShaderReadOnly, + qfv_LT_ShaderReadOnly_to_TransferDst, qfv_LT_Undefined_to_DepthStencil, qfv_LT_Undefined_to_Color, }; diff --git a/include/QF/Vulkan/scrap.h b/include/QF/Vulkan/scrap.h index 563a46cc2..80c95bd96 100644 --- a/include/QF/Vulkan/scrap.h +++ b/include/QF/Vulkan/scrap.h @@ -9,7 +9,7 @@ struct qfv_stagebuf_s; struct qfv_device_s; scrap_t *QFV_CreateScrap (struct qfv_device_s *device, int size, - QFFormat format); + QFFormat format, struct qfv_stagebuf_s *stage); size_t QFV_ScrapSize (scrap_t *scrap); void QFV_ScrapClear (scrap_t *scrap); void QFV_DestroyScrap (scrap_t *scrap); diff --git a/libs/video/renderer/vulkan/barrier.c b/libs/video/renderer/vulkan/barrier.c index e257eb990..935b370e0 100644 --- a/libs/video/renderer/vulkan/barrier.c +++ b/libs/video/renderer/vulkan/barrier.c @@ -50,6 +50,15 @@ const VkImageMemoryBarrier imageLayoutTransitionBarriers[] = { VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, 0, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } }, + // shader read only optimal -> transfer dst optimal + { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, + VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, 0, + { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } + }, // undefined -> depth stencil attachment optimal { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0, 0, @@ -80,6 +89,9 @@ const qfv_pipelinestagepair_t imageLayoutTransitionStages[] = { // transfer dst optimal -> shader read only optimal { VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT }, + // shader read only optimal -> transfer dst optimal + { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT }, // undefined -> depth stencil attachment optimal { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT }, diff --git a/libs/video/renderer/vulkan/scrap.c b/libs/video/renderer/vulkan/scrap.c index 6e17e786c..bc5efeda5 100644 --- a/libs/video/renderer/vulkan/scrap.c +++ b/libs/video/renderer/vulkan/scrap.c @@ -76,8 +76,10 @@ struct scrap_s { }; scrap_t * -QFV_CreateScrap (qfv_device_t *device, int size, QFFormat format) +QFV_CreateScrap (qfv_device_t *device, int size, QFFormat format, + qfv_stagebuf_t *stage) { + qfv_devfuncs_t *dfunc = device->funcs; int bpp = 0; VkFormat fmt = VK_FORMAT_UNDEFINED; @@ -132,6 +134,32 @@ QFV_CreateScrap (qfv_device_t *device, int size, QFFormat format) scrap->batch_tail = &scrap->batch; scrap->batch_free = 0; scrap->batch_count = 0; + + VkImageMemoryBarrier barrier; + qfv_pipelinestagepair_t stages; + + qfv_packet_t *packet = QFV_PacketAcquire (stage); + // no data for the packet + stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_TransferDst]; + barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_TransferDst]; + barrier.image = scrap->image; + dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, + 0, 0, 0, 0, 0, + 1, &barrier); + VkClearColorValue color = { + float32:{0xde/255.0, 0xad/255.0, 0xbe/255.0, 0xef/255.0}, + }; + VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + dfunc->vkCmdClearColorImage (packet->cmd, scrap->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + &color, 1, &range); + stages = imageLayoutTransitionStages[qfv_LT_TransferDst_to_ShaderReadOnly]; + barrier=imageLayoutTransitionBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]; + barrier.image = scrap->image; + dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, + 0, 0, 0, 0, 0, + 1, &barrier); + QFV_PacketSubmit (packet); return scrap; } @@ -286,12 +314,11 @@ QFV_ScrapFlush (scrap_t *scrap) copy->a[i].imageExtent.depth = 1; } - VkImageMemoryBarrier barrier; qfv_pipelinestagepair_t stages; - stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_TransferDst]; - barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_TransferDst]; + stages = imageLayoutTransitionStages[qfv_LT_ShaderReadOnly_to_TransferDst]; + barrier=imageLayoutTransitionBarriers[qfv_LT_ShaderReadOnly_to_TransferDst]; barrier.image = scrap->image; dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, 0, 0, 0, 0, 0, diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index d8c45d556..f485b0259 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -1262,7 +1262,7 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx) bctx->elementss_tail = &bctx->elementss; bctx->instsurfs_tail = &bctx->instsurfs; - bctx->light_scrap = QFV_CreateScrap (device, 2048, tex_frgba); + bctx->light_scrap = QFV_CreateScrap (device, 2048, tex_frgba, ctx->staging); size_t size = QFV_ScrapSize (bctx->light_scrap); bctx->light_stage = QFV_CreateStagingBuffer (device, size, 3, ctx->cmdpool); diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 7345fccd5..2e41e2252 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -367,9 +367,9 @@ Vulkan_Draw_Init (vulkan_ctx_t *ctx) 0, 0); create_quad_buffers (ctx); - dctx->scrap = QFV_CreateScrap (device, 2048, tex_rgba); dctx->stage = QFV_CreateStagingBuffer (device, 4 * 1024 * 1024, 4, ctx->cmdpool); + dctx->scrap = QFV_CreateScrap (device, 2048, tex_rgba, dctx->stage); dctx->sampler = QFV_GetSampler (ctx, "quakepic"); qpic_t *charspic = Draw_Font8x8Pic ();