From 1adcd47dcbd80e0435d42e61dab3f00a22d1ca38 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 9 Feb 2018 20:52:25 +1000 Subject: Renderer: Add a base Initialize() method to match Shutdown() --- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/Renderer.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index ce52b0718d..5e1250549a 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -57,13 +57,7 @@ Renderer::Renderer(std::unique_ptr swap_chain) m_sampler_states[i].hex = RenderState::GetPointSamplerState().hex; } -Renderer::~Renderer() -{ - UpdateActiveConfig(); - - DestroyShaders(); - DestroySemaphores(); -} +Renderer::~Renderer() = default; Renderer* Renderer::GetInstance() { @@ -77,6 +71,9 @@ bool Renderer::IsHeadless() const bool Renderer::Initialize() { + if (!::Renderer::Initialize()) + return false; + BindEFBToStateTracker(); if (!CreateSemaphores()) @@ -131,6 +128,18 @@ bool Renderer::Initialize() return true; } +void Renderer::Shutdown() +{ + ::Renderer::Shutdown(); + + // Submit the current command buffer, in case there's a partial frame. + StateTracker::GetInstance()->EndRenderPass(); + g_command_buffer_mgr->ExecuteCommandBuffer(false, true); + + DestroyShaders(); + DestroySemaphores(); +} + bool Renderer::CreateSemaphores() { // Create two semaphores, one that is triggered when the swapchain buffer is ready, another after -- cgit v1.2.3 From 2644e920cca0fb4cb55d08b2c1920d8595140eb3 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 9 Sep 2017 16:09:24 +1000 Subject: Renderer: Add backbuffer format to base class --- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 43 +++++++++++++++++++-------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/Renderer.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 5e1250549a..a49052d2e5 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -49,7 +49,8 @@ namespace Vulkan { Renderer::Renderer(std::unique_ptr swap_chain) : ::Renderer(swap_chain ? static_cast(swap_chain->GetWidth()) : 1, - swap_chain ? static_cast(swap_chain->GetHeight()) : 0), + swap_chain ? static_cast(swap_chain->GetHeight()) : 0, + swap_chain ? swap_chain->GetTextureFormat() : AbstractTextureFormat::Undefined), m_swap_chain(std::move(swap_chain)) { UpdateActiveConfig(); @@ -95,6 +96,23 @@ bool Renderer::Initialize() return false; } + // Swap chain render pass. + if (m_swap_chain) + { + m_swap_chain_render_pass = + g_object_cache->GetRenderPass(m_swap_chain->GetSurfaceFormat().format, VK_FORMAT_UNDEFINED, + 1, VK_ATTACHMENT_LOAD_OP_LOAD); + m_swap_chain_clear_render_pass = + g_object_cache->GetRenderPass(m_swap_chain->GetSurfaceFormat().format, VK_FORMAT_UNDEFINED, + 1, VK_ATTACHMENT_LOAD_OP_CLEAR); + if (m_swap_chain_render_pass == VK_NULL_HANDLE || + m_swap_chain_clear_render_pass == VK_NULL_HANDLE) + { + PanicAlert("Failed to create swap chain render passes."); + return false; + } + } + m_bounding_box = std::make_unique(); if (!m_bounding_box->Initialize()) { @@ -398,7 +416,7 @@ void Renderer::RenderText(const std::string& text, int left, int top, u32 color) u32 backbuffer_width = m_swap_chain->GetWidth(); u32 backbuffer_height = m_swap_chain->GetHeight(); - m_raster_font->PrintMultiLineText(m_swap_chain->GetRenderPass(), text, + m_raster_font->PrintMultiLineText(m_swap_chain_render_pass, text, left * 2.0f / static_cast(backbuffer_width) - 1, 1 - top * 2.0f / static_cast(backbuffer_height), backbuffer_width, backbuffer_height, color); @@ -816,20 +834,18 @@ void Renderer::DrawScreen(VKTexture* xfb_texture, const EFBRectangle& xfb_region m_current_framebuffer_width = backbuffer->GetWidth(); m_current_framebuffer_height = backbuffer->GetHeight(); + // Draw to the backbuffer. + VkRect2D region = {{0, 0}, {backbuffer->GetWidth(), backbuffer->GetHeight()}}; + StateTracker::GetInstance()->SetRenderPass(m_swap_chain_render_pass, + m_swap_chain_clear_render_pass); + StateTracker::GetInstance()->SetFramebuffer(m_swap_chain->GetCurrentFramebuffer(), region); + // Begin render pass for rendering to the swap chain. VkClearValue clear_value = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; - VkRenderPassBeginInfo info = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - nullptr, - m_swap_chain->GetRenderPass(), - m_swap_chain->GetCurrentFramebuffer(), - {{0, 0}, {backbuffer->GetWidth(), backbuffer->GetHeight()}}, - 1, - &clear_value}; - vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &info, - VK_SUBPASS_CONTENTS_INLINE); + StateTracker::GetInstance()->BeginClearRenderPass(region, &clear_value, 1); // Draw - BlitScreen(m_swap_chain->GetRenderPass(), GetTargetRectangle(), xfb_region, + BlitScreen(m_swap_chain_render_pass, GetTargetRectangle(), xfb_region, xfb_texture->GetRawTexIdentifier()); // Draw OSD @@ -840,7 +856,8 @@ void Renderer::DrawScreen(VKTexture* xfb_texture, const EFBRectangle& xfb_region OSD::DrawMessages(); // End drawing to backbuffer - vkCmdEndRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer()); + StateTracker::GetInstance()->EndRenderPass(); + BindEFBToStateTracker(); // Transition the backbuffer to PRESENT_SRC to ensure all commands drawing // to it have finished before present. -- cgit v1.2.3 From 5ca18ff04e6dd69e09a5675db8f9474a51bdfcc0 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 10 Oct 2018 19:40:47 +1000 Subject: Vulkan: Restore viewport/scissor state on RestoreAPIState --- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Source/Core/VideoBackends/Vulkan/Renderer.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index a49052d2e5..764250cbe9 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -857,7 +857,6 @@ void Renderer::DrawScreen(VKTexture* xfb_texture, const EFBRectangle& xfb_region // End drawing to backbuffer StateTracker::GetInstance()->EndRenderPass(); - BindEFBToStateTracker(); // Transition the backbuffer to PRESENT_SRC to ensure all commands drawing // to it have finished before present. @@ -1047,6 +1046,8 @@ void Renderer::RestoreAPIState() static_cast(m_current_framebuffer)->TransitionForSample(); BindEFBToStateTracker(); + BPFunctions::SetViewport(); + BPFunctions::SetScissor(); // Instruct the state tracker to re-bind everything before the next draw StateTracker::GetInstance()->SetPendingRebind(); -- cgit v1.2.3 From 7afd5cc2fb7e45f2c497e5aed007a017b8461335 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 27 Nov 2018 17:16:53 +1000 Subject: Use main buffers for utility draws --- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 169 +++----------------------- 1 file changed, 17 insertions(+), 152 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/Renderer.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 764250cbe9..6bec599882 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -259,158 +259,6 @@ void Renderer::SetPipeline(const AbstractPipeline* pipeline) StateTracker::GetInstance()->SetPipeline(static_cast(pipeline)); } -void Renderer::DrawUtilityPipeline(const void* uniforms, u32 uniforms_size, const void* vertices, - u32 vertex_stride, u32 num_vertices) -{ - // Binding the utility pipeline layout breaks the standard layout. - StateTracker::GetInstance()->SetPendingRebind(); - - // Upload uniforms. - VkBuffer uniform_buffer = g_object_cache->GetUtilityShaderUniformBuffer()->GetBuffer(); - u32 uniform_buffer_offset = 0; - if (uniforms_size > 0) - std::tie(uniform_buffer, uniform_buffer_offset) = - UpdateUtilityUniformBuffer(uniforms, uniforms_size); - - // Upload vertices. - VkBuffer vertex_buffer = VK_NULL_HANDLE; - VkDeviceSize vertex_buffer_offset = 0; - if (vertices) - { - u32 vertices_size = vertex_stride * num_vertices; - StreamBuffer* vbo_buf = g_object_cache->GetUtilityShaderVertexBuffer(); - if (!vbo_buf->ReserveMemory(vertices_size, vertex_stride)) - { - Util::ExecuteCurrentCommandsAndRestoreState(true); - if (!vbo_buf->ReserveMemory(vertices_size, vertex_stride)) - { - PanicAlert("Failed to reserve vertex buffer space for utility draw."); - return; - } - } - - vertex_buffer = vbo_buf->GetBuffer(); - vertex_buffer_offset = vbo_buf->GetCurrentOffset(); - std::memcpy(vbo_buf->GetCurrentHostPointer(), vertices, vertices_size); - vbo_buf->CommitMemory(vertices_size); - } - - // Allocate descriptor sets. - std::array dsets; - dsets[0] = g_command_buffer_mgr->AllocateDescriptorSet( - g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_SINGLE_UNIFORM_BUFFER)); - dsets[1] = g_command_buffer_mgr->AllocateDescriptorSet( - g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_PIXEL_SHADER_SAMPLERS)); - - // Flush first if failed. - if (dsets[0] == VK_NULL_HANDLE || dsets[1] == VK_NULL_HANDLE) - { - Util::ExecuteCurrentCommandsAndRestoreState(true); - dsets[0] = g_command_buffer_mgr->AllocateDescriptorSet( - g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_SINGLE_UNIFORM_BUFFER)); - dsets[1] = g_command_buffer_mgr->AllocateDescriptorSet( - g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_PIXEL_SHADER_SAMPLERS)); - - if (dsets[0] == VK_NULL_HANDLE || dsets[1] == VK_NULL_HANDLE) - { - PanicAlert("Failed to allocate descriptor sets in utility draw."); - return; - } - } - - // Build UBO descriptor set. - std::array dswrites; - VkDescriptorBufferInfo dsbuffer = {uniform_buffer, 0, std::max(uniforms_size, 4u)}; - dswrites[0] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, dsets[0], 0, 0, 1, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, nullptr, &dsbuffer, nullptr}; - dswrites[1] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - nullptr, - dsets[1], - 0, - 0, - NUM_PIXEL_SHADER_SAMPLERS, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - StateTracker::GetInstance()->GetPSSamplerBindings().data(), - nullptr, - nullptr}; - - // Build commands. - VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - StateTracker::GetInstance()->GetPipeline()->GetVkPipeline()); - if (vertex_buffer != VK_NULL_HANDLE) - vkCmdBindVertexBuffers(command_buffer, 0, 1, &vertex_buffer, &vertex_buffer_offset); - - // Update and bind descriptors. - VkPipelineLayout pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_UTILITY); - vkUpdateDescriptorSets(g_vulkan_context->GetDevice(), static_cast(dswrites.size()), - dswrites.data(), 0, nullptr); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, - static_cast(dsets.size()), dsets.data(), 1, &uniform_buffer_offset); - - // Ensure we're in a render pass before drawing, just in case we had to flush. - StateTracker::GetInstance()->BeginRenderPass(); - vkCmdDraw(command_buffer, num_vertices, 1, 0, 0); -} - -void Renderer::DispatchComputeShader(const AbstractShader* shader, const void* uniforms, - u32 uniforms_size, u32 groups_x, u32 groups_y, u32 groups_z) -{ - // Binding the utility pipeline layout breaks the standard layout. - StateTracker::GetInstance()->SetPendingRebind(); - StateTracker::GetInstance()->EndRenderPass(); - - // Upload uniforms. - VkBuffer uniform_buffer = g_object_cache->GetUtilityShaderUniformBuffer()->GetBuffer(); - u32 uniform_buffer_offset = 0; - if (uniforms_size > 0) - std::tie(uniform_buffer, uniform_buffer_offset) = - UpdateUtilityUniformBuffer(uniforms, uniforms_size); - - // Flush first if failed. - VkDescriptorSet dset = g_command_buffer_mgr->AllocateDescriptorSet( - g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_COMPUTE)); - if (dset == VK_NULL_HANDLE) - { - Util::ExecuteCurrentCommandsAndRestoreState(true); - dset = g_command_buffer_mgr->AllocateDescriptorSet( - g_object_cache->GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT_COMPUTE)); - if (dset == VK_NULL_HANDLE) - { - PanicAlert("Failed to allocate descriptor sets in utility dispatch."); - return; - } - } - - std::array dswrites; - VkDescriptorBufferInfo dsbuffer = {uniform_buffer, 0, std::max(uniforms_size, 4u)}; - dswrites[0] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, dset, 0, 0, 1, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, nullptr, &dsbuffer, nullptr}; - dswrites[1] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - nullptr, - dset, - 1, - 0, - NUM_PIXEL_SHADER_SAMPLERS, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - StateTracker::GetInstance()->GetPSSamplerBindings().data(), - nullptr, - nullptr}; - - // TODO: Texel buffers, storage images. - - // Build commands. - VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); - VkPipelineLayout pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_UTILITY); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, - static_cast(shader)->GetComputePipeline()); - vkUpdateDescriptorSets(g_vulkan_context->GetDevice(), static_cast(dswrites.size()), - dswrites.data(), 0, nullptr); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, 0, 1, - &dset, 1, &uniform_buffer_offset); - vkCmdDispatch(command_buffer, groups_x, groups_y, groups_z); -} - void Renderer::RenderText(const std::string& text, int left, int top, u32 color) { u32 backbuffer_width = m_swap_chain->GetWidth(); @@ -1185,6 +1033,23 @@ void Renderer::SetViewport(float x, float y, float width, float height, float ne StateTracker::GetInstance()->SetViewport(viewport); } +void Renderer::Draw(u32 base_vertex, u32 num_vertices) +{ + if (StateTracker::GetInstance()->Bind()) + return; + + vkCmdDraw(g_command_buffer_mgr->GetCurrentCommandBuffer(), num_vertices, 1, base_vertex, 0); +} + +void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) +{ + if (!StateTracker::GetInstance()->Bind()) + return; + + vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), num_indices, 1, base_index, + base_vertex, 0); +} + void Renderer::RecompileShaders() { DestroyShaders(); -- cgit v1.2.3