diff options
Diffstat (limited to 'src')
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 | ||
| 42 | void FixedPipelineState::Fill(const Maxwell& regs) { | 42 | void 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 | ||
| 92 | void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) { | 95 | void 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 | ||
| 175 | std::size_t FixedPipelineState::Hash() const noexcept { | 178 | std::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 | ||
| 180 | bool FixedPipelineState::operator==(const FixedPipelineState& rhs) const noexcept { | 183 | bool 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 | ||
| 184 | u32 FixedPipelineState::PackComparisonOp(Maxwell::ComparisonOp op) noexcept { | 187 | u32 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 | }; |
| 210 | static_assert(std::has_unique_object_representations_v<FixedPipelineState>); | 216 | static_assert(std::has_unique_object_representations_v<FixedPipelineState>); |
| 211 | static_assert(std::is_trivially_copyable_v<FixedPipelineState>); | 217 | static_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( | |||
| 177 | vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, | 177 | vk::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 | ||
| 118 | std::size_t GraphicsPipelineCacheKey::Hash() const noexcept { | 118 | std::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 | ||
| 123 | bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) const noexcept { | 123 | bool 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 | ||
| 127 | std::size_t ComputePipelineCacheKey::Hash() const noexcept { | 127 | std::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 | }; |
| 60 | static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>); | 64 | static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>); |
| 61 | static_assert(std::is_trivially_copyable_v<GraphicsPipelineCacheKey>); | 65 | static_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 | ||