Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/Cafe/HW/Latte/Renderer/Vulkan/TextureReadbackVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,8 @@ void LatteTextureReadbackInfoVk::StartTransfer()

renderer->barrier_image<VulkanRenderer::ANY_TRANSFER | VulkanRenderer::IMAGE_WRITE, VulkanRenderer::TRANSFER_READ>(baseTexture, region.imageSubresource, VK_IMAGE_LAYOUT_GENERAL);

renderer->barrier_sequentializeTransfer();

vkCmdCopyImageToBuffer(renderer->getCurrentCommandBuffer(), baseTexture->GetImageObj()->m_image, VK_IMAGE_LAYOUT_GENERAL, m_buffer, 1, &region);

renderer->barrier_sequentializeTransfer();

renderer->barrier_image<VulkanRenderer::TRANSFER_READ, VulkanRenderer::ANY_TRANSFER | VulkanRenderer::IMAGE_WRITE>(baseTexture, region.imageSubresource, VK_IMAGE_LAYOUT_GENERAL); // make sure transfer is finished before image is modified
renderer->barrier_bufferRange<VulkanRenderer::TRANSFER_WRITE, VulkanRenderer::HOST_READ>(m_buffer, m_buffer_offset, m_image_size); // make sure transfer is finished before result is read

Expand Down
35 changes: 22 additions & 13 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3222,6 +3222,14 @@ void VulkanRenderer::ProcessDestructionQueue()
m_spinlockDestructionQueue.unlock();
}

void VkDescriptorSetInfo::ForEachView(const std::function<void(LatteTextureViewVk*)>& fun)
{
for (auto& view : list_referencedViews)
{
fun(view);
}
}

VkDescriptorSetInfo::~VkDescriptorSetInfo()
{
for (auto& it : list_referencedViews)
Expand Down Expand Up @@ -3701,9 +3709,9 @@ void VulkanRenderer::bufferCache_upload(uint8* buffer, sint32 size, uint32 buffe

vkMemAllocator.FlushReservation(uploadResv);

barrier_bufferRange<ANY_TRANSFER | HOST_WRITE, ANY_TRANSFER,
BUFFER_SHADER_READ, TRANSFER_WRITE>(
uploadResv.vkBuffer, uploadResv.bufferOffset, uploadResv.size, // make sure any in-flight transfers are completed
barrier_bufferRange<TRANSFER_WRITE | HOST_WRITE, TRANSFER_READ,
TRANSFER_READ | BUFFER_SHADER_READ, TRANSFER_WRITE>(
uploadResv.vkBuffer, uploadResv.bufferOffset, uploadResv.size, // make sure source data is visible
m_bufferCache, bufferOffset, size); // make sure all reads are completed before we overwrite the data

VkBufferCopy region;
Expand All @@ -3712,15 +3720,18 @@ void VulkanRenderer::bufferCache_upload(uint8* buffer, sint32 size, uint32 buffe
region.size = size;
vkCmdCopyBuffer(m_state.currentCommandBuffer, uploadResv.vkBuffer, m_bufferCache, 1, &region);

barrier_sequentializeTransfer();
barrier_bufferRange<TRANSFER_WRITE, BUFFER_SHADER_READ>(m_bufferCache, bufferOffset, size);
}

void VulkanRenderer::bufferCache_copy(uint32 srcOffset, uint32 dstOffset, uint32 size)
{
cemu_assert_debug(!m_useHostMemoryForCache);
draw_endRenderPass();

barrier_sequentializeTransfer();
barrier_bufferRange<BUFFER_SHADER_WRITE | TRANSFER_WRITE, TRANSFER_READ,
TRANSFER_READ | BUFFER_SHADER_READ, TRANSFER_WRITE>(
m_bufferCache, srcOffset, size, // make sure source data is visible
m_bufferCache, dstOffset, size); // make sure all reads are completed before we overwrite the data

bool isOverlapping = (srcOffset + size) > dstOffset && (srcOffset) < (dstOffset + size);
cemu_assert_debug(!isOverlapping);
Expand All @@ -3731,7 +3742,7 @@ void VulkanRenderer::bufferCache_copy(uint32 srcOffset, uint32 dstOffset, uint32
bufferCopy.size = size;
vkCmdCopyBuffer(m_state.currentCommandBuffer, m_bufferCache, m_bufferCache, 1, &bufferCopy);

barrier_sequentializeTransfer();
barrier_bufferRange<TRANSFER_WRITE, BUFFER_SHADER_READ>(m_bufferCache, dstOffset, size);
}

void VulkanRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint32 dstOffset, uint32 size)
Expand All @@ -3748,20 +3759,18 @@ void VulkanRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uin
else
dstBuffer = m_bufferCache;

barrier_bufferRange<BUFFER_SHADER_WRITE, TRANSFER_READ,
ANY_TRANSFER | BUFFER_SHADER_READ, TRANSFER_WRITE>(
m_xfbRingBuffer, srcOffset, size, // wait for all writes to finish
dstBuffer, dstOffset, size); // wait for all reads to finish

barrier_sequentializeTransfer();
barrier_bufferRange<BUFFER_SHADER_WRITE | TRANSFER_WRITE, TRANSFER_READ,
TRANSFER_READ | BUFFER_SHADER_READ, TRANSFER_WRITE>(
m_xfbRingBuffer, srcOffset, size, // make sure source data is visible
dstBuffer, dstOffset, size); // make sure all reads are completed before we overwrite the data

VkBufferCopy bufferCopy{};
bufferCopy.srcOffset = srcOffset;
bufferCopy.dstOffset = dstOffset;
bufferCopy.size = size;
vkCmdCopyBuffer(m_state.currentCommandBuffer, m_xfbRingBuffer, dstBuffer, 1, &bufferCopy);

barrier_sequentializeTransfer();
barrier_bufferRange<TRANSFER_WRITE, BUFFER_SHADER_READ>(dstBuffer, dstOffset, size); // make sure writes are visible to host
}

void VulkanRenderer::AppendOverlayDebugInfo()
Expand Down
37 changes: 9 additions & 28 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Cafe/HW/Latte/Renderer/Vulkan/CachedFBOVk.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/VKRMemoryManager.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.h"
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
#include "util/math/vector2.h"
#include "util/helpers/Semaphore.h"
#include "util/containers/flat_hash_map.hpp"
Expand All @@ -26,6 +27,8 @@ struct VkDescriptorSetInfo
{
VKRObjectDescriptorSet* m_vkObjDescriptorSet{};

void ForEachView(const std::function<void(LatteTextureViewVk*)>& fun);

~VkDescriptorSetInfo();

std::vector<LatteTextureViewVk*> list_referencedViews;
Expand Down Expand Up @@ -409,7 +412,7 @@ class VulkanRenderer : public Renderer
}

// 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

// draw sequence
Expand Down Expand Up @@ -546,7 +549,8 @@ class VulkanRenderer : public Renderer
void draw_handleSpecialState5();

// draw synchronization helper
void sync_inputTexturesChanged();
void sync_performFlushBarrier(CachedFBOVk* fboVk);
bool sync_isInputTexturesSyncRequired();
void sync_RenderPassLoadTextures(CachedFBOVk* fboVk);
void sync_RenderPassStoreTextures(CachedFBOVk* fboVk);

Expand Down Expand Up @@ -825,6 +829,7 @@ class VulkanRenderer : public Renderer
bufMemBarrier.offset = offset;
bufMemBarrier.size = size;
vkCmdPipelineBarrier(m_state.currentCommandBuffer, srcStages, dstStages, 0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
}

template<uint32 TSrcSyncOpA, uint32 TDstSyncOpA, uint32 TSrcSyncOpB, uint32 TDstSyncOpB>
Expand Down Expand Up @@ -863,32 +868,7 @@ class VulkanRenderer : public Renderer
bufMemBarrier[1].size = sizeB;

vkCmdPipelineBarrier(m_state.currentCommandBuffer, srcStagesA|srcStagesB, dstStagesA|dstStagesB, 0, 0, nullptr, 2, bufMemBarrier, 0, nullptr);
}

void barrier_sequentializeTransfer()
{
VkMemoryBarrier memBarrier{};
memBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memBarrier.pNext = nullptr;

VkPipelineStageFlags srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT;
VkPipelineStageFlags dstStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;

memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
memBarrier.dstAccessMask = 0;

memBarrier.srcAccessMask |= (VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT);
memBarrier.dstAccessMask |= (VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT);

vkCmdPipelineBarrier(m_state.currentCommandBuffer, srcStages, dstStages, 0, 1, &memBarrier, 0, nullptr, 0, nullptr);
}

void barrier_sequentializeCommand()
{
VkPipelineStageFlags srcStages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;

vkCmdPipelineBarrier(m_state.currentCommandBuffer, srcStages, dstStages, 0, 0, nullptr, 0, nullptr, 0, nullptr);
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
}

template<uint32 TSrcSyncOp, uint32 TDstSyncOp>
Expand Down Expand Up @@ -916,6 +896,7 @@ class VulkanRenderer : public Renderer
0, NULL,
0, NULL,
1, &imageMemBarrier);
performanceMonitor.vk.numDrawBarriersPerFrame.increment();
}

template<uint32 TSrcSyncOp, uint32 TDstSyncOp>
Expand Down
Loading
Loading