mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-9174 Vulkan: Cleanup image/buffer barriers
This commit is contained in:
@@ -30,7 +30,6 @@
|
||||
#include "VKAllocator.h"
|
||||
#include "VKBuffer.h"
|
||||
#include "VKDevice.h"
|
||||
#include "VKRenderer.h"
|
||||
|
||||
#define VK_BUFFER_HOST_COHERENT_MEMORY
|
||||
|
||||
@@ -233,6 +232,11 @@ void VKBuffer_Dispose(VKDevice* device, void* data) {
|
||||
VKBuffer_Destroy(device, buffer);
|
||||
}
|
||||
|
||||
// TODO This is an internal API and should not be used from VKBuffer!
|
||||
void VKRenderer_RecordBarriers(VKRenderer* renderer,
|
||||
VkBufferMemoryBarrier* bufferBarriers, VKBarrierBatch* bufferBatch,
|
||||
VkImageMemoryBarrier* imageBarriers, VKBarrierBatch* imageBatch);
|
||||
|
||||
VKBuffer *VKBuffer_CreateFromRaster(VKDevice *device,
|
||||
VKBuffer_RasterInfo info,
|
||||
VkPipelineStageFlags stage,
|
||||
@@ -270,19 +274,10 @@ VKBuffer *VKBuffer_CreateFromRaster(VKDevice *device,
|
||||
|
||||
device->vkUnmapMemory(device->handle, buffer->range.memory);
|
||||
{
|
||||
VkCommandBuffer cb = VKRenderer_Record(device->renderer);
|
||||
VkBufferMemoryBarrier barrier;
|
||||
VKBarrierBatch barrierBatch = {};
|
||||
VKBuffer_AddBarrier(&barrier, &barrierBatch, buffer,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, stage, access);
|
||||
|
||||
if (barrierBatch.barrierCount > 0) {
|
||||
device->vkCmdPipelineBarrier(cb, barrierBatch.srcStages,
|
||||
barrierBatch.dstStages,
|
||||
0, 0, NULL,
|
||||
barrierBatch.barrierCount, &barrier,
|
||||
0, NULL);
|
||||
}
|
||||
VKBuffer_AddBarrier(&barrier, &barrierBatch, buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, stage, access);
|
||||
VKRenderer_RecordBarriers(device->renderer, &barrier, &barrierBatch, NULL, NULL);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -558,36 +558,6 @@ void VKRenderer_Flush(VKRenderer* renderer) {
|
||||
renderer, submitInfo.commandBufferCount, pendingPresentations);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare image barrier info to be executed in batch, if needed.
|
||||
*/
|
||||
void VKRenderer_AddImageBarrier(VkImageMemoryBarrier* barriers, VKBarrierBatch* batch,
|
||||
VKImage* image, VkPipelineStageFlags stage, VkAccessFlags access, VkImageLayout layout) {
|
||||
assert(barriers != NULL && batch != NULL && image != NULL);
|
||||
// TODO Even if stage, access and layout didn't change, we may still need a barrier against WaW hazard.
|
||||
if (stage != image->lastStage || access != image->lastAccess || layout != image->layout) {
|
||||
barriers[batch->barrierCount] = (VkImageMemoryBarrier) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = image->lastAccess,
|
||||
.dstAccessMask = access,
|
||||
.oldLayout = image->layout,
|
||||
.newLayout = layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image->handle,
|
||||
.subresourceRange = { VKUtil_GetFormatGroup(image->format).aspect, 0, 1, 0, 1 }
|
||||
};
|
||||
batch->barrierCount++;
|
||||
batch->srcStages |= image->lastStage;
|
||||
batch->dstStages |= stage;
|
||||
image->lastStage = stage;
|
||||
image->lastAccess = access;
|
||||
image->layout = layout;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Color RGBA components in a suitable for the current render pass.
|
||||
*/
|
||||
@@ -890,24 +860,20 @@ VkBool32 VKRenderer_FlushRenderPass(VKSDOps* surface) {
|
||||
}
|
||||
ARRAY_RESIZE(surface->renderPass->usedSurfaces, 0);
|
||||
|
||||
|
||||
// Insert barriers to prepare surface for rendering.
|
||||
VkImageMemoryBarrier barriers[2];
|
||||
VKBarrierBatch barrierBatch = {};
|
||||
VKRenderer_AddImageBarrier(barriers, &barrierBatch, surface->image,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
VKImage_AddBarrier(barriers, &barrierBatch, surface->image,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
if (surface->stencil != NULL) {
|
||||
VKRenderer_AddImageBarrier(barriers, &barrierBatch, surface->stencil,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
if (barrierBatch.barrierCount > 0) {
|
||||
device->vkCmdPipelineBarrier(cb, barrierBatch.srcStages, barrierBatch.dstStages,
|
||||
0, 0, NULL, 0, NULL, barrierBatch.barrierCount, barriers);
|
||||
VKImage_AddBarrier(barriers, &barrierBatch, surface->stencil,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
VKRenderer_RecordBarriers(renderer, NULL, NULL, barriers, &barrierBatch);
|
||||
|
||||
// If there is a pending clear, record it into render pass.
|
||||
if (clear) VKRenderer_BeginRenderPass(surface);
|
||||
@@ -1003,10 +969,9 @@ void VKRenderer_FlushSurface(VKSDOps* surface) {
|
||||
.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||
}};
|
||||
VKBarrierBatch barrierBatch = {1, surface->image->lastStage | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT};
|
||||
VKRenderer_AddImageBarrier(barriers, &barrierBatch, surface->image, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
device->vkCmdPipelineBarrier(cb, barrierBatch.srcStages, barrierBatch.dstStages,
|
||||
0, 0, NULL, 0, NULL, barrierBatch.barrierCount, barriers);
|
||||
VKImage_AddBarrier(barriers, &barrierBatch, surface->image, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
VKRenderer_RecordBarriers(renderer, NULL, NULL, barriers, &barrierBatch);
|
||||
}
|
||||
|
||||
// Do blit.
|
||||
|
||||
@@ -76,12 +76,6 @@ void VKRenderer_FlushDraw(VKSDOps* surface);
|
||||
*/
|
||||
VkCommandBuffer VKRenderer_Record(VKRenderer* renderer);
|
||||
|
||||
/**
|
||||
* Prepare image barrier info to be executed in batch, if needed.
|
||||
*/
|
||||
void VKRenderer_AddImageBarrier(VkImageMemoryBarrier* barriers, VKBarrierBatch* batch,
|
||||
VKImage* image, VkPipelineStageFlags stage, VkAccessFlags access, VkImageLayout layout);
|
||||
|
||||
/**
|
||||
* Record barrier batches into the primary command buffer.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user