diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.h | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 70 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.cpp | 58 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.h | 20 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 64 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 17 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 15 |
13 files changed, 315 insertions, 66 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index df229f41b..f13ff09c6 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -48,23 +48,16 @@ void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& | |||
| 48 | } | 48 | } |
| 49 | } // Anonymous namespace | 49 | } // Anonymous namespace |
| 50 | 50 | ||
| 51 | void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | 51 | void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features) { |
| 52 | bool has_extended_dynamic_state, bool has_dynamic_vertex_input) { | ||
| 53 | const Maxwell& regs = maxwell3d.regs; | 52 | const Maxwell& regs = maxwell3d.regs; |
| 54 | const auto topology_ = maxwell3d.draw_manager->GetDrawState().topology; | 53 | const auto topology_ = maxwell3d.draw_manager->GetDrawState().topology; |
| 55 | const std::array enabled_lut{ | ||
| 56 | regs.polygon_offset_point_enable, | ||
| 57 | regs.polygon_offset_line_enable, | ||
| 58 | regs.polygon_offset_fill_enable, | ||
| 59 | }; | ||
| 60 | const u32 topology_index = static_cast<u32>(topology_); | ||
| 61 | 54 | ||
| 62 | raw1 = 0; | 55 | raw1 = 0; |
| 63 | extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0); | 56 | extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0); |
| 64 | dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0); | 57 | extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0); |
| 58 | extended_dynamic_state_3.Assign(features.has_extended_dynamic_state_3 ? 1 : 0); | ||
| 59 | dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0); | ||
| 65 | xfb_enabled.Assign(regs.transform_feedback_enabled != 0); | 60 | xfb_enabled.Assign(regs.transform_feedback_enabled != 0); |
| 66 | primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); | ||
| 67 | depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); | ||
| 68 | depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip == | 61 | depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip == |
| 69 | Maxwell::ViewportClipControl::GeometryClip::Passthrough || | 62 | Maxwell::ViewportClipControl::GeometryClip::Passthrough || |
| 70 | regs.viewport_clip_control.geometry_clip == | 63 | regs.viewport_clip_control.geometry_clip == |
| @@ -84,7 +77,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||
| 84 | msaa_mode.Assign(regs.anti_alias_samples_mode); | 77 | msaa_mode.Assign(regs.anti_alias_samples_mode); |
| 85 | 78 | ||
| 86 | raw2 = 0; | 79 | raw2 = 0; |
| 87 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); | 80 | |
| 88 | const auto test_func = | 81 | const auto test_func = |
| 89 | regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL; | 82 | regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL; |
| 90 | alpha_test_func.Assign(PackComparisonOp(test_func)); | 83 | alpha_test_func.Assign(PackComparisonOp(test_func)); |
| @@ -106,7 +99,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||
| 106 | point_size = Common::BitCast<u32>(regs.point_size); | 99 | point_size = Common::BitCast<u32>(regs.point_size); |
| 107 | 100 | ||
| 108 | if (maxwell3d.dirty.flags[Dirty::VertexInput]) { | 101 | if (maxwell3d.dirty.flags[Dirty::VertexInput]) { |
| 109 | if (has_dynamic_vertex_input) { | 102 | if (features.has_dynamic_vertex_input) { |
| 110 | // Dirty flag will be reset by the command buffer update | 103 | // Dirty flag will be reset by the command buffer update |
| 111 | static constexpr std::array LUT{ | 104 | static constexpr std::array LUT{ |
| 112 | 0u, // Invalid | 105 | 0u, // Invalid |
| @@ -158,9 +151,17 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||
| 158 | return static_cast<u16>(viewport.swizzle.raw); | 151 | return static_cast<u16>(viewport.swizzle.raw); |
| 159 | }); | 152 | }); |
| 160 | } | 153 | } |
| 154 | dynamic_state.raw1 = 0; | ||
| 155 | dynamic_state.raw2 = 0; | ||
| 161 | if (!extended_dynamic_state) { | 156 | if (!extended_dynamic_state) { |
| 162 | dynamic_state.Refresh(regs); | 157 | dynamic_state.Refresh(regs); |
| 163 | } | 158 | } |
| 159 | if (!extended_dynamic_state_2) { | ||
| 160 | dynamic_state.Refresh2(regs, topology); | ||
| 161 | } | ||
| 162 | if (!extended_dynamic_state_3) { | ||
| 163 | dynamic_state.Refresh3(regs); | ||
| 164 | } | ||
| 164 | if (xfb_enabled) { | 165 | if (xfb_enabled) { |
| 165 | RefreshXfbState(xfb_state, regs); | 166 | RefreshXfbState(xfb_state, regs); |
| 166 | } | 167 | } |
| @@ -212,8 +213,6 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { | |||
| 212 | packed_front_face = 1 - packed_front_face; | 213 | packed_front_face = 1 - packed_front_face; |
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | raw1 = 0; | ||
| 216 | raw2 = 0; | ||
| 217 | front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op.fail)); | 216 | front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op.fail)); |
| 218 | front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op.zfail)); | 217 | front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op.zfail)); |
| 219 | front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op.zpass)); | 218 | front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op.zpass)); |
| @@ -242,6 +241,21 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { | |||
| 242 | }); | 241 | }); |
| 243 | } | 242 | } |
| 244 | 243 | ||
| 244 | void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology_) { | ||
| 245 | const std::array enabled_lut{ | ||
| 246 | regs.polygon_offset_point_enable, | ||
| 247 | regs.polygon_offset_line_enable, | ||
| 248 | regs.polygon_offset_fill_enable, | ||
| 249 | }; | ||
| 250 | const u32 topology_index = static_cast<u32>(topology_); | ||
| 251 | |||
| 252 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); | ||
| 253 | primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); | ||
| 254 | depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); | ||
| 255 | } | ||
| 256 | |||
| 257 | void FixedPipelineState::DynamicState::Refresh3(const Maxwell&) {} | ||
| 258 | |||
| 245 | size_t FixedPipelineState::Hash() const noexcept { | 259 | size_t FixedPipelineState::Hash() const noexcept { |
| 246 | const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), Size()); | 260 | const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), Size()); |
| 247 | return static_cast<size_t>(hash); | 261 | return static_cast<size_t>(hash); |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 03bf64b57..ac2ec3edc 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -17,6 +17,14 @@ namespace Vulkan { | |||
| 17 | 17 | ||
| 18 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 18 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 19 | 19 | ||
| 20 | struct DynamicFeatures { | ||
| 21 | bool has_extended_dynamic_state; | ||
| 22 | bool has_extended_dynamic_state_2; | ||
| 23 | bool has_extended_dynamic_state_2_extra; | ||
| 24 | bool has_extended_dynamic_state_3; | ||
| 25 | bool has_dynamic_vertex_input; | ||
| 26 | }; | ||
| 27 | |||
| 20 | struct FixedPipelineState { | 28 | struct FixedPipelineState { |
| 21 | static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept; | 29 | static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept; |
| 22 | static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept; | 30 | static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept; |
| @@ -133,6 +141,14 @@ struct FixedPipelineState { | |||
| 133 | struct DynamicState { | 141 | struct DynamicState { |
| 134 | union { | 142 | union { |
| 135 | u32 raw1; | 143 | u32 raw1; |
| 144 | BitField<0, 2, u32> cull_face; | ||
| 145 | BitField<2, 1, u32> cull_enable; | ||
| 146 | BitField<3, 1, u32> primitive_restart_enable; | ||
| 147 | BitField<4, 1, u32> depth_bias_enable; | ||
| 148 | BitField<5, 1, u32> rasterize_enable; | ||
| 149 | }; | ||
| 150 | union { | ||
| 151 | u32 raw2; | ||
| 136 | StencilFace<0> front; | 152 | StencilFace<0> front; |
| 137 | StencilFace<12> back; | 153 | StencilFace<12> back; |
| 138 | BitField<24, 1, u32> stencil_enable; | 154 | BitField<24, 1, u32> stencil_enable; |
| @@ -142,15 +158,12 @@ struct FixedPipelineState { | |||
| 142 | BitField<28, 1, u32> front_face; | 158 | BitField<28, 1, u32> front_face; |
| 143 | BitField<29, 3, u32> depth_test_func; | 159 | BitField<29, 3, u32> depth_test_func; |
| 144 | }; | 160 | }; |
| 145 | union { | ||
| 146 | u32 raw2; | ||
| 147 | BitField<0, 2, u32> cull_face; | ||
| 148 | BitField<2, 1, u32> cull_enable; | ||
| 149 | }; | ||
| 150 | // Vertex stride is a 12 bits value, we have 4 bits to spare per element | 161 | // Vertex stride is a 12 bits value, we have 4 bits to spare per element |
| 151 | std::array<u16, Maxwell::NumVertexArrays> vertex_strides; | 162 | std::array<u16, Maxwell::NumVertexArrays> vertex_strides; |
| 152 | 163 | ||
| 153 | void Refresh(const Maxwell& regs); | 164 | void Refresh(const Maxwell& regs); |
| 165 | void Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology); | ||
| 166 | void Refresh3(const Maxwell& regs); | ||
| 154 | 167 | ||
| 155 | Maxwell::ComparisonOp DepthTestFunc() const noexcept { | 168 | Maxwell::ComparisonOp DepthTestFunc() const noexcept { |
| 156 | return UnpackComparisonOp(depth_test_func); | 169 | return UnpackComparisonOp(depth_test_func); |
| @@ -168,10 +181,10 @@ struct FixedPipelineState { | |||
| 168 | union { | 181 | union { |
| 169 | u32 raw1; | 182 | u32 raw1; |
| 170 | BitField<0, 1, u32> extended_dynamic_state; | 183 | BitField<0, 1, u32> extended_dynamic_state; |
| 171 | BitField<1, 1, u32> dynamic_vertex_input; | 184 | BitField<1, 1, u32> extended_dynamic_state_2; |
| 172 | BitField<2, 1, u32> xfb_enabled; | 185 | BitField<2, 1, u32> extended_dynamic_state_3; |
| 173 | BitField<3, 1, u32> primitive_restart_enable; | 186 | BitField<3, 1, u32> dynamic_vertex_input; |
| 174 | BitField<4, 1, u32> depth_bias_enable; | 187 | BitField<4, 1, u32> xfb_enabled; |
| 175 | BitField<5, 1, u32> depth_clamp_disabled; | 188 | BitField<5, 1, u32> depth_clamp_disabled; |
| 176 | BitField<6, 1, u32> ndc_minus_one_to_one; | 189 | BitField<6, 1, u32> ndc_minus_one_to_one; |
| 177 | BitField<7, 2, u32> polygon_mode; | 190 | BitField<7, 2, u32> polygon_mode; |
| @@ -186,7 +199,6 @@ struct FixedPipelineState { | |||
| 186 | }; | 199 | }; |
| 187 | union { | 200 | union { |
| 188 | u32 raw2; | 201 | u32 raw2; |
| 189 | BitField<0, 1, u32> rasterize_enable; | ||
| 190 | BitField<1, 3, u32> alpha_test_func; | 202 | BitField<1, 3, u32> alpha_test_func; |
| 191 | BitField<4, 1, u32> early_z; | 203 | BitField<4, 1, u32> early_z; |
| 192 | BitField<5, 1, u32> depth_enabled; | 204 | BitField<5, 1, u32> depth_enabled; |
| @@ -215,8 +227,7 @@ struct FixedPipelineState { | |||
| 215 | DynamicState dynamic_state; | 227 | DynamicState dynamic_state; |
| 216 | VideoCommon::TransformFeedbackState xfb_state; | 228 | VideoCommon::TransformFeedbackState xfb_state; |
| 217 | 229 | ||
| 218 | void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, bool has_extended_dynamic_state, | 230 | void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features); |
| 219 | bool has_dynamic_vertex_input); | ||
| 220 | 231 | ||
| 221 | size_t Hash() const noexcept; | 232 | size_t Hash() const noexcept; |
| 222 | 233 | ||
| @@ -231,14 +242,18 @@ struct FixedPipelineState { | |||
| 231 | // When transform feedback is enabled, use the whole struct | 242 | // When transform feedback is enabled, use the whole struct |
| 232 | return sizeof(*this); | 243 | return sizeof(*this); |
| 233 | } | 244 | } |
| 234 | if (dynamic_vertex_input) { | 245 | if (dynamic_vertex_input && extended_dynamic_state_2) { |
| 235 | // Exclude dynamic state and attributes | 246 | // Exclude dynamic state and attributes |
| 236 | return offsetof(FixedPipelineState, attributes); | 247 | return offsetof(FixedPipelineState, attributes); |
| 237 | } | 248 | } |
| 238 | if (extended_dynamic_state) { | 249 | if (extended_dynamic_state_2) { |
| 239 | // Exclude dynamic state | 250 | // Exclude dynamic state |
| 240 | return offsetof(FixedPipelineState, dynamic_state); | 251 | return offsetof(FixedPipelineState, dynamic_state); |
| 241 | } | 252 | } |
| 253 | if (extended_dynamic_state) { | ||
| 254 | // Exclude dynamic state | ||
| 255 | return offsetof(FixedPipelineState, dynamic_state.raw2); | ||
| 256 | } | ||
| 242 | // Default | 257 | // Default |
| 243 | return offsetof(FixedPipelineState, xfb_state); | 258 | return offsetof(FixedPipelineState, xfb_state); |
| 244 | } | 259 | } |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 515d8d869..d21d5aaf4 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -525,6 +525,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 525 | if (!key.state.extended_dynamic_state) { | 525 | if (!key.state.extended_dynamic_state) { |
| 526 | dynamic = key.state.dynamic_state; | 526 | dynamic = key.state.dynamic_state; |
| 527 | } | 527 | } |
| 528 | if (!key.state.extended_dynamic_state_2) { | ||
| 529 | dynamic.raw2 = key.state.dynamic_state.raw2; | ||
| 530 | } | ||
| 528 | static_vector<VkVertexInputBindingDescription, 32> vertex_bindings; | 531 | static_vector<VkVertexInputBindingDescription, 32> vertex_bindings; |
| 529 | static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors; | 532 | static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors; |
| 530 | static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes; | 533 | static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes; |
| @@ -625,7 +628,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 625 | .pNext = nullptr, | 628 | .pNext = nullptr, |
| 626 | .flags = 0, | 629 | .flags = 0, |
| 627 | .topology = input_assembly_topology, | 630 | .topology = input_assembly_topology, |
| 628 | .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && | 631 | .primitiveRestartEnable = key.state.dynamic_state.primitive_restart_enable != 0 && |
| 629 | ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && | 632 | ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && |
| 630 | device.IsTopologyListPrimitiveRestartSupported()) || | 633 | device.IsTopologyListPrimitiveRestartSupported()) || |
| 631 | SupportsPrimitiveRestart(input_assembly_topology) || | 634 | SupportsPrimitiveRestart(input_assembly_topology) || |
| @@ -674,13 +677,13 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 674 | .depthClampEnable = | 677 | .depthClampEnable = |
| 675 | static_cast<VkBool32>(key.state.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE), | 678 | static_cast<VkBool32>(key.state.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE), |
| 676 | .rasterizerDiscardEnable = | 679 | .rasterizerDiscardEnable = |
| 677 | static_cast<VkBool32>(key.state.rasterize_enable == 0 ? VK_TRUE : VK_FALSE), | 680 | static_cast<VkBool32>(dynamic.rasterize_enable == 0 ? VK_TRUE : VK_FALSE), |
| 678 | .polygonMode = | 681 | .polygonMode = |
| 679 | MaxwellToVK::PolygonMode(FixedPipelineState::UnpackPolygonMode(key.state.polygon_mode)), | 682 | MaxwellToVK::PolygonMode(FixedPipelineState::UnpackPolygonMode(key.state.polygon_mode)), |
| 680 | .cullMode = static_cast<VkCullModeFlags>( | 683 | .cullMode = static_cast<VkCullModeFlags>( |
| 681 | dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE), | 684 | dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE), |
| 682 | .frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()), | 685 | .frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()), |
| 683 | .depthBiasEnable = key.state.depth_bias_enable, | 686 | .depthBiasEnable = (dynamic.depth_bias_enable == 0 ? VK_TRUE : VK_FALSE), |
| 684 | .depthBiasConstantFactor = 0.0f, | 687 | .depthBiasConstantFactor = 0.0f, |
| 685 | .depthBiasClamp = 0.0f, | 688 | .depthBiasClamp = 0.0f, |
| 686 | .depthBiasSlopeFactor = 0.0f, | 689 | .depthBiasSlopeFactor = 0.0f, |
| @@ -788,7 +791,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 788 | .pAttachments = cb_attachments.data(), | 791 | .pAttachments = cb_attachments.data(), |
| 789 | .blendConstants = {}, | 792 | .blendConstants = {}, |
| 790 | }; | 793 | }; |
| 791 | static_vector<VkDynamicState, 19> dynamic_states{ | 794 | static_vector<VkDynamicState, 22> dynamic_states{ |
| 792 | VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, | 795 | VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, |
| 793 | VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, | 796 | VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, |
| 794 | VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, | 797 | VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, |
| @@ -811,6 +814,14 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 811 | dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT); | 814 | dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT); |
| 812 | } | 815 | } |
| 813 | dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end()); | 816 | dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end()); |
| 817 | if (key.state.extended_dynamic_state_2) { | ||
| 818 | static constexpr std::array extended2{ | ||
| 819 | VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT, | ||
| 820 | VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT, | ||
| 821 | VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT, | ||
| 822 | }; | ||
| 823 | dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end()); | ||
| 824 | } | ||
| 814 | } | 825 | } |
| 815 | const VkPipelineDynamicStateCreateInfo dynamic_state_ci{ | 826 | const VkPipelineDynamicStateCreateInfo dynamic_state_ci{ |
| 816 | .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | 827 | .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 58b955821..1292b6bdf 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -351,6 +351,14 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | |||
| 351 | LOG_WARNING(Render_Vulkan, "maxVertexInputBindings is too low: {} < {}", | 351 | LOG_WARNING(Render_Vulkan, "maxVertexInputBindings is too low: {} < {}", |
| 352 | device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays); | 352 | device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays); |
| 353 | } | 353 | } |
| 354 | |||
| 355 | dynamic_features = DynamicFeatures{ | ||
| 356 | .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(), | ||
| 357 | .has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported(), | ||
| 358 | .has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported(), | ||
| 359 | .has_extended_dynamic_state_3 = device.IsExtExtendedDynamicState3Supported(), | ||
| 360 | .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(), | ||
| 361 | }; | ||
| 354 | } | 362 | } |
| 355 | 363 | ||
| 356 | PipelineCache::~PipelineCache() = default; | 364 | PipelineCache::~PipelineCache() = default; |
| @@ -362,8 +370,7 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() { | |||
| 362 | current_pipeline = nullptr; | 370 | current_pipeline = nullptr; |
| 363 | return nullptr; | 371 | return nullptr; |
| 364 | } | 372 | } |
| 365 | graphics_key.state.Refresh(*maxwell3d, device.IsExtExtendedDynamicStateSupported(), | 373 | graphics_key.state.Refresh(*maxwell3d, dynamic_features); |
| 366 | device.IsExtVertexInputDynamicStateSupported()); | ||
| 367 | 374 | ||
| 368 | if (current_pipeline) { | 375 | if (current_pipeline) { |
| 369 | GraphicsPipeline* const next{current_pipeline->Next(graphics_key)}; | 376 | GraphicsPipeline* const next{current_pipeline->Next(graphics_key)}; |
| @@ -439,14 +446,17 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading | |||
| 439 | }); | 446 | }); |
| 440 | ++state.total; | 447 | ++state.total; |
| 441 | }}; | 448 | }}; |
| 442 | const bool extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(); | ||
| 443 | const bool dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(); | ||
| 444 | const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) { | 449 | const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) { |
| 445 | GraphicsPipelineCacheKey key; | 450 | GraphicsPipelineCacheKey key; |
| 446 | file.read(reinterpret_cast<char*>(&key), sizeof(key)); | 451 | file.read(reinterpret_cast<char*>(&key), sizeof(key)); |
| 447 | 452 | ||
| 448 | if ((key.state.extended_dynamic_state != 0) != extended_dynamic_state || | 453 | if ((key.state.extended_dynamic_state != 0) != |
| 449 | (key.state.dynamic_vertex_input != 0) != dynamic_vertex_input) { | 454 | dynamic_features.has_extended_dynamic_state || |
| 455 | (key.state.extended_dynamic_state_2 != 0) != | ||
| 456 | dynamic_features.has_extended_dynamic_state_2 || | ||
| 457 | (key.state.extended_dynamic_state_3 != 0) != | ||
| 458 | dynamic_features.has_extended_dynamic_state_3 || | ||
| 459 | (key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) { | ||
| 450 | return; | 460 | return; |
| 451 | } | 461 | } |
| 452 | workers.QueueWork([this, key, envs = std::move(envs), &state, &callback]() mutable { | 462 | workers.QueueWork([this, key, envs = std::move(envs), &state, &callback]() mutable { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 61f9e9366..b4f593ef5 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -160,6 +160,7 @@ private: | |||
| 160 | 160 | ||
| 161 | Common::ThreadWorker workers; | 161 | Common::ThreadWorker workers; |
| 162 | Common::ThreadWorker serialization_thread; | 162 | Common::ThreadWorker serialization_thread; |
| 163 | DynamicFeatures dynamic_features; | ||
| 163 | }; | 164 | }; |
| 164 | 165 | ||
| 165 | } // namespace Vulkan | 166 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 6f1adc97f..f52cebc22 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -680,16 +680,26 @@ void RasterizerVulkan::UpdateDynamicStates() { | |||
| 680 | UpdateLineWidth(regs); | 680 | UpdateLineWidth(regs); |
| 681 | if (device.IsExtExtendedDynamicStateSupported()) { | 681 | if (device.IsExtExtendedDynamicStateSupported()) { |
| 682 | UpdateCullMode(regs); | 682 | UpdateCullMode(regs); |
| 683 | UpdateDepthBoundsTestEnable(regs); | 683 | |
| 684 | UpdateDepthTestEnable(regs); | ||
| 685 | UpdateDepthWriteEnable(regs); | ||
| 686 | UpdateDepthCompareOp(regs); | 684 | UpdateDepthCompareOp(regs); |
| 687 | UpdateFrontFace(regs); | 685 | UpdateFrontFace(regs); |
| 688 | UpdateStencilOp(regs); | 686 | UpdateStencilOp(regs); |
| 689 | UpdateStencilTestEnable(regs); | 687 | |
| 690 | if (device.IsExtVertexInputDynamicStateSupported()) { | 688 | if (device.IsExtVertexInputDynamicStateSupported()) { |
| 691 | UpdateVertexInput(regs); | 689 | UpdateVertexInput(regs); |
| 692 | } | 690 | } |
| 691 | |||
| 692 | if (state_tracker.TouchStateEnable()) { | ||
| 693 | UpdateDepthBoundsTestEnable(regs); | ||
| 694 | UpdateDepthTestEnable(regs); | ||
| 695 | UpdateDepthWriteEnable(regs); | ||
| 696 | UpdateStencilTestEnable(regs); | ||
| 697 | if (device.IsExtExtendedDynamicState2Supported()) { | ||
| 698 | UpdatePrimitiveRestartEnable(regs); | ||
| 699 | UpdateRasterizerDiscardEnable(regs); | ||
| 700 | UpdateDepthBiasEnable(regs); | ||
| 701 | } | ||
| 702 | } | ||
| 693 | } | 703 | } |
| 694 | } | 704 | } |
| 695 | 705 | ||
| @@ -909,6 +919,58 @@ void RasterizerVulkan::UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& r | |||
| 909 | }); | 919 | }); |
| 910 | } | 920 | } |
| 911 | 921 | ||
| 922 | void RasterizerVulkan::UpdatePrimitiveRestartEnable(Tegra::Engines::Maxwell3D::Regs& regs) { | ||
| 923 | if (!state_tracker.TouchPrimitiveRestartEnable()) { | ||
| 924 | return; | ||
| 925 | } | ||
| 926 | scheduler.Record([enable = regs.primitive_restart.enabled](vk::CommandBuffer cmdbuf) { | ||
| 927 | cmdbuf.SetPrimitiveRestartEnableEXT(enable); | ||
| 928 | }); | ||
| 929 | } | ||
| 930 | |||
| 931 | void RasterizerVulkan::UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs) { | ||
| 932 | if (!state_tracker.TouchRasterizerDiscardEnable()) { | ||
| 933 | return; | ||
| 934 | } | ||
| 935 | scheduler.Record([disable = regs.rasterize_enable](vk::CommandBuffer cmdbuf) { | ||
| 936 | cmdbuf.SetRasterizerDiscardEnableEXT(disable == 0); | ||
| 937 | }); | ||
| 938 | } | ||
| 939 | |||
| 940 | void RasterizerVulkan::UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs) { | ||
| 941 | if (!state_tracker.TouchDepthBiasEnable()) { | ||
| 942 | return; | ||
| 943 | } | ||
| 944 | constexpr size_t POINT = 0; | ||
| 945 | constexpr size_t LINE = 1; | ||
| 946 | constexpr size_t POLYGON = 2; | ||
| 947 | constexpr std::array POLYGON_OFFSET_ENABLE_LUT = { | ||
| 948 | POINT, // Points | ||
| 949 | LINE, // Lines | ||
| 950 | LINE, // LineLoop | ||
| 951 | LINE, // LineStrip | ||
| 952 | POLYGON, // Triangles | ||
| 953 | POLYGON, // TriangleStrip | ||
| 954 | POLYGON, // TriangleFan | ||
| 955 | POLYGON, // Quads | ||
| 956 | POLYGON, // QuadStrip | ||
| 957 | POLYGON, // Polygon | ||
| 958 | LINE, // LinesAdjacency | ||
| 959 | LINE, // LineStripAdjacency | ||
| 960 | POLYGON, // TrianglesAdjacency | ||
| 961 | POLYGON, // TriangleStripAdjacency | ||
| 962 | POLYGON, // Patches | ||
| 963 | }; | ||
| 964 | const std::array enabled_lut{ | ||
| 965 | regs.polygon_offset_point_enable, | ||
| 966 | regs.polygon_offset_line_enable, | ||
| 967 | regs.polygon_offset_fill_enable, | ||
| 968 | }; | ||
| 969 | const u32 topology_index = static_cast<u32>(maxwell3d->draw_manager->GetDrawState().topology); | ||
| 970 | const u32 enable = enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]]; | ||
| 971 | scheduler.Record([enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthBiasEnableEXT(enable); }); | ||
| 972 | } | ||
| 973 | |||
| 912 | void RasterizerVulkan::UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs) { | 974 | void RasterizerVulkan::UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 913 | if (!state_tracker.TouchDepthCompareOp()) { | 975 | if (!state_tracker.TouchDepthCompareOp()) { |
| 914 | return; | 976 | return; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 43a210da0..c09415a6a 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -139,6 +139,9 @@ private: | |||
| 139 | void UpdateDepthTestEnable(Tegra::Engines::Maxwell3D::Regs& regs); | 139 | void UpdateDepthTestEnable(Tegra::Engines::Maxwell3D::Regs& regs); |
| 140 | void UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs); | 140 | void UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs); |
| 141 | void UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs); | 141 | void UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs); |
| 142 | void UpdatePrimitiveRestartEnable(Tegra::Engines::Maxwell3D::Regs& regs); | ||
| 143 | void UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs); | ||
| 144 | void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs); | ||
| 142 | void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs); | 145 | void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs); |
| 143 | void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs); | 146 | void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs); |
| 144 | void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs); | 147 | void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs); |
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index edb41b171..339679ff9 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp | |||
| @@ -27,10 +27,27 @@ using Flags = Maxwell3D::DirtyState::Flags; | |||
| 27 | 27 | ||
| 28 | Flags MakeInvalidationFlags() { | 28 | Flags MakeInvalidationFlags() { |
| 29 | static constexpr int INVALIDATION_FLAGS[]{ | 29 | static constexpr int INVALIDATION_FLAGS[]{ |
| 30 | Viewports, Scissors, DepthBias, BlendConstants, DepthBounds, | 30 | Viewports, |
| 31 | StencilProperties, LineWidth, CullMode, DepthBoundsEnable, DepthTestEnable, | 31 | Scissors, |
| 32 | DepthWriteEnable, DepthCompareOp, FrontFace, StencilOp, StencilTestEnable, | 32 | DepthBias, |
| 33 | VertexBuffers, VertexInput, | 33 | BlendConstants, |
| 34 | DepthBounds, | ||
| 35 | StencilProperties, | ||
| 36 | LineWidth, | ||
| 37 | CullMode, | ||
| 38 | DepthBoundsEnable, | ||
| 39 | DepthTestEnable, | ||
| 40 | DepthWriteEnable, | ||
| 41 | DepthCompareOp, | ||
| 42 | FrontFace, | ||
| 43 | StencilOp, | ||
| 44 | StencilTestEnable, | ||
| 45 | VertexBuffers, | ||
| 46 | VertexInput, | ||
| 47 | StateEnable, | ||
| 48 | PrimitiveRestartEnable, | ||
| 49 | RasterizerDiscardEnable, | ||
| 50 | DepthBiasEnable, | ||
| 34 | }; | 51 | }; |
| 35 | Flags flags{}; | 52 | Flags flags{}; |
| 36 | for (const int flag : INVALIDATION_FLAGS) { | 53 | for (const int flag : INVALIDATION_FLAGS) { |
| @@ -96,16 +113,20 @@ void SetupDirtyCullMode(Tables& tables) { | |||
| 96 | table[OFF(gl_cull_test_enabled)] = CullMode; | 113 | table[OFF(gl_cull_test_enabled)] = CullMode; |
| 97 | } | 114 | } |
| 98 | 115 | ||
| 99 | void SetupDirtyDepthBoundsEnable(Tables& tables) { | 116 | void SetupDirtyStateEnable(Tables& tables) { |
| 100 | tables[0][OFF(depth_bounds_enable)] = DepthBoundsEnable; | 117 | const auto setup = [&](size_t position, u8 flag) { |
| 101 | } | 118 | tables[0][position] = flag; |
| 102 | 119 | tables[1][position] = StateEnable; | |
| 103 | void SetupDirtyDepthTestEnable(Tables& tables) { | 120 | }; |
| 104 | tables[0][OFF(depth_test_enable)] = DepthTestEnable; | 121 | setup(OFF(depth_bounds_enable), DepthBoundsEnable); |
| 105 | } | 122 | setup(OFF(depth_test_enable), DepthTestEnable); |
| 106 | 123 | setup(OFF(depth_write_enabled), DepthWriteEnable); | |
| 107 | void SetupDirtyDepthWriteEnable(Tables& tables) { | 124 | setup(OFF(stencil_enable), StencilTestEnable); |
| 108 | tables[0][OFF(depth_write_enabled)] = DepthWriteEnable; | 125 | setup(OFF(primitive_restart.enabled), PrimitiveRestartEnable); |
| 126 | setup(OFF(rasterize_enable), RasterizerDiscardEnable); | ||
| 127 | setup(OFF(polygon_offset_point_enable), DepthBiasEnable); | ||
| 128 | setup(OFF(polygon_offset_line_enable), DepthBiasEnable); | ||
| 129 | setup(OFF(polygon_offset_fill_enable), DepthBiasEnable); | ||
| 109 | } | 130 | } |
| 110 | 131 | ||
| 111 | void SetupDirtyDepthCompareOp(Tables& tables) { | 132 | void SetupDirtyDepthCompareOp(Tables& tables) { |
| @@ -133,10 +154,6 @@ void SetupDirtyStencilOp(Tables& tables) { | |||
| 133 | tables[1][OFF(stencil_two_side_enable)] = StencilOp; | 154 | tables[1][OFF(stencil_two_side_enable)] = StencilOp; |
| 134 | } | 155 | } |
| 135 | 156 | ||
| 136 | void SetupDirtyStencilTestEnable(Tables& tables) { | ||
| 137 | tables[0][OFF(stencil_enable)] = StencilTestEnable; | ||
| 138 | } | ||
| 139 | |||
| 140 | void SetupDirtyBlending(Tables& tables) { | 157 | void SetupDirtyBlending(Tables& tables) { |
| 141 | tables[0][OFF(color_mask_common)] = Blending; | 158 | tables[0][OFF(color_mask_common)] = Blending; |
| 142 | tables[0][OFF(blend_per_target_enabled)] = Blending; | 159 | tables[0][OFF(blend_per_target_enabled)] = Blending; |
| @@ -185,13 +202,10 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) { | |||
| 185 | SetupDirtyStencilProperties(tables); | 202 | SetupDirtyStencilProperties(tables); |
| 186 | SetupDirtyLineWidth(tables); | 203 | SetupDirtyLineWidth(tables); |
| 187 | SetupDirtyCullMode(tables); | 204 | SetupDirtyCullMode(tables); |
| 188 | SetupDirtyDepthBoundsEnable(tables); | 205 | SetupDirtyStateEnable(tables); |
| 189 | SetupDirtyDepthTestEnable(tables); | ||
| 190 | SetupDirtyDepthWriteEnable(tables); | ||
| 191 | SetupDirtyDepthCompareOp(tables); | 206 | SetupDirtyDepthCompareOp(tables); |
| 192 | SetupDirtyFrontFace(tables); | 207 | SetupDirtyFrontFace(tables); |
| 193 | SetupDirtyStencilOp(tables); | 208 | SetupDirtyStencilOp(tables); |
| 194 | SetupDirtyStencilTestEnable(tables); | ||
| 195 | SetupDirtyBlending(tables); | 209 | SetupDirtyBlending(tables); |
| 196 | SetupDirtyViewportSwizzles(tables); | 210 | SetupDirtyViewportSwizzles(tables); |
| 197 | SetupDirtyVertexAttributes(tables); | 211 | SetupDirtyVertexAttributes(tables); |
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 2296dea60..583bfe135 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h | |||
| @@ -45,6 +45,10 @@ enum : u8 { | |||
| 45 | FrontFace, | 45 | FrontFace, |
| 46 | StencilOp, | 46 | StencilOp, |
| 47 | StencilTestEnable, | 47 | StencilTestEnable, |
| 48 | PrimitiveRestartEnable, | ||
| 49 | RasterizerDiscardEnable, | ||
| 50 | DepthBiasEnable, | ||
| 51 | StateEnable, | ||
| 48 | 52 | ||
| 49 | Blending, | 53 | Blending, |
| 50 | ViewportSwizzles, | 54 | ViewportSwizzles, |
| @@ -111,6 +115,10 @@ public: | |||
| 111 | return Exchange(Dirty::CullMode, false); | 115 | return Exchange(Dirty::CullMode, false); |
| 112 | } | 116 | } |
| 113 | 117 | ||
| 118 | bool TouchStateEnable() { | ||
| 119 | return Exchange(Dirty::StateEnable, false); | ||
| 120 | } | ||
| 121 | |||
| 114 | bool TouchDepthBoundsTestEnable() { | 122 | bool TouchDepthBoundsTestEnable() { |
| 115 | return Exchange(Dirty::DepthBoundsEnable, false); | 123 | return Exchange(Dirty::DepthBoundsEnable, false); |
| 116 | } | 124 | } |
| @@ -123,6 +131,18 @@ public: | |||
| 123 | return Exchange(Dirty::DepthWriteEnable, false); | 131 | return Exchange(Dirty::DepthWriteEnable, false); |
| 124 | } | 132 | } |
| 125 | 133 | ||
| 134 | bool TouchPrimitiveRestartEnable() { | ||
| 135 | return Exchange(Dirty::PrimitiveRestartEnable, false); | ||
| 136 | } | ||
| 137 | |||
| 138 | bool TouchRasterizerDiscardEnable() { | ||
| 139 | return Exchange(Dirty::RasterizerDiscardEnable, false); | ||
| 140 | } | ||
| 141 | |||
| 142 | bool TouchDepthBiasEnable() { | ||
| 143 | return Exchange(Dirty::DepthBiasEnable, false); | ||
| 144 | } | ||
| 145 | |||
| 126 | bool TouchDepthCompareOp() { | 146 | bool TouchDepthCompareOp() { |
| 127 | return Exchange(Dirty::DepthCompareOp, false); | 147 | return Exchange(Dirty::DepthCompareOp, false); |
| 128 | } | 148 | } |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 207fae8c9..9a420a293 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -569,6 +569,34 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 569 | LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state"); | 569 | LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state"); |
| 570 | } | 570 | } |
| 571 | 571 | ||
| 572 | VkPhysicalDeviceExtendedDynamicState2FeaturesEXT dynamic_state2; | ||
| 573 | if (ext_extended_dynamic_state2) { | ||
| 574 | dynamic_state2 = { | ||
| 575 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, | ||
| 576 | .pNext = nullptr, | ||
| 577 | .extendedDynamicState2 = VK_TRUE, | ||
| 578 | .extendedDynamicState2LogicOp = ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE, | ||
| 579 | .extendedDynamicState2PatchControlPoints = | ||
| 580 | ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE, | ||
| 581 | }; | ||
| 582 | SetNext(next, dynamic_state2); | ||
| 583 | } else { | ||
| 584 | LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state 2"); | ||
| 585 | } | ||
| 586 | |||
| 587 | VkPhysicalDeviceExtendedDynamicState3FeaturesEXT dynamic_state3; | ||
| 588 | if (ext_extended_dynamic_state3) { | ||
| 589 | dynamic_state3 = { | ||
| 590 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, | ||
| 591 | .pNext = nullptr, | ||
| 592 | .extendedDynamicState3ColorBlendEnable = VK_TRUE, | ||
| 593 | .extendedDynamicState3ColorBlendEquation = VK_TRUE, | ||
| 594 | }; | ||
| 595 | SetNext(next, dynamic_state3); | ||
| 596 | } else { | ||
| 597 | LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state 3"); | ||
| 598 | } | ||
| 599 | |||
| 572 | VkPhysicalDeviceLineRasterizationFeaturesEXT line_raster; | 600 | VkPhysicalDeviceLineRasterizationFeaturesEXT line_raster; |
| 573 | if (ext_line_rasterization) { | 601 | if (ext_line_rasterization) { |
| 574 | line_raster = { | 602 | line_raster = { |
| @@ -1091,6 +1119,8 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1091 | bool has_ext_transform_feedback{}; | 1119 | bool has_ext_transform_feedback{}; |
| 1092 | bool has_ext_custom_border_color{}; | 1120 | bool has_ext_custom_border_color{}; |
| 1093 | bool has_ext_extended_dynamic_state{}; | 1121 | bool has_ext_extended_dynamic_state{}; |
| 1122 | bool has_ext_extended_dynamic_state2{}; | ||
| 1123 | bool has_ext_extended_dynamic_state3{}; | ||
| 1094 | bool has_ext_shader_atomic_int64{}; | 1124 | bool has_ext_shader_atomic_int64{}; |
| 1095 | bool has_ext_provoking_vertex{}; | 1125 | bool has_ext_provoking_vertex{}; |
| 1096 | bool has_ext_vertex_input_dynamic_state{}; | 1126 | bool has_ext_vertex_input_dynamic_state{}; |
| @@ -1135,6 +1165,10 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1135 | test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false); | 1165 | test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false); |
| 1136 | test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); | 1166 | test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); |
| 1137 | test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); | 1167 | test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); |
| 1168 | test(has_ext_extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME, | ||
| 1169 | false); | ||
| 1170 | test(has_ext_extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, | ||
| 1171 | false); | ||
| 1138 | test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, true); | 1172 | test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, true); |
| 1139 | test(has_ext_provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, false); | 1173 | test(has_ext_provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, false); |
| 1140 | test(has_ext_vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME, | 1174 | test(has_ext_vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME, |
| @@ -1284,6 +1318,36 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1284 | ext_extended_dynamic_state = true; | 1318 | ext_extended_dynamic_state = true; |
| 1285 | } | 1319 | } |
| 1286 | } | 1320 | } |
| 1321 | if (has_ext_extended_dynamic_state2) { | ||
| 1322 | VkPhysicalDeviceExtendedDynamicState2FeaturesEXT extended_dynamic_state2; | ||
| 1323 | extended_dynamic_state2.sType = | ||
| 1324 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT; | ||
| 1325 | extended_dynamic_state2.pNext = nullptr; | ||
| 1326 | features.pNext = &extended_dynamic_state2; | ||
| 1327 | physical.GetFeatures2(features); | ||
| 1328 | |||
| 1329 | if (extended_dynamic_state2.extendedDynamicState2) { | ||
| 1330 | extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); | ||
| 1331 | ext_extended_dynamic_state2 = true; | ||
| 1332 | ext_extended_dynamic_state2_extra = | ||
| 1333 | extended_dynamic_state2.extendedDynamicState2LogicOp && | ||
| 1334 | extended_dynamic_state2.extendedDynamicState2PatchControlPoints; | ||
| 1335 | } | ||
| 1336 | } | ||
| 1337 | if (has_ext_extended_dynamic_state3) { | ||
| 1338 | VkPhysicalDeviceExtendedDynamicState3FeaturesEXT extended_dynamic_state3; | ||
| 1339 | extended_dynamic_state3.sType = | ||
| 1340 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT; | ||
| 1341 | extended_dynamic_state3.pNext = nullptr; | ||
| 1342 | features.pNext = &extended_dynamic_state3; | ||
| 1343 | physical.GetFeatures2(features); | ||
| 1344 | |||
| 1345 | if (extended_dynamic_state3.extendedDynamicState3ColorBlendEnable && | ||
| 1346 | extended_dynamic_state3.extendedDynamicState3ColorBlendEquation) { | ||
| 1347 | extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); | ||
| 1348 | ext_extended_dynamic_state3 = true; | ||
| 1349 | } | ||
| 1350 | } | ||
| 1287 | if (has_ext_line_rasterization) { | 1351 | if (has_ext_line_rasterization) { |
| 1288 | VkPhysicalDeviceLineRasterizationFeaturesEXT line_raster; | 1352 | VkPhysicalDeviceLineRasterizationFeaturesEXT line_raster; |
| 1289 | line_raster.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT; | 1353 | line_raster.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT; |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index d0d7c2299..51b049c0d 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -286,6 +286,20 @@ public: | |||
| 286 | return ext_extended_dynamic_state; | 286 | return ext_extended_dynamic_state; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | /// Returns true if the device supports VK_EXT_extended_dynamic_state2. | ||
| 290 | bool IsExtExtendedDynamicState2Supported() const { | ||
| 291 | return ext_extended_dynamic_state2; | ||
| 292 | } | ||
| 293 | |||
| 294 | bool IsExtExtendedDynamicState2ExtrasSupported() const { | ||
| 295 | return ext_extended_dynamic_state2_extra; | ||
| 296 | } | ||
| 297 | |||
| 298 | /// Returns true if the device supports VK_EXT_extended_dynamic_state3. | ||
| 299 | bool IsExtExtendedDynamicState3Supported() const { | ||
| 300 | return ext_extended_dynamic_state3; | ||
| 301 | } | ||
| 302 | |||
| 289 | /// Returns true if the device supports VK_EXT_line_rasterization. | 303 | /// Returns true if the device supports VK_EXT_line_rasterization. |
| 290 | bool IsExtLineRasterizationSupported() const { | 304 | bool IsExtLineRasterizationSupported() const { |
| 291 | return ext_line_rasterization; | 305 | return ext_line_rasterization; |
| @@ -468,6 +482,9 @@ private: | |||
| 468 | bool ext_transform_feedback{}; ///< Support for VK_EXT_transform_feedback. | 482 | bool ext_transform_feedback{}; ///< Support for VK_EXT_transform_feedback. |
| 469 | bool ext_custom_border_color{}; ///< Support for VK_EXT_custom_border_color. | 483 | bool ext_custom_border_color{}; ///< Support for VK_EXT_custom_border_color. |
| 470 | bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state. | 484 | bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state. |
| 485 | bool ext_extended_dynamic_state2{}; ///< Support for VK_EXT_extended_dynamic_state2. | ||
| 486 | bool ext_extended_dynamic_state2_extra{}; ///< Support for VK_EXT_extended_dynamic_state2. | ||
| 487 | bool ext_extended_dynamic_state3{}; ///< Support for VK_EXT_extended_dynamic_state3. | ||
| 471 | bool ext_line_rasterization{}; ///< Support for VK_EXT_line_rasterization. | 488 | bool ext_line_rasterization{}; ///< Support for VK_EXT_line_rasterization. |
| 472 | bool ext_vertex_input_dynamic_state{}; ///< Support for VK_EXT_vertex_input_dynamic_state. | 489 | bool ext_vertex_input_dynamic_state{}; ///< Support for VK_EXT_vertex_input_dynamic_state. |
| 473 | bool ext_shader_stencil_export{}; ///< Support for VK_EXT_shader_stencil_export. | 490 | bool ext_shader_stencil_export{}; ///< Support for VK_EXT_shader_stencil_export. |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index f8f8ed9f8..4dde325ff 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -122,6 +122,9 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 122 | X(vkCmdSetDepthCompareOpEXT); | 122 | X(vkCmdSetDepthCompareOpEXT); |
| 123 | X(vkCmdSetDepthTestEnableEXT); | 123 | X(vkCmdSetDepthTestEnableEXT); |
| 124 | X(vkCmdSetDepthWriteEnableEXT); | 124 | X(vkCmdSetDepthWriteEnableEXT); |
| 125 | X(vkCmdSetPrimitiveRestartEnableEXT); | ||
| 126 | X(vkCmdSetRasterizerDiscardEnableEXT); | ||
| 127 | X(vkCmdSetDepthBiasEnableEXT); | ||
| 125 | X(vkCmdSetFrontFaceEXT); | 128 | X(vkCmdSetFrontFaceEXT); |
| 126 | X(vkCmdSetLineWidth); | 129 | X(vkCmdSetLineWidth); |
| 127 | X(vkCmdSetPrimitiveTopologyEXT); | 130 | X(vkCmdSetPrimitiveTopologyEXT); |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 493a48573..0d3f71460 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -234,6 +234,9 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 234 | PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT{}; | 234 | PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT{}; |
| 235 | PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT{}; | 235 | PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT{}; |
| 236 | PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT{}; | 236 | PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT{}; |
| 237 | PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT{}; | ||
| 238 | PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT{}; | ||
| 239 | PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{}; | ||
| 237 | PFN_vkCmdSetEvent vkCmdSetEvent{}; | 240 | PFN_vkCmdSetEvent vkCmdSetEvent{}; |
| 238 | PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{}; | 241 | PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{}; |
| 239 | PFN_vkCmdSetLineWidth vkCmdSetLineWidth{}; | 242 | PFN_vkCmdSetLineWidth vkCmdSetLineWidth{}; |
| @@ -1219,6 +1222,18 @@ public: | |||
| 1219 | dld->vkCmdSetDepthWriteEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); | 1222 | dld->vkCmdSetDepthWriteEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); |
| 1220 | } | 1223 | } |
| 1221 | 1224 | ||
| 1225 | void SetPrimitiveRestartEnableEXT(bool enable) const noexcept { | ||
| 1226 | dld->vkCmdSetPrimitiveRestartEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | void SetRasterizerDiscardEnableEXT(bool enable) const noexcept { | ||
| 1230 | dld->vkCmdSetRasterizerDiscardEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | void SetDepthBiasEnableEXT(bool enable) const noexcept { | ||
| 1234 | dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); | ||
| 1235 | } | ||
| 1236 | |||
| 1222 | void SetFrontFaceEXT(VkFrontFace front_face) const noexcept { | 1237 | void SetFrontFaceEXT(VkFrontFace front_face) const noexcept { |
| 1223 | dld->vkCmdSetFrontFaceEXT(handle, front_face); | 1238 | dld->vkCmdSetFrontFaceEXT(handle, front_face); |
| 1224 | } | 1239 | } |