backport rework from feedback loop branch

This commit is contained in:
goeiecool9999 2025-12-27 14:01:20 +01:00
parent f3dbc86f9b
commit 4b42b508a1
2 changed files with 62 additions and 49 deletions

View File

@ -547,6 +547,7 @@ private:
void draw_handleSpecialState5(); void draw_handleSpecialState5();
// draw synchronization helper // draw synchronization helper
void sync_performFlushBarrier();
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);

View File

@ -975,8 +975,40 @@ VkDescriptorSetInfo* VulkanRenderer::draw_getOrCreateDescriptorSet(PipelineInfo*
return dsInfo; return dsInfo;
} }
void VulkanRenderer::sync_performFlushBarrier()
{
VkMemoryBarrier memoryBarrier{};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = 0;
memoryBarrier.dstAccessMask = 0;
VkPipelineStageFlags srcStage = 0;
VkPipelineStageFlags dstStage = 0;
// src
srcStage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
memoryBarrier.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
srcStage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
memoryBarrier.srcAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
// dst
dstStage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
memoryBarrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
dstStage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
memoryBarrier.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
vkCmdPipelineBarrier(m_state.currentCommandBuffer, srcStage, dstStage, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
m_state.currentFlushIndex++;
}
bool VulkanRenderer::sync_isInputTexturesSyncRequired() bool VulkanRenderer::sync_isInputTexturesSyncRequired()
{ {
bool required = false;
auto checkSync = [&](const VkDescriptorSetInfo* info) { auto checkSync = [&](const VkDescriptorSetInfo* info) {
if (info) if (info)
{ {
@ -984,71 +1016,50 @@ bool VulkanRenderer::sync_isInputTexturesSyncRequired()
{ {
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_write == m_state.currentFlushIndex)
return true; required = true;
} }
} }
return false;
}; };
return checkSync(m_state.activeVertexDS) || checkSync(m_state.activeGeometryDS) || checkSync(m_state.activePixelDS); checkSync(m_state.activeVertexDS);
checkSync(m_state.activeGeometryDS);
checkSync(m_state.activePixelDS);
return required;
} }
void VulkanRenderer::sync_RenderPassLoadTextures(CachedFBOVk* fboVk) void VulkanRenderer::sync_RenderPassLoadTextures(CachedFBOVk* fboVk)
{ {
bool readFlushRequired = false; bool flushRequired = false;
// always called after draw_inputTexturesChanged()
for (auto& tex : fboVk->GetTextures()) for (auto& tex : fboVk->GetTextures())
{ {
LatteTextureVk* texVk = (LatteTextureVk*)tex; LatteTextureVk* texVk = (LatteTextureVk*)tex;
// write-before-write
//RAW
if (texVk->m_vkFlushIndex_write == m_state.currentFlushIndex) if (texVk->m_vkFlushIndex_write == m_state.currentFlushIndex)
readFlushRequired = true; flushRequired = true;
if ((texVk->GetImageAspect() | VK_IMAGE_ASPECT_DEPTH_BIT) != 0)
texVk->m_vkFlushIndex_read = m_state.currentFlushIndex; texVk->m_vkFlushIndex_read = m_state.currentFlushIndex;
// todo - also check for write-before-write ?
if (texVk->m_vkFlushIndex_read == m_state.currentFlushIndex)
readFlushRequired = true;
}
// barrier here
if (readFlushRequired)
{
VkMemoryBarrier memoryBarrier{};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = 0;
memoryBarrier.dstAccessMask = 0;
VkPipelineStageFlags srcStage = 0;
VkPipelineStageFlags dstStage = 0;
// src
srcStage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
memoryBarrier.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
srcStage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
memoryBarrier.srcAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
// dst
dstStage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
memoryBarrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
dstStage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
memoryBarrier.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
vkCmdPipelineBarrier(m_state.currentCommandBuffer, srcStage, dstStage, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
m_state.currentFlushIndex++;
} }
if (flushRequired)
sync_performFlushBarrier();
} }
void VulkanRenderer::sync_RenderPassStoreTextures(CachedFBOVk* fboVk) void VulkanRenderer::sync_RenderPassStoreTextures(CachedFBOVk* fboVk)
{ {
bool flushRequired = false;
for (auto& tex : fboVk->GetTextures()) for (auto& tex : fboVk->GetTextures())
{ {
LatteTextureVk* texVk = (LatteTextureVk*)tex; LatteTextureVk* texVk = (LatteTextureVk*)tex;
//WAR
if (texVk->m_vkFlushIndex_read == m_state.currentFlushIndex)
flushRequired = true;
//WAW
if (texVk->m_vkFlushIndex_write == m_state.currentFlushIndex)
flushRequired = true;
texVk->m_vkFlushIndex_write = m_state.currentFlushIndex; texVk->m_vkFlushIndex_write = m_state.currentFlushIndex;
} }
if (flushRequired)
sync_performFlushBarrier();
} }
void VulkanRenderer::draw_prepareDescriptorSets(PipelineInfo* pipeline_info, VkDescriptorSetInfo*& vertexDS, VkDescriptorSetInfo*& pixelDS, VkDescriptorSetInfo*& geometryDS) void VulkanRenderer::draw_prepareDescriptorSets(PipelineInfo* pipeline_info, VkDescriptorSetInfo*& vertexDS, VkDescriptorSetInfo*& pixelDS, VkDescriptorSetInfo*& geometryDS)
@ -1116,23 +1127,23 @@ void VulkanRenderer::draw_setRenderPass()
auto vkObjRenderPass = fboVk->GetRenderPassObj(); auto vkObjRenderPass = fboVk->GetRenderPassObj();
auto vkObjFramebuffer = fboVk->GetFramebufferObj(); auto vkObjFramebuffer = fboVk->GetFramebufferObj();
const bool syncSkipAllowed = !(GetConfig().vk_accurate_barriers || m_state.activePipelineInfo->neverSkipAccurateBarrier); const bool syncSkipAllowed = !m_state.hasRenderSelfDependency || !(GetConfig().vk_accurate_barriers || m_state.activePipelineInfo->neverSkipAccurateBarrier);
const bool FBOChanged = m_state.activeRenderpassFBO != fboVk; const bool FBOChanged = m_state.activeRenderpassFBO != fboVk;
bool inputSyncNecessary = false; const bool passReusable = !FBOChanged && syncSkipAllowed;
if (m_state.descriptorSetsChanged)
inputSyncNecessary = sync_isInputTexturesSyncRequired();
const bool passReusable = !FBOChanged && !inputSyncNecessary;
if (passReusable) if (passReusable)
{ {
if (sync_isInputTexturesSyncRequired())
sync_performFlushBarrier();
// reuse previous render pass // reuse previous render pass
return; return;
} }
draw_endRenderPass(); draw_endRenderPass();
if (sync_isInputTexturesSyncRequired())
sync_performFlushBarrier();
sync_RenderPassLoadTextures(fboVk); sync_RenderPassLoadTextures(fboVk);
if (m_featureControl.deviceExtensions.dynamic_rendering) if (m_featureControl.deviceExtensions.dynamic_rendering)
@ -1167,6 +1178,7 @@ void VulkanRenderer::draw_endRenderPass()
{ {
if (!m_state.activeRenderpassFBO) if (!m_state.activeRenderpassFBO)
return; return;
if (m_featureControl.deviceExtensions.dynamic_rendering) if (m_featureControl.deviceExtensions.dynamic_rendering)
vkCmdEndRenderingKHR(m_state.currentCommandBuffer); vkCmdEndRenderingKHR(m_state.currentCommandBuffer);
else else