mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-10-30 07:11:05 +00:00
Refactor barrier usage.
This commit is contained in:
parent
b876766848
commit
c2ca5dcdad
2 changed files with 55 additions and 30 deletions
|
|
@ -124,6 +124,7 @@ static std::unique_ptr<RenderCommandFence> g_copyCommandFence;
|
||||||
|
|
||||||
static std::unique_ptr<RenderSwapChain> g_swapChain;
|
static std::unique_ptr<RenderSwapChain> g_swapChain;
|
||||||
static std::unique_ptr<RenderCommandSemaphore> g_acquireSemaphores[NUM_FRAMES];
|
static std::unique_ptr<RenderCommandSemaphore> g_acquireSemaphores[NUM_FRAMES];
|
||||||
|
static std::unique_ptr<RenderCommandSemaphore> g_renderSemaphores[NUM_FRAMES];
|
||||||
static uint32_t g_backBufferIndex;
|
static uint32_t g_backBufferIndex;
|
||||||
static GuestSurface* g_backBuffer;
|
static GuestSurface* g_backBuffer;
|
||||||
|
|
||||||
|
|
@ -264,6 +265,17 @@ static std::vector<uint32_t> g_tempDescriptorIndices[NUM_FRAMES];
|
||||||
static RenderBufferReference g_quadIndexBuffer;
|
static RenderBufferReference g_quadIndexBuffer;
|
||||||
static uint32_t g_quadCount;
|
static uint32_t g_quadCount;
|
||||||
|
|
||||||
|
static std::vector<RenderTextureBarrier> g_barriers;
|
||||||
|
|
||||||
|
static void FlushBarriers()
|
||||||
|
{
|
||||||
|
if (!g_barriers.empty())
|
||||||
|
{
|
||||||
|
g_commandLists[g_frame]->barriers(RenderBarrierStage::GRAPHICS, g_barriers);
|
||||||
|
g_barriers.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void SetRenderState(GuestDevice* device, uint32_t value)
|
static void SetRenderState(GuestDevice* device, uint32_t value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -506,6 +518,9 @@ static void CreateHostDevice()
|
||||||
{
|
{
|
||||||
for (auto& acquireSemaphore : g_acquireSemaphores)
|
for (auto& acquireSemaphore : g_acquireSemaphores)
|
||||||
acquireSemaphore = g_device->createCommandSemaphore();
|
acquireSemaphore = g_device->createCommandSemaphore();
|
||||||
|
|
||||||
|
for (auto& renderSemaphore : g_renderSemaphores)
|
||||||
|
renderSemaphore = g_device->createCommandSemaphore();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPipelineLayoutBuilder pipelineLayoutBuilder;
|
RenderPipelineLayoutBuilder pipelineLayoutBuilder;
|
||||||
|
|
@ -556,12 +571,13 @@ static void BeginCommandList()
|
||||||
|
|
||||||
bool acquired = g_swapChain->acquireTexture(g_acquireSemaphores[g_frame].get(), &g_backBufferIndex);
|
bool acquired = g_swapChain->acquireTexture(g_acquireSemaphores[g_frame].get(), &g_backBufferIndex);
|
||||||
assert(acquired);
|
assert(acquired);
|
||||||
|
|
||||||
g_backBuffer->texture = g_swapChain->getTexture(g_backBufferIndex);
|
g_backBuffer->texture = g_swapChain->getTexture(g_backBufferIndex);
|
||||||
|
g_backBuffer->pendingBarrier = true;
|
||||||
|
|
||||||
auto& commandList = g_commandLists[g_frame];
|
auto& commandList = g_commandLists[g_frame];
|
||||||
|
|
||||||
commandList->begin();
|
commandList->begin();
|
||||||
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(g_backBuffer->texture, RenderTextureLayout::COLOR_WRITE));
|
|
||||||
commandList->setGraphicsPipelineLayout(g_pipelineLayout.get());
|
commandList->setGraphicsPipelineLayout(g_pipelineLayout.get());
|
||||||
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
|
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
|
||||||
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 1);
|
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 1);
|
||||||
|
|
@ -802,25 +818,31 @@ static uint32_t HashVertexDeclaration(uint32_t vertexDeclaration)
|
||||||
|
|
||||||
static void Present()
|
static void Present()
|
||||||
{
|
{
|
||||||
|
g_barriers.emplace_back(g_backBuffer->texture, RenderTextureLayout::PRESENT);
|
||||||
|
FlushBarriers();
|
||||||
|
|
||||||
auto& commandList = g_commandLists[g_frame];
|
auto& commandList = g_commandLists[g_frame];
|
||||||
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(g_backBuffer->texture, RenderTextureLayout::PRESENT));
|
|
||||||
commandList->end();
|
commandList->end();
|
||||||
|
|
||||||
if (g_vulkan)
|
if (g_vulkan)
|
||||||
{
|
{
|
||||||
const RenderCommandList* commandLists[] = { commandList.get() };
|
const RenderCommandList* commandLists[] = { commandList.get() };
|
||||||
RenderCommandSemaphore* waitSemaphores[] = { g_acquireSemaphores[g_frame].get()};
|
RenderCommandSemaphore* waitSemaphores[] = { g_acquireSemaphores[g_frame].get()};
|
||||||
|
RenderCommandSemaphore* signalSemaphores[] = { g_renderSemaphores[g_frame].get()};
|
||||||
|
|
||||||
g_queue->executeCommandLists(
|
g_queue->executeCommandLists(
|
||||||
commandLists, std::size(commandLists),
|
commandLists, std::size(commandLists),
|
||||||
waitSemaphores, std::size(waitSemaphores),
|
waitSemaphores, std::size(waitSemaphores),
|
||||||
nullptr, 0,
|
signalSemaphores, std::size(signalSemaphores),
|
||||||
g_commandFences[g_frame].get());
|
g_commandFences[g_frame].get());
|
||||||
|
|
||||||
|
g_swapChain->present(g_backBufferIndex, signalSemaphores, std::size(signalSemaphores));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_queue->executeCommandLists(commandList.get(), g_commandFences[g_frame].get());
|
g_queue->executeCommandLists(commandList.get(), g_commandFences[g_frame].get());
|
||||||
}
|
|
||||||
g_swapChain->present(g_backBufferIndex, nullptr, 0);
|
g_swapChain->present(g_backBufferIndex, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
g_frame = g_nextFrame;
|
g_frame = g_nextFrame;
|
||||||
g_nextFrame = (g_frame + 1) % NUM_FRAMES;
|
g_nextFrame = (g_frame + 1) % NUM_FRAMES;
|
||||||
|
|
@ -969,31 +991,18 @@ static void StretchRect(GuestDevice* device, uint32_t flags, uint32_t, GuestText
|
||||||
const bool isDepthStencil = (flags & 0x4) != 0;
|
const bool isDepthStencil = (flags & 0x4) != 0;
|
||||||
const auto surface = isDepthStencil ? g_depthStencil : g_renderTarget;
|
const auto surface = isDepthStencil ? g_depthStencil : g_renderTarget;
|
||||||
|
|
||||||
RenderTextureBarrier srcBarriers[] =
|
g_barriers.emplace_back(surface->texture, RenderTextureLayout::COPY_SOURCE);
|
||||||
{
|
g_barriers.emplace_back(texture->texture.get(), RenderTextureLayout::COPY_DEST);
|
||||||
RenderTextureBarrier(surface->texture, RenderTextureLayout::COPY_SOURCE),
|
FlushBarriers();
|
||||||
RenderTextureBarrier(texture->texture.get(), RenderTextureLayout::COPY_DEST)
|
|
||||||
};
|
|
||||||
|
|
||||||
auto& commandList = g_commandLists[g_frame];
|
g_commandLists[g_frame]->copyTexture(texture->texture.get(), surface->texture);
|
||||||
|
|
||||||
commandList->barriers(RenderBarrierStage::GRAPHICS, srcBarriers, std::size(srcBarriers));
|
surface->pendingBarrier = true;
|
||||||
commandList->copyTexture(texture->texture.get(), surface->texture);
|
texture->pendingBarrier = true;
|
||||||
|
|
||||||
RenderTextureBarrier dstBarriers[] =
|
|
||||||
{
|
|
||||||
RenderTextureBarrier(surface->texture, isDepthStencil ? RenderTextureLayout::DEPTH_WRITE : RenderTextureLayout::COLOR_WRITE),
|
|
||||||
RenderTextureBarrier(texture->texture.get(), RenderTextureLayout::SHADER_READ)
|
|
||||||
};
|
|
||||||
|
|
||||||
commandList->barriers(RenderBarrierStage::GRAPHICS, dstBarriers, std::size(dstBarriers));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetRenderTarget(GuestDevice* device, uint32_t index, GuestSurface* renderTarget)
|
static void SetRenderTarget(GuestDevice* device, uint32_t index, GuestSurface* renderTarget)
|
||||||
{
|
{
|
||||||
if (renderTarget != nullptr)
|
|
||||||
g_commandLists[g_frame]->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(renderTarget->texture, RenderTextureLayout::COLOR_WRITE));
|
|
||||||
|
|
||||||
SetDirtyValue(g_dirtyStates.renderTargetAndDepthStencil, g_renderTarget, renderTarget);
|
SetDirtyValue(g_dirtyStates.renderTargetAndDepthStencil, g_renderTarget, renderTarget);
|
||||||
SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.renderTargetFormat, renderTarget != nullptr ? renderTarget->format : RenderFormat::UNKNOWN);
|
SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.renderTargetFormat, renderTarget != nullptr ? renderTarget->format : RenderFormat::UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
@ -1005,15 +1014,26 @@ static GuestSurface* GetDepthStencilSurface(GuestDevice* device)
|
||||||
|
|
||||||
static void SetDepthStencilSurface(GuestDevice* device, GuestSurface* depthStencil)
|
static void SetDepthStencilSurface(GuestDevice* device, GuestSurface* depthStencil)
|
||||||
{
|
{
|
||||||
if (depthStencil != nullptr)
|
|
||||||
g_commandLists[g_frame]->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(depthStencil->texture, RenderTextureLayout::DEPTH_WRITE));
|
|
||||||
|
|
||||||
SetDirtyValue(g_dirtyStates.renderTargetAndDepthStencil, g_depthStencil, depthStencil);
|
SetDirtyValue(g_dirtyStates.renderTargetAndDepthStencil, g_depthStencil, depthStencil);
|
||||||
SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.depthStencilFormat, depthStencil != nullptr ? depthStencil->format : RenderFormat::UNKNOWN);
|
SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.depthStencilFormat, depthStencil != nullptr ? depthStencil->format : RenderFormat::UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FlushFramebuffer()
|
static void FlushFramebuffer()
|
||||||
{
|
{
|
||||||
|
auto& commandList = g_commandLists[g_frame];
|
||||||
|
|
||||||
|
if (g_renderTarget != nullptr && g_renderTarget->pendingBarrier)
|
||||||
|
{
|
||||||
|
g_barriers.emplace_back(g_renderTarget->texture, RenderTextureLayout::COLOR_WRITE);
|
||||||
|
g_renderTarget->pendingBarrier = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_depthStencil != nullptr && g_depthStencil->pendingBarrier)
|
||||||
|
{
|
||||||
|
g_barriers.emplace_back(g_depthStencil->texture, RenderTextureLayout::DEPTH_WRITE);
|
||||||
|
g_depthStencil->pendingBarrier = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_dirtyStates.renderTargetAndDepthStencil)
|
if (g_dirtyStates.renderTargetAndDepthStencil)
|
||||||
{
|
{
|
||||||
GuestSurface* framebufferContainer = nullptr;
|
GuestSurface* framebufferContainer = nullptr;
|
||||||
|
|
@ -1035,8 +1055,6 @@ static void FlushFramebuffer()
|
||||||
framebufferKey = nullptr;
|
framebufferKey = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& commandList = g_commandLists[g_frame];
|
|
||||||
|
|
||||||
if (framebufferContainer != nullptr)
|
if (framebufferContainer != nullptr)
|
||||||
{
|
{
|
||||||
auto& framebuffer = framebufferContainer->framebuffers[framebufferKey];
|
auto& framebuffer = framebufferContainer->framebuffers[framebufferKey];
|
||||||
|
|
@ -1066,6 +1084,8 @@ static void FlushFramebuffer()
|
||||||
|
|
||||||
g_dirtyStates.renderTargetAndDepthStencil = false;
|
g_dirtyStates.renderTargetAndDepthStencil = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlushBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Clear(GuestDevice* device, uint32_t flags, uint32_t, be<float>* color, double z)
|
static void Clear(GuestDevice* device, uint32_t flags, uint32_t, be<float>* color, double z)
|
||||||
|
|
@ -1105,8 +1125,11 @@ static void GetViewport(GuestDevice* device, GuestViewport* viewport)
|
||||||
|
|
||||||
static void SetTexture(GuestDevice* device, uint32_t index, GuestTexture* texture)
|
static void SetTexture(GuestDevice* device, uint32_t index, GuestTexture* texture)
|
||||||
{
|
{
|
||||||
if (texture != nullptr)
|
if (texture != nullptr && texture->pendingBarrier)
|
||||||
g_commandLists[g_frame]->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(texture->texture.get(), RenderTextureLayout::SHADER_READ));
|
{
|
||||||
|
g_barriers.emplace_back(texture->texture.get(), RenderTextureLayout::SHADER_READ);
|
||||||
|
texture->pendingBarrier = false;
|
||||||
|
}
|
||||||
|
|
||||||
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.textureIndices[index], texture != nullptr ? texture->descriptorIndex : NULL);
|
SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.textureIndices[index], texture != nullptr ? texture->descriptorIndex : NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ struct GuestTexture : GuestResource
|
||||||
RenderFormat format = RenderFormat::UNKNOWN;
|
RenderFormat format = RenderFormat::UNKNOWN;
|
||||||
void* mappedMemory = nullptr;
|
void* mappedMemory = nullptr;
|
||||||
uint32_t descriptorIndex = 0;
|
uint32_t descriptorIndex = 0;
|
||||||
|
bool pendingBarrier = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GuestLockedRect
|
struct GuestLockedRect
|
||||||
|
|
@ -147,6 +148,7 @@ struct GuestSurface : GuestResource
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
RenderFormat format = RenderFormat::UNKNOWN;
|
RenderFormat format = RenderFormat::UNKNOWN;
|
||||||
ankerl::unordered_dense::map<const RenderTexture*, std::unique_ptr<RenderFramebuffer>> framebuffers;
|
ankerl::unordered_dense::map<const RenderTexture*, std::unique_ptr<RenderFramebuffer>> framebuffers;
|
||||||
|
bool pendingBarrier = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuestDeclType
|
enum GuestDeclType
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue