diff options
4 files changed, 84 insertions, 121 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 6b5264c22..07358b0f9 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/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, ®s.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); diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 54474fee7..09d05702d 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/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); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 739801f5d..15d9ac3b0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/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) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 9fcb46f8a..e684c17a6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/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; |