diff options
Diffstat (limited to 'src')
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( | |||
| 179 | VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, | 179 | VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, |
| 180 | const VKDevice& device, VKScheduler& scheduler, | 180 | const VKDevice& device, VKScheduler& scheduler, |
| 181 | VKDescriptorPool& descriptor_pool, | 181 | VKDescriptorPool& descriptor_pool, |
| 182 | VKUpdateDescriptorQueue& update_descriptor_queue) | 182 | VKUpdateDescriptorQueue& update_descriptor_queue, |
| 183 | VKRenderPassCache& renderpass_cache) | ||
| 183 | : RasterizerCache{rasterizer}, system{system}, device{device}, scheduler{scheduler}, | 184 | : RasterizerCache{rasterizer}, system{system}, device{device}, scheduler{scheduler}, |
| 184 | descriptor_pool{descriptor_pool}, update_descriptor_queue{update_descriptor_queue}, | 185 | descriptor_pool{descriptor_pool}, update_descriptor_queue{update_descriptor_queue}, |
| 185 | renderpass_cache(device) {} | 186 | renderpass_cache{renderpass_cache} {} |
| 186 | 187 | ||
| 187 | VKPipelineCache::~VKPipelineCache() = default; | 188 | VKPipelineCache::~VKPipelineCache() = default; |
| 188 | 189 | ||
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: | |||
| 161 | explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, | 161 | explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, |
| 162 | const VKDevice& device, VKScheduler& scheduler, | 162 | const VKDevice& device, VKScheduler& scheduler, |
| 163 | VKDescriptorPool& descriptor_pool, | 163 | VKDescriptorPool& descriptor_pool, |
| 164 | VKUpdateDescriptorQueue& update_descriptor_queue); | 164 | VKUpdateDescriptorQueue& update_descriptor_queue, |
| 165 | VKRenderPassCache& renderpass_cache); | ||
| 165 | ~VKPipelineCache(); | 166 | ~VKPipelineCache(); |
| 166 | 167 | ||
| 167 | std::array<Shader, Maxwell::MaxShaderProgram> GetShaders(); | 168 | std::array<Shader, Maxwell::MaxShaderProgram> GetShaders(); |
| @@ -184,8 +185,7 @@ private: | |||
| 184 | VKScheduler& scheduler; | 185 | VKScheduler& scheduler; |
| 185 | VKDescriptorPool& descriptor_pool; | 186 | VKDescriptorPool& descriptor_pool; |
| 186 | VKUpdateDescriptorQueue& update_descriptor_queue; | 187 | VKUpdateDescriptorQueue& update_descriptor_queue; |
| 187 | 188 | VKRenderPassCache& renderpass_cache; | |
| 188 | VKRenderPassCache renderpass_cache; | ||
| 189 | 189 | ||
| 190 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; | 190 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; |
| 191 | 191 | ||
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 | |||
| 287 | screen_info{screen_info}, device{device}, resource_manager{resource_manager}, | 287 | screen_info{screen_info}, device{device}, resource_manager{resource_manager}, |
| 288 | memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler}, | 288 | memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler}, |
| 289 | staging_pool(device, memory_manager, scheduler), descriptor_pool(device), | 289 | staging_pool(device, memory_manager, scheduler), descriptor_pool(device), |
| 290 | update_descriptor_queue(device, scheduler), | 290 | update_descriptor_queue(device, scheduler), renderpass_cache(device), |
| 291 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 291 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 292 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 292 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 293 | texture_cache(system, *this, device, resource_manager, memory_manager, scheduler, | 293 | texture_cache(system, *this, device, resource_manager, memory_manager, scheduler, |
| 294 | staging_pool), | 294 | staging_pool), |
| 295 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue), | 295 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, |
| 296 | renderpass_cache), | ||
| 296 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), | 297 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), |
| 297 | sampler_cache(device), query_cache(system, *this, device, scheduler) { | 298 | sampler_cache(device), query_cache(system, *this, device, scheduler) { |
| 298 | scheduler.SetQueryCache(query_cache); | 299 | scheduler.SetQueryCache(query_cache); |
| @@ -365,13 +366,16 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 365 | void RasterizerVulkan::Clear() { | 366 | void RasterizerVulkan::Clear() { |
| 366 | MICROPROFILE_SCOPE(Vulkan_Clearing); | 367 | MICROPROFILE_SCOPE(Vulkan_Clearing); |
| 367 | 368 | ||
| 368 | query_cache.UpdateCounters(); | ||
| 369 | |||
| 370 | const auto& gpu = system.GPU().Maxwell3D(); | 369 | const auto& gpu = system.GPU().Maxwell3D(); |
| 371 | if (!system.GPU().Maxwell3D().ShouldExecute()) { | 370 | if (!system.GPU().Maxwell3D().ShouldExecute()) { |
| 372 | return; | 371 | return; |
| 373 | } | 372 | } |
| 374 | 373 | ||
| 374 | sampled_views.clear(); | ||
| 375 | image_views.clear(); | ||
| 376 | |||
| 377 | query_cache.UpdateCounters(); | ||
| 378 | |||
| 375 | const auto& regs = gpu.regs; | 379 | const auto& regs = gpu.regs; |
| 376 | const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || | 380 | const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || |
| 377 | regs.clear_buffers.A; | 381 | regs.clear_buffers.A; |
| @@ -380,52 +384,54 @@ void RasterizerVulkan::Clear() { | |||
| 380 | if (!use_color && !use_depth && !use_stencil) { | 384 | if (!use_color && !use_depth && !use_stencil) { |
| 381 | return; | 385 | return; |
| 382 | } | 386 | } |
| 383 | // Clearing images requires to be out of a renderpass | ||
| 384 | scheduler.RequestOutsideRenderPassOperationContext(); | ||
| 385 | 387 | ||
| 386 | // TODO(Rodrigo): Implement clears rendering a quad or using beginning a renderpass. | 388 | [[maybe_unused]] const auto texceptions = UpdateAttachments(); |
| 389 | DEBUG_ASSERT(texceptions.none()); | ||
| 390 | SetupImageTransitions(0, color_attachments, zeta_attachment); | ||
| 387 | 391 | ||
| 388 | if (use_color) { | 392 | const vk::RenderPass renderpass = renderpass_cache.GetRenderPass(GetRenderPassParams(0)); |
| 389 | View color_view; | 393 | const auto [framebuffer, render_area] = ConfigureFramebuffers(renderpass); |
| 390 | { | 394 | scheduler.RequestRenderpass({renderpass, framebuffer, {{0, 0}, render_area}, 0, nullptr}); |
| 391 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); | 395 | |
| 392 | color_view = texture_cache.GetColorBufferSurface(regs.clear_buffers.RT.Value(), false); | 396 | const auto& scissor = regs.scissor_test[0]; |
| 393 | } | 397 | const vk::Offset2D scissor_offset(scissor.min_x, scissor.min_y); |
| 398 | vk::Extent2D scissor_extent{scissor.max_x - scissor.min_x, scissor.max_y - scissor.min_y}; | ||
| 399 | scissor_extent.width = std::min(scissor_extent.width, render_area.width); | ||
| 400 | scissor_extent.height = std::min(scissor_extent.height, render_area.height); | ||
| 394 | 401 | ||
| 395 | color_view->Transition(vk::ImageLayout::eTransferDstOptimal, | 402 | const u32 layer = regs.clear_buffers.layer; |
| 396 | vk::PipelineStageFlagBits::eTransfer, | 403 | const vk::ClearRect clear_rect({scissor_offset, scissor_extent}, layer, 1); |
| 397 | vk::AccessFlagBits::eTransferWrite); | ||
| 398 | 404 | ||
| 405 | if (use_color) { | ||
| 399 | const std::array clear_color = {regs.clear_color[0], regs.clear_color[1], | 406 | const std::array clear_color = {regs.clear_color[0], regs.clear_color[1], |
| 400 | regs.clear_color[2], regs.clear_color[3]}; | 407 | regs.clear_color[2], regs.clear_color[3]}; |
| 401 | const vk::ClearColorValue clear(clear_color); | 408 | const vk::ClearValue clear_value{clear_color}; |
| 402 | scheduler.Record([image = color_view->GetImage(), | 409 | const u32 color_attachment = regs.clear_buffers.RT; |
| 403 | subresource = color_view->GetImageSubresourceRange(), | 410 | scheduler.Record([color_attachment, clear_value, clear_rect](auto cmdbuf, auto& dld) { |
| 404 | clear](auto cmdbuf, auto& dld) { | 411 | const vk::ClearAttachment attachment(vk::ImageAspectFlagBits::eColor, color_attachment, |
| 405 | cmdbuf.clearColorImage(image, vk::ImageLayout::eTransferDstOptimal, clear, subresource, | 412 | clear_value); |
| 406 | dld); | 413 | cmdbuf.clearAttachments(1, &attachment, 1, &clear_rect, dld); |
| 407 | }); | 414 | }); |
| 408 | } | 415 | } |
| 409 | if (use_depth || use_stencil) { | ||
| 410 | View zeta_surface; | ||
| 411 | { | ||
| 412 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); | ||
| 413 | zeta_surface = texture_cache.GetDepthBufferSurface(false); | ||
| 414 | } | ||
| 415 | 416 | ||
| 416 | zeta_surface->Transition(vk::ImageLayout::eTransferDstOptimal, | 417 | if (!use_depth && !use_stencil) { |
| 417 | vk::PipelineStageFlagBits::eTransfer, | 418 | return; |
| 418 | vk::AccessFlagBits::eTransferWrite); | 419 | } |
| 419 | 420 | vk::ImageAspectFlags aspect_flags; | |
| 420 | const vk::ClearDepthStencilValue clear(regs.clear_depth, | 421 | if (use_depth) { |
| 421 | static_cast<u32>(regs.clear_stencil)); | 422 | aspect_flags |= vk::ImageAspectFlagBits::eDepth; |
| 422 | scheduler.Record([image = zeta_surface->GetImage(), | 423 | } |
| 423 | subresource = zeta_surface->GetImageSubresourceRange(), | 424 | if (use_stencil) { |
| 424 | clear](auto cmdbuf, auto& dld) { | 425 | aspect_flags |= vk::ImageAspectFlagBits::eStencil; |
| 425 | cmdbuf.clearDepthStencilImage(image, vk::ImageLayout::eTransferDstOptimal, clear, | ||
| 426 | subresource, dld); | ||
| 427 | }); | ||
| 428 | } | 426 | } |
| 427 | |||
| 428 | scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil, | ||
| 429 | clear_rect, aspect_flags](auto cmdbuf, auto& dld) { | ||
| 430 | const vk::ClearDepthStencilValue clear_zeta(clear_depth, clear_stencil); | ||
| 431 | const vk::ClearValue clear_value{clear_zeta}; | ||
| 432 | const vk::ClearAttachment attachment(aspect_flags, 0, clear_value); | ||
| 433 | cmdbuf.clearAttachments(1, &attachment, 1, &clear_rect, dld); | ||
| 434 | }); | ||
| 429 | } | 435 | } |
| 430 | 436 | ||
| 431 | void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) { | 437 | 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: | |||
| 253 | VKStagingBufferPool staging_pool; | 253 | VKStagingBufferPool staging_pool; |
| 254 | VKDescriptorPool descriptor_pool; | 254 | VKDescriptorPool descriptor_pool; |
| 255 | VKUpdateDescriptorQueue update_descriptor_queue; | 255 | VKUpdateDescriptorQueue update_descriptor_queue; |
| 256 | VKRenderPassCache renderpass_cache; | ||
| 256 | QuadArrayPass quad_array_pass; | 257 | QuadArrayPass quad_array_pass; |
| 257 | Uint8Pass uint8_pass; | 258 | Uint8Pass uint8_pass; |
| 258 | 259 | ||