From 3956b21cb74386bb2621cdfc1cebcc1cf65e7670 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 11 Jun 2016 16:24:27 +0300 Subject: [PATCH] vk/gl/dx12: Dynamic cb flush for vulkan; fix glsl/hlsl vertex shader generation for some games; dx12: ignore fbo textures during flip if no surface target is set (#1766) * gl/vk/dx12: Fix vertex shader code generation for buggy games dx12: revert vsh attribute changes * vk: dynamically flush command buffers if we exceed available resources * dx12: do not prepare flip texture if it has not been initialized --- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 29 +++++++++++++++------------ rpcs3/Emu/RSX/GL/GLVertexProgram.cpp | 2 +- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 29 ++++++++++++++++++++++----- rpcs3/Emu/RSX/VK/VKGSRender.h | 1 + rpcs3/Emu/RSX/VK/VKHelpers.h | 3 ++- rpcs3/Emu/RSX/VK/VKVertexProgram.cpp | 2 +- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 8f71e92e44..c0ab86bc4e 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -508,23 +508,26 @@ void D3D12GSRender::flip(int buffer) memcpy((char*)mapped_buffer + row * row_pitch, (char*)src_buffer + row * w * 4, w * 4); m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + texture_size)); offset = heap_offset; - } - CHECK_HRESULT( - m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, 1), - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(storage.ram_framebuffer.GetAddressOf()) + CHECK_HRESULT( + m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, 1), + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, + IID_PPV_ARGS(storage.ram_framebuffer.GetAddressOf()) ) ); - get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.ram_framebuffer.Get(), 0), 0, 0, 0, - &CD3DX12_TEXTURE_COPY_LOCATION(m_buffer_data.get_heap(), { offset, { DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)row_pitch } }), nullptr); + get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(storage.ram_framebuffer.Get(), 0), 0, 0, 0, + &CD3DX12_TEXTURE_COPY_LOCATION(m_buffer_data.get_heap(), { offset,{ DXGI_FORMAT_R8G8B8A8_UNORM, (UINT)w, (UINT)h, 1, (UINT)row_pitch } }), nullptr); + + get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(storage.ram_framebuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ)); + resource_to_flip = storage.ram_framebuffer.Get(); + } + else + resource_to_flip = nullptr; - get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(storage.ram_framebuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ)); - resource_to_flip = storage.ram_framebuffer.Get(); viewport_w = (float)w, viewport_h = (float)h; } else diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 94be8b220b..7a72a78f64 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -173,7 +173,7 @@ void add_input(std::stringstream & OS, const ParamItem &PI, const std::vector sizes{ uniform_buffer_pool, uniform_texel_pool, texture_pool }; @@ -507,6 +507,24 @@ void VKGSRender::begin() //TODO: Fence sync, ring-buffers, etc //CHECK_RESULT(vkDeviceWaitIdle((*m_device))); + //Ease resource pressure if the number of draw calls becomes too high + if (m_used_descriptors >= DESCRIPTOR_MAX_DRAW_CALLS) + { + close_and_submit_command_buffer({}, m_submit_fence); + CHECK_RESULT(vkWaitForFences((*m_device), 1, &m_submit_fence, VK_TRUE, ~0ULL)); + + vkResetDescriptorPool(*m_device, descriptor_pool, 0); + CHECK_RESULT(vkResetFences(*m_device, 1, &m_submit_fence)); + CHECK_RESULT(vkResetCommandPool(*m_device, m_command_buffer_pool, 0)); + open_command_buffer(); + + m_used_descriptors = 0; + m_uniform_buffer_ring_info.m_get_pos = m_uniform_buffer_ring_info.get_current_put_pos_minus_one(); + m_index_buffer_ring_info.m_get_pos = m_index_buffer_ring_info.get_current_put_pos_minus_one(); + m_attrib_ring_info.m_get_pos = m_attrib_ring_info.get_current_put_pos_minus_one(); + m_texture_upload_buffer_ring_info.m_get_pos = m_texture_upload_buffer_ring_info.get_current_put_pos_minus_one(); + } + VkDescriptorSetAllocateInfo alloc_info = {}; alloc_info.descriptorPool = descriptor_pool; alloc_info.descriptorSetCount = 1; @@ -514,7 +532,6 @@ void VKGSRender::begin() alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; VkDescriptorSet new_descriptor_set; - CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &new_descriptor_set)); descriptor_sets = new_descriptor_set; @@ -532,6 +549,7 @@ void VKGSRender::begin() //TODO: Set up other render-state parameters into the program pipeline m_draw_calls++; + m_used_descriptors++; } namespace @@ -1210,5 +1228,6 @@ void VKGSRender::flip(int buffer) open_command_buffer(); m_draw_calls = 0; + m_used_descriptors = 0; m_frame->flip(m_context); } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 7c2142b54a..3788265446 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -70,6 +70,7 @@ private: std::vector > m_sampler_to_clean; u32 m_draw_calls = 0; + u32 m_used_descriptors = 0; u8 m_draw_buffers_count = 0; public: diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index f8d3d2e53b..e57be7f091 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -14,6 +14,7 @@ #include "../Common/TextureUtils.h" #include "../Common/ring_buffer_helper.h" +#define DESCRIPTOR_MAX_DRAW_CALLS 1024 extern cfg::bool_entry g_cfg_rsx_debug_output; namespace rsx @@ -1212,7 +1213,7 @@ namespace vk { VkDescriptorPoolCreateInfo infos = {}; infos.flags = 0; - infos.maxSets = 1000; + infos.maxSets = DESCRIPTOR_MAX_DRAW_CALLS; infos.poolSizeCount = size_descriptors_count; infos.pPoolSizes = sizes; infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index 0d92043266..06e68c15c4 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -208,7 +208,7 @@ namespace vk return; } - OS << " vec4 " << PI.name << " = vec4(0., 0., 0., 1.);" << std::endl; + OS << " vec4 " << PI.name << "= texelFetch(" << PI.name << "_buffer, gl_VertexIndex).rgba;" << std::endl; } }