summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-06-22 19:07:04 -0300
committerGravatar ReinUsesLisp2020-06-26 20:57:22 -0300
commit8584a77eb2e51e702d4c941e0fca07aafc47f29b (patch)
tree0a6929b316f2d92dc04b898053a3da09401844c9 /src
parentvulkan/fixed_pipeline_state: Move state out of individual structures (diff)
downloadyuzu-8584a77eb2e51e702d4c941e0fca07aafc47f29b.tar.gz
yuzu-8584a77eb2e51e702d4c941e0fca07aafc47f29b.tar.xz
yuzu-8584a77eb2e51e702d4c941e0fca07aafc47f29b.zip
vk_pipeline_cache: Avoid hashing and comparing dynamic state when possible
With extended dynamic states, some bytes don't have to be collected from the pipeline key, hence we can avoid hashing and comparing them on lookups.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp11
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h32
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp18
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp7
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
6 files changed, 51 insertions, 23 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 07358b0f9..d1f0ea932 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -39,7 +39,7 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
39 39
40} // Anonymous namespace 40} // Anonymous namespace
41 41
42void FixedPipelineState::Fill(const Maxwell& regs) { 42void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_state) {
43 const auto& clip = regs.view_volume_clip_control; 43 const auto& clip = regs.view_volume_clip_control;
44 const std::array enabled_lut = {regs.polygon_offset_point_enable, 44 const std::array enabled_lut = {regs.polygon_offset_point_enable,
45 regs.polygon_offset_line_enable, 45 regs.polygon_offset_line_enable,
@@ -86,7 +86,10 @@ void FixedPipelineState::Fill(const Maxwell& regs) {
86 std::transform(transform.begin(), transform.end(), viewport_swizzles.begin(), 86 std::transform(transform.begin(), transform.end(), viewport_swizzles.begin(),
87 [](const auto& viewport) { return static_cast<u16>(viewport.swizzle.raw); }); 87 [](const auto& viewport) { return static_cast<u16>(viewport.swizzle.raw); });
88 88
89 dynamic_state.Fill(regs); 89 if (!has_extended_dynamic_state) {
90 no_extended_dynamic_state.Assign(1);
91 dynamic_state.Fill(regs);
92 }
90} 93}
91 94
92void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) { 95void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) {
@@ -173,12 +176,12 @@ void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) {
173} 176}
174 177
175std::size_t FixedPipelineState::Hash() const noexcept { 178std::size_t FixedPipelineState::Hash() const noexcept {
176 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); 179 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), Size());
177 return static_cast<std::size_t>(hash); 180 return static_cast<std::size_t>(hash);
178} 181}
179 182
180bool FixedPipelineState::operator==(const FixedPipelineState& rhs) const noexcept { 183bool FixedPipelineState::operator==(const FixedPipelineState& rhs) const noexcept {
181 return std::memcmp(this, &rhs, sizeof *this) == 0; 184 return std::memcmp(this, &rhs, Size()) == 0;
182} 185}
183 186
184u32 FixedPipelineState::PackComparisonOp(Maxwell::ComparisonOp op) noexcept { 187u32 FixedPipelineState::PackComparisonOp(Maxwell::ComparisonOp op) noexcept {
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 09d05702d..cdcbb65f5 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -177,18 +177,19 @@ struct FixedPipelineState {
177 177
178 union { 178 union {
179 u32 raw; 179 u32 raw;
180 BitField<0, 1, u32> primitive_restart_enable; 180 BitField<0, 1, u32> no_extended_dynamic_state;
181 BitField<1, 1, u32> depth_bias_enable; 181 BitField<2, 1, u32> primitive_restart_enable;
182 BitField<2, 1, u32> depth_clamp_disabled; 182 BitField<3, 1, u32> depth_bias_enable;
183 BitField<3, 1, u32> ndc_minus_one_to_one; 183 BitField<4, 1, u32> depth_clamp_disabled;
184 BitField<4, 2, u32> polygon_mode; 184 BitField<5, 1, u32> ndc_minus_one_to_one;
185 BitField<6, 5, u32> patch_control_points_minus_one; 185 BitField<6, 2, u32> polygon_mode;
186 BitField<11, 2, u32> tessellation_primitive; 186 BitField<8, 5, u32> patch_control_points_minus_one;
187 BitField<13, 2, u32> tessellation_spacing; 187 BitField<13, 2, u32> tessellation_primitive;
188 BitField<15, 1, u32> tessellation_clockwise; 188 BitField<15, 2, u32> tessellation_spacing;
189 BitField<16, 1, u32> logic_op_enable; 189 BitField<17, 1, u32> tessellation_clockwise;
190 BitField<17, 4, u32> logic_op; 190 BitField<18, 1, u32> logic_op_enable;
191 BitField<21, 1, u32> rasterize_enable; 191 BitField<19, 4, u32> logic_op;
192 BitField<23, 1, u32> rasterize_enable;
192 }; 193 };
193 u32 point_size; 194 u32 point_size;
194 std::array<u32, Maxwell::NumVertexArrays> binding_divisors; 195 std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
@@ -197,7 +198,7 @@ struct FixedPipelineState {
197 std::array<u16, Maxwell::NumViewports> viewport_swizzles; 198 std::array<u16, Maxwell::NumViewports> viewport_swizzles;
198 DynamicState dynamic_state; 199 DynamicState dynamic_state;
199 200
200 void Fill(const Maxwell& regs); 201 void Fill(const Maxwell& regs, bool has_extended_dynamic_state);
201 202
202 std::size_t Hash() const noexcept; 203 std::size_t Hash() const noexcept;
203 204
@@ -206,6 +207,11 @@ struct FixedPipelineState {
206 bool operator!=(const FixedPipelineState& rhs) const noexcept { 207 bool operator!=(const FixedPipelineState& rhs) const noexcept {
207 return !operator==(rhs); 208 return !operator==(rhs);
208 } 209 }
210
211 std::size_t Size() const noexcept {
212 const std::size_t total_size = sizeof *this;
213 return total_size - (no_extended_dynamic_state != 0 ? 0 : sizeof(DynamicState));
214 }
209}; 215};
210static_assert(std::has_unique_object_representations_v<FixedPipelineState>); 216static_assert(std::has_unique_object_representations_v<FixedPipelineState>);
211static_assert(std::is_trivially_copyable_v<FixedPipelineState>); 217static_assert(std::is_trivially_copyable_v<FixedPipelineState>);
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 15d9ac3b0..844445105 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -177,8 +177,22 @@ std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules(
177vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, 177vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params,
178 const SPIRVProgram& program) const { 178 const SPIRVProgram& program) const {
179 const auto& state = fixed_state; 179 const auto& state = fixed_state;
180 const auto& dynamic = fixed_state.dynamic_state; 180 const auto& viewport_swizzles = state.viewport_swizzles;
181 const auto& viewport_swizzles = fixed_state.viewport_swizzles; 181
182 FixedPipelineState::DynamicState dynamic;
183 if (device.IsExtExtendedDynamicStateSupported()) {
184 // Insert dummy values, as long as they are valid they don't matter as extended dynamic
185 // state is ignored
186 dynamic.raw1 = 0;
187 dynamic.raw2 = 0;
188 for (FixedPipelineState::VertexBinding& binding : dynamic.vertex_bindings) {
189 // Enable all vertex bindings
190 binding.raw = 0;
191 binding.enabled.Assign(1);
192 }
193 } else {
194 dynamic = state.dynamic_state;
195 }
182 196
183 std::vector<VkVertexInputBindingDescription> vertex_bindings; 197 std::vector<VkVertexInputBindingDescription> vertex_bindings;
184 std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; 198 std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index e684c17a6..3da835324 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -116,12 +116,12 @@ u32 FillDescriptorLayout(const ShaderEntries& entries,
116} // Anonymous namespace 116} // Anonymous namespace
117 117
118std::size_t GraphicsPipelineCacheKey::Hash() const noexcept { 118std::size_t GraphicsPipelineCacheKey::Hash() const noexcept {
119 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); 119 const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), Size());
120 return static_cast<std::size_t>(hash); 120 return static_cast<std::size_t>(hash);
121} 121}
122 122
123bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) const noexcept { 123bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) const noexcept {
124 return std::memcmp(&rhs, this, sizeof *this) == 0; 124 return std::memcmp(&rhs, this, Size()) == 0;
125} 125}
126 126
127std::size_t ComputePipelineCacheKey::Hash() const noexcept { 127std::size_t ComputePipelineCacheKey::Hash() const noexcept {
@@ -312,7 +312,8 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
312 const auto& gpu = system.GPU().Maxwell3D(); 312 const auto& gpu = system.GPU().Maxwell3D();
313 313
314 Specialization specialization; 314 Specialization specialization;
315 if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points) { 315 if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points ||
316 device.IsExtExtendedDynamicStateSupported()) {
316 float point_size; 317 float point_size;
317 std::memcpy(&point_size, &fixed_state.point_size, sizeof(float)); 318 std::memcpy(&point_size, &fixed_state.point_size, sizeof(float));
318 specialization.point_size = point_size; 319 specialization.point_size = point_size;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 7f6c56261..0a3fe65fb 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -56,6 +56,10 @@ struct GraphicsPipelineCacheKey {
56 bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept { 56 bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept {
57 return !operator==(rhs); 57 return !operator==(rhs);
58 } 58 }
59
60 std::size_t Size() const noexcept {
61 return sizeof(renderpass_params) + sizeof(padding) + sizeof(shaders) + fixed_state.Size();
62 }
59}; 63};
60static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>); 64static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>);
61static_assert(std::is_trivially_copyable_v<GraphicsPipelineCacheKey>); 65static_assert(std::is_trivially_copyable_v<GraphicsPipelineCacheKey>);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 40d8df8c7..7625871c2 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -413,7 +413,7 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
413 413
414 const auto& gpu = system.GPU().Maxwell3D(); 414 const auto& gpu = system.GPU().Maxwell3D();
415 GraphicsPipelineCacheKey key; 415 GraphicsPipelineCacheKey key;
416 key.fixed_state.Fill(gpu.regs); 416 key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported());
417 417
418 buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed)); 418 buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed));
419 419