mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-06-02 12:45:01 -06:00
Remove global memory barrier and only sync images that would actually race
This commit is contained in:
parent
cea40e9835
commit
cc01133d06
@ -78,6 +78,8 @@ protected:
|
|||||||
LatteTextureView* CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount) override;
|
LatteTextureView* CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
uint64 m_vkFlushIndex{}; // used to track read-write dependencies within the same renderpass
|
||||||
|
|
||||||
uint64 m_vkFlushIndex_read{};
|
uint64 m_vkFlushIndex_read{};
|
||||||
uint64 m_vkFlushIndex_write{};
|
uint64 m_vkFlushIndex_write{};
|
||||||
|
|
||||||
|
|||||||
@ -412,7 +412,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// invalidation / flushing
|
// invalidation / flushing
|
||||||
uint64 currentFlushIndex{0};
|
uint64 currentFlushIndex{1};
|
||||||
bool requestFlush{ false }; // flush after every draw operation. The renderpass dependencies dont handle dependencies across multiple drawcalls inside a single renderpass
|
bool requestFlush{ false }; // flush after every draw operation. The renderpass dependencies dont handle dependencies across multiple drawcalls inside a single renderpass
|
||||||
|
|
||||||
// draw sequence
|
// draw sequence
|
||||||
@ -549,7 +549,7 @@ private:
|
|||||||
void draw_handleSpecialState5();
|
void draw_handleSpecialState5();
|
||||||
|
|
||||||
// draw synchronization helper
|
// draw synchronization helper
|
||||||
void sync_performFlushBarrier();
|
void sync_performFlushBarrier(CachedFBOVk* fboVk);
|
||||||
bool sync_isInputTexturesSyncRequired();
|
bool sync_isInputTexturesSyncRequired();
|
||||||
void sync_RenderPassLoadTextures(CachedFBOVk* fboVk);
|
void sync_RenderPassLoadTextures(CachedFBOVk* fboVk);
|
||||||
void sync_RenderPassStoreTextures(CachedFBOVk* fboVk);
|
void sync_RenderPassStoreTextures(CachedFBOVk* fboVk);
|
||||||
|
|||||||
@ -975,30 +975,62 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
|
|||||||
return dsInfo;
|
return dsInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::sync_performFlushBarrier()
|
void VulkanRenderer::sync_performFlushBarrier(CachedFBOVk* fboVk)
|
||||||
{
|
{
|
||||||
VkMemoryBarrier memoryBarrier{};
|
size_t barrierCount = 0;
|
||||||
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
VkImageMemoryBarrier imageMemBarriers[8 + 2 + LATTE_NUM_MAX_TEX_UNITS]{};
|
||||||
memoryBarrier.srcAccessMask = 0;
|
|
||||||
memoryBarrier.dstAccessMask = 0;
|
auto addImgMemBarrierForTexView = [&](LatteTextureViewVk* view) {
|
||||||
|
VkImageSubresourceRange range = {
|
||||||
|
view->GetBaseImage()->GetImageAspect(),
|
||||||
|
(uint32_t)view->firstMip,
|
||||||
|
(uint32_t)view->numMip,
|
||||||
|
(uint32_t)view->firstSlice,
|
||||||
|
(uint32_t)view->numSlice};
|
||||||
|
auto baseTex = (LatteTextureVk*)view->baseTexture;
|
||||||
|
const auto idx = barrierCount++;
|
||||||
|
imageMemBarriers[idx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||||
|
imageMemBarriers[idx].image = baseTex->GetImageObj()->m_image;
|
||||||
|
imageMemBarriers[idx].subresourceRange = range;
|
||||||
|
imageMemBarriers[idx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
imageMemBarriers[idx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
imageMemBarriers[idx].oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
imageMemBarriers[idx].newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
imageMemBarriers[idx].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
imageMemBarriers[idx].srcAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
imageMemBarriers[idx].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
imageMemBarriers[idx].dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
imageMemBarriers[idx].dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
|
view->GetBaseImage()->m_vkFlushIndex = m_state.currentFlushIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& i : fboVk->colorBuffer)
|
||||||
|
{
|
||||||
|
if (!i.texture)
|
||||||
|
continue;
|
||||||
|
addImgMemBarrierForTexView(static_cast<LatteTextureViewVk*>(i.texture));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto i = fboVk->depthBuffer.texture)
|
||||||
|
{
|
||||||
|
addImgMemBarrierForTexView(static_cast<LatteTextureViewVk*>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_state.activeVertexDS)
|
||||||
|
m_state.activeVertexDS->ForEachView(addImgMemBarrierForTexView);
|
||||||
|
if (m_state.activeGeometryDS)
|
||||||
|
m_state.activeGeometryDS->ForEachView(addImgMemBarrierForTexView);
|
||||||
|
if (m_state.activePixelDS)
|
||||||
|
m_state.activePixelDS->ForEachView(addImgMemBarrierForTexView);
|
||||||
|
|
||||||
VkPipelineStageFlags stages = 0;
|
VkPipelineStageFlags stages = 0;
|
||||||
|
|
||||||
// src & dst
|
|
||||||
stages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
stages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||||
|
|
||||||
// src
|
vkCmdPipelineBarrier(m_state.currentCommandBuffer, stages, stages, 0, 0, nullptr, 0, nullptr, barrierCount, imageMemBarriers);
|
||||||
memoryBarrier.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
||||||
memoryBarrier.srcAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
||||||
|
|
||||||
// dst
|
|
||||||
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
||||||
memoryBarrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
||||||
memoryBarrier.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
||||||
|
|
||||||
vkCmdPipelineBarrier(m_state.currentCommandBuffer, stages, stages, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
|
|
||||||
|
|
||||||
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
|
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
|
||||||
|
|
||||||
@ -1014,7 +1046,7 @@ bool VulkanRenderer::sync_isInputTexturesSyncRequired()
|
|||||||
for (auto& tex : info->list_fboCandidates)
|
for (auto& tex : info->list_fboCandidates)
|
||||||
{
|
{
|
||||||
tex->m_vkFlushIndex_read = m_state.currentFlushIndex;
|
tex->m_vkFlushIndex_read = m_state.currentFlushIndex;
|
||||||
if (tex->m_vkFlushIndex_write == m_state.currentFlushIndex)
|
if (tex->m_vkFlushIndex < tex->m_vkFlushIndex_write)
|
||||||
required = true;
|
required = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1030,10 +1062,10 @@ void VulkanRenderer::sync_RenderPassLoadTextures(CachedFBOVk* fboVk)
|
|||||||
|
|
||||||
auto checkImageSyncHazard = [&](LatteTextureVk* texVk, bool isWrite = false) {
|
auto checkImageSyncHazard = [&](LatteTextureVk* texVk, bool isWrite = false) {
|
||||||
//RAW / WAW
|
//RAW / WAW
|
||||||
if (texVk->m_vkFlushIndex_write == m_state.currentFlushIndex)
|
if (texVk->m_vkFlushIndex < texVk->m_vkFlushIndex_write)
|
||||||
flushRequired = true;
|
flushRequired = true;
|
||||||
//WAR
|
//WAR
|
||||||
if (isWrite && texVk->m_vkFlushIndex_read == m_state.currentFlushIndex)
|
if (isWrite && texVk->m_vkFlushIndex < texVk->m_vkFlushIndex_read)
|
||||||
flushRequired = true;
|
flushRequired = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1052,7 +1084,7 @@ void VulkanRenderer::sync_RenderPassLoadTextures(CachedFBOVk* fboVk)
|
|||||||
m_state.activePixelDS->ForEachView(checkViewSync);
|
m_state.activePixelDS->ForEachView(checkViewSync);
|
||||||
|
|
||||||
if (flushRequired)
|
if (flushRequired)
|
||||||
sync_performFlushBarrier();
|
sync_performFlushBarrier(fboVk);
|
||||||
|
|
||||||
for (auto& tex : fboVk->GetTextures())
|
for (auto& tex : fboVk->GetTextures())
|
||||||
{
|
{
|
||||||
@ -1165,7 +1197,7 @@ void VulkanRenderer::draw_setRenderPass()
|
|||||||
|
|
||||||
sync_RenderPassLoadTextures(fboVk);
|
sync_RenderPassLoadTextures(fboVk);
|
||||||
if (sync_isInputTexturesSyncRequired())
|
if (sync_isInputTexturesSyncRequired())
|
||||||
sync_performFlushBarrier();
|
sync_performFlushBarrier(fboVk);
|
||||||
|
|
||||||
if (m_featureControl.deviceExtensions.dynamic_rendering)
|
if (m_featureControl.deviceExtensions.dynamic_rendering)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user