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<RenderCommandSemaphore> g_acquireSemaphores[NUM_FRAMES];
 | 
			
		||||
static std::unique_ptr<RenderCommandSemaphore> g_renderSemaphores[NUM_FRAMES];
 | 
			
		||||
static uint32_t g_backBufferIndex;
 | 
			
		||||
static GuestSurface* g_backBuffer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +265,17 @@ static std::vector<uint32_t> g_tempDescriptorIndices[NUM_FRAMES];
 | 
			
		|||
static RenderBufferReference g_quadIndexBuffer;
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -506,6 +518,9 @@ static void CreateHostDevice()
 | 
			
		|||
    {
 | 
			
		||||
        for (auto& acquireSemaphore : g_acquireSemaphores)
 | 
			
		||||
            acquireSemaphore = g_device->createCommandSemaphore();
 | 
			
		||||
 | 
			
		||||
        for (auto& renderSemaphore : g_renderSemaphores)
 | 
			
		||||
            renderSemaphore = g_device->createCommandSemaphore();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RenderPipelineLayoutBuilder pipelineLayoutBuilder;
 | 
			
		||||
| 
						 | 
				
			
			@ -556,12 +571,13 @@ static void BeginCommandList()
 | 
			
		|||
 | 
			
		||||
    bool acquired = g_swapChain->acquireTexture(g_acquireSemaphores[g_frame].get(), &g_backBufferIndex);
 | 
			
		||||
    assert(acquired);
 | 
			
		||||
 | 
			
		||||
    g_backBuffer->texture = g_swapChain->getTexture(g_backBufferIndex);
 | 
			
		||||
    g_backBuffer->pendingBarrier = true;
 | 
			
		||||
 | 
			
		||||
    auto& commandList = g_commandLists[g_frame];
 | 
			
		||||
 | 
			
		||||
    commandList->begin();
 | 
			
		||||
    commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(g_backBuffer->texture, RenderTextureLayout::COLOR_WRITE));
 | 
			
		||||
    commandList->setGraphicsPipelineLayout(g_pipelineLayout.get());
 | 
			
		||||
    commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
 | 
			
		||||
    commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -802,25 +818,31 @@ static uint32_t HashVertexDeclaration(uint32_t vertexDeclaration)
 | 
			
		|||
 | 
			
		||||
static void Present() 
 | 
			
		||||
{
 | 
			
		||||
    g_barriers.emplace_back(g_backBuffer->texture, RenderTextureLayout::PRESENT);
 | 
			
		||||
    FlushBarriers();
 | 
			
		||||
 | 
			
		||||
    auto& commandList = g_commandLists[g_frame];
 | 
			
		||||
    commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(g_backBuffer->texture, RenderTextureLayout::PRESENT));
 | 
			
		||||
    commandList->end();
 | 
			
		||||
 | 
			
		||||
    if (g_vulkan)
 | 
			
		||||
    {
 | 
			
		||||
        const RenderCommandList* commandLists[] = { commandList.get() };
 | 
			
		||||
        RenderCommandSemaphore* waitSemaphores[] = { g_acquireSemaphores[g_frame].get()};
 | 
			
		||||
        RenderCommandSemaphore* signalSemaphores[] = { g_renderSemaphores[g_frame].get()};
 | 
			
		||||
 | 
			
		||||
        g_queue->executeCommandLists(
 | 
			
		||||
            commandLists, std::size(commandLists), 
 | 
			
		||||
            waitSemaphores, std::size(waitSemaphores), 
 | 
			
		||||
            nullptr, 0, 
 | 
			
		||||
            signalSemaphores, std::size(signalSemaphores),
 | 
			
		||||
            g_commandFences[g_frame].get());
 | 
			
		||||
 | 
			
		||||
        g_swapChain->present(g_backBufferIndex, signalSemaphores, std::size(signalSemaphores));
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        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_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 auto surface = isDepthStencil ? g_depthStencil : g_renderTarget;
 | 
			
		||||
 | 
			
		||||
    RenderTextureBarrier srcBarriers[] =
 | 
			
		||||
    {
 | 
			
		||||
        RenderTextureBarrier(surface->texture, RenderTextureLayout::COPY_SOURCE),
 | 
			
		||||
        RenderTextureBarrier(texture->texture.get(), RenderTextureLayout::COPY_DEST)
 | 
			
		||||
    };
 | 
			
		||||
    g_barriers.emplace_back(surface->texture, RenderTextureLayout::COPY_SOURCE);
 | 
			
		||||
    g_barriers.emplace_back(texture->texture.get(), RenderTextureLayout::COPY_DEST);
 | 
			
		||||
    FlushBarriers();
 | 
			
		||||
 | 
			
		||||
    auto& commandList = g_commandLists[g_frame];
 | 
			
		||||
    g_commandLists[g_frame]->copyTexture(texture->texture.get(), surface->texture);
 | 
			
		||||
 | 
			
		||||
    commandList->barriers(RenderBarrierStage::GRAPHICS, srcBarriers, std::size(srcBarriers));
 | 
			
		||||
    commandList->copyTexture(texture->texture.get(), surface->texture);
 | 
			
		||||
 | 
			
		||||
    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));
 | 
			
		||||
    surface->pendingBarrier = true;
 | 
			
		||||
    texture->pendingBarrier = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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.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) 
 | 
			
		||||
{
 | 
			
		||||
    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.pipelineState, g_pipelineState.depthStencilFormat, depthStencil != nullptr ? depthStencil->format : RenderFormat::UNKNOWN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
    {
 | 
			
		||||
        GuestSurface* framebufferContainer = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -1035,8 +1055,6 @@ static void FlushFramebuffer()
 | 
			
		|||
            framebufferKey = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto& commandList = g_commandLists[g_frame];
 | 
			
		||||
 | 
			
		||||
        if (framebufferContainer != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            auto& framebuffer = framebufferContainer->framebuffers[framebufferKey];
 | 
			
		||||
| 
						 | 
				
			
			@ -1066,6 +1084,8 @@ static void FlushFramebuffer()
 | 
			
		|||
 | 
			
		||||
        g_dirtyStates.renderTargetAndDepthStencil = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FlushBarriers();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) 
 | 
			
		||||
{
 | 
			
		||||
    if (texture != nullptr)
 | 
			
		||||
        g_commandLists[g_frame]->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(texture->texture.get(), RenderTextureLayout::SHADER_READ));
 | 
			
		||||
    if (texture != nullptr && texture->pendingBarrier)
 | 
			
		||||
    {
 | 
			
		||||
        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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,6 +97,7 @@ struct GuestTexture : GuestResource
 | 
			
		|||
    RenderFormat format = RenderFormat::UNKNOWN;
 | 
			
		||||
    void* mappedMemory = nullptr;
 | 
			
		||||
    uint32_t descriptorIndex = 0;
 | 
			
		||||
    bool pendingBarrier = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct GuestLockedRect
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +148,7 @@ struct GuestSurface : GuestResource
 | 
			
		|||
    uint32_t height = 0;
 | 
			
		||||
    RenderFormat format = RenderFormat::UNKNOWN;
 | 
			
		||||
    ankerl::unordered_dense::map<const RenderTexture*, std::unique_ptr<RenderFramebuffer>> framebuffers;
 | 
			
		||||
    bool pendingBarrier = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum GuestDeclType
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue