Skip to content

Commit

Permalink
A bit better.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Aug 2, 2023
1 parent 1fdb12a commit ccf1aff
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 16 deletions.
34 changes: 22 additions & 12 deletions Source/gs/GSH_Vulkan/GSH_Vulkan.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include "GSH_Vulkan.h"
#include <cstring>
#include "std_experimental_map.h"
#include "../GsPixelFormats.h"
#include "../../Log.h"
#include "../../AppConfig.h"
#include "GSH_Vulkan.h"
#include "GSH_VulkanPlatformDefs.h"
#include "GSH_VulkanDrawDesktop.h"
#include "GSH_VulkanDrawMobile.h"
Expand Down Expand Up @@ -269,7 +270,12 @@ void CGSH_Vulkan::FlipImpl()
}

PresentBackbuffer();
m_copiedThisFrame = false;
for(auto& xferHistoryPair : m_xferHistory)
{
xferHistoryPair.second.Advance();
}
std::experimental::erase_if(m_xferHistory,
[](const auto& xferTrackerPair) { return xferTrackerPair.second.IsEmpty(); });
CGSHandler::FlipImpl();
}

Expand Down Expand Up @@ -1321,15 +1327,18 @@ void CGSH_Vulkan::ProcessLocalToHostTransfer()
bool readsEnabled = CAppConfig::GetInstance().GetPreferenceBoolean(PREF_CGSHANDLER_GS_RAM_READS_ENABLED);
if(readsEnabled)
{
//Make sure our local RAM copy is in sync with GPU
//SyncMemoryCache();
//TODO: Handle transfers with offsets in TRXPOS.

m_draw->FlushRenderPass();

auto bltBuf = make_convertible<BITBLTBUF>(m_nReg[GS_REG_BITBLTBUF]);
auto trxReg = make_convertible<TRXREG>(m_nReg[GS_REG_TRXREG]);
auto trxPos = make_convertible<TRXPOS>(m_nReg[GS_REG_TRXPOS]);

m_xferHistory.insert(std::make_pair(bltBuf, LOCAL_TO_HOST_XFER_HISTORY{}));
auto transfer = m_xferHistory.find(bltBuf);
transfer->second.MarkUsed();

CGsCachedArea area;
area.SetArea(bltBuf.nSrcPsm, bltBuf.GetSrcPtr(), bltBuf.GetSrcWidth(), trxReg.nRRH);

Expand Down Expand Up @@ -1358,18 +1367,19 @@ void CGSH_Vulkan::ProcessLocalToHostTransfer()
m_context->device.vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &bufferCopy);
}

if(!m_copiedThisFrame)
if(!transfer->second.IsRecurring())
{
void* bufferPtr = nullptr;
auto result = m_context->device.vkMapMemory(m_context->device, dstBuffer.GetMemory(), copyBase, copySize, 0, &bufferPtr);
CHECKVULKANERROR(result);
m_frameCommandBuffer->Flush();
m_context->device.vkQueueWaitIdle(m_context->queue);
}

memcpy(m_memoryCache + copyBase, bufferPtr, copySize);
void* bufferPtr = nullptr;
auto result = m_context->device.vkMapMemory(m_context->device, dstBuffer.GetMemory(), copyBase, copySize, 0, &bufferPtr);
CHECKVULKANERROR(result);

m_context->device.vkUnmapMemory(m_context->device, dstBuffer.GetMemory());
memcpy(m_memoryCache + copyBase, bufferPtr, copySize);

m_copiedThisFrame = true;
}
m_context->device.vkUnmapMemory(m_context->device, dstBuffer.GetMemory());
}
}

Expand Down
42 changes: 41 additions & 1 deletion Source/gs/GSH_Vulkan/GSH_Vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "GSH_VulkanTransferHost.h"
#include "GSH_VulkanTransferLocal.h"
#include <vector>
#include <map>
#include "../GSHandler.h"
#include "../GsDebuggerInterface.h"
#include "../GsCachedArea.h"
Expand Down Expand Up @@ -88,6 +89,45 @@ class CGSH_Vulkan : public CGSHandler, public CGsDebuggerInterface
CLUT_CACHE_SIZE = 32,
};

struct LOCAL_TO_HOST_XFER_HISTORY
{
static constexpr int MAX_FRAME_COUNT = 16;
static constexpr int RECURRING_THRESHOLD = 4;

std::array<bool, MAX_FRAME_COUNT> used = {};
int frameCount = 0;

void Advance()
{
frameCount++;
if(frameCount == MAX_FRAME_COUNT)
{
memmove(used.data(), used.data() + 1, sizeof(bool) * MAX_FRAME_COUNT - 1);
frameCount--;
used[frameCount] = false;
}
}

void MarkUsed()
{
used[frameCount] = true;
}

bool IsRecurring() const
{
if(frameCount != (MAX_FRAME_COUNT - 1)) return false;
auto result = std::count_if(std::begin(used), std::end(used), [](bool used) { return used; });
return result >= RECURRING_THRESHOLD;
}

bool IsEmpty() const
{
if(frameCount != (MAX_FRAME_COUNT - 1)) return false;
auto result = std::count_if(std::begin(used), std::end(used), [](bool used) { return used; });
return result == 0;
}
};

virtual void PresentBackbuffer() = 0;

std::vector<VkPhysicalDevice> GetPhysicalDevices();
Expand Down Expand Up @@ -186,7 +226,6 @@ class CGSH_Vulkan : public CGSHandler, public CGsDebuggerInterface
GSH_Vulkan::TransferLocalPtr m_transferLocal;

uint8* m_memoryCache = nullptr;
bool m_copiedThisFrame = false;

//Draw context
VERTEX m_vtxBuffer[3];
Expand All @@ -201,6 +240,7 @@ class CGSH_Vulkan : public CGSHandler, public CGsDebuggerInterface
CLUTKEY m_clutStates[CLUT_CACHE_SIZE];
uint32 m_nextClutCacheIndex = 0;
std::vector<uint8> m_xferBuffer;
std::map<uint64, LOCAL_TO_HOST_XFER_HISTORY> m_xferHistory;

//Optimization for Virtua Fighter 2, Sega Rally 95
float m_lastLineU = 0;
Expand Down
5 changes: 2 additions & 3 deletions Source/gs/GSHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,9 +594,8 @@ void CGSHandler::FeedImageData(const void* data, uint32 length)
void CGSHandler::ReadImageData(void* data, uint32 length)
{
assert(m_writeBufferProcessIndex == m_writeBufferSize);
//SubmitWriteBuffer();
//SendGSCall([this, data, length]() { ReadImageDataImpl(data, length); }, true);
ReadImageDataImpl(data, length);
SubmitWriteBuffer();
SendGSCall([this, data, length]() { ReadImageDataImpl(data, length); }, true);
}

void CGSHandler::ProcessWriteBuffer(const CGsPacketMetadata* metadata)
Expand Down

0 comments on commit ccf1aff

Please sign in to comment.