[vulkan] Fixing inconsistences within VK_EXT_extended_dynamic_state1 handling
This commit is contained in:
parent
191af43721
commit
348433b4dc
|
|
@ -50,6 +50,38 @@ void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell&
|
|||
});
|
||||
state.varyings = regs.stream_out_layout;
|
||||
}
|
||||
|
||||
Maxwell::PrimitiveTopology NormalizeDynamicTopologyClass(Maxwell::PrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
case Maxwell::PrimitiveTopology::Points:
|
||||
return Maxwell::PrimitiveTopology::Points;
|
||||
|
||||
case Maxwell::PrimitiveTopology::Lines:
|
||||
case Maxwell::PrimitiveTopology::LineStrip:
|
||||
return Maxwell::PrimitiveTopology::Lines;
|
||||
|
||||
case Maxwell::PrimitiveTopology::Triangles:
|
||||
case Maxwell::PrimitiveTopology::TriangleStrip:
|
||||
case Maxwell::PrimitiveTopology::TriangleFan:
|
||||
case Maxwell::PrimitiveTopology::Quads:
|
||||
case Maxwell::PrimitiveTopology::QuadStrip:
|
||||
case Maxwell::PrimitiveTopology::Polygon:
|
||||
case Maxwell::PrimitiveTopology::LineLoop:
|
||||
return Maxwell::PrimitiveTopology::Triangles;
|
||||
|
||||
case Maxwell::PrimitiveTopology::LinesAdjacency:
|
||||
case Maxwell::PrimitiveTopology::LineStripAdjacency:
|
||||
return Maxwell::PrimitiveTopology::LinesAdjacency;
|
||||
|
||||
case Maxwell::PrimitiveTopology::TrianglesAdjacency:
|
||||
case Maxwell::PrimitiveTopology::TriangleStripAdjacency:
|
||||
return Maxwell::PrimitiveTopology::TrianglesAdjacency;
|
||||
|
||||
case Maxwell::PrimitiveTopology::Patches:
|
||||
return Maxwell::PrimitiveTopology::Patches;
|
||||
}
|
||||
return topology;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features) {
|
||||
|
|
@ -71,7 +103,9 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
|||
tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() ==
|
||||
Maxwell::Tessellation::OutputPrimitives::Triangles_CW);
|
||||
patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
|
||||
topology.Assign(topology_);
|
||||
const bool can_normalize_topology =
|
||||
features.has_extended_dynamic_state && features.has_extended_dynamic_state_2;
|
||||
topology.Assign(can_normalize_topology ? NormalizeDynamicTopologyClass(topology_) : topology_);
|
||||
msaa_mode.Assign(regs.anti_alias_samples_mode);
|
||||
|
||||
raw2 = 0;
|
||||
|
|
|
|||
|
|
@ -831,7 +831,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
.blendConstants = {}
|
||||
};
|
||||
static_vector<VkDynamicState, 34> dynamic_states{
|
||||
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
|
||||
VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
|
||||
VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
|
||||
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
|
||||
|
|
@ -839,8 +838,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
};
|
||||
if (key.state.extended_dynamic_state) {
|
||||
static constexpr std::array extended{
|
||||
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
|
||||
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
|
||||
VK_DYNAMIC_STATE_CULL_MODE_EXT,
|
||||
VK_DYNAMIC_STATE_FRONT_FACE_EXT,
|
||||
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
|
||||
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
|
||||
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
|
||||
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
|
||||
|
|
@ -851,6 +853,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
|
||||
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
|
||||
} else {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
|
||||
}
|
||||
|
||||
// EDS2 - Core (3 states)
|
||||
|
|
|
|||
|
|
@ -1032,6 +1032,7 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
|||
UpdateCullMode(regs);
|
||||
UpdateDepthCompareOp(regs);
|
||||
UpdateFrontFace(regs);
|
||||
UpdatePrimitiveTopology(regs);
|
||||
UpdateStencilOp(regs);
|
||||
if (state_tracker.TouchStateEnable()) {
|
||||
UpdateDepthBoundsTestEnable(regs);
|
||||
|
|
@ -1106,8 +1107,14 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
|||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f,
|
||||
};
|
||||
scheduler.Record([viewport](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetViewport(0, viewport);
|
||||
const bool use_viewport_with_count = device.IsExtExtendedDynamicStateSupported();
|
||||
scheduler.Record([viewport, use_viewport_with_count](vk::CommandBuffer cmdbuf) {
|
||||
if (use_viewport_with_count) {
|
||||
std::array viewports{viewport};
|
||||
cmdbuf.SetViewportWithCountEXT(viewports);
|
||||
} else {
|
||||
cmdbuf.SetViewport(0, viewport);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -1123,10 +1130,15 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
|||
GetViewportState(device, regs, 12, scale), GetViewportState(device, regs, 13, scale),
|
||||
GetViewportState(device, regs, 14, scale), GetViewportState(device, regs, 15, scale),
|
||||
};
|
||||
scheduler.Record([this, viewport_list](vk::CommandBuffer cmdbuf) {
|
||||
const bool use_viewport_with_count = device.IsExtExtendedDynamicStateSupported();
|
||||
scheduler.Record([this, viewport_list, use_viewport_with_count](vk::CommandBuffer cmdbuf) {
|
||||
const u32 num_viewports = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
|
||||
const vk::Span<VkViewport> viewports(viewport_list.data(), num_viewports);
|
||||
cmdbuf.SetViewport(0, viewports);
|
||||
if (use_viewport_with_count) {
|
||||
cmdbuf.SetViewportWithCountEXT(viewports);
|
||||
} else {
|
||||
cmdbuf.SetViewport(0, viewports);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1147,8 +1159,14 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
|
|||
scissor.offset.y = static_cast<int32_t>(y);
|
||||
scissor.extent.width = width;
|
||||
scissor.extent.height = height;
|
||||
scheduler.Record([scissor](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetScissor(0, scissor);
|
||||
const bool use_scissor_with_count = device.IsExtExtendedDynamicStateSupported();
|
||||
scheduler.Record([scissor, use_scissor_with_count](vk::CommandBuffer cmdbuf) {
|
||||
if (use_scissor_with_count) {
|
||||
std::array scissors{scissor};
|
||||
cmdbuf.SetScissorWithCountEXT(scissors);
|
||||
} else {
|
||||
cmdbuf.SetScissor(0, scissor);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -1176,10 +1194,15 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
|
|||
GetScissorState(regs, 14, up_scale, down_shift),
|
||||
GetScissorState(regs, 15, up_scale, down_shift),
|
||||
};
|
||||
scheduler.Record([this, scissor_list](vk::CommandBuffer cmdbuf) {
|
||||
const bool use_scissor_with_count = device.IsExtExtendedDynamicStateSupported();
|
||||
scheduler.Record([this, scissor_list, use_scissor_with_count](vk::CommandBuffer cmdbuf) {
|
||||
const u32 num_scissors = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
|
||||
const vk::Span<VkRect2D> scissors(scissor_list.data(), num_scissors);
|
||||
cmdbuf.SetScissor(0, scissors);
|
||||
if (use_scissor_with_count) {
|
||||
cmdbuf.SetScissorWithCountEXT(scissors);
|
||||
} else {
|
||||
cmdbuf.SetScissor(0, scissors);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1451,6 +1474,17 @@ void RasterizerVulkan::UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& reg
|
|||
});
|
||||
}
|
||||
|
||||
void RasterizerVulkan::UpdatePrimitiveTopology([[maybe_unused]] Tegra::Engines::Maxwell3D::Regs& regs) {
|
||||
const auto topology = maxwell3d->draw_manager->GetDrawState().topology;
|
||||
if (!state_tracker.ChangePrimitiveTopology(topology)) {
|
||||
return;
|
||||
}
|
||||
const auto vk_topology = MaxwellToVK::PrimitiveTopology(device, topology);
|
||||
scheduler.Record([vk_topology](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetPrimitiveTopologyEXT(vk_topology);
|
||||
});
|
||||
}
|
||||
|
||||
void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) {
|
||||
if (!state_tracker.TouchFrontFace()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ private:
|
|||
void UpdateDepthTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
void UpdateDepthWriteEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
void UpdateDepthCompareOp(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
void UpdatePrimitiveTopology(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
void UpdatePrimitiveRestartEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
void UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs);
|
||||
|
|
|
|||
|
|
@ -1150,8 +1150,6 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
|||
|
||||
if (u32(Settings::values.dyna_state.GetValue()) == 0) {
|
||||
LOG_INFO(Render_Vulkan, "Extended Dynamic State disabled by user setting, clearing all EDS features");
|
||||
features.custom_border_color.customBorderColors = false;
|
||||
features.custom_border_color.customBorderColorWithoutFormat = false;
|
||||
features.extended_dynamic_state.extendedDynamicState = false;
|
||||
features.extended_dynamic_state2.extendedDynamicState2 = false;
|
||||
}
|
||||
|
|
@ -1187,7 +1185,7 @@ void Device::RemoveUnsuitableExtensions() {
|
|||
RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control,
|
||||
VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME);
|
||||
|
||||
/* */ // VK_EXT_extended_dynamic_state
|
||||
// VK_EXT_extended_dynamic_state
|
||||
extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState;
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state,
|
||||
features.extended_dynamic_state,
|
||||
|
|
@ -1200,7 +1198,6 @@ void Device::RemoveUnsuitableExtensions() {
|
|||
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
|
||||
// VK_EXT_robustness2
|
||||
// Enable if at least one robustness2 feature is available
|
||||
extensions.robustness_2 = features.robustness2.robustBufferAccess2 ||
|
||||
features.robustness2.robustImageAccess2 ||
|
||||
features.robustness2.nullDescriptor;
|
||||
|
|
@ -1209,7 +1206,6 @@ void Device::RemoveUnsuitableExtensions() {
|
|||
VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
|
||||
// VK_EXT_image_robustness
|
||||
// Enable if robustImageAccess is available
|
||||
extensions.image_robustness = features.image_robustness.robustImageAccess;
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.image_robustness, features.image_robustness,
|
||||
VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME);
|
||||
|
|
@ -1305,15 +1301,15 @@ void Device::RemoveUnsuitableExtensions() {
|
|||
RemoveExtensionFeatureIfUnsuitable(extensions.swapchain_maintenance1, features.swapchain_maintenance1,
|
||||
VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_maintenance1 (core in Vulkan 1.1, no features)
|
||||
// VK_KHR_maintenance1
|
||||
extensions.maintenance1 = loaded_extensions.contains(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
|
||||
RemoveExtensionIfUnsuitable(extensions.maintenance1, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_maintenance2 (core in Vulkan 1.1, no features)
|
||||
// VK_KHR_maintenance2
|
||||
extensions.maintenance2 = loaded_extensions.contains(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
|
||||
RemoveExtensionIfUnsuitable(extensions.maintenance2, VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_maintenance3 (core in Vulkan 1.1, no features)
|
||||
// VK_KHR_maintenance3
|
||||
extensions.maintenance3 = loaded_extensions.contains(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
|
||||
RemoveExtensionIfUnsuitable(extensions.maintenance3, VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
|
||||
|
||||
|
|
@ -1343,15 +1339,15 @@ void Device::RemoveUnsuitableExtensions() {
|
|||
RemoveExtensionFeatureIfUnsuitable(extensions.maintenance6, features.maintenance6,
|
||||
VK_KHR_MAINTENANCE_6_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_maintenance7 (proposed for Vulkan 1.4, no features)
|
||||
// VK_KHR_maintenance7
|
||||
extensions.maintenance7 = loaded_extensions.contains(VK_KHR_MAINTENANCE_7_EXTENSION_NAME);
|
||||
RemoveExtensionIfUnsuitable(extensions.maintenance7, VK_KHR_MAINTENANCE_7_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_maintenance8 (proposed for Vulkan 1.4, no features)
|
||||
// VK_KHR_maintenance8
|
||||
extensions.maintenance8 = loaded_extensions.contains(VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
|
||||
RemoveExtensionIfUnsuitable(extensions.maintenance8, VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_maintenance9 (proposed for Vulkan 1.4, no features)
|
||||
// VK_KHR_maintenance9
|
||||
extensions.maintenance9 = loaded_extensions.contains(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
|
||||
RemoveExtensionIfUnsuitable(extensions.maintenance9, VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,10 +133,12 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
|||
X(vkCmdSetDepthBounds);
|
||||
X(vkCmdSetEvent);
|
||||
X(vkCmdSetScissor);
|
||||
X(vkCmdSetScissorWithCountEXT);
|
||||
X(vkCmdSetStencilCompareMask);
|
||||
X(vkCmdSetStencilReference);
|
||||
X(vkCmdSetStencilWriteMask);
|
||||
X(vkCmdSetViewport);
|
||||
X(vkCmdSetViewportWithCountEXT);
|
||||
X(vkCmdWaitEvents);
|
||||
X(vkCmdBindVertexBuffers2EXT);
|
||||
X(vkCmdSetCullModeEXT);
|
||||
|
|
@ -243,6 +245,15 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
|||
Proc(dld.vkCmdDrawIndirectCount, dld, "vkCmdDrawIndirectCountKHR", device);
|
||||
Proc(dld.vkCmdDrawIndexedIndirectCount, dld, "vkCmdDrawIndexedIndirectCountKHR", device);
|
||||
}
|
||||
if (!dld.vkCmdSetPrimitiveTopologyEXT) {
|
||||
Proc(dld.vkCmdSetPrimitiveTopologyEXT, dld, "vkCmdSetPrimitiveTopology", device);
|
||||
}
|
||||
if (!dld.vkCmdSetViewportWithCountEXT) {
|
||||
Proc(dld.vkCmdSetViewportWithCountEXT, dld, "vkCmdSetViewportWithCount", device);
|
||||
}
|
||||
if (!dld.vkCmdSetScissorWithCountEXT) {
|
||||
Proc(dld.vkCmdSetScissorWithCountEXT, dld, "vkCmdSetScissorWithCount", device);
|
||||
}
|
||||
#undef X
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -248,12 +248,14 @@ struct DeviceDispatch : InstanceDispatch {
|
|||
PFN_vkCmdSetLineWidth vkCmdSetLineWidth{};
|
||||
PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{};
|
||||
PFN_vkCmdSetScissor vkCmdSetScissor{};
|
||||
PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT{};
|
||||
PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask{};
|
||||
PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT{};
|
||||
PFN_vkCmdSetStencilReference vkCmdSetStencilReference{};
|
||||
PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT{};
|
||||
PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask{};
|
||||
PFN_vkCmdSetViewport vkCmdSetViewport{};
|
||||
PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT{};
|
||||
PFN_vkCmdWaitEvents vkCmdWaitEvents{};
|
||||
PFN_vkCreateBuffer vkCreateBuffer{};
|
||||
PFN_vkCreateBufferView vkCreateBufferView{};
|
||||
|
|
@ -1361,6 +1363,14 @@ public:
|
|||
dld->vkCmdSetScissor(handle, first, scissors.size(), scissors.data());
|
||||
}
|
||||
|
||||
void SetViewportWithCountEXT(Span<VkViewport> viewports) const noexcept {
|
||||
dld->vkCmdSetViewportWithCountEXT(handle, viewports.size(), viewports.data());
|
||||
}
|
||||
|
||||
void SetScissorWithCountEXT(Span<VkRect2D> scissors) const noexcept {
|
||||
dld->vkCmdSetScissorWithCountEXT(handle, scissors.size(), scissors.data());
|
||||
}
|
||||
|
||||
void SetBlendConstants(const float blend_constants[4]) const noexcept {
|
||||
dld->vkCmdSetBlendConstants(handle, blend_constants);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue