forked from suyu/suyu
vulkan/fixed_pipeline_state: Move state out of individual structures
This commit is contained in:
parent
c94b398f14
commit
1a84209418
4 changed files with 84 additions and 121 deletions
|
@ -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 {
|
||||
std::memcpy(&point_size, ®s.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()));
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -89,8 +89,7 @@ struct FixedPipelineState {
|
|||
}
|
||||
};
|
||||
|
||||
struct VertexInput {
|
||||
union Attribute {
|
||||
union VertexAttribute {
|
||||
u32 raw;
|
||||
BitField<0, 1, u32> enabled;
|
||||
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>
|
||||
union StencilFace {
|
||||
BitField<Position + 0, 3, u32> action_stencil_fail;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue