Pārlūkot izejas kodu

vulkan/fixed_pipeline_state: Move state out of individual structures

ReinUsesLisp 6 gadi atpakaļ
vecāks
revīzija
1a84209418

+ 21 - 31
src/video_core/renderer_vulkan/fixed_pipeline_state.cpp

@@ -39,24 +39,7 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
 
 } // Anonymous namespace
 
-void FixedPipelineState::VertexInput::Fill(const Maxwell& regs) noexcept {
-    for (std::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()));
-    }
-    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
-        binding_divisors[index] =
-            regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0;
-    }
-}
-
-void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept {
+void FixedPipelineState::Fill(const Maxwell& regs) {
     const auto& clip = regs.view_volume_clip_control;
     const std::array enabled_lut = {regs.polygon_offset_point_enable,
                                     regs.polygon_offset_line_enable,
@@ -76,19 +59,34 @@ void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept {
     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);
+
     std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast
-}
 
-void FixedPipelineState::ColorBlending::Fill(const Maxwell& regs) noexcept {
+    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
+        binding_divisors[index] =
+            regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0;
+    }
+
+    for (std::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()));
+    }
+
     for (std::size_t index = 0; index < std::size(attachments); ++index) {
         attachments[index].Fill(regs, index);
     }
-}
 
-void FixedPipelineState::ViewportSwizzles::Fill(const Maxwell& regs) noexcept {
     const auto& transform = regs.viewport_transform;
-    std::transform(transform.begin(), transform.end(), swizzles.begin(),
+    std::transform(transform.begin(), transform.end(), viewport_swizzles.begin(),
                    [](const auto& viewport) { return static_cast<u16>(viewport.swizzle.raw); });
+
+    dynamic_state.Fill(regs);
 }
 
 void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) {
@@ -174,14 +172,6 @@ void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) {
     }
 }
 
-void FixedPipelineState::Fill(const Maxwell& regs) {
-    vertex_input.Fill(regs);
-    rasterizer.Fill(regs);
-    color_blending.Fill(regs);
-    viewport_swizzles.Fill(regs);
-    dynamic_state.Fill(regs);
-}
-
 std::size_t FixedPipelineState::Hash() const noexcept {
     const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
     return static_cast<std::size_t>(hash);

+ 34 - 60
src/video_core/renderer_vulkan/fixed_pipeline_state.h

@@ -89,63 +89,21 @@ struct FixedPipelineState {
         }
     };
 
-    struct VertexInput {
-        union Attribute {
-            u32 raw;
-            BitField<0, 1, u32> enabled;
-            BitField<1, 5, u32> buffer;
-            BitField<6, 14, u32> offset;
-            BitField<20, 3, u32> type;
-            BitField<23, 6, u32> size;
-
-            constexpr Maxwell::VertexAttribute::Type Type() const noexcept {
-                return static_cast<Maxwell::VertexAttribute::Type>(type.Value());
-            }
-
-            constexpr Maxwell::VertexAttribute::Size Size() const noexcept {
-                return static_cast<Maxwell::VertexAttribute::Size>(size.Value());
-            }
-        };
-
-        std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
-        std::array<Attribute, Maxwell::NumVertexAttributes> attributes;
-
-        void Fill(const Maxwell& regs) noexcept;
-    };
-
-    struct Rasterizer {
-        union {
-            u32 raw;
-            BitField<0, 1, u32> primitive_restart_enable;
-            BitField<1, 1, u32> depth_bias_enable;
-            BitField<2, 1, u32> depth_clamp_disabled;
-            BitField<3, 1, u32> ndc_minus_one_to_one;
-            BitField<4, 2, u32> polygon_mode;
-            BitField<6, 5, u32> patch_control_points_minus_one;
-            BitField<11, 2, u32> tessellation_primitive;
-            BitField<13, 2, u32> tessellation_spacing;
-            BitField<15, 1, u32> tessellation_clockwise;
-            BitField<16, 1, u32> logic_op_enable;
-            BitField<17, 4, u32> logic_op;
-            BitField<21, 1, u32> rasterize_enable;
-        };
-
-        // TODO(Rodrigo): Move this to push constants
-        u32 point_size;
-
-        void Fill(const Maxwell& regs) noexcept;
-    };
-
-    struct ColorBlending {
-        std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments;
-
-        void Fill(const Maxwell& regs) noexcept;
-    };
-
-    struct ViewportSwizzles {
-        std::array<u16, Maxwell::NumViewports> swizzles;
+    union VertexAttribute {
+        u32 raw;
+        BitField<0, 1, u32> enabled;
+        BitField<1, 5, u32> buffer;
+        BitField<6, 14, u32> offset;
+        BitField<20, 3, u32> type;
+        BitField<23, 6, u32> size;
+
+        constexpr Maxwell::VertexAttribute::Type Type() const noexcept {
+            return static_cast<Maxwell::VertexAttribute::Type>(type.Value());
+        }
 
-        void Fill(const Maxwell& regs) noexcept;
+        constexpr Maxwell::VertexAttribute::Size Size() const noexcept {
+            return static_cast<Maxwell::VertexAttribute::Size>(size.Value());
+        }
     };
 
     template <std::size_t Position>
@@ -217,10 +175,26 @@ struct FixedPipelineState {
         }
     };
 
-    VertexInput vertex_input;
-    Rasterizer rasterizer;
-    ColorBlending color_blending;
-    ViewportSwizzles viewport_swizzles;
+    union {
+        u32 raw;
+        BitField<0, 1, u32> primitive_restart_enable;
+        BitField<1, 1, u32> depth_bias_enable;
+        BitField<2, 1, u32> depth_clamp_disabled;
+        BitField<3, 1, u32> ndc_minus_one_to_one;
+        BitField<4, 2, u32> polygon_mode;
+        BitField<6, 5, u32> patch_control_points_minus_one;
+        BitField<11, 2, u32> tessellation_primitive;
+        BitField<13, 2, u32> tessellation_spacing;
+        BitField<15, 1, u32> tessellation_clockwise;
+        BitField<16, 1, u32> logic_op_enable;
+        BitField<17, 4, u32> logic_op;
+        BitField<21, 1, u32> rasterize_enable;
+    };
+    u32 point_size;
+    std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
+    std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes;
+    std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments;
+    std::array<u16, Maxwell::NumViewports> viewport_swizzles;
     DynamicState dynamic_state;
 
     void Fill(const Maxwell& regs);

+ 26 - 27
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

@@ -176,20 +176,18 @@ std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules(
 
 vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params,
                                                 const SPIRVProgram& program) const {
-    const auto& vi = fixed_state.vertex_input;
-    const auto& cd = fixed_state.color_blending;
-    const auto& rs = fixed_state.rasterizer;
-    const auto& ds = fixed_state.dynamic_state;
-    const auto& viewport_swizzles = fixed_state.viewport_swizzles.swizzles;
+    const auto& state = fixed_state;
+    const auto& dynamic = fixed_state.dynamic_state;
+    const auto& viewport_swizzles = fixed_state.viewport_swizzles;
 
     std::vector<VkVertexInputBindingDescription> vertex_bindings;
     std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors;
     for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
-        const auto& binding = ds.vertex_bindings[index];
+        const auto& binding = dynamic.vertex_bindings[index];
         if (!binding.enabled) {
             continue;
         }
-        const bool instanced = vi.binding_divisors[index] != 0;
+        const bool instanced = state.binding_divisors[index] != 0;
         const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
 
         auto& vertex_binding = vertex_bindings.emplace_back();
@@ -200,14 +198,14 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
         if (instanced) {
             auto& binding_divisor = vertex_binding_divisors.emplace_back();
             binding_divisor.binding = static_cast<u32>(index);
-            binding_divisor.divisor = vi.binding_divisors[index];
+            binding_divisor.divisor = state.binding_divisors[index];
         }
     }
 
     std::vector<VkVertexInputAttributeDescription> vertex_attributes;
     const auto& input_attributes = program[0]->entries.attributes;
-    for (std::size_t index = 0; index < std::size(vi.attributes); ++index) {
-        const auto& attribute = vi.attributes[index];
+    for (std::size_t index = 0; index < state.attributes.size(); ++index) {
+        const auto& attribute = state.attributes[index];
         if (!attribute.enabled) {
             continue;
         }
@@ -244,15 +242,15 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
     input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
     input_assembly_ci.pNext = nullptr;
     input_assembly_ci.flags = 0;
-    input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, ds.Topology());
+    input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology());
     input_assembly_ci.primitiveRestartEnable =
-        rs.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology);
+        state.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology);
 
     VkPipelineTessellationStateCreateInfo tessellation_ci;
     tessellation_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
     tessellation_ci.pNext = nullptr;
     tessellation_ci.flags = 0;
-    tessellation_ci.patchControlPoints = rs.patch_control_points_minus_one.Value() + 1;
+    tessellation_ci.patchControlPoints = state.patch_control_points_minus_one.Value() + 1;
 
     VkPipelineViewportStateCreateInfo viewport_ci;
     viewport_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
@@ -280,13 +278,13 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
     rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
     rasterization_ci.pNext = nullptr;
     rasterization_ci.flags = 0;
-    rasterization_ci.depthClampEnable = rs.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE;
-    rasterization_ci.rasterizerDiscardEnable = rs.rasterize_enable == 0 ? VK_TRUE : VK_FALSE;
+    rasterization_ci.depthClampEnable = state.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE;
+    rasterization_ci.rasterizerDiscardEnable = state.rasterize_enable == 0 ? VK_TRUE : VK_FALSE;
     rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL;
     rasterization_ci.cullMode =
-        ds.cull_enable ? MaxwellToVK::CullFace(ds.CullFace()) : VK_CULL_MODE_NONE;
-    rasterization_ci.frontFace = MaxwellToVK::FrontFace(ds.FrontFace());
-    rasterization_ci.depthBiasEnable = rs.depth_bias_enable;
+        dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE;
+    rasterization_ci.frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace());
+    rasterization_ci.depthBiasEnable = state.depth_bias_enable;
     rasterization_ci.depthBiasConstantFactor = 0.0f;
     rasterization_ci.depthBiasClamp = 0.0f;
     rasterization_ci.depthBiasSlopeFactor = 0.0f;
@@ -307,14 +305,15 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
     depth_stencil_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
     depth_stencil_ci.pNext = nullptr;
     depth_stencil_ci.flags = 0;
-    depth_stencil_ci.depthTestEnable = ds.depth_test_enable;
-    depth_stencil_ci.depthWriteEnable = ds.depth_write_enable;
-    depth_stencil_ci.depthCompareOp =
-        ds.depth_test_enable ? MaxwellToVK::ComparisonOp(ds.DepthTestFunc()) : VK_COMPARE_OP_ALWAYS;
-    depth_stencil_ci.depthBoundsTestEnable = ds.depth_bounds_enable;
-    depth_stencil_ci.stencilTestEnable = ds.stencil_enable;
-    depth_stencil_ci.front = GetStencilFaceState(ds.front);
-    depth_stencil_ci.back = GetStencilFaceState(ds.back);
+    depth_stencil_ci.depthTestEnable = dynamic.depth_test_enable;
+    depth_stencil_ci.depthWriteEnable = dynamic.depth_write_enable;
+    depth_stencil_ci.depthCompareOp = dynamic.depth_test_enable
+                                          ? MaxwellToVK::ComparisonOp(dynamic.DepthTestFunc())
+                                          : VK_COMPARE_OP_ALWAYS;
+    depth_stencil_ci.depthBoundsTestEnable = dynamic.depth_bounds_enable;
+    depth_stencil_ci.stencilTestEnable = dynamic.stencil_enable;
+    depth_stencil_ci.front = GetStencilFaceState(dynamic.front);
+    depth_stencil_ci.back = GetStencilFaceState(dynamic.back);
     depth_stencil_ci.minDepthBounds = 0.0f;
     depth_stencil_ci.maxDepthBounds = 0.0f;
 
@@ -324,7 +323,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
         static constexpr std::array COMPONENT_TABLE = {
             VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT,
             VK_COLOR_COMPONENT_A_BIT};
-        const auto& blend = cd.attachments[index];
+        const auto& blend = state.attachments[index];
 
         VkColorComponentFlags color_components = 0;
         for (std::size_t i = 0; i < COMPONENT_TABLE.size(); ++i) {

+ 3 - 3
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@@ -314,16 +314,16 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
     Specialization specialization;
     if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points) {
         float point_size;
-        std::memcpy(&point_size, &fixed_state.rasterizer.point_size, sizeof(float));
+        std::memcpy(&point_size, &fixed_state.point_size, sizeof(float));
         specialization.point_size = point_size;
         ASSERT(point_size != 0.0f);
     }
     for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) {
-        const auto& attribute = fixed_state.vertex_input.attributes[i];
+        const auto& attribute = fixed_state.attributes[i];
         specialization.enabled_attributes[i] = attribute.enabled.Value() != 0;
         specialization.attribute_types[i] = attribute.Type();
     }
-    specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one;
+    specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one;
 
     SPIRVProgram program;
     std::vector<VkDescriptorSetLayoutBinding> bindings;