summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan/fixed_pipeline_state.cpp')
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp92
1 files changed, 67 insertions, 25 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 362278f01..d70153df3 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -15,9 +15,7 @@
#include "video_core/renderer_vulkan/vk_state_tracker.h"
namespace Vulkan {
-
namespace {
-
constexpr size_t POINT = 0;
constexpr size_t LINE = 1;
constexpr size_t POLYGON = 2;
@@ -39,10 +37,20 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
POLYGON, // Patches
};
+void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
+ std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) {
+ return VideoCommon::TransformFeedbackState::Layout{
+ .stream = layout.stream,
+ .varying_count = layout.varying_count,
+ .stride = layout.stride,
+ };
+ });
+ state.varyings = regs.tfb_varying_locs;
+}
} // Anonymous namespace
void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
- bool has_extended_dynamic_state) {
+ bool has_extended_dynamic_state, bool has_dynamic_vertex_input) {
const Maxwell& regs = maxwell3d.regs;
const std::array enabled_lut{
regs.polygon_offset_point_enable,
@@ -52,6 +60,9 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
raw1 = 0;
+ extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0);
+ dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0);
+ xfb_enabled.Assign(regs.tfb_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.view_volume_clip_control.depth_clamp_disabled.Value());
@@ -63,37 +74,66 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
tessellation_clockwise.Assign(regs.tess_mode.cw.Value());
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
logic_op.Assign(PackLogicOp(regs.logic_op.operation));
- rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
topology.Assign(regs.draw.topology);
msaa_mode.Assign(regs.multisample_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;
alpha_test_func.Assign(PackComparisonOp(test_func));
early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
-
+ depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0);
+ depth_format.Assign(static_cast<u32>(regs.zeta.format));
+ y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0);
+ provoking_vertex_last.Assign(regs.provoking_vertex_last != 0 ? 1 : 0);
+ conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
+ smooth_lines.Assign(regs.line_smooth_enable != 0 ? 1 : 0);
+
+ for (size_t i = 0; i < regs.rt.size(); ++i) {
+ color_formats[i] = static_cast<u8>(regs.rt[i].format);
+ }
alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
point_size = Common::BitCast<u32>(regs.point_size);
- if (maxwell3d.dirty.flags[Dirty::InstanceDivisors]) {
- maxwell3d.dirty.flags[Dirty::InstanceDivisors] = false;
- for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
- const bool is_enabled = regs.instanced_arrays.IsInstancingEnabled(index);
- binding_divisors[index] = is_enabled ? regs.vertex_array[index].divisor : 0;
- }
- }
- if (maxwell3d.dirty.flags[Dirty::VertexAttributes]) {
- maxwell3d.dirty.flags[Dirty::VertexAttributes] = false;
- for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
- const auto& input = regs.vertex_attrib_format[index];
- auto& attribute = attributes[index];
- attribute.raw = 0;
- attribute.enabled.Assign(input.IsConstant() ? 0 : 1);
- attribute.buffer.Assign(input.buffer);
- attribute.offset.Assign(input.offset);
- attribute.type.Assign(static_cast<u32>(input.type.Value()));
- attribute.size.Assign(static_cast<u32>(input.size.Value()));
+ if (maxwell3d.dirty.flags[Dirty::VertexInput]) {
+ if (has_dynamic_vertex_input) {
+ // Dirty flag will be reset by the command buffer update
+ static constexpr std::array LUT{
+ 0u, // Invalid
+ 1u, // SignedNorm
+ 1u, // UnsignedNorm
+ 2u, // SignedInt
+ 3u, // UnsignedInt
+ 1u, // UnsignedScaled
+ 1u, // SignedScaled
+ 1u, // Float
+ };
+ const auto& attrs = regs.vertex_attrib_format;
+ attribute_types = 0;
+ for (size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) {
+ const u32 mask = attrs[i].constant != 0 ? 0 : 3;
+ const u32 type = LUT[static_cast<size_t>(attrs[i].type.Value())];
+ attribute_types |= static_cast<u64>(type & mask) << (i * 2);
+ }
+ } else {
+ maxwell3d.dirty.flags[Dirty::VertexInput] = false;
+ enabled_divisors = 0;
+ for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
+ const bool is_enabled = regs.instanced_arrays.IsInstancingEnabled(index);
+ binding_divisors[index] = is_enabled ? regs.vertex_array[index].divisor : 0;
+ enabled_divisors |= (is_enabled ? u64{1} : 0) << index;
+ }
+ for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
+ const auto& input = regs.vertex_attrib_format[index];
+ auto& attribute = attributes[index];
+ attribute.raw = 0;
+ attribute.enabled.Assign(input.constant ? 0 : 1);
+ attribute.buffer.Assign(input.buffer);
+ attribute.offset.Assign(input.offset);
+ attribute.type.Assign(static_cast<u32>(input.type.Value()));
+ attribute.size.Assign(static_cast<u32>(input.size.Value()));
+ }
}
}
if (maxwell3d.dirty.flags[Dirty::Blending]) {
@@ -109,10 +149,12 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
return static_cast<u16>(viewport.swizzle.raw);
});
}
- if (!has_extended_dynamic_state) {
- no_extended_dynamic_state.Assign(1);
+ if (!extended_dynamic_state) {
dynamic_state.Refresh(regs);
}
+ if (xfb_enabled) {
+ RefreshXfbState(xfb_state, regs);
+ }
}
void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t index) {