diff options
Diffstat (limited to 'src/video_core/renderer_vulkan/fixed_pipeline_state.cpp')
-rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | 119 |
1 files changed, 69 insertions, 50 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index e62b36822..3d328a250 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -48,43 +48,30 @@ void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& } } // Anonymous namespace -void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, - bool has_extended_dynamic_state, bool has_dynamic_vertex_input) { +void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features) { const Maxwell& regs = maxwell3d.regs; const auto topology_ = maxwell3d.draw_manager->GetDrawState().topology; - const std::array enabled_lut{ - regs.polygon_offset_point_enable, - regs.polygon_offset_line_enable, - regs.polygon_offset_fill_enable, - }; - const u32 topology_index = static_cast<u32>(topology_); raw1 = 0; - extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0); - dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0); + extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0); + extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0); + extended_dynamic_state_2_extra.Assign(features.has_extended_dynamic_state_2_extra ? 1 : 0); + extended_dynamic_state_3_blend.Assign(features.has_extended_dynamic_state_3_blend ? 1 : 0); + extended_dynamic_state_3_enables.Assign(features.has_extended_dynamic_state_3_enables ? 1 : 0); + dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0); xfb_enabled.Assign(regs.transform_feedback_enabled != 0); - primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); - depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); - depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip == - Maxwell::ViewportClipControl::GeometryClip::Passthrough || - regs.viewport_clip_control.geometry_clip == - Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ || - regs.viewport_clip_control.geometry_clip == - Maxwell::ViewportClipControl::GeometryClip::FrustumZ); ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); - patch_control_points_minus_one.Assign(regs.patch_vertices - 1); tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value())); tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value())); tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() == Maxwell::Tessellation::OutputPrimitives::Triangles_CW); - logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); - logic_op.Assign(PackLogicOp(regs.logic_op.op)); + patch_control_points_minus_one.Assign(regs.patch_vertices - 1); topology.Assign(topology_); msaa_mode.Assign(regs.anti_alias_samples_mode); raw2 = 0; - rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); + const auto test_func = regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL; alpha_test_func.Assign(PackComparisonOp(test_func)); @@ -97,6 +84,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0); alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0); alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0); + app_stage.Assign(maxwell3d.engine_state); for (size_t i = 0; i < regs.rt.size(); ++i) { color_formats[i] = static_cast<u8>(regs.rt[i].format); @@ -105,7 +93,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, point_size = Common::BitCast<u32>(regs.point_size); if (maxwell3d.dirty.flags[Dirty::VertexInput]) { - if (has_dynamic_vertex_input) { + if (features.has_dynamic_vertex_input) { // Dirty flag will be reset by the command buffer update static constexpr std::array LUT{ 0u, // Invalid @@ -144,12 +132,6 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, } } } - if (maxwell3d.dirty.flags[Dirty::Blending]) { - maxwell3d.dirty.flags[Dirty::Blending] = false; - for (size_t index = 0; index < attachments.size(); ++index) { - attachments[index].Refresh(regs, index); - } - } if (maxwell3d.dirty.flags[Dirty::ViewportSwizzles]) { maxwell3d.dirty.flags[Dirty::ViewportSwizzles] = false; const auto& transform = regs.viewport_transform; @@ -157,8 +139,27 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, return static_cast<u16>(viewport.swizzle.raw); }); } + dynamic_state.raw1 = 0; + dynamic_state.raw2 = 0; if (!extended_dynamic_state) { dynamic_state.Refresh(regs); + std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) { + return static_cast<u16>(array.stride.Value()); + }); + } + if (!extended_dynamic_state_2_extra) { + dynamic_state.Refresh2(regs, topology, extended_dynamic_state_2); + } + if (!extended_dynamic_state_3_blend) { + if (maxwell3d.dirty.flags[Dirty::Blending]) { + maxwell3d.dirty.flags[Dirty::Blending] = false; + for (size_t index = 0; index < attachments.size(); ++index) { + attachments[index].Refresh(regs, index); + } + } + } + if (!extended_dynamic_state_3_enables) { + dynamic_state.Refresh3(regs); } if (xfb_enabled) { RefreshXfbState(xfb_state, regs); @@ -175,12 +176,11 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t mask_a.Assign(mask.A); // TODO: C++20 Use templated lambda to deduplicate code + if (!regs.blend.enable[index]) { + return; + } - if (!regs.blend_per_target_enabled) { - if (!regs.blend.enable[index]) { - return; - } - const auto& src = regs.blend; + const auto setup_blend = [&]<typename T>(const T& src) { equation_rgb.Assign(PackBlendEquation(src.color_op)); equation_a.Assign(PackBlendEquation(src.alpha_op)); factor_source_rgb.Assign(PackBlendFactor(src.color_source)); @@ -188,20 +188,13 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t factor_source_a.Assign(PackBlendFactor(src.alpha_source)); factor_dest_a.Assign(PackBlendFactor(src.alpha_dest)); enable.Assign(1); - return; - } + }; - if (!regs.blend.enable[index]) { + if (!regs.blend_per_target_enabled) { + setup_blend(regs.blend); return; } - const auto& src = regs.blend_per_target[index]; - equation_rgb.Assign(PackBlendEquation(src.color_op)); - equation_a.Assign(PackBlendEquation(src.alpha_op)); - factor_source_rgb.Assign(PackBlendFactor(src.color_source)); - factor_dest_rgb.Assign(PackBlendFactor(src.color_dest)); - factor_source_a.Assign(PackBlendFactor(src.alpha_source)); - factor_dest_a.Assign(PackBlendFactor(src.alpha_dest)); - enable.Assign(1); + setup_blend(regs.blend_per_target[index]); } void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { @@ -211,8 +204,6 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { packed_front_face = 1 - packed_front_face; } - raw1 = 0; - raw2 = 0; front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op.fail)); front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op.zfail)); front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op.zpass)); @@ -236,9 +227,37 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { depth_test_func.Assign(PackComparisonOp(regs.depth_test_func)); cull_face.Assign(PackCullFace(regs.gl_cull_face)); cull_enable.Assign(regs.gl_cull_test_enabled != 0 ? 1 : 0); - std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) { - return static_cast<u16>(array.stride.Value()); - }); +} + +void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs, + Maxwell::PrimitiveTopology topology_, + bool base_feautures_supported) { + logic_op.Assign(PackLogicOp(regs.logic_op.op)); + + if (base_feautures_supported) { + return; + } + + const std::array enabled_lut{ + regs.polygon_offset_point_enable, + regs.polygon_offset_line_enable, + regs.polygon_offset_fill_enable, + }; + const u32 topology_index = static_cast<u32>(topology_); + + rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); + primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); + depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); +} + +void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs) { + logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); + depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip == + Maxwell::ViewportClipControl::GeometryClip::Passthrough || + regs.viewport_clip_control.geometry_clip == + Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ || + regs.viewport_clip_control.geometry_clip == + Maxwell::ViewportClipControl::GeometryClip::FrustumZ); } size_t FixedPipelineState::Hash() const noexcept { |