summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2020-06-22 09:01:37 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2020-06-27 01:57:22 +0200
commit1a84209418fe6ed416c2283f6d10abe4392e0473 (patch)
treeb699fdbcd5de0897ecf614bfe28188a42be97665 /src/video_core/renderer_vulkan
parentvk_rasterizer: Use VK_EXT_extended_dynamic_state (diff)
downloadyuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.tar
yuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.tar.gz
yuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.tar.bz2
yuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.tar.lz
yuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.tar.xz
yuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.tar.zst
yuzu-1a84209418fe6ed416c2283f6d10abe4392e0473.zip
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp52
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h94
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp53
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp6
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, &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);
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;