summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-22 20:52:29 -0300
committerGravatar ReinUsesLisp2020-04-23 17:34:16 -0300
commit8c37cd1af689ce0ff0cd37e4579508a898ea3807 (patch)
treef354fc82f12f6ea80ce32903dbe8c66da9746952
parentvk_renderpass_cache: Pack renderpass cache key to 12 bytes (diff)
downloadyuzu-8c37cd1af689ce0ff0cd37e4579508a898ea3807.tar.gz
yuzu-8c37cd1af689ce0ff0cd37e4579508a898ea3807.tar.xz
yuzu-8c37cd1af689ce0ff0cd37e4579508a898ea3807.zip
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.
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp15
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h8
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp18
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h49
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp16
5 files changed, 59 insertions, 47 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index be1c31978..a7f256ff9 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -140,6 +140,12 @@ void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size
140 enable.Assign(1); 140 enable.Assign(1);
141} 141}
142 142
143void FixedPipelineState::Fill(const Maxwell& regs) {
144 rasterizer.Fill(regs);
145 depth_stencil.Fill(regs);
146 color_blending.Fill(regs);
147}
148
143std::size_t FixedPipelineState::Hash() const noexcept { 149std::size_t FixedPipelineState::Hash() const noexcept {
144 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); 150 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
145 return static_cast<std::size_t>(hash); 151 return static_cast<std::size_t>(hash);
@@ -149,15 +155,6 @@ bool FixedPipelineState::operator==(const FixedPipelineState& rhs) const noexcep
149 return std::memcmp(this, &rhs, sizeof *this) == 0; 155 return std::memcmp(this, &rhs, sizeof *this) == 0;
150} 156}
151 157
152FixedPipelineState GetFixedPipelineState(const Maxwell& regs) {
153 FixedPipelineState fixed_state;
154 fixed_state.rasterizer.Fill(regs);
155 fixed_state.depth_stencil.Fill(regs);
156 fixed_state.color_blending.Fill(regs);
157 fixed_state.padding = {};
158 return fixed_state;
159}
160
161u32 FixedPipelineState::PackComparisonOp(Maxwell::ComparisonOp op) noexcept { 158u32 FixedPipelineState::PackComparisonOp(Maxwell::ComparisonOp op) noexcept {
162 // OpenGL enums go from 0x200 to 0x207 and the others from 1 to 8 159 // OpenGL enums go from 0x200 to 0x207 and the others from 1 to 8
163 // If we substract 0x200 to OpenGL enums and 1 to the others we get a 0-7 range. 160 // If we substract 0x200 to OpenGL enums and 1 to the others we get a 0-7 range.
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 9fe6bdbf9..d4fd4d3f1 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -17,7 +17,7 @@ namespace Vulkan {
17 17
18using Maxwell = Tegra::Engines::Maxwell3D::Regs; 18using Maxwell = Tegra::Engines::Maxwell3D::Regs;
19 19
20struct alignas(32) FixedPipelineState { 20struct FixedPipelineState {
21 static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept; 21 static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept;
22 static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept; 22 static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept;
23 23
@@ -237,7 +237,8 @@ struct alignas(32) FixedPipelineState {
237 Rasterizer rasterizer; 237 Rasterizer rasterizer;
238 DepthStencil depth_stencil; 238 DepthStencil depth_stencil;
239 ColorBlending color_blending; 239 ColorBlending color_blending;
240 std::array<u8, 20> padding; 240
241 void Fill(const Maxwell& regs);
241 242
242 std::size_t Hash() const noexcept; 243 std::size_t Hash() const noexcept;
243 244
@@ -250,9 +251,6 @@ struct alignas(32) FixedPipelineState {
250static_assert(std::has_unique_object_representations_v<FixedPipelineState>); 251static_assert(std::has_unique_object_representations_v<FixedPipelineState>);
251static_assert(std::is_trivially_copyable_v<FixedPipelineState>); 252static_assert(std::is_trivially_copyable_v<FixedPipelineState>);
252static_assert(std::is_trivially_constructible_v<FixedPipelineState>); 253static_assert(std::is_trivially_constructible_v<FixedPipelineState>);
253static_assert(sizeof(FixedPipelineState) % 32 == 0, "Size is not aligned");
254
255FixedPipelineState GetFixedPipelineState(const Maxwell& regs);
256 254
257} // namespace Vulkan 255} // namespace Vulkan
258 256
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 91b1b16a5..e6d4adc92 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -161,6 +161,24 @@ u32 FillDescriptorLayout(const ShaderEntries& entries,
161 161
162} // Anonymous namespace 162} // Anonymous namespace
163 163
164std::size_t GraphicsPipelineCacheKey::Hash() const noexcept {
165 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
166 return static_cast<std::size_t>(hash);
167}
168
169bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) const noexcept {
170 return std::memcmp(&rhs, this, sizeof *this) == 0;
171}
172
173std::size_t ComputePipelineCacheKey::Hash() const noexcept {
174 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
175 return static_cast<std::size_t>(hash);
176}
177
178bool ComputePipelineCacheKey::operator==(const ComputePipelineCacheKey& rhs) const noexcept {
179 return std::memcmp(&rhs, this, sizeof *this) == 0;
180}
181
164CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stage, 182CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stage,
165 GPUVAddr gpu_addr, VAddr cpu_addr, ProgramCode program_code, 183 GPUVAddr gpu_addr, VAddr cpu_addr, ProgramCode program_code,
166 u32 main_offset) 184 u32 main_offset)
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 602a0a340..84d26b822 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -7,7 +7,6 @@
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <memory> 9#include <memory>
10#include <tuple>
11#include <type_traits> 10#include <type_traits>
12#include <unordered_map> 11#include <unordered_map>
13#include <utility> 12#include <utility>
@@ -51,42 +50,38 @@ using ProgramCode = std::vector<u64>;
51 50
52struct GraphicsPipelineCacheKey { 51struct GraphicsPipelineCacheKey {
53 FixedPipelineState fixed_state; 52 FixedPipelineState fixed_state;
54 std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders;
55 RenderPassParams renderpass_params; 53 RenderPassParams renderpass_params;
54 std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders;
55 u64 padding; // This is necessary for unique object representations
56 56
57 std::size_t Hash() const noexcept { 57 std::size_t Hash() const noexcept;
58 std::size_t hash = fixed_state.Hash(); 58
59 for (const auto& shader : shaders) { 59 bool operator==(const GraphicsPipelineCacheKey& rhs) const noexcept;
60 boost::hash_combine(hash, shader);
61 }
62 boost::hash_combine(hash, renderpass_params.Hash());
63 return hash;
64 }
65 60
66 bool operator==(const GraphicsPipelineCacheKey& rhs) const noexcept { 61 bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept {
67 return std::tie(fixed_state, shaders, renderpass_params) == 62 return !operator==(rhs);
68 std::tie(rhs.fixed_state, rhs.shaders, rhs.renderpass_params);
69 } 63 }
70}; 64};
65static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>);
66static_assert(std::is_trivially_copyable_v<GraphicsPipelineCacheKey>);
67static_assert(std::is_trivially_constructible_v<GraphicsPipelineCacheKey>);
71 68
72struct ComputePipelineCacheKey { 69struct ComputePipelineCacheKey {
73 GPUVAddr shader{}; 70 GPUVAddr shader;
74 u32 shared_memory_size{}; 71 u32 shared_memory_size;
75 std::array<u32, 3> workgroup_size{}; 72 std::array<u32, 3> workgroup_size;
76 73
77 std::size_t Hash() const noexcept { 74 std::size_t Hash() const noexcept;
78 return static_cast<std::size_t>(shader) ^ 75
79 ((static_cast<std::size_t>(shared_memory_size) >> 7) << 40) ^ 76 bool operator==(const ComputePipelineCacheKey& rhs) const noexcept;
80 static_cast<std::size_t>(workgroup_size[0]) ^
81 (static_cast<std::size_t>(workgroup_size[1]) << 16) ^
82 (static_cast<std::size_t>(workgroup_size[2]) << 24);
83 }
84 77
85 bool operator==(const ComputePipelineCacheKey& rhs) const noexcept { 78 bool operator!=(const ComputePipelineCacheKey& rhs) const noexcept {
86 return std::tie(shader, shared_memory_size, workgroup_size) == 79 return !operator==(rhs);
87 std::tie(rhs.shader, rhs.shared_memory_size, rhs.workgroup_size);
88 } 80 }
89}; 81};
82static_assert(std::has_unique_object_representations_v<ComputePipelineCacheKey>);
83static_assert(std::is_trivially_copyable_v<ComputePipelineCacheKey>);
84static_assert(std::is_trivially_constructible_v<ComputePipelineCacheKey>);
90 85
91} // namespace Vulkan 86} // namespace Vulkan
92 87
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) {
316 query_cache.UpdateCounters(); 316 query_cache.UpdateCounters();
317 317
318 const auto& gpu = system.GPU().Maxwell3D(); 318 const auto& gpu = system.GPU().Maxwell3D();
319 GraphicsPipelineCacheKey key{GetFixedPipelineState(gpu.regs)}; 319 GraphicsPipelineCacheKey key;
320 key.fixed_state.Fill(gpu.regs);
320 321
321 buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed)); 322 buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed));
322 323
@@ -334,10 +335,11 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
334 335
335 buffer_cache.Unmap(); 336 buffer_cache.Unmap();
336 337
337 const auto texceptions = UpdateAttachments(); 338 const Texceptions texceptions = UpdateAttachments();
338 SetupImageTransitions(texceptions, color_attachments, zeta_attachment); 339 SetupImageTransitions(texceptions, color_attachments, zeta_attachment);
339 340
340 key.renderpass_params = GetRenderPassParams(texceptions); 341 key.renderpass_params = GetRenderPassParams(texceptions);
342 key.padding = 0;
341 343
342 auto& pipeline = pipeline_cache.GetGraphicsPipeline(key); 344 auto& pipeline = pipeline_cache.GetGraphicsPipeline(key);
343 scheduler.BindGraphicsPipeline(pipeline.GetHandle()); 345 scheduler.BindGraphicsPipeline(pipeline.GetHandle());
@@ -453,10 +455,12 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) {
453 query_cache.UpdateCounters(); 455 query_cache.UpdateCounters();
454 456
455 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 457 const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
456 const ComputePipelineCacheKey key{ 458 ComputePipelineCacheKey key;
457 code_addr, 459 key.shader = code_addr;
458 launch_desc.shared_alloc, 460 key.shared_memory_size = launch_desc.shared_alloc;
459 {launch_desc.block_dim_x, launch_desc.block_dim_y, launch_desc.block_dim_z}}; 461 key.workgroup_size = {launch_desc.block_dim_x, launch_desc.block_dim_y,
462 launch_desc.block_dim_z};
463
460 auto& pipeline = pipeline_cache.GetComputePipeline(key); 464 auto& pipeline = pipeline_cache.GetComputePipeline(key);
461 465
462 // Compute dispatches can't be executed inside a renderpass 466 // Compute dispatches can't be executed inside a renderpass