summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp29
-rw-r--r--src/video_core/renderer_vulkan/vk_renderpass_cache.cpp53
-rw-r--r--src/video_core/renderer_vulkan/vk_renderpass_cache.h59
4 files changed, 59 insertions, 84 deletions
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 8332b42aa..45bd1fc6c 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -288,7 +288,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
288 depth_stencil_ci.maxDepthBounds = 0.0f; 288 depth_stencil_ci.maxDepthBounds = 0.0f;
289 289
290 std::array<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments; 290 std::array<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments;
291 const std::size_t num_attachments = renderpass_params.color_attachments.size(); 291 const auto num_attachments = static_cast<std::size_t>(renderpass_params.num_color_attachments);
292 for (std::size_t index = 0; index < num_attachments; ++index) { 292 for (std::size_t index = 0; index < num_attachments; ++index) {
293 static constexpr std::array COMPONENT_TABLE = { 293 static constexpr std::array COMPONENT_TABLE = {
294 VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, 294 VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT,
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(
1245} 1245}
1246 1246
1247RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { 1247RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const {
1248 using namespace VideoCore::Surface;
1249
1250 const auto& regs = system.GPU().Maxwell3D().regs; 1248 const auto& regs = system.GPU().Maxwell3D().regs;
1251 RenderPassParams renderpass_params; 1249 RenderPassParams params;
1252 1250 params.num_color_attachments = static_cast<u8>(regs.rt_control.count);
1253 for (std::size_t rt = 0; rt < static_cast<std::size_t>(regs.rt_control.count); ++rt) { 1251 std::transform(regs.rt.begin(), regs.rt.end(), params.color_formats.begin(),
1254 const auto& rendertarget = regs.rt[rt]; 1252 [](const auto& rt) { return static_cast<u8>(rt.format); });
1255 if (rendertarget.Address() == 0 || rendertarget.format == Tegra::RenderTargetFormat::NONE) { 1253 params.texceptions = static_cast<u8>(texceptions.to_ullong());
1256 continue; 1254 params.zeta_format = regs.zeta_enable ? static_cast<u8>(regs.zeta.format) : 0;
1257 } 1255 params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX];
1258 renderpass_params.color_attachments.push_back(RenderPassParams::ColorAttachment{ 1256 return params;
1259 static_cast<u32>(rt), PixelFormatFromRenderTargetFormat(rendertarget.format),
1260 texceptions[rt]});
1261 }
1262
1263 renderpass_params.has_zeta = regs.zeta_enable;
1264 if (renderpass_params.has_zeta) {
1265 renderpass_params.zeta_pixel_format = PixelFormatFromDepthFormat(regs.zeta.format);
1266 renderpass_params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX];
1267 }
1268
1269 return renderpass_params;
1270} 1257}
1271 1258
1272} // namespace Vulkan 1259} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp
index 4e5286a69..3f71d005e 100644
--- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp
@@ -2,9 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
5#include <memory> 6#include <memory>
6#include <vector> 7#include <vector>
7 8
9#include "common/cityhash.h"
8#include "video_core/engines/maxwell_3d.h" 10#include "video_core/engines/maxwell_3d.h"
9#include "video_core/renderer_vulkan/maxwell_to_vk.h" 11#include "video_core/renderer_vulkan/maxwell_to_vk.h"
10#include "video_core/renderer_vulkan/vk_device.h" 12#include "video_core/renderer_vulkan/vk_device.h"
@@ -13,6 +15,15 @@
13 15
14namespace Vulkan { 16namespace Vulkan {
15 17
18std::size_t RenderPassParams::Hash() const noexcept {
19 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
20 return static_cast<std::size_t>(hash);
21}
22
23bool RenderPassParams::operator==(const RenderPassParams& rhs) const noexcept {
24 return std::memcmp(&rhs, this, sizeof *this) == 0;
25}
26
16VKRenderPassCache::VKRenderPassCache(const VKDevice& device) : device{device} {} 27VKRenderPassCache::VKRenderPassCache(const VKDevice& device) : device{device} {}
17 28
18VKRenderPassCache::~VKRenderPassCache() = default; 29VKRenderPassCache::~VKRenderPassCache() = default;
@@ -27,20 +38,22 @@ VkRenderPass VKRenderPassCache::GetRenderPass(const RenderPassParams& params) {
27} 38}
28 39
29vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& params) const { 40vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& params) const {
41 using namespace VideoCore::Surface;
30 std::vector<VkAttachmentDescription> descriptors; 42 std::vector<VkAttachmentDescription> descriptors;
31 std::vector<VkAttachmentReference> color_references; 43 std::vector<VkAttachmentReference> color_references;
32 44
33 for (std::size_t rt = 0; rt < params.color_attachments.size(); ++rt) { 45 const std::size_t num_attachments = static_cast<std::size_t>(params.num_color_attachments);
34 const auto attachment = params.color_attachments[rt]; 46 for (std::size_t rt = 0; rt < num_attachments; ++rt) {
35 const auto format = 47 const auto guest_format = static_cast<Tegra::RenderTargetFormat>(params.color_formats[rt]);
36 MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, attachment.pixel_format); 48 const PixelFormat pixel_format = PixelFormatFromRenderTargetFormat(guest_format);
49 const auto format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, pixel_format);
37 ASSERT_MSG(format.attachable, "Trying to attach a non-attachable format with format={}", 50 ASSERT_MSG(format.attachable, "Trying to attach a non-attachable format with format={}",
38 static_cast<u32>(attachment.pixel_format)); 51 static_cast<int>(pixel_format));
39 52
40 // TODO(Rodrigo): Add eMayAlias when it's needed. 53 // TODO(Rodrigo): Add MAY_ALIAS_BIT when it's needed.
41 const auto color_layout = attachment.is_texception 54 const VkImageLayout color_layout = ((params.texceptions >> rt) & 1) != 0
42 ? VK_IMAGE_LAYOUT_GENERAL 55 ? VK_IMAGE_LAYOUT_GENERAL
43 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 56 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
44 VkAttachmentDescription& descriptor = descriptors.emplace_back(); 57 VkAttachmentDescription& descriptor = descriptors.emplace_back();
45 descriptor.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT; 58 descriptor.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
46 descriptor.format = format.format; 59 descriptor.format = format.format;
@@ -58,15 +71,17 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
58 } 71 }
59 72
60 VkAttachmentReference zeta_attachment_ref; 73 VkAttachmentReference zeta_attachment_ref;
61 if (params.has_zeta) { 74 const bool has_zeta = params.zeta_format != 0;
62 const auto format = 75 if (has_zeta) {
63 MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, params.zeta_pixel_format); 76 const auto guest_format = static_cast<Tegra::DepthFormat>(params.zeta_format);
77 const PixelFormat pixel_format = PixelFormatFromDepthFormat(guest_format);
78 const auto format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, pixel_format);
64 ASSERT_MSG(format.attachable, "Trying to attach a non-attachable format with format={}", 79 ASSERT_MSG(format.attachable, "Trying to attach a non-attachable format with format={}",
65 static_cast<u32>(params.zeta_pixel_format)); 80 static_cast<int>(pixel_format));
66 81
67 const auto zeta_layout = params.zeta_texception 82 const VkImageLayout zeta_layout = params.zeta_texception != 0
68 ? VK_IMAGE_LAYOUT_GENERAL 83 ? VK_IMAGE_LAYOUT_GENERAL
69 : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 84 : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
70 VkAttachmentDescription& descriptor = descriptors.emplace_back(); 85 VkAttachmentDescription& descriptor = descriptors.emplace_back();
71 descriptor.flags = 0; 86 descriptor.flags = 0;
72 descriptor.format = format.format; 87 descriptor.format = format.format;
@@ -78,7 +93,7 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
78 descriptor.initialLayout = zeta_layout; 93 descriptor.initialLayout = zeta_layout;
79 descriptor.finalLayout = zeta_layout; 94 descriptor.finalLayout = zeta_layout;
80 95
81 zeta_attachment_ref.attachment = static_cast<u32>(params.color_attachments.size()); 96 zeta_attachment_ref.attachment = static_cast<u32>(num_attachments);
82 zeta_attachment_ref.layout = zeta_layout; 97 zeta_attachment_ref.layout = zeta_layout;
83 } 98 }
84 99
@@ -90,7 +105,7 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
90 subpass_description.colorAttachmentCount = static_cast<u32>(color_references.size()); 105 subpass_description.colorAttachmentCount = static_cast<u32>(color_references.size());
91 subpass_description.pColorAttachments = color_references.data(); 106 subpass_description.pColorAttachments = color_references.data();
92 subpass_description.pResolveAttachments = nullptr; 107 subpass_description.pResolveAttachments = nullptr;
93 subpass_description.pDepthStencilAttachment = params.has_zeta ? &zeta_attachment_ref : nullptr; 108 subpass_description.pDepthStencilAttachment = has_zeta ? &zeta_attachment_ref : nullptr;
94 subpass_description.preserveAttachmentCount = 0; 109 subpass_description.preserveAttachmentCount = 0;
95 subpass_description.pPreserveAttachments = nullptr; 110 subpass_description.pPreserveAttachments = nullptr;
96 111
@@ -101,7 +116,7 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param
101 stage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 116 stage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
102 } 117 }
103 118
104 if (params.has_zeta) { 119 if (has_zeta) {
105 access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 120 access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
106 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 121 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
107 stage |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; 122 stage |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.h b/src/video_core/renderer_vulkan/vk_renderpass_cache.h
index 921b6efb5..0e988b26b 100644
--- a/src/video_core/renderer_vulkan/vk_renderpass_cache.h
+++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.h
@@ -4,8 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <type_traits>
8#include <tuple>
9#include <unordered_map> 8#include <unordered_map>
10 9
11#include <boost/container/static_vector.hpp> 10#include <boost/container/static_vector.hpp>
@@ -19,51 +18,25 @@ namespace Vulkan {
19 18
20class VKDevice; 19class VKDevice;
21 20
22// TODO(Rodrigo): Optimize this structure for faster hashing
23
24struct RenderPassParams { 21struct RenderPassParams {
25 struct ColorAttachment { 22 u8 num_color_attachments;
26 u32 index = 0; 23 std::array<u8, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> color_formats;
27 VideoCore::Surface::PixelFormat pixel_format = VideoCore::Surface::PixelFormat::Invalid; 24 u8 texceptions;
28 bool is_texception = false; 25
29 26 u8 zeta_format;
30 std::size_t Hash() const noexcept { 27 u8 zeta_texception;
31 return static_cast<std::size_t>(pixel_format) | 28
32 static_cast<std::size_t>(is_texception) << 6 | 29 std::size_t Hash() const noexcept;
33 static_cast<std::size_t>(index) << 7; 30
34 } 31 bool operator==(const RenderPassParams& rhs) const noexcept;
35
36 bool operator==(const ColorAttachment& rhs) const noexcept {
37 return std::tie(index, pixel_format, is_texception) ==
38 std::tie(rhs.index, rhs.pixel_format, rhs.is_texception);
39 }
40 };
41
42 boost::container::static_vector<ColorAttachment,
43 Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
44 color_attachments{};
45 // TODO(Rodrigo): Unify has_zeta into zeta_pixel_format and zeta_component_type.
46 VideoCore::Surface::PixelFormat zeta_pixel_format = VideoCore::Surface::PixelFormat::Invalid;
47 bool has_zeta = false;
48 bool zeta_texception = false;
49
50 std::size_t Hash() const noexcept {
51 std::size_t hash = 0;
52 for (const auto& rt : color_attachments) {
53 boost::hash_combine(hash, rt.Hash());
54 }
55 boost::hash_combine(hash, zeta_pixel_format);
56 boost::hash_combine(hash, has_zeta);
57 boost::hash_combine(hash, zeta_texception);
58 return hash;
59 }
60 32
61 bool operator==(const RenderPassParams& rhs) const { 33 bool operator!=(const RenderPassParams& rhs) const noexcept {
62 return std::tie(color_attachments, zeta_pixel_format, has_zeta, zeta_texception) == 34 return !operator==(rhs);
63 std::tie(rhs.color_attachments, rhs.zeta_pixel_format, rhs.has_zeta,
64 rhs.zeta_texception);
65 } 35 }
66}; 36};
37static_assert(std::has_unique_object_representations_v<RenderPassParams>);
38static_assert(std::is_trivially_copyable_v<RenderPassParams>);
39static_assert(std::is_trivially_constructible_v<RenderPassParams>);
67 40
68} // namespace Vulkan 41} // namespace Vulkan
69 42