diff options
Diffstat (limited to 'src/video_core')
4 files changed, 53 insertions, 45 deletions
| diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 056ef495c..91e7b7791 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -179,10 +179,11 @@ Tegra::Engines::ConstBufferEngineInterface& CachedShader::GetEngine(  VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer,                                   const VKDevice& device, VKScheduler& scheduler,                                   VKDescriptorPool& descriptor_pool, -                                 VKUpdateDescriptorQueue& update_descriptor_queue) +                                 VKUpdateDescriptorQueue& update_descriptor_queue, +                                 VKRenderPassCache& renderpass_cache)      : RasterizerCache{rasterizer}, system{system}, device{device}, scheduler{scheduler},        descriptor_pool{descriptor_pool}, update_descriptor_queue{update_descriptor_queue}, -      renderpass_cache(device) {} +      renderpass_cache{renderpass_cache} {}  VKPipelineCache::~VKPipelineCache() = default; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 21340c9a4..c4c112290 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -161,7 +161,8 @@ public:      explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer,                               const VKDevice& device, VKScheduler& scheduler,                               VKDescriptorPool& descriptor_pool, -                             VKUpdateDescriptorQueue& update_descriptor_queue); +                             VKUpdateDescriptorQueue& update_descriptor_queue, +                             VKRenderPassCache& renderpass_cache);      ~VKPipelineCache();      std::array<Shader, Maxwell::MaxShaderProgram> GetShaders(); @@ -184,8 +185,7 @@ private:      VKScheduler& scheduler;      VKDescriptorPool& descriptor_pool;      VKUpdateDescriptorQueue& update_descriptor_queue; - -    VKRenderPassCache renderpass_cache; +    VKRenderPassCache& renderpass_cache;      std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index c9886cc16..755aad643 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -287,12 +287,13 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind        screen_info{screen_info}, device{device}, resource_manager{resource_manager},        memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler},        staging_pool(device, memory_manager, scheduler), descriptor_pool(device), -      update_descriptor_queue(device, scheduler), +      update_descriptor_queue(device, scheduler), renderpass_cache(device),        quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),        uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),        texture_cache(system, *this, device, resource_manager, memory_manager, scheduler,                      staging_pool), -      pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue), +      pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, +                     renderpass_cache),        buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool),        sampler_cache(device), query_cache(system, *this, device, scheduler) {      scheduler.SetQueryCache(query_cache); @@ -365,13 +366,16 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {  void RasterizerVulkan::Clear() {      MICROPROFILE_SCOPE(Vulkan_Clearing); -    query_cache.UpdateCounters(); -      const auto& gpu = system.GPU().Maxwell3D();      if (!system.GPU().Maxwell3D().ShouldExecute()) {          return;      } +    sampled_views.clear(); +    image_views.clear(); + +    query_cache.UpdateCounters(); +      const auto& regs = gpu.regs;      const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||                             regs.clear_buffers.A; @@ -380,52 +384,54 @@ void RasterizerVulkan::Clear() {      if (!use_color && !use_depth && !use_stencil) {          return;      } -    // Clearing images requires to be out of a renderpass -    scheduler.RequestOutsideRenderPassOperationContext(); -    // TODO(Rodrigo): Implement clears rendering a quad or using beginning a renderpass. +    [[maybe_unused]] const auto texceptions = UpdateAttachments(); +    DEBUG_ASSERT(texceptions.none()); +    SetupImageTransitions(0, color_attachments, zeta_attachment); -    if (use_color) { -        View color_view; -        { -            MICROPROFILE_SCOPE(Vulkan_RenderTargets); -            color_view = texture_cache.GetColorBufferSurface(regs.clear_buffers.RT.Value(), false); -        } +    const vk::RenderPass renderpass = renderpass_cache.GetRenderPass(GetRenderPassParams(0)); +    const auto [framebuffer, render_area] = ConfigureFramebuffers(renderpass); +    scheduler.RequestRenderpass({renderpass, framebuffer, {{0, 0}, render_area}, 0, nullptr}); + +    const auto& scissor = regs.scissor_test[0]; +    const vk::Offset2D scissor_offset(scissor.min_x, scissor.min_y); +    vk::Extent2D scissor_extent{scissor.max_x - scissor.min_x, scissor.max_y - scissor.min_y}; +    scissor_extent.width = std::min(scissor_extent.width, render_area.width); +    scissor_extent.height = std::min(scissor_extent.height, render_area.height); -        color_view->Transition(vk::ImageLayout::eTransferDstOptimal, -                               vk::PipelineStageFlagBits::eTransfer, -                               vk::AccessFlagBits::eTransferWrite); +    const u32 layer = regs.clear_buffers.layer; +    const vk::ClearRect clear_rect({scissor_offset, scissor_extent}, layer, 1); +    if (use_color) {          const std::array clear_color = {regs.clear_color[0], regs.clear_color[1],                                          regs.clear_color[2], regs.clear_color[3]}; -        const vk::ClearColorValue clear(clear_color); -        scheduler.Record([image = color_view->GetImage(), -                          subresource = color_view->GetImageSubresourceRange(), -                          clear](auto cmdbuf, auto& dld) { -            cmdbuf.clearColorImage(image, vk::ImageLayout::eTransferDstOptimal, clear, subresource, -                                   dld); +        const vk::ClearValue clear_value{clear_color}; +        const u32 color_attachment = regs.clear_buffers.RT; +        scheduler.Record([color_attachment, clear_value, clear_rect](auto cmdbuf, auto& dld) { +            const vk::ClearAttachment attachment(vk::ImageAspectFlagBits::eColor, color_attachment, +                                                 clear_value); +            cmdbuf.clearAttachments(1, &attachment, 1, &clear_rect, dld);          });      } -    if (use_depth || use_stencil) { -        View zeta_surface; -        { -            MICROPROFILE_SCOPE(Vulkan_RenderTargets); -            zeta_surface = texture_cache.GetDepthBufferSurface(false); -        } -        zeta_surface->Transition(vk::ImageLayout::eTransferDstOptimal, -                                 vk::PipelineStageFlagBits::eTransfer, -                                 vk::AccessFlagBits::eTransferWrite); - -        const vk::ClearDepthStencilValue clear(regs.clear_depth, -                                               static_cast<u32>(regs.clear_stencil)); -        scheduler.Record([image = zeta_surface->GetImage(), -                          subresource = zeta_surface->GetImageSubresourceRange(), -                          clear](auto cmdbuf, auto& dld) { -            cmdbuf.clearDepthStencilImage(image, vk::ImageLayout::eTransferDstOptimal, clear, -                                          subresource, dld); -        }); +    if (!use_depth && !use_stencil) { +        return; +    } +    vk::ImageAspectFlags aspect_flags; +    if (use_depth) { +        aspect_flags |= vk::ImageAspectFlagBits::eDepth; +    } +    if (use_stencil) { +        aspect_flags |= vk::ImageAspectFlagBits::eStencil;      } + +    scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil, +                      clear_rect, aspect_flags](auto cmdbuf, auto& dld) { +        const vk::ClearDepthStencilValue clear_zeta(clear_depth, clear_stencil); +        const vk::ClearValue clear_value{clear_zeta}; +        const vk::ClearAttachment attachment(aspect_flags, 0, clear_value); +        cmdbuf.clearAttachments(1, &attachment, 1, &clear_rect, dld); +    });  }  void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index b2e73d98d..3185868e9 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -253,6 +253,7 @@ private:      VKStagingBufferPool staging_pool;      VKDescriptorPool descriptor_pool;      VKUpdateDescriptorQueue update_descriptor_queue; +    VKRenderPassCache renderpass_cache;      QuadArrayPass quad_array_pass;      Uint8Pass uint8_pass; | 
