summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Mat M2020-03-17 17:27:15 -0400
committerGravatar GitHub2020-03-17 17:27:15 -0400
commitd787856621348048f73ef5e6d5aaa868a9b52d40 (patch)
treef994ebf6ef329c5fdc6d61ffe2901cec50130b67
parentMerge pull request #3519 from ReinUsesLisp/int-formats (diff)
parentvk_rasterizer: Implement layered clears (diff)
downloadyuzu-d787856621348048f73ef5e6d5aaa868a9b52d40.tar.gz
yuzu-d787856621348048f73ef5e6d5aaa868a9b52d40.tar.xz
yuzu-d787856621348048f73ef5e6d5aaa868a9b52d40.zip
Merge pull request #3518 from ReinUsesLisp/scissor-clears
vk_rasterizer: Implement scissor clears and layered clears
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp86
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h1
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(
179VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, 179VKPipelineCache::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
187VKPipelineCache::~VKPipelineCache() = default; 188VKPipelineCache::~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) {
365void RasterizerVulkan::Clear() { 366void 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
431void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) { 437void 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