renderer_vulkan: add locks to avoid scheduler flushes from CPU
This commit is contained in:
		@@ -86,7 +86,10 @@ public:
 | 
			
		||||
            uncommitted_operations.emplace_back(std::move(func));
 | 
			
		||||
        }
 | 
			
		||||
        pending_operations.emplace_back(std::move(uncommitted_operations));
 | 
			
		||||
        QueueFence(new_fence);
 | 
			
		||||
        {
 | 
			
		||||
            std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
 | 
			
		||||
            QueueFence(new_fence);
 | 
			
		||||
        }
 | 
			
		||||
        if (!delay_fence) {
 | 
			
		||||
            func();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -132,12 +132,16 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
 | 
			
		||||
    const bool use_accelerated =
 | 
			
		||||
        rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
 | 
			
		||||
    const bool is_srgb = use_accelerated && screen_info.is_srgb;
 | 
			
		||||
    RenderScreenshot(*framebuffer, use_accelerated);
 | 
			
		||||
 | 
			
		||||
    Frame* frame = present_manager.GetRenderFrame();
 | 
			
		||||
    blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
 | 
			
		||||
    scheduler.Flush(*frame->render_ready);
 | 
			
		||||
    present_manager.Present(frame);
 | 
			
		||||
    {
 | 
			
		||||
        std::scoped_lock lock{rasterizer.LockCaches()};
 | 
			
		||||
        RenderScreenshot(*framebuffer, use_accelerated);
 | 
			
		||||
 | 
			
		||||
        Frame* frame = present_manager.GetRenderFrame();
 | 
			
		||||
        blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
 | 
			
		||||
        scheduler.Flush(*frame->render_ready);
 | 
			
		||||
        present_manager.Present(frame);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gpu.RendererFrameEndNotify();
 | 
			
		||||
    rasterizer.TickFrame();
 | 
			
		||||
 
 | 
			
		||||
@@ -198,7 +198,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
 | 
			
		||||
    if (!pipeline) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
 | 
			
		||||
    std::scoped_lock lock{LockCaches()};
 | 
			
		||||
    // update engine as channel may be different.
 | 
			
		||||
    pipeline->SetEngine(maxwell3d, gpu_memory);
 | 
			
		||||
    pipeline->Configure(is_indexed);
 | 
			
		||||
@@ -708,6 +708,7 @@ void RasterizerVulkan::TiledCacheBarrier() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerVulkan::FlushCommands() {
 | 
			
		||||
    std::scoped_lock lock{LockCaches()};
 | 
			
		||||
    if (draw_counter == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@@ -805,6 +806,7 @@ void RasterizerVulkan::FlushWork() {
 | 
			
		||||
    if ((++draw_counter & 7) != 7) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    std::scoped_lock lock{LockCaches()};
 | 
			
		||||
    if (draw_counter < DRAWS_TO_DISPATCH) {
 | 
			
		||||
        // Send recorded tasks to the worker thread
 | 
			
		||||
        scheduler.DispatchWork();
 | 
			
		||||
@@ -1486,7 +1488,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
 | 
			
		||||
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
 | 
			
		||||
    CreateChannel(channel);
 | 
			
		||||
    {
 | 
			
		||||
        std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
 | 
			
		||||
        std::scoped_lock lock{LockCaches()};
 | 
			
		||||
        texture_cache.CreateChannel(channel);
 | 
			
		||||
        buffer_cache.CreateChannel(channel);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1499,7 +1501,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
 | 
			
		||||
    const s32 channel_id = channel.bind_id;
 | 
			
		||||
    BindToChannel(channel_id);
 | 
			
		||||
    {
 | 
			
		||||
        std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
 | 
			
		||||
        std::scoped_lock lock{LockCaches()};
 | 
			
		||||
        texture_cache.BindToChannel(channel_id);
 | 
			
		||||
        buffer_cache.BindToChannel(channel_id);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1512,7 +1514,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
 | 
			
		||||
void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
 | 
			
		||||
    EraseChannel(channel_id);
 | 
			
		||||
    {
 | 
			
		||||
        std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
 | 
			
		||||
        std::scoped_lock lock{LockCaches()};
 | 
			
		||||
        texture_cache.EraseChannel(channel_id);
 | 
			
		||||
        buffer_cache.EraseChannel(channel_id);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -133,6 +133,10 @@ public:
 | 
			
		||||
 | 
			
		||||
    void ReleaseChannel(s32 channel_id) override;
 | 
			
		||||
 | 
			
		||||
    std::scoped_lock<std::recursive_mutex, std::recursive_mutex> LockCaches() {
 | 
			
		||||
        return std::scoped_lock{buffer_cache.mutex, texture_cache.mutex};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static constexpr size_t MAX_TEXTURES = 192;
 | 
			
		||||
    static constexpr size_t MAX_IMAGES = 48;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user