vulkan/fixed_pipeline_state: Move state out of individual structures

This commit is contained in:
ReinUsesLisp 2020-06-22 04:01:37 -03:00
parent c94b398f14
commit 1a84209418
4 changed files with 84 additions and 121 deletions

View file

@ -39,24 +39,7 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
} // Anonymous namespace } // Anonymous namespace
void FixedPipelineState::VertexInput::Fill(const Maxwell& regs) noexcept { void FixedPipelineState::Fill(const Maxwell& regs) {
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 {
const auto& clip = regs.view_volume_clip_control; const auto& clip = regs.view_volume_clip_control;
const std::array enabled_lut = {regs.polygon_offset_point_enable, const std::array enabled_lut = {regs.polygon_offset_point_enable,
regs.polygon_offset_line_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_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
logic_op.Assign(PackLogicOp(regs.logic_op.operation)); logic_op.Assign(PackLogicOp(regs.logic_op.operation));
rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); 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 std::memcpy(&point_size, &regs.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast
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()));
} }
void FixedPipelineState::ColorBlending::Fill(const Maxwell& regs) noexcept {
for (std::size_t index = 0; index < std::size(attachments); ++index) { for (std::size_t index = 0; index < std::size(attachments); ++index) {
attachments[index].Fill(regs, index); attachments[index].Fill(regs, index);
} }
}
void FixedPipelineState::ViewportSwizzles::Fill(const Maxwell& regs) noexcept {
const auto& transform = regs.viewport_transform; 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); }); [](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) { 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 { std::size_t FixedPipelineState::Hash() const noexcept {
const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this);
return static_cast<std::size_t>(hash); return static_cast<std::size_t>(hash);

View file

@ -89,8 +89,7 @@ struct FixedPipelineState {
} }
}; };
struct VertexInput { union VertexAttribute {
union Attribute {
u32 raw; u32 raw;
BitField<0, 1, u32> enabled; BitField<0, 1, u32> enabled;
BitField<1, 5, u32> buffer; BitField<1, 5, u32> buffer;
@ -107,47 +106,6 @@ struct FixedPipelineState {
} }
}; };
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;
void Fill(const Maxwell& regs) noexcept;
};
template <std::size_t Position> template <std::size_t Position>
union StencilFace { union StencilFace {
BitField<Position + 0, 3, u32> action_stencil_fail; BitField<Position + 0, 3, u32> action_stencil_fail;
@ -217,10 +175,26 @@ struct FixedPipelineState {
} }
}; };
VertexInput vertex_input; union {
Rasterizer rasterizer; u32 raw;
ColorBlending color_blending; BitField<0, 1, u32> primitive_restart_enable;
ViewportSwizzles viewport_swizzles; 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; DynamicState dynamic_state;
void Fill(const Maxwell& regs); void Fill(const Maxwell& regs);

View file

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

View file

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