From f665c921144264ba2ed0fef37d9db28d552a5511 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 22 Apr 2020 20:14:35 -0300 Subject: vk_renderpass_cache: Pack renderpass cache key to 12 bytes --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 29 +++++++----------------- 1 file changed, 8 insertions(+), 21 deletions(-) (limited to 'src/video_core/renderer_vulkan/vk_rasterizer.cpp') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8a1f57891..ef21b186b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1245,28 +1245,15 @@ std::size_t RasterizerVulkan::CalculateConstBufferSize( } RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { - using namespace VideoCore::Surface; - const auto& regs = system.GPU().Maxwell3D().regs; - RenderPassParams renderpass_params; - - for (std::size_t rt = 0; rt < static_cast(regs.rt_control.count); ++rt) { - const auto& rendertarget = regs.rt[rt]; - if (rendertarget.Address() == 0 || rendertarget.format == Tegra::RenderTargetFormat::NONE) { - continue; - } - renderpass_params.color_attachments.push_back(RenderPassParams::ColorAttachment{ - static_cast(rt), PixelFormatFromRenderTargetFormat(rendertarget.format), - texceptions[rt]}); - } - - renderpass_params.has_zeta = regs.zeta_enable; - if (renderpass_params.has_zeta) { - renderpass_params.zeta_pixel_format = PixelFormatFromDepthFormat(regs.zeta.format); - renderpass_params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX]; - } - - return renderpass_params; + RenderPassParams params; + params.num_color_attachments = static_cast(regs.rt_control.count); + std::transform(regs.rt.begin(), regs.rt.end(), params.color_formats.begin(), + [](const auto& rt) { return static_cast(rt.format); }); + params.texceptions = static_cast(texceptions.to_ullong()); + params.zeta_format = regs.zeta_enable ? static_cast(regs.zeta.format) : 0; + params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX]; + return params; } } // namespace Vulkan -- cgit v1.2.3 From 8c37cd1af689ce0ff0cd37e4579508a898ea3807 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 22 Apr 2020 20:52:29 -0300 Subject: vk_pipeline_cache: Unify pipeline cache keys into a single operation This allows us to call Common::CityHash and std::memcmp only once for GraphicsPipelineCacheKey. While we are at it, do the same for compute. --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/video_core/renderer_vulkan/vk_rasterizer.cpp') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index ef21b186b..8a5482e55 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -316,7 +316,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { query_cache.UpdateCounters(); const auto& gpu = system.GPU().Maxwell3D(); - GraphicsPipelineCacheKey key{GetFixedPipelineState(gpu.regs)}; + GraphicsPipelineCacheKey key; + key.fixed_state.Fill(gpu.regs); buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed)); @@ -334,10 +335,11 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { buffer_cache.Unmap(); - const auto texceptions = UpdateAttachments(); + const Texceptions texceptions = UpdateAttachments(); SetupImageTransitions(texceptions, color_attachments, zeta_attachment); key.renderpass_params = GetRenderPassParams(texceptions); + key.padding = 0; auto& pipeline = pipeline_cache.GetGraphicsPipeline(key); scheduler.BindGraphicsPipeline(pipeline.GetHandle()); @@ -453,10 +455,12 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) { query_cache.UpdateCounters(); const auto& launch_desc = system.GPU().KeplerCompute().launch_description; - const ComputePipelineCacheKey key{ - code_addr, - launch_desc.shared_alloc, - {launch_desc.block_dim_x, launch_desc.block_dim_y, launch_desc.block_dim_z}}; + ComputePipelineCacheKey key; + key.shader = code_addr; + key.shared_memory_size = launch_desc.shared_alloc; + key.workgroup_size = {launch_desc.block_dim_x, launch_desc.block_dim_y, + launch_desc.block_dim_z}; + auto& pipeline = pipeline_cache.GetComputePipeline(key); // Compute dispatches can't be executed inside a renderpass -- cgit v1.2.3 From 3e35101895aed4e0cf2be3f90459fbad6e417203 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 22 Apr 2020 21:21:10 -0300 Subject: vk_rasterizer: Fix framebuffer creation validation errors Framebuffer creation was ignoring the number of color attachments. --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_vulkan/vk_rasterizer.cpp') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8a5482e55..8f4de5665 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -692,7 +692,7 @@ std::tuple RasterizerVulkan::ConfigureFramebuffers( FramebufferCacheKey key{renderpass, std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()}; - const auto try_push = [&](const View& view) { + const auto try_push = [&key](const View& view) { if (!view) { return false; } @@ -703,7 +703,9 @@ std::tuple RasterizerVulkan::ConfigureFramebuffers( return true; }; - for (std::size_t index = 0; index < std::size(color_attachments); ++index) { + const auto& regs = system.GPU().Maxwell3D().regs; + const std::size_t num_attachments = static_cast(regs.rt_control.count); + for (std::size_t index = 0; index < num_attachments; ++index) { if (try_push(color_attachments[index])) { texture_cache.MarkColorBufferInUse(index); } -- cgit v1.2.3 From 527a1574c3f1262a6b6b010fa8234a701b299609 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 24 Apr 2020 22:16:49 -0300 Subject: vk_rasterizer: Pack texceptions and color formats on invalid formats Sometimes for unknown reasons NVN games can bind a render target format of 0. This may be a yuzu bug. With the commits before this the formats were specified without being "packed", assuming all formats and texceptions will be written like in the color_attachments vector. To address this issue, iterate all render targets and pack them as they are valid. This way they will match color_attachments. - Fixes validation errors and graphical issues on Breath of the Wild. --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_vulkan/vk_rasterizer.cpp') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8f4de5665..4eafdc14d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1252,11 +1252,25 @@ std::size_t RasterizerVulkan::CalculateConstBufferSize( RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { const auto& regs = system.GPU().Maxwell3D().regs; + const std::size_t num_attachments = static_cast(regs.rt_control.count); + RenderPassParams params; - params.num_color_attachments = static_cast(regs.rt_control.count); - std::transform(regs.rt.begin(), regs.rt.end(), params.color_formats.begin(), - [](const auto& rt) { return static_cast(rt.format); }); - params.texceptions = static_cast(texceptions.to_ullong()); + params.color_formats = {}; + std::size_t color_texceptions = 0; + + std::size_t index = 0; + for (std::size_t rt = 0; rt < num_attachments; ++rt) { + const auto& rendertarget = regs.rt[rt]; + if (rendertarget.Address() == 0 || rendertarget.format == Tegra::RenderTargetFormat::NONE) { + continue; + } + params.color_formats[index] = static_cast(rendertarget.format); + color_texceptions |= (texceptions[rt] ? 1ULL : 0ULL) << index; + ++index; + } + params.num_color_attachments = static_cast(index); + params.texceptions = static_cast(color_texceptions); + params.zeta_format = regs.zeta_enable ? static_cast(regs.zeta.format) : 0; params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX]; return params; -- cgit v1.2.3