mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	fixed_pipeline_state: Add requirements for VK_EXT_extended_dynamic_state
This moves dynamic state present in VK_EXT_extended_dynamic_state to a separate structure in FixedPipelineState. This is structure is at the bottom allowing us to hash and memcmp only when the extension is not supported.
This commit is contained in:
		@@ -39,28 +39,21 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
 | 
			
		||||
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
void FixedPipelineState::DepthStencil::Fill(const Maxwell& regs) noexcept {
 | 
			
		||||
    raw = 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));
 | 
			
		||||
    front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func));
 | 
			
		||||
    if (regs.stencil_two_side_enable) {
 | 
			
		||||
        back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail));
 | 
			
		||||
        back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail));
 | 
			
		||||
        back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass));
 | 
			
		||||
        back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func));
 | 
			
		||||
    } else {
 | 
			
		||||
        back.action_stencil_fail.Assign(front.action_stencil_fail);
 | 
			
		||||
        back.action_depth_fail.Assign(front.action_depth_fail);
 | 
			
		||||
        back.action_depth_pass.Assign(front.action_depth_pass);
 | 
			
		||||
        back.test_func.Assign(front.test_func);
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
    depth_test_enable.Assign(regs.depth_test_enable);
 | 
			
		||||
    depth_write_enable.Assign(regs.depth_write_enabled);
 | 
			
		||||
    depth_bounds_enable.Assign(regs.depth_bounds_enable);
 | 
			
		||||
    stencil_enable.Assign(regs.stencil_enable);
 | 
			
		||||
    depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept {
 | 
			
		||||
@@ -70,21 +63,11 @@ void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept {
 | 
			
		||||
                                    regs.polygon_offset_fill_enable};
 | 
			
		||||
    const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
 | 
			
		||||
 | 
			
		||||
    u32 packed_front_face = PackFrontFace(regs.front_face);
 | 
			
		||||
    if (regs.screen_y_control.triangle_rast_flip != 0) {
 | 
			
		||||
        // Flip front face
 | 
			
		||||
        packed_front_face = 1 - packed_front_face;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    raw = 0;
 | 
			
		||||
    topology.Assign(topology_index);
 | 
			
		||||
    primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
 | 
			
		||||
    cull_enable.Assign(regs.cull_test_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());
 | 
			
		||||
    ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
 | 
			
		||||
    cull_face.Assign(PackCullFace(regs.cull_face));
 | 
			
		||||
    front_face.Assign(packed_front_face);
 | 
			
		||||
    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.tess_mode.prim.Value()));
 | 
			
		||||
@@ -147,11 +130,56 @@ void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size
 | 
			
		||||
    enable.Assign(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) {
 | 
			
		||||
    const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
 | 
			
		||||
    u32 packed_front_face = PackFrontFace(regs.front_face);
 | 
			
		||||
    if (regs.screen_y_control.triangle_rast_flip != 0) {
 | 
			
		||||
        // Flip front face
 | 
			
		||||
        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));
 | 
			
		||||
    front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func));
 | 
			
		||||
    if (regs.stencil_two_side_enable) {
 | 
			
		||||
        back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail));
 | 
			
		||||
        back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail));
 | 
			
		||||
        back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass));
 | 
			
		||||
        back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func));
 | 
			
		||||
    } else {
 | 
			
		||||
        back.action_stencil_fail.Assign(front.action_stencil_fail);
 | 
			
		||||
        back.action_depth_fail.Assign(front.action_depth_fail);
 | 
			
		||||
        back.action_depth_pass.Assign(front.action_depth_pass);
 | 
			
		||||
        back.test_func.Assign(front.test_func);
 | 
			
		||||
    }
 | 
			
		||||
    stencil_enable.Assign(regs.stencil_enable);
 | 
			
		||||
    depth_write_enable.Assign(regs.depth_write_enabled);
 | 
			
		||||
    depth_bounds_enable.Assign(regs.depth_bounds_enable);
 | 
			
		||||
    depth_test_enable.Assign(regs.depth_test_enable);
 | 
			
		||||
    front_face.Assign(packed_front_face);
 | 
			
		||||
    depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
 | 
			
		||||
    topology.Assign(topology_index);
 | 
			
		||||
    cull_face.Assign(PackCullFace(regs.cull_face));
 | 
			
		||||
    cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0);
 | 
			
		||||
 | 
			
		||||
    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
 | 
			
		||||
        const auto& input = regs.vertex_array[index];
 | 
			
		||||
        VertexBinding& binding = vertex_bindings[index];
 | 
			
		||||
        binding.raw = 0;
 | 
			
		||||
        binding.enabled.Assign(input.IsEnabled() ? 1 : 0);
 | 
			
		||||
        binding.stride.Assign(static_cast<u16>(input.stride.Value()));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FixedPipelineState::Fill(const Maxwell& regs) {
 | 
			
		||||
    vertex_input.Fill(regs);
 | 
			
		||||
    rasterizer.Fill(regs);
 | 
			
		||||
    depth_stencil.Fill(regs);
 | 
			
		||||
    color_blending.Fill(regs);
 | 
			
		||||
    viewport_swizzles.Fill(regs);
 | 
			
		||||
    dynamic_state.Fill(regs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::size_t FixedPipelineState::Hash() const noexcept {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,14 +60,6 @@ struct FixedPipelineState {
 | 
			
		||||
 | 
			
		||||
        void Fill(const Maxwell& regs, std::size_t index);
 | 
			
		||||
 | 
			
		||||
        std::size_t Hash() const noexcept;
 | 
			
		||||
 | 
			
		||||
        bool operator==(const BlendingAttachment& rhs) const noexcept;
 | 
			
		||||
 | 
			
		||||
        bool operator!=(const BlendingAttachment& rhs) const noexcept {
 | 
			
		||||
            return !operator==(rhs);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        constexpr std::array<bool, 4> Mask() const noexcept {
 | 
			
		||||
            return {mask_r != 0, mask_g != 0, mask_b != 0, mask_a != 0};
 | 
			
		||||
        }
 | 
			
		||||
@@ -98,12 +90,6 @@ struct FixedPipelineState {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct VertexInput {
 | 
			
		||||
        union Binding {
 | 
			
		||||
            u16 raw;
 | 
			
		||||
            BitField<0, 1, u16> enabled;
 | 
			
		||||
            BitField<1, 12, u16> stride;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        union Attribute {
 | 
			
		||||
            u32 raw;
 | 
			
		||||
            BitField<0, 1, u32> enabled;
 | 
			
		||||
@@ -121,111 +107,33 @@ struct FixedPipelineState {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        std::array<Binding, Maxwell::NumVertexArrays> bindings;
 | 
			
		||||
        std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
 | 
			
		||||
        std::array<Attribute, Maxwell::NumVertexAttributes> attributes;
 | 
			
		||||
 | 
			
		||||
        void SetBinding(std::size_t index, bool enabled, u32 stride, u32 divisor) noexcept {
 | 
			
		||||
            auto& binding = bindings[index];
 | 
			
		||||
            binding.raw = 0;
 | 
			
		||||
            binding.enabled.Assign(enabled ? 1 : 0);
 | 
			
		||||
            binding.stride.Assign(static_cast<u16>(stride));
 | 
			
		||||
            binding_divisors[index] = divisor;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void SetAttribute(std::size_t index, bool enabled, u32 buffer, u32 offset,
 | 
			
		||||
                          Maxwell::VertexAttribute::Type type,
 | 
			
		||||
                          Maxwell::VertexAttribute::Size size) noexcept {
 | 
			
		||||
            auto& attribute = attributes[index];
 | 
			
		||||
            attribute.raw = 0;
 | 
			
		||||
            attribute.enabled.Assign(enabled ? 1 : 0);
 | 
			
		||||
            attribute.buffer.Assign(buffer);
 | 
			
		||||
            attribute.offset.Assign(offset);
 | 
			
		||||
            attribute.type.Assign(static_cast<u32>(type));
 | 
			
		||||
            attribute.size.Assign(static_cast<u32>(size));
 | 
			
		||||
        }
 | 
			
		||||
        void Fill(const Maxwell& regs) noexcept;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct Rasterizer {
 | 
			
		||||
        union {
 | 
			
		||||
            u32 raw;
 | 
			
		||||
            BitField<0, 4, u32> topology;
 | 
			
		||||
            BitField<4, 1, u32> primitive_restart_enable;
 | 
			
		||||
            BitField<5, 1, u32> cull_enable;
 | 
			
		||||
            BitField<6, 1, u32> depth_bias_enable;
 | 
			
		||||
            BitField<7, 1, u32> depth_clamp_disabled;
 | 
			
		||||
            BitField<8, 1, u32> ndc_minus_one_to_one;
 | 
			
		||||
            BitField<9, 2, u32> cull_face;
 | 
			
		||||
            BitField<11, 1, u32> front_face;
 | 
			
		||||
            BitField<12, 2, u32> polygon_mode;
 | 
			
		||||
            BitField<14, 5, u32> patch_control_points_minus_one;
 | 
			
		||||
            BitField<19, 2, u32> tessellation_primitive;
 | 
			
		||||
            BitField<21, 2, u32> tessellation_spacing;
 | 
			
		||||
            BitField<23, 1, u32> tessellation_clockwise;
 | 
			
		||||
            BitField<24, 1, u32> logic_op_enable;
 | 
			
		||||
            BitField<25, 4, u32> logic_op;
 | 
			
		||||
            BitField<29, 1, u32> rasterize_enable;
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
        constexpr Maxwell::PrimitiveTopology Topology() const noexcept {
 | 
			
		||||
            return static_cast<Maxwell::PrimitiveTopology>(topology.Value());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::CullFace CullFace() const noexcept {
 | 
			
		||||
            return UnpackCullFace(cull_face.Value());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::FrontFace FrontFace() const noexcept {
 | 
			
		||||
            return UnpackFrontFace(front_face.Value());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct DepthStencil {
 | 
			
		||||
        template <std::size_t Position>
 | 
			
		||||
        union StencilFace {
 | 
			
		||||
            BitField<Position + 0, 3, u32> action_stencil_fail;
 | 
			
		||||
            BitField<Position + 3, 3, u32> action_depth_fail;
 | 
			
		||||
            BitField<Position + 6, 3, u32> action_depth_pass;
 | 
			
		||||
            BitField<Position + 9, 3, u32> test_func;
 | 
			
		||||
 | 
			
		||||
            Maxwell::StencilOp ActionStencilFail() const noexcept {
 | 
			
		||||
                return UnpackStencilOp(action_stencil_fail);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Maxwell::StencilOp ActionDepthFail() const noexcept {
 | 
			
		||||
                return UnpackStencilOp(action_depth_fail);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Maxwell::StencilOp ActionDepthPass() const noexcept {
 | 
			
		||||
                return UnpackStencilOp(action_depth_pass);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Maxwell::ComparisonOp TestFunc() const noexcept {
 | 
			
		||||
                return UnpackComparisonOp(test_func);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        union {
 | 
			
		||||
            u32 raw;
 | 
			
		||||
            StencilFace<0> front;
 | 
			
		||||
            StencilFace<12> back;
 | 
			
		||||
            BitField<24, 1, u32> depth_test_enable;
 | 
			
		||||
            BitField<25, 1, u32> depth_write_enable;
 | 
			
		||||
            BitField<26, 1, u32> depth_bounds_enable;
 | 
			
		||||
            BitField<27, 1, u32> stencil_enable;
 | 
			
		||||
            BitField<28, 3, u32> depth_test_func;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        void Fill(const Maxwell& regs) noexcept;
 | 
			
		||||
 | 
			
		||||
        Maxwell::ComparisonOp DepthTestFunc() const noexcept {
 | 
			
		||||
            return UnpackComparisonOp(depth_test_func);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ColorBlending {
 | 
			
		||||
@@ -240,11 +148,80 @@ struct FixedPipelineState {
 | 
			
		||||
        void Fill(const Maxwell& regs) noexcept;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template <std::size_t Position>
 | 
			
		||||
    union StencilFace {
 | 
			
		||||
        BitField<Position + 0, 3, u32> action_stencil_fail;
 | 
			
		||||
        BitField<Position + 3, 3, u32> action_depth_fail;
 | 
			
		||||
        BitField<Position + 6, 3, u32> action_depth_pass;
 | 
			
		||||
        BitField<Position + 9, 3, u32> test_func;
 | 
			
		||||
 | 
			
		||||
        Maxwell::StencilOp ActionStencilFail() const noexcept {
 | 
			
		||||
            return UnpackStencilOp(action_stencil_fail);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::StencilOp ActionDepthFail() const noexcept {
 | 
			
		||||
            return UnpackStencilOp(action_depth_fail);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::StencilOp ActionDepthPass() const noexcept {
 | 
			
		||||
            return UnpackStencilOp(action_depth_pass);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::ComparisonOp TestFunc() const noexcept {
 | 
			
		||||
            return UnpackComparisonOp(test_func);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    union VertexBinding {
 | 
			
		||||
        u16 raw;
 | 
			
		||||
        BitField<0, 12, u16> stride;
 | 
			
		||||
        BitField<12, 1, u16> enabled;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct DynamicState {
 | 
			
		||||
        union {
 | 
			
		||||
            u32 raw1;
 | 
			
		||||
            StencilFace<0> front;
 | 
			
		||||
            StencilFace<12> back;
 | 
			
		||||
            BitField<24, 1, u32> stencil_enable;
 | 
			
		||||
            BitField<25, 1, u32> depth_write_enable;
 | 
			
		||||
            BitField<26, 1, u32> depth_bounds_enable;
 | 
			
		||||
            BitField<27, 1, u32> depth_test_enable;
 | 
			
		||||
            BitField<28, 1, u32> front_face;
 | 
			
		||||
            BitField<29, 3, u32> depth_test_func;
 | 
			
		||||
        };
 | 
			
		||||
        union {
 | 
			
		||||
            u32 raw2;
 | 
			
		||||
            BitField<0, 4, u32> topology;
 | 
			
		||||
            BitField<4, 2, u32> cull_face;
 | 
			
		||||
            BitField<6, 1, u32> cull_enable;
 | 
			
		||||
        };
 | 
			
		||||
        std::array<VertexBinding, Maxwell::NumVertexArrays> vertex_bindings;
 | 
			
		||||
 | 
			
		||||
        void Fill(const Maxwell& regs);
 | 
			
		||||
 | 
			
		||||
        Maxwell::ComparisonOp DepthTestFunc() const noexcept {
 | 
			
		||||
            return UnpackComparisonOp(depth_test_func);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::CullFace CullFace() const noexcept {
 | 
			
		||||
            return UnpackCullFace(cull_face.Value());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Maxwell::FrontFace FrontFace() const noexcept {
 | 
			
		||||
            return UnpackFrontFace(front_face.Value());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        constexpr Maxwell::PrimitiveTopology Topology() const noexcept {
 | 
			
		||||
            return static_cast<Maxwell::PrimitiveTopology>(topology.Value());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    VertexInput vertex_input;
 | 
			
		||||
    Rasterizer rasterizer;
 | 
			
		||||
    DepthStencil depth_stencil;
 | 
			
		||||
    ColorBlending color_blending;
 | 
			
		||||
    ViewportSwizzles viewport_swizzles;
 | 
			
		||||
    DynamicState dynamic_state;
 | 
			
		||||
 | 
			
		||||
    void Fill(const Maxwell& regs);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -177,15 +177,15 @@ 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& ds = fixed_state.depth_stencil;
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    std::vector<VkVertexInputBindingDescription> vertex_bindings;
 | 
			
		||||
    std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors;
 | 
			
		||||
    for (std::size_t index = 0; index < std::size(vi.bindings); ++index) {
 | 
			
		||||
        const auto& binding = vi.bindings[index];
 | 
			
		||||
    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
 | 
			
		||||
        const auto& binding = ds.vertex_bindings[index];
 | 
			
		||||
        if (!binding.enabled) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
@@ -244,7 +244,7 @@ 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, rs.Topology());
 | 
			
		||||
    input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, ds.Topology());
 | 
			
		||||
    input_assembly_ci.primitiveRestartEnable =
 | 
			
		||||
        rs.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology);
 | 
			
		||||
 | 
			
		||||
@@ -284,8 +284,8 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
 | 
			
		||||
    rasterization_ci.rasterizerDiscardEnable = rs.rasterize_enable == 0 ? VK_TRUE : VK_FALSE;
 | 
			
		||||
    rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL;
 | 
			
		||||
    rasterization_ci.cullMode =
 | 
			
		||||
        rs.cull_enable ? MaxwellToVK::CullFace(rs.CullFace()) : VK_CULL_MODE_NONE;
 | 
			
		||||
    rasterization_ci.frontFace = MaxwellToVK::FrontFace(rs.FrontFace());
 | 
			
		||||
        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;
 | 
			
		||||
    rasterization_ci.depthBiasConstantFactor = 0.0f;
 | 
			
		||||
    rasterization_ci.depthBiasClamp = 0.0f;
 | 
			
		||||
 
 | 
			
		||||
@@ -312,7 +312,7 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
 | 
			
		||||
    const auto& gpu = system.GPU().Maxwell3D();
 | 
			
		||||
 | 
			
		||||
    Specialization specialization;
 | 
			
		||||
    if (fixed_state.rasterizer.Topology() == Maxwell::PrimitiveTopology::Points) {
 | 
			
		||||
    if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points) {
 | 
			
		||||
        float point_size;
 | 
			
		||||
        std::memcpy(&point_size, &fixed_state.rasterizer.point_size, sizeof(float));
 | 
			
		||||
        specialization.point_size = point_size;
 | 
			
		||||
 
 | 
			
		||||
@@ -44,10 +44,10 @@ class VKUpdateDescriptorQueue;
 | 
			
		||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
 | 
			
		||||
 | 
			
		||||
struct GraphicsPipelineCacheKey {
 | 
			
		||||
    FixedPipelineState fixed_state;
 | 
			
		||||
    RenderPassParams renderpass_params;
 | 
			
		||||
    u32 padding;
 | 
			
		||||
    std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders;
 | 
			
		||||
    u64 padding; // This is necessary for unique object representations
 | 
			
		||||
    FixedPipelineState fixed_state;
 | 
			
		||||
 | 
			
		||||
    std::size_t Hash() const noexcept;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -822,7 +822,7 @@ RasterizerVulkan::DrawParameters RasterizerVulkan::SetupGeometry(FixedPipelineSt
 | 
			
		||||
    const auto& gpu = system.GPU().Maxwell3D();
 | 
			
		||||
    const auto& regs = gpu.regs;
 | 
			
		||||
 | 
			
		||||
    SetupVertexArrays(fixed_state.vertex_input, buffer_bindings);
 | 
			
		||||
    SetupVertexArrays(buffer_bindings);
 | 
			
		||||
 | 
			
		||||
    const u32 base_instance = regs.vb_base_instance;
 | 
			
		||||
    const u32 num_instances = is_instanced ? gpu.mme_draw.instance_count : 1;
 | 
			
		||||
@@ -940,30 +940,14 @@ void RasterizerVulkan::EndTransformFeedback() {
 | 
			
		||||
        [](vk::CommandBuffer cmdbuf) { cmdbuf.EndTransformFeedbackEXT(0, 0, nullptr, nullptr); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input,
 | 
			
		||||
                                         BufferBindings& buffer_bindings) {
 | 
			
		||||
void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) {
 | 
			
		||||
    const auto& regs = system.GPU().Maxwell3D().regs;
 | 
			
		||||
 | 
			
		||||
    for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
 | 
			
		||||
        const auto& attrib = regs.vertex_attrib_format[index];
 | 
			
		||||
        if (attrib.IsConstant()) {
 | 
			
		||||
            vertex_input.SetAttribute(index, false, 0, 0, {}, {});
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        vertex_input.SetAttribute(index, true, attrib.buffer, attrib.offset, attrib.type.Value(),
 | 
			
		||||
                                  attrib.size.Value());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
 | 
			
		||||
        const auto& vertex_array = regs.vertex_array[index];
 | 
			
		||||
        if (!vertex_array.IsEnabled()) {
 | 
			
		||||
            vertex_input.SetBinding(index, false, 0, 0);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        vertex_input.SetBinding(
 | 
			
		||||
            index, true, vertex_array.stride,
 | 
			
		||||
            regs.instanced_arrays.IsInstancingEnabled(index) ? vertex_array.divisor : 0);
 | 
			
		||||
 | 
			
		||||
        const GPUVAddr start{vertex_array.StartAddress()};
 | 
			
		||||
        const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -185,8 +185,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    bool WalkAttachmentOverlaps(const CachedSurfaceView& attachment);
 | 
			
		||||
 | 
			
		||||
    void SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input,
 | 
			
		||||
                           BufferBindings& buffer_bindings);
 | 
			
		||||
    void SetupVertexArrays(BufferBindings& buffer_bindings);
 | 
			
		||||
 | 
			
		||||
    void SetupIndexBuffer(BufferBindings& buffer_bindings, DrawParameters& params, bool is_indexed);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user