mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
Move some code around, get rid of some unnecessary fences
This commit is contained in:
parent
7b5def9ff6
commit
31df6bf0fe
@ -36,11 +36,6 @@ void FrameData::Init(VulkanContext *vulkan, int index) {
|
||||
vulkan->SetDebugName(fence, VK_OBJECT_TYPE_FENCE, StringFromFormat("fence%d", index).c_str());
|
||||
readyForFence = true;
|
||||
|
||||
// This fence is used for synchronizing readbacks. Does not need preinitialization.
|
||||
// TODO: Put this in frameDataShared, only one is needed.
|
||||
readbackFence = vulkan->CreateFence(false);
|
||||
vulkan->SetDebugName(fence, VK_OBJECT_TYPE_FENCE, "readbackFence");
|
||||
|
||||
VkQueryPoolCreateInfo query_ci{ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO };
|
||||
query_ci.queryCount = MAX_TIMESTAMP_QUERIES;
|
||||
query_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
|
||||
@ -52,7 +47,6 @@ void FrameData::Destroy(VulkanContext *vulkan) {
|
||||
vkDestroyCommandPool(device, cmdPoolInit, nullptr);
|
||||
vkDestroyCommandPool(device, cmdPoolMain, nullptr);
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
vkDestroyFence(device, readbackFence, nullptr);
|
||||
vkDestroyQueryPool(device, profile.queryPool, nullptr);
|
||||
}
|
||||
|
||||
@ -144,7 +138,7 @@ void FrameData::SubmitPending(VulkanContext *vulkan, FrameSubmitType type, Frame
|
||||
}
|
||||
|
||||
if ((hasMainCommands || hasPresentCommands) && type == FrameSubmitType::Sync) {
|
||||
fenceToTrigger = readbackFence;
|
||||
fenceToTrigger = sharedData.readbackFence;
|
||||
}
|
||||
|
||||
if (hasMainCommands) {
|
||||
@ -206,8 +200,8 @@ void FrameData::SubmitPending(VulkanContext *vulkan, FrameSubmitType type, Frame
|
||||
|
||||
if (type == FrameSubmitType::Sync) {
|
||||
// Hard stall of the GPU, not ideal, but necessary so the CPU has the contents of the readback.
|
||||
vkWaitForFences(vulkan->GetDevice(), 1, &readbackFence, true, UINT64_MAX);
|
||||
vkResetFences(vulkan->GetDevice(), 1, &readbackFence);
|
||||
vkWaitForFences(vulkan->GetDevice(), 1, &sharedData.readbackFence, true, UINT64_MAX);
|
||||
vkResetFences(vulkan->GetDevice(), 1, &sharedData.readbackFence);
|
||||
syncDone = true;
|
||||
}
|
||||
}
|
||||
@ -219,10 +213,15 @@ void FrameDataShared::Init(VulkanContext *vulkan) {
|
||||
_dbg_assert_(res == VK_SUCCESS);
|
||||
res = vkCreateSemaphore(vulkan->GetDevice(), &semaphoreCreateInfo, nullptr, &renderingCompleteSemaphore);
|
||||
_dbg_assert_(res == VK_SUCCESS);
|
||||
|
||||
// This fence is used for synchronizing readbacks. Does not need preinitialization.
|
||||
readbackFence = vulkan->CreateFence(false);
|
||||
vulkan->SetDebugName(readbackFence, VK_OBJECT_TYPE_FENCE, "readbackFence");
|
||||
}
|
||||
|
||||
void FrameDataShared::Destroy(VulkanContext *vulkan) {
|
||||
VkDevice device = vulkan->GetDevice();
|
||||
vkDestroySemaphore(device, acquireSemaphore, nullptr);
|
||||
vkDestroySemaphore(device, renderingCompleteSemaphore, nullptr);
|
||||
vkDestroyFence(device, readbackFence, nullptr);
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ struct FrameDataShared {
|
||||
VkSemaphore acquireSemaphore = VK_NULL_HANDLE;
|
||||
VkSemaphore renderingCompleteSemaphore = VK_NULL_HANDLE;
|
||||
|
||||
// For synchronous readbacks.
|
||||
VkFence readbackFence = VK_NULL_HANDLE;
|
||||
|
||||
void Init(VulkanContext *vulkan);
|
||||
void Destroy(VulkanContext *vulkan);
|
||||
};
|
||||
@ -49,7 +52,6 @@ struct FrameData {
|
||||
bool readyForFence = true;
|
||||
|
||||
VkFence fence = VK_NULL_HANDLE;
|
||||
VkFence readbackFence = VK_NULL_HANDLE; // Strictly speaking we might only need one global of these.
|
||||
|
||||
// These are on different threads so need separate pools.
|
||||
VkCommandPool cmdPoolInit = VK_NULL_HANDLE; // Written to from main thread
|
||||
|
@ -67,39 +67,9 @@ void VulkanQueueRunner::CreateDeviceObjects() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) {
|
||||
if (readbackBuffer_ && requiredSize <= readbackBufferSize_) {
|
||||
return;
|
||||
}
|
||||
if (readbackBuffer_) {
|
||||
vulkan_->Delete().QueueDeleteBufferAllocation(readbackBuffer_, readbackAllocation_);
|
||||
}
|
||||
|
||||
readbackBufferSize_ = requiredSize;
|
||||
|
||||
VkDevice device = vulkan_->GetDevice();
|
||||
|
||||
VkBufferCreateInfo buf{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
buf.size = readbackBufferSize_;
|
||||
buf.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo{};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
|
||||
VmaAllocationInfo allocInfo{};
|
||||
|
||||
VkResult res = vmaCreateBuffer(vulkan_->Allocator(), &buf, &allocCreateInfo, &readbackBuffer_, &readbackAllocation_, &allocInfo);
|
||||
_assert_(res == VK_SUCCESS);
|
||||
|
||||
const VkMemoryType &memoryType = vulkan_->GetMemoryProperties().memoryTypes[allocInfo.memoryType];
|
||||
readbackBufferIsCoherent_ = (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::DestroyDeviceObjects() {
|
||||
INFO_LOG(G3D, "VulkanQueueRunner::DestroyDeviceObjects");
|
||||
if (readbackBuffer_) {
|
||||
vulkan_->Delete().QueueDeleteBufferAllocation(readbackBuffer_, readbackAllocation_);
|
||||
}
|
||||
readbackBufferSize_ = 0;
|
||||
DestroyReadbackBuffer();
|
||||
|
||||
renderPasses_.IterateMut([&](const RPKey &rpkey, VKRRenderPass *rp) {
|
||||
_assert_(rp);
|
||||
@ -1974,6 +1944,40 @@ void VulkanQueueRunner::SetupTransferDstWriteAfterWrite(VKRImage &img, VkImageAs
|
||||
);
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) {
|
||||
if (readbackBuffer_ && requiredSize <= readbackBufferSize_) {
|
||||
return;
|
||||
}
|
||||
if (readbackBuffer_) {
|
||||
vulkan_->Delete().QueueDeleteBufferAllocation(readbackBuffer_, readbackAllocation_);
|
||||
}
|
||||
|
||||
readbackBufferSize_ = requiredSize;
|
||||
|
||||
VkDevice device = vulkan_->GetDevice();
|
||||
|
||||
VkBufferCreateInfo buf{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
buf.size = readbackBufferSize_;
|
||||
buf.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo{};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
|
||||
VmaAllocationInfo allocInfo{};
|
||||
|
||||
VkResult res = vmaCreateBuffer(vulkan_->Allocator(), &buf, &allocCreateInfo, &readbackBuffer_, &readbackAllocation_, &allocInfo);
|
||||
_assert_(res == VK_SUCCESS);
|
||||
|
||||
const VkMemoryType &memoryType = vulkan_->GetMemoryProperties().memoryTypes[allocInfo.memoryType];
|
||||
readbackBufferIsCoherent_ = (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::DestroyReadbackBuffer() {
|
||||
if (readbackBuffer_) {
|
||||
vulkan_->Delete().QueueDeleteBufferAllocation(readbackBuffer_, readbackAllocation_);
|
||||
}
|
||||
readbackBufferSize_ = 0;
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::PerformReadback(const VKRStep &step, VkCommandBuffer cmd) {
|
||||
ResizeReadbackBuffer(sizeof(uint32_t) * step.readback.srcRect.extent.width * step.readback.srcRect.extent.height);
|
||||
|
||||
|
@ -298,6 +298,7 @@ private:
|
||||
void LogReadbackImage(const VKRStep &pass);
|
||||
|
||||
void ResizeReadbackBuffer(VkDeviceSize requiredSize);
|
||||
void DestroyReadbackBuffer();
|
||||
|
||||
void ApplyMGSHack(std::vector<VKRStep *> &steps);
|
||||
void ApplySonicHack(std::vector<VKRStep *> &steps);
|
||||
|
Loading…
Reference in New Issue
Block a user