renderer_vulkan: Improve handling of required vs optional extensions. (#2792)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

* renderer_vulkan: Improve handling of required vs optional extensions.

* documents: Update quickstart Vulkan requirements.
This commit is contained in:
squidbus 2025-04-15 22:31:58 -07:00 committed by GitHub
parent 247e935353
commit 3bc876ca78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 43 additions and 29 deletions

View file

@ -29,8 +29,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
### GPU
- A graphics card with at least 1GB of VRAM
- Keep your graphics drivers up to date
- Vulkan 1.3 support (required)
- Up-to-date graphics drivers
- Vulkan 1.3 with the `VK_KHR_swapchain` and `VK_KHR_push_descriptor` extensions
### RAM

View file

@ -242,18 +242,21 @@ bool Instance::CreateDevice() {
// These extensions are promoted by Vulkan 1.3, but for greater compatibility we use Vulkan 1.2
// with extensions.
add_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME);
add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
add_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME);
add_extension(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
ASSERT(add_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_MAINTENANCE_4_EXTENSION_NAME));
add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
// Required
ASSERT(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME));
// Optional
depth_range_unrestricted = add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
dynamic_state_3 = add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
if (dynamic_state_3) {
dynamic_state_3_features =

View file

@ -104,6 +104,11 @@ public:
return depth_clip_control;
}
/// Returns true when VK_EXT_depth_range_unrestricted is supported
bool IsDepthRangeUnrestrictedSupported() const {
return depth_range_unrestricted;
}
/// Returns true when the extendedDynamicState3ColorWriteMask feature of
/// VK_EXT_extended_dynamic_state3 is supported.
bool IsDynamicColorWriteMaskSupported() const {
@ -340,6 +345,7 @@ private:
bool custom_border_color{};
bool fragment_shader_barycentric{};
bool depth_clip_control{};
bool depth_range_unrestricted{};
bool dynamic_state_3{};
bool vertex_input_dynamic_state{};
bool robustness2{};

View file

@ -1018,32 +1018,37 @@ void Rasterizer::UpdateViewportScissorState() const {
const auto zoffset = vp_ctl.zoffset_enable ? vp.zoffset : 0.f;
const auto zscale = vp_ctl.zscale_enable ? vp.zscale : 1.f;
vk::Viewport viewport = {
.minDepth = zoffset - zscale * reduce_z,
.maxDepth = zscale + zoffset,
};
if (!instance.IsDepthRangeUnrestrictedSupported()) {
// Unrestricted depth range not supported by device. Make best attempt
// by restricting to valid range.
viewport.minDepth = std::max(viewport.minDepth, 0.f);
viewport.maxDepth = std::min(viewport.maxDepth, 1.f);
}
if (regs.IsClipDisabled()) {
// In case if clipping is disabled we patch the shader to convert vertex position
// from screen space coordinates to NDC by defining a render space as full hardware
// window range [0..16383, 0..16383] and setting the viewport to its size.
viewports.push_back({
.x = 0.f,
.y = 0.f,
.width = float(std::min<u32>(instance.GetMaxViewportWidth(), 16_KB)),
.height = float(std::min<u32>(instance.GetMaxViewportHeight(), 16_KB)),
.minDepth = zoffset - zscale * reduce_z,
.maxDepth = zscale + zoffset,
});
viewport.x = 0.f;
viewport.y = 0.f;
viewport.width = float(std::min<u32>(instance.GetMaxViewportWidth(), 16_KB));
viewport.height = float(std::min<u32>(instance.GetMaxViewportHeight(), 16_KB));
} else {
const auto xoffset = vp_ctl.xoffset_enable ? vp.xoffset : 0.f;
const auto xscale = vp_ctl.xscale_enable ? vp.xscale : 1.f;
const auto yoffset = vp_ctl.yoffset_enable ? vp.yoffset : 0.f;
const auto yscale = vp_ctl.yscale_enable ? vp.yscale : 1.f;
viewports.push_back({
.x = xoffset - xscale,
.y = yoffset - yscale,
.width = xscale * 2.0f,
.height = yscale * 2.0f,
.minDepth = zoffset - zscale * reduce_z,
.maxDepth = zscale + zoffset,
});
viewport.x = xoffset - xscale;
viewport.y = yoffset - yscale;
viewport.width = xscale * 2.0f;
viewport.height = yscale * 2.0f;
}
viewports.push_back(viewport);
auto vp_scsr = scsr;
if (regs.mode_control.vport_scissor_enable) {