vk_copies(copies.size());
const VkImageAspectFlags aspect_mask = dst.AspectMask();
ASSERT(aspect_mask == src.AspectMask());
+ const bool dst_is_3d = dst.info.type == ImageType::e3D;
+ const bool src_is_3d = src.info.type == ImageType::e3D;
std::ranges::transform(copies, vk_copies.begin(), [aspect_mask](const auto& copy) {
return MakeImageCopy(copy, aspect_mask);
@@ -1447,7 +1467,8 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
const VkImage dst_image = dst.Handle();
const VkImage src_image = src.Handle();
scheduler.RequestOutsideRenderPassOperationContext();
- scheduler.Record([dst_image, src_image, aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
+ scheduler.Record([dst_image, src_image, aspect_mask, dst_is_3d, src_is_3d,
+ vk_copies](vk::CommandBuffer cmdbuf) {
RangedBarrierRange dst_range;
RangedBarrierRange src_range;
for (const VkImageCopy& copy : vk_copies) {
@@ -1467,7 +1488,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = src_image,
- .subresourceRange = src_range.SubresourceRange(aspect_mask),
+ .subresourceRange = src_range.SubresourceRange(aspect_mask, src_is_3d),
},
VkImageMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -1481,7 +1502,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = dst_image,
- .subresourceRange = dst_range.SubresourceRange(aspect_mask),
+ .subresourceRange = dst_range.SubresourceRange(aspect_mask, dst_is_3d),
},
};
const std::array post_barriers{
@@ -1495,7 +1516,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = src_image,
- .subresourceRange = src_range.SubresourceRange(aspect_mask),
+ .subresourceRange = src_range.SubresourceRange(aspect_mask, src_is_3d),
},
VkImageMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -1512,7 +1533,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = dst_image,
- .subresourceRange = dst_range.SubresourceRange(aspect_mask),
+ .subresourceRange = dst_range.SubresourceRange(aspect_mask, dst_is_3d),
},
};
cmdbuf.PipelineBarrier(
@@ -1691,10 +1712,12 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
const VkBuffer src_buffer = buffer;
const VkImage temp_vk_image = *temp_wrapper->original_image;
const VkImageAspectFlags vk_aspect_mask = temp_wrapper->aspect_mask;
+ const bool temp_is_3d = temp_info.type == ImageType::e3D;
- scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies,
+ scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, temp_is_3d, vk_copies,
keep = temp_wrapper](vk::CommandBuffer cmdbuf) {
- CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, VideoCommon::FixSmallVectorADL(vk_copies));
+ CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false,
+ temp_is_3d, VideoCommon::FixSmallVectorADL(vk_copies));
});
// Use MSAACopyPass to convert from non-MSAA to MSAA
@@ -1730,10 +1753,12 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
const VkImage vk_image = *original_image;
const VkImageAspectFlags vk_aspect_mask = aspect_mask;
const bool was_initialized = std::exchange(initialized, true);
+ const bool is_3d_image = info.type == ImageType::e3D;
- scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized,
+ scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized, is_3d_image,
vk_copies](vk::CommandBuffer cmdbuf) {
- CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized, VideoCommon::FixSmallVectorADL(vk_copies));
+ CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized,
+ is_3d_image, VideoCommon::FixSmallVectorADL(vk_copies));
});
if (is_rescaled) {
@@ -2112,7 +2137,10 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
}
}
const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
- if (ImageUsageFlags(format_info, format) != image.UsageFlags()) {
+ const VkImageUsageFlags desired_view_usage = ImageUsageFlags(format_info, format);
+ const VkImageUsageFlags image_usage = image.UsageFlags();
+ const VkImageUsageFlags view_usage = desired_view_usage & image_usage;
+ if (desired_view_usage != image_usage) {
LOG_WARNING(Render_Vulkan,
"Image view format {} has different usage flags than image format {}", format,
image.info.format);
@@ -2120,7 +2148,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
const VkImageViewUsageCreateInfo image_view_usage{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
.pNext = nullptr,
- .usage = ImageUsageFlags(format_info, format),
+ .usage = view_usage,
};
const VkImageViewCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 71210ffe6e..a92f44cc30 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1191,7 +1191,7 @@ void TextureCache::DownloadImageIntoBuffer(typename TextureCache
::Image* i
template
void TextureCache::RefreshContents(Image& image, ImageId image_id) {
if (False(image.flags & ImageFlagBits::CpuModified)) {
- // Only upload modified images
+ runtime.TransitionImageLayout(image);
return;
}
diff --git a/src/video_core/vulkan_common/vulkan.h b/src/video_core/vulkan_common/vulkan.h
index 8d2e8e2a37..8d774a853e 100644
--- a/src/video_core/vulkan_common/vulkan.h
+++ b/src/video_core/vulkan_common/vulkan.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -22,16 +22,13 @@
#include
-// Define maintenance 7-9 extension names (not yet in official Vulkan headers)
+// Define maintenance 7-8 extension names
#ifndef VK_KHR_MAINTENANCE_7_EXTENSION_NAME
#define VK_KHR_MAINTENANCE_7_EXTENSION_NAME "VK_KHR_maintenance7"
#endif
#ifndef VK_KHR_MAINTENANCE_8_EXTENSION_NAME
#define VK_KHR_MAINTENANCE_8_EXTENSION_NAME "VK_KHR_maintenance8"
#endif
-#ifndef VK_KHR_MAINTENANCE_9_EXTENSION_NAME
-#define VK_KHR_MAINTENANCE_9_EXTENSION_NAME "VK_KHR_maintenance9"
-#endif
// Sanitize macros
#undef CreateEvent
diff --git a/src/video_core/vulkan_common/vulkan_debug_callback.cpp b/src/video_core/vulkan_common/vulkan_debug_callback.cpp
index cd6653c86e..c3aba89179 100644
--- a/src/video_core/vulkan_common/vulkan_debug_callback.cpp
+++ b/src/video_core/vulkan_common/vulkan_debug_callback.cpp
@@ -43,19 +43,9 @@ VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
case 0xdff2e5c1u: // VUID-vkCmdSetRasterizerDiscardEnable-None-04871
case 0x0cc85f41u: // VUID-vkCmdSetPrimitiveRestartEnable-None-04866
case 0x01257b492: // VUID-vkCmdSetLogicOpEXT-None-0486
- // The below are due to incorrect reporting of vertexInputDynamicState
- case 0x398e0dabu: // VUID-vkCmdSetVertexInputEXT-None-04790
- // The below are due to incorrect reporting of extendedDynamicState3
- case 0x970c11a5u: // VUID-vkCmdSetColorWriteMaskEXT-extendedDynamicState3ColorWriteMask-07364
- case 0x6b453f78u: // VUID-vkCmdSetColorBlendEnableEXT-extendedDynamicState3ColorBlendEnable-07355
- case 0xf66469d0u: // VUID-vkCmdSetColorBlendEquationEXT-extendedDynamicState3ColorBlendEquation-07356
- case 0x1d43405eu: // VUID-vkCmdSetLogicOpEnableEXT-extendedDynamicState3LogicOpEnable-07365
- case 0x638462e8u: // VUID-vkCmdSetDepthClampEnableEXT-extendedDynamicState3DepthClampEnable-07448
// Misc
case 0xe0a2da61u: // VUID-vkCmdDrawIndexed-format-07753
-#else
- case 0x682a878au: // VUID-vkCmdBindVertexBuffers2EXT-pBuffers-parameter
- case 0x99fb7dfdu: // UNASSIGNED-RequiredParameter (vkCmdBindVertexBuffers2EXT pBuffers[0])
+#else
case 0xe8616bf2u: // Bound VkDescriptorSet 0x0[] was destroyed. Likely push_descriptor related
case 0x1608dec0u: // Image layout in vkUpdateDescriptorSet doesn't match descriptor use
case 0x55362756u: // Descriptor binding and framebuffer attachment overlap
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index a2ff3ee6ed..c84c7b6a5a 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -475,6 +475,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (extensions.descriptor_indexing && Settings::values.descriptor_indexing.GetValue()) {
first_next = &descriptor_indexing;
+ } else {
+ RemoveExtension(extensions.descriptor_indexing,
+ VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
}
is_blit_depth24_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D24_UNORM_S8_UINT);
@@ -498,14 +501,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
CollectToolingInfo();
if (is_qualcomm) {
- // Qualcomm Adreno GPUs doesn't handle scaled vertex attributes; keep emulation enabled
must_emulate_scaled_formats = true;
- LOG_WARNING(Render_Vulkan,
- "Qualcomm drivers require scaled vertex format emulation; forcing fallback");
-
- LOG_WARNING(Render_Vulkan,
- "Disabling shader float controls and 64-bit integer features on Qualcomm proprietary drivers");
- RemoveExtension(extensions.shader_float_controls, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64,
VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME);
features.shader_atomic_int64.shaderBufferInt64Atomics = false;
@@ -523,9 +519,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
bool should_patch_bcn = api_level >= 28;
const bool bcn_debug_override = Settings::values.patch_old_qcom_drivers.GetValue();
if (bcn_debug_override != should_patch_bcn) {
- LOG_WARNING(Render_Vulkan,
- "BCn patch debug override active: {} (auto-detected: {})",
- bcn_debug_override, should_patch_bcn);
should_patch_bcn = bcn_debug_override;
}
@@ -540,11 +533,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
} else {
LOG_ERROR(Render_Vulkan, "BCn patch failed! Driver code may now crash");
}
- } else {
- LOG_WARNING(Render_Vulkan,
- "BCn texture patching skipped for stability (Android API {} < 28). "
- "Driver version {}.{} would support patching, but may crash on older Android.",
- api_level, major, minor);
}
} else if (patch_status == ADRENOTOOLS_BCN_BLOB) {
LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures natively (no patch needed)");
@@ -563,7 +551,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
features.shader_float16_int8.shaderFloat16 = false;
}
- // Mali/ NVIDIA proprietary drivers: Shader stencil export not supported
+ // NVIDIA proprietary drivers: Shader stencil export not supported
+ if (properties.properties.driverVersion >= VK_MAKE_API_VERSION(510, 0, 0, 0)) {
+ LOG_WARNING(Render_Vulkan,
+ "NVIDIA Drivers >= 510 do not support MSAA->MSAA image blits. "
+ "MSAA scaling will use 3D helpers. MSAA resolves work normally.");
+ cant_blit_msaa = true;
+ }
+
// Use hardware depth/stencil blits instead when available
if (!extensions.shader_stencil_export) {
LOG_INFO(Render_Vulkan,
@@ -610,10 +605,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
const size_t derived_budget =
(std::max)(MIN_SAMPLER_BUDGET, sampler_limit - reserved);
sampler_heap_budget = derived_budget;
- LOG_WARNING(Render_Vulkan,
- "Qualcomm driver reports max {} samplers; reserving {} (25%) and "
- "allowing Eden to use {} (75%) to avoid heap exhaustion",
- sampler_limit, reserved, sampler_heap_budget);
}
}
@@ -660,53 +651,25 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
const auto dyna_state = Settings::values.dyna_state.GetValue();
- // Base dynamic states (VIEWPORT, SCISSOR, DEPTH_BIAS, etc.) are ALWAYS active in vk_graphics_pipeline.cpp
- // This slider controls EXTENDED dynamic states with accumulative levels per Vulkan specs:
- // Level 0 = Core Dynamic States only (Vulkan 1.0)
- // Level 1 = Core + VK_EXT_extended_dynamic_state
- // Level 2 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2
- // Level 3 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2 + VK_EXT_extended_dynamic_state3
-
switch (dyna_state) {
case Settings::ExtendedDynamicState::Disabled:
- // Level 0: Disable all extended dynamic state extensions
+ // Level 0: Disable all configured extended dynamic state extensions
RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state,
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
- RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
- VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
- dynamic_state3_blending = false;
- dynamic_state3_enables = false;
break;
case Settings::ExtendedDynamicState::EDS1:
- // Level 1: Enable EDS1, disable EDS2 and EDS3
+ // Level 1: Enable EDS1, disable EDS2
RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
- RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
- VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
- dynamic_state3_blending = false;
- dynamic_state3_enables = false;
break;
case Settings::ExtendedDynamicState::EDS2:
- // Level 2: Enable EDS1 + EDS2, disable EDS3
- RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
- VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
- dynamic_state3_blending = false;
- dynamic_state3_enables = false;
- break;
- case Settings::ExtendedDynamicState::EDS3:
default:
- // Level 3: Enable all (EDS1 + EDS2 + EDS3)
+ // Level 2: Enable EDS1 + EDS2
break;
}
- // VK_EXT_vertex_input_dynamic_state is independent from EDS
- // It can be enabled even without extended_dynamic_state
- if (!Settings::values.vertex_input_dynamic_state.GetValue()) {
- RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
- }
-
logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), first_next, dld);
graphics_queue = logical.GetQueue(graphics_family);
@@ -1063,6 +1026,11 @@ bool Device::GetSuitability(bool requires_swapchain) {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
SetNext(next, properties.push_descriptor);
}
+ if (extensions.conservative_rasterization) {
+ properties.conservative_rasterization.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT;
+ SetNext(next, properties.conservative_rasterization);
+ }
if (extensions.subgroup_size_control || features.subgroup_size_control.subgroupSizeControl) {
properties.subgroup_size_control.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES;
@@ -1093,6 +1061,22 @@ bool Device::GetSuitability(bool requires_swapchain) {
// Unload extensions if feature support is insufficient.
RemoveUnsuitableExtensions();
+ // Query VK_EXT_custom_border_color properties if the extension is enabled.
+ if (extensions.custom_border_color) {
+ auto proc = dld.vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceCustomBorderColorPropertiesEXT");
+ if (proc != nullptr) {
+ auto vkGetPhysicalDeviceCustomBorderColorPropertiesEXT =
+ reinterpret_cast(
+ proc);
+ custom_border_color_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT;
+ custom_border_color_properties.pNext = nullptr;
+ vkGetPhysicalDeviceCustomBorderColorPropertiesEXT(physical, &custom_border_color_properties);
+ has_custom_border_color_properties = true;
+ } else {
+ has_custom_border_color_properties = false;
+ }
+ }
+
// Check limits.
struct Limit {
u32 minimum;
@@ -1117,46 +1101,14 @@ bool Device::GetSuitability(bool requires_swapchain) {
// VK_DYNAMIC_STATE
- // Driver detection variables for workarounds in GetSuitability
- const VkDriverId driver_id = properties.driver.driverID;
+ // VK_EXT_extended_dynamic_state below this will appear drivers that need workarounds.
// VK_EXT_extended_dynamic_state2 below this will appear drivers that need workarounds.
- // VK_EXT_extended_dynamic_state3 below this will appear drivers that need workarounds.
-
- // Samsung: Broken extendedDynamicState3ColorBlendEquation
- // Disable blend equation dynamic state, force static pipeline state
- if (extensions.extended_dynamic_state3 &&
- (driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) {
- LOG_WARNING(Render_Vulkan,
- "Samsung: Disabling broken extendedDynamicState3ColorBlendEquation");
- features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
- features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
- }
-
- // Intel Windows < 27.20.100.0: Broken VertexInputDynamicState
- // Same for NVIDIA Proprietary < 580.119.02, unknown when VIDS was first NOT broken
- // Disable VertexInputDynamicState on old Intel Windows drivers
- if (extensions.vertex_input_dynamic_state) {
- const u32 version = (properties.properties.driverVersion << 3) >> 3;
- if ((driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS && version < VK_MAKE_API_VERSION(27, 20, 100, 0))
- || (driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY && version < VK_MAKE_API_VERSION(580, 119, 02, 0))) {
- LOG_WARNING(Render_Vulkan, "Disabling broken VK_EXT_vertex_input_dynamic_state");
- RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
- }
- }
-
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;
- features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
- features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
- features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask = false;
- features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false;
- features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable = false;
}
// Return whether we were suitable.
@@ -1165,15 +1117,9 @@ bool Device::GetSuitability(bool requires_swapchain) {
void Device::RemoveUnsuitableExtensions() {
// VK_EXT_custom_border_color
- // Enable extension if driver supports it, then check individual features
- // - customBorderColors: Required to use VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
- // - customBorderColorWithoutFormat: Optional, allows VK_FORMAT_UNDEFINED
- // If only customBorderColors is available, we must provide a specific format
if (extensions.custom_border_color) {
// Verify that at least customBorderColors is available
if (!features.custom_border_color.customBorderColors) {
- LOG_WARNING(Render_Vulkan,
- "VK_EXT_custom_border_color reported but customBorderColors feature not available, disabling");
extensions.custom_border_color = false;
}
}
@@ -1196,7 +1142,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,
@@ -1208,67 +1154,7 @@ void Device::RemoveUnsuitableExtensions() {
features.extended_dynamic_state2,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
- // VK_EXT_extended_dynamic_state3
- const bool supports_color_blend_enable =
- features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable;
- const bool supports_color_blend_equation =
- features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation;
- const bool supports_color_write_mask =
- features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask;
- dynamic_state3_blending = supports_color_blend_enable && supports_color_blend_equation &&
- supports_color_write_mask;
-
- const bool supports_depth_clamp_enable =
- features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable;
- const bool supports_logic_op_enable =
- features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable;
- const bool supports_line_raster_mode =
- features.extended_dynamic_state3.extendedDynamicState3LineRasterizationMode &&
- extensions.line_rasterization && features.line_rasterization.rectangularLines;
- const bool supports_conservative_raster_mode =
- features.extended_dynamic_state3.extendedDynamicState3ConservativeRasterizationMode &&
- extensions.conservative_rasterization;
- const bool supports_line_stipple_enable =
- features.extended_dynamic_state3.extendedDynamicState3LineStippleEnable &&
- extensions.line_rasterization && features.line_rasterization.stippledRectangularLines;
- const bool supports_alpha_to_coverage =
- features.extended_dynamic_state3.extendedDynamicState3AlphaToCoverageEnable;
- const bool supports_alpha_to_one =
- features.extended_dynamic_state3.extendedDynamicState3AlphaToOneEnable &&
- features.features.alphaToOne;
-
- dynamic_state3_depth_clamp_enable = supports_depth_clamp_enable;
- dynamic_state3_logic_op_enable = supports_logic_op_enable;
- dynamic_state3_line_raster_mode = supports_line_raster_mode;
- dynamic_state3_conservative_raster_mode = supports_conservative_raster_mode;
- dynamic_state3_line_stipple_enable = supports_line_stipple_enable;
- dynamic_state3_alpha_to_coverage = supports_alpha_to_coverage;
- dynamic_state3_alpha_to_one = supports_alpha_to_one;
-
- dynamic_state3_enables = dynamic_state3_depth_clamp_enable || dynamic_state3_logic_op_enable ||
- dynamic_state3_line_raster_mode ||
- dynamic_state3_conservative_raster_mode ||
- dynamic_state3_line_stipple_enable ||
- dynamic_state3_alpha_to_coverage || dynamic_state3_alpha_to_one;
-
- extensions.extended_dynamic_state3 = dynamic_state3_blending || dynamic_state3_enables;
- if (!extensions.extended_dynamic_state3) {
- dynamic_state3_blending = false;
- dynamic_state3_enables = false;
- dynamic_state3_depth_clamp_enable = false;
- dynamic_state3_logic_op_enable = false;
- dynamic_state3_line_raster_mode = false;
- dynamic_state3_conservative_raster_mode = false;
- dynamic_state3_line_stipple_enable = false;
- dynamic_state3_alpha_to_coverage = false;
- dynamic_state3_alpha_to_one = false;
- }
- RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state3,
- features.extended_dynamic_state3,
- VK_EXT_EXTENDED_DYNAMIC_STATE_3_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;
@@ -1277,25 +1163,10 @@ 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);
- // VK_EXT_provoking_vertex
- if (Settings::values.provoking_vertex.GetValue()) {
- extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast
- && features.provoking_vertex
- .transformFeedbackPreservesProvokingVertex;
- RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex,
- features.provoking_vertex,
- VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
- } else {
- RemoveExtensionFeature(extensions.provoking_vertex,
- features.provoking_vertex,
- VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
- }
-
// VK_KHR_shader_atomic_int64
extensions.shader_atomic_int64 = features.shader_atomic_int64.shaderBufferInt64Atomics &&
features.shader_atomic_int64.shaderSharedInt64Atomics;
@@ -1319,28 +1190,32 @@ void Device::RemoveUnsuitableExtensions() {
VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME);
// VK_EXT_transform_feedback
- // We only require the basic transformFeedback feature and at least
- // one transform feedback buffer. We keep transformFeedbackQueries as it's used by
- // the streaming byte count implementation. GeometryStreams and multiple streams
- // are not strictly required since we currently support only stream 0.
extensions.transform_feedback =
features.transform_feedback.transformFeedback &&
properties.transform_feedback.maxTransformFeedbackBuffers > 0 &&
properties.transform_feedback.transformFeedbackQueries;
RemoveExtensionFeatureIfUnsuitable(extensions.transform_feedback, features.transform_feedback,
VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
- if (extensions.transform_feedback) {
- LOG_INFO(Render_Vulkan, "VK_EXT_transform_feedback enabled (buffers={}, queries={})",
- properties.transform_feedback.maxTransformFeedbackBuffers,
- properties.transform_feedback.transformFeedbackQueries);
- }
- // VK_EXT_vertex_input_dynamic_state
- extensions.vertex_input_dynamic_state =
- features.vertex_input_dynamic_state.vertexInputDynamicState;
- RemoveExtensionFeatureIfUnsuitable(extensions.vertex_input_dynamic_state,
- features.vertex_input_dynamic_state,
- VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
+ // VK_EXT_provoking_vertex
+ extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast;
+ RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex,
+ features.provoking_vertex,
+ VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
+
+ // VK_EXT_line_rasterization
+ extensions.line_rasterization = features.line_rasterization.rectangularLines ||
+ features.line_rasterization.bresenhamLines ||
+ features.line_rasterization.smoothLines;
+ RemoveExtensionFeatureIfUnsuitable(extensions.line_rasterization,
+ features.line_rasterization,
+ VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME);
+
+ // VK_EXT_conditional_rendering
+ extensions.conditional_rendering = features.conditional_rendering.conditionalRendering;
+ RemoveExtensionFeatureIfUnsuitable(extensions.conditional_rendering,
+ features.conditional_rendering,
+ VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME);
// VK_EXT_multi_draw
extensions.multi_draw = features.multi_draw.multiDraw;
@@ -1377,35 +1252,15 @@ void Device::RemoveUnsuitableExtensions() {
features.workgroup_memory_explicit_layout,
VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME);
- // VK_EXT_swapchain_maintenance1 (extension only, has features)
- // Requires VK_EXT_surface_maintenance1 instance extension
- extensions.swapchain_maintenance1 = features.swapchain_maintenance1.swapchainMaintenance1;
- if (extensions.swapchain_maintenance1) {
- // Check if VK_EXT_surface_maintenance1 instance extension is available
- const auto instance_extensions = vk::EnumerateInstanceExtensionProperties(dld);
- const bool has_surface_maintenance1 = instance_extensions && std::ranges::any_of(*instance_extensions,
- [](const VkExtensionProperties& prop) {
- return std::strcmp(prop.extensionName, VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME) == 0;
- });
- if (!has_surface_maintenance1) {
- LOG_WARNING(Render_Vulkan,
- "VK_EXT_swapchain_maintenance1 requires VK_EXT_surface_maintenance1, disabling");
- extensions.swapchain_maintenance1 = false;
- features.swapchain_maintenance1.swapchainMaintenance1 = false;
- }
- }
- 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);
@@ -1416,17 +1271,6 @@ void Device::RemoveUnsuitableExtensions() {
// VK_KHR_maintenance5
extensions.maintenance5 = features.maintenance5.maintenance5;
-
- if (extensions.maintenance5) {
- LOG_INFO(Render_Vulkan, "VK_KHR_maintenance5 properties: polygonModePointSize={} "
- "depthStencilSwizzleOne={} earlyFragmentTests={} nonStrictWideLines={}",
- properties.maintenance5.polygonModePointSize,
- properties.maintenance5.depthStencilSwizzleOneSupport,
- properties.maintenance5.earlyFragmentMultisampleCoverageAfterSampleCounting &&
- properties.maintenance5.earlyFragmentSampleMaskTestBeforeSampleCounting,
- properties.maintenance5.nonStrictWideLinesUseParallelogram);
- }
-
RemoveExtensionFeatureIfUnsuitable(extensions.maintenance5, features.maintenance5,
VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
@@ -1435,17 +1279,13 @@ 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)
- extensions.maintenance9 = loaded_extensions.contains(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
- RemoveExtensionIfUnsuitable(extensions.maintenance9, VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
}
void Device::SetupFamilies(VkSurfaceKHR surface) {
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index d29a8cd3f3..2afb57def5 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -48,12 +48,12 @@ VK_DEFINE_HANDLE(VmaAllocator)
// Define all features which may be used by the implementation and require an extension here.
#define FOR_EACH_VK_FEATURE_EXT(FEATURE) \
+ FEATURE(EXT, ConditionalRendering, CONDITIONAL_RENDERING, conditional_rendering) \
FEATURE(EXT, CustomBorderColor, CUSTOM_BORDER_COLOR, custom_border_color) \
FEATURE(EXT, DepthBiasControl, DEPTH_BIAS_CONTROL, depth_bias_control) \
FEATURE(EXT, DepthClipControl, DEPTH_CLIP_CONTROL, depth_clip_control) \
FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \
FEATURE(EXT, ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, extended_dynamic_state2) \
- FEATURE(EXT, ExtendedDynamicState3, EXTENDED_DYNAMIC_STATE_3, extended_dynamic_state3) \
FEATURE(EXT, 4444Formats, 4444_FORMATS, format_a4b4g4r4) \
FEATURE(EXT, IndexTypeUint8, INDEX_TYPE_UINT8, index_type_uint8) \
FEATURE(EXT, LineRasterization, LINE_RASTERIZATION, line_rasterization) \
@@ -63,8 +63,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
FEATURE(EXT, ProvokingVertex, PROVOKING_VERTEX, provoking_vertex) \
FEATURE(EXT, Robustness2, ROBUSTNESS_2, robustness2) \
FEATURE(EXT, TransformFeedback, TRANSFORM_FEEDBACK, transform_feedback) \
- FEATURE(EXT, VertexInputDynamicState, VERTEX_INPUT_DYNAMIC_STATE, vertex_input_dynamic_state) \
- FEATURE(EXT, SwapchainMaintenance1, SWAPCHAIN_MAINTENANCE_1, swapchain_maintenance1) \
FEATURE(KHR, Maintenance5, MAINTENANCE_5, maintenance5) \
FEATURE(KHR, Maintenance6, MAINTENANCE_6, maintenance6) \
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
@@ -76,7 +74,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
// Define miscellaneous extensions which may be used by the implementation here.
#define FOR_EACH_VK_EXTENSION(EXTENSION) \
- EXTENSION(EXT, CONDITIONAL_RENDERING, conditional_rendering) \
EXTENSION(EXT, CONSERVATIVE_RASTERIZATION, conservative_rasterization) \
EXTENSION(EXT, DEPTH_RANGE_UNRESTRICTED, depth_range_unrestricted) \
EXTENSION(EXT, MEMORY_BUDGET, memory_budget) \
@@ -100,7 +97,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
EXTENSION(KHR, MAINTENANCE_3, maintenance3) \
EXTENSION(KHR, MAINTENANCE_7, maintenance7) \
EXTENSION(KHR, MAINTENANCE_8, maintenance8) \
- EXTENSION(KHR, MAINTENANCE_9, maintenance9) \
EXTENSION(NV, DEVICE_DIAGNOSTICS_CONFIG, device_diagnostics_config) \
EXTENSION(NV, GEOMETRY_SHADER_PASSTHROUGH, geometry_shader_passthrough) \
EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \
@@ -125,13 +121,11 @@ VK_DEFINE_HANDLE(VmaAllocator)
EXTENSION_NAME(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \
- EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
- EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \
EXTENSION_NAME(VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME) \
EXTENSION_NAME(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME) \
EXTENSION_NAME(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME)
@@ -189,8 +183,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
FEATURE_NAME(shader_float16_int8, shaderInt8) \
FEATURE_NAME(timeline_semaphore, timelineSemaphore) \
FEATURE_NAME(transform_feedback, transformFeedback) \
- FEATURE_NAME(uniform_buffer_standard_layout, uniformBufferStandardLayout) \
- FEATURE_NAME(vertex_input_dynamic_state, vertexInputDynamicState)
+ FEATURE_NAME(uniform_buffer_standard_layout, uniformBufferStandardLayout)
// These features are not required but can be helpful for drivers that can use it.
#define FOR_EACH_VK_OPTIONAL_FEATURE(FEATURE_NAME) \
@@ -448,7 +441,7 @@ public:
return extensions.viewport_array2;
}
- /// Returns true if the device supporst VK_EXT_DESCRIPTOR_INDEXING
+ /// Returns true if the device supporst VK_EXT_descriptor_indexing.
bool isExtDescriptorIndexingSupported() const {
return extensions.descriptor_indexing;
}
@@ -478,11 +471,6 @@ public:
return extensions.swapchain_mutable_format;
}
- /// Returns true if VK_EXT_swapchain_maintenance1 is enabled.
- bool IsExtSwapchainMaintenance1Enabled() const {
- return extensions.swapchain_maintenance1;
- }
-
/// Returns true if VK_KHR_shader_float_controls is enabled.
bool IsKhrShaderFloatControlsSupported() const {
return extensions.shader_float_controls;
@@ -519,13 +507,11 @@ public:
}
/// Returns true if the device supports VK_EXT_shader_stencil_export.
- /// Note: Most Mali/NVIDIA drivers don't support this. Use hardware blits as fallback.
bool IsExtShaderStencilExportSupported() const {
return extensions.shader_stencil_export;
}
- /// Returns true if depth/stencil operations can be performed efficiently.
- /// Either through shader export or hardware blits.
+ /// Returns true if depth/stencil operations through shader export or hardware blits.
bool CanPerformDepthStencilOperations() const {
return extensions.shader_stencil_export || is_blit_depth24_stencil8_supported ||
is_blit_depth32_stencil8_supported;
@@ -561,11 +547,14 @@ public:
return extensions.transform_feedback;
}
- /// Returns true if the device supports VK_EXT_transform_feedback properly.
bool AreTransformFeedbackGeometryStreamsSupported() const {
return features.transform_feedback.geometryStreams;
}
+ bool IsTransformFeedbackProvokingVertexPreserved() const {
+ return features.provoking_vertex.transformFeedbackPreservesProvokingVertex;
+ }
+
/// Returns true if the device supports VK_EXT_custom_border_color.
bool IsExtCustomBorderColorSupported() const {
return extensions.custom_border_color;
@@ -611,6 +600,16 @@ public:
return features.custom_border_color.customBorderColorWithoutFormat;
}
+ /// Returns true if physical device custom border color properties were queried.
+ bool HasCustomBorderColorProperties() const {
+ return has_custom_border_color_properties;
+ }
+
+ /// Returns the queried VkPhysicalDeviceCustomBorderColorPropertiesEXT.
+ const VkPhysicalDeviceCustomBorderColorPropertiesEXT& GetCustomBorderColorProperties() const {
+ return custom_border_color_properties;
+ }
+
/// Returns true if the device supports VK_EXT_extended_dynamic_state.
bool IsExtExtendedDynamicStateSupported() const {
return extensions.extended_dynamic_state;
@@ -625,32 +624,21 @@ public:
return features.extended_dynamic_state2.extendedDynamicState2LogicOp;
}
- /// Returns true if the device supports VK_EXT_extended_dynamic_state3.
- bool IsExtExtendedDynamicState3Supported() const {
- return extensions.extended_dynamic_state3;
- }
-
/// Returns true if the device supports VK_EXT_4444_formats.
bool IsExt4444FormatsSupported() const {
return features.format_a4b4g4r4.formatA4B4G4R4;
}
- /// Returns true if the device supports VK_EXT_extended_dynamic_state3.
- bool IsExtExtendedDynamicState3BlendingSupported() const {
- return dynamic_state3_blending;
- }
-
- /// Returns true if the device supports VK_EXT_extended_dynamic_state3.
- bool IsExtExtendedDynamicState3EnablesSupported() const {
- return dynamic_state3_enables;
- }
-
- /// Returns true if the device supports VK_EXT_filter_cubic
+ /// Returns true if the device supports VK_EXT_filter_cubic.
bool IsExtFilterCubicSupported() const {
return extensions.filter_cubic;
}
- /// Returns true if the device supports VK_QCOM_filter_cubic_weights
+ /// Custom border color properties retrieved from the physical device (if available).
+ VkPhysicalDeviceCustomBorderColorPropertiesEXT custom_border_color_properties{};
+ bool has_custom_border_color_properties = false;
+
+ /// Returns true if the device supports VK_QCOM_filter_cubic_weights.
bool IsQcomFilterCubicWeightsSupported() const {
return extensions.filter_cubic_weights;
}
@@ -661,55 +649,36 @@ public:
}
bool SupportsRectangularLines() const {
- return features.line_rasterization.rectangularLines != VK_FALSE;
+ return features.line_rasterization.rectangularLines;
+ }
+
+ bool SupportsBresenhamLines() const {
+ return features.line_rasterization.bresenhamLines;
}
bool SupportsSmoothLines() const {
- return features.line_rasterization.smoothLines != VK_FALSE;
+ return features.line_rasterization.smoothLines;
}
bool SupportsStippledRectangularLines() const {
- return features.line_rasterization.stippledRectangularLines != VK_FALSE;
+ return features.line_rasterization.stippledRectangularLines;
}
+ bool SupportsStippledBresenhamLines() const {
+ return features.line_rasterization.stippledBresenhamLines;
+ }
+
+ bool SupportsStippledSmoothLines() const {
+ return features.line_rasterization.stippledSmoothLines;
+ }
+
+ /// Returns true if the device supports AlphaToOne.
bool SupportsAlphaToOne() const {
- return features.features.alphaToOne != VK_FALSE;
+ return features.features.alphaToOne;
}
- bool SupportsDynamicState3DepthClampEnable() const {
- return dynamic_state3_depth_clamp_enable;
- }
- bool SupportsDynamicState3LogicOpEnable() const {
- return dynamic_state3_logic_op_enable;
- }
-
- bool SupportsDynamicState3LineRasterizationMode() const {
- return dynamic_state3_line_raster_mode;
- }
-
- bool SupportsDynamicState3ConservativeRasterizationMode() const {
- return dynamic_state3_conservative_raster_mode;
- }
-
- bool SupportsDynamicState3LineStippleEnable() const {
- return dynamic_state3_line_stipple_enable;
- }
-
- bool SupportsDynamicState3AlphaToCoverageEnable() const {
- return dynamic_state3_alpha_to_coverage;
- }
-
- bool SupportsDynamicState3AlphaToOneEnable() const {
- return dynamic_state3_alpha_to_one;
- }
-
- /// Returns true if the device supports VK_EXT_vertex_input_dynamic_state.
- bool IsExtVertexInputDynamicStateSupported() const {
- return extensions.vertex_input_dynamic_state;
- }
-
- /// Returns true if the device supports VK_EXT_shader_demote_to_helper_invocation
+ /// Returns true if the device supports VK_EXT_shader_demote_to_helper_invocation.
bool IsExtShaderDemoteToHelperInvocationSupported() const {
return extensions.shader_demote_to_helper_invocation;
}
@@ -718,21 +687,37 @@ public:
bool IsExtConservativeRasterizationSupported() const {
return extensions.conservative_rasterization;
}
+
+ /// Returns true if the device supports conservative rasterization for points and lines.
+ bool SupportsConservativePointAndLineRasterization() const {
+ return extensions.conservative_rasterization &&
+ properties.conservative_rasterization.conservativePointAndLineRasterization;
+ }
/// Returns true if the device supports VK_EXT_provoking_vertex.
bool IsExtProvokingVertexSupported() const {
return extensions.provoking_vertex;
}
+ /// Returns true if the device supports provoking-vertex LAST mode.
+ bool IsProvokingVertexLastSupported() const {
+ return features.provoking_vertex.provokingVertexLast;
+ }
+
/// Returns true if the device supports VK_KHR_shader_atomic_int64.
bool IsExtShaderAtomicInt64Supported() const {
return extensions.shader_atomic_int64;
}
- bool IsExtConditionalRendering() const {
+ /// Returns true if the device supports VK_EXT_conditional_rendering.
+ bool IsExtConditionalRenderingSupported() const {
return extensions.conditional_rendering;
}
+ bool IsExtConditionalRendering() const {
+ return IsExtConditionalRenderingSupported();
+ }
+
bool HasTimelineSemaphore() const;
/// Returns the minimum supported version of SPIR-V.
@@ -751,7 +736,7 @@ public:
return has_renderdoc || has_nsight_graphics || has_radeon_gpu_profiler;
}
- /// @returns True if compute pipelines can cause crashing.
+ /// Returns true if compute pipelines can cause crashing.
bool HasBrokenCompute() const {
return has_broken_compute;
}
@@ -898,11 +883,6 @@ public:
return extensions.maintenance8;
}
- /// Returns true if the device supports VK_KHR_maintenance9.
- bool IsKhrMaintenance9Supported() const {
- return extensions.maintenance9;
- }
-
/// Returns true if the device supports UINT8 index buffer conversion via compute shader.
bool SupportsUint8Indices() const {
return features.bit8_storage.storageBuffer8BitAccess &&
@@ -1027,6 +1007,7 @@ private:
VkPhysicalDeviceSubgroupProperties subgroup_properties{};
VkPhysicalDeviceFloatControlsProperties float_controls{};
VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor{};
+ VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_rasterization{};
VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control{};
VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback{};
VkPhysicalDeviceMaintenance5PropertiesKHR maintenance5{};
@@ -1059,15 +1040,6 @@ private:
bool supports_d24_depth{}; ///< Supports D24 depth buffers.
bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting.
bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation
- bool dynamic_state3_blending{}; ///< Has blending features of dynamic_state3.
- bool dynamic_state3_enables{}; ///< Has at least one enable feature of dynamic_state3.
- bool dynamic_state3_depth_clamp_enable{};
- bool dynamic_state3_logic_op_enable{};
- bool dynamic_state3_line_raster_mode{};
- bool dynamic_state3_conservative_raster_mode{};
- bool dynamic_state3_line_stipple_enable{};
- bool dynamic_state3_alpha_to_coverage{};
- bool dynamic_state3_alpha_to_one{};
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
size_t sampler_heap_budget{}; ///< Sampler budget for buggy drivers (0 = unlimited).
u64 device_access_memory{}; ///< Total size of device local memory in bytes.
diff --git a/src/video_core/vulkan_common/vulkan_instance.cpp b/src/video_core/vulkan_common/vulkan_instance.cpp
index 47e18dd6a5..9cf65ad252 100644
--- a/src/video_core/vulkan_common/vulkan_instance.cpp
+++ b/src/video_core/vulkan_common/vulkan_instance.cpp
@@ -81,14 +81,6 @@ namespace {
#endif
if (enable_validation && AreExtensionsSupported(dld, *properties, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME}))
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
- // VK_EXT_surface_maintenance1 is required for VK_EXT_swapchain_maintenance1
- if (window_type != Core::Frontend::WindowSystemType::Headless && AreExtensionsSupported(dld, *properties, std::array{VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME})) {
- extensions.push_back(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME);
- // Some(which?) drivers dont like being told to load this extension(why?)
- // NVIDIA on FreeBSD is totally fine with this through
- if (AreExtensionsSupported(dld, *properties, std::array{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}))
- extensions.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
- }
}
return extensions;
}
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index 926f48de89..f1854d4792 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -127,18 +127,20 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkCmdPipelineBarrier);
X(vkCmdPushConstants);
X(vkCmdPushDescriptorSetWithTemplateKHR);
+ X(vkCmdResetQueryPool);
X(vkCmdSetBlendConstants);
X(vkCmdSetDepthBias);
X(vkCmdSetDepthBias2EXT);
X(vkCmdSetDepthBounds);
X(vkCmdSetEvent);
X(vkCmdSetScissor);
+ X(vkCmdSetScissorWithCountEXT);
X(vkCmdSetStencilCompareMask);
X(vkCmdSetStencilReference);
X(vkCmdSetStencilWriteMask);
X(vkCmdSetViewport);
+ X(vkCmdSetViewportWithCountEXT);
X(vkCmdWaitEvents);
- X(vkCmdBindVertexBuffers2EXT);
X(vkCmdSetCullModeEXT);
X(vkCmdSetDepthBoundsTestEnableEXT);
X(vkCmdSetDepthCompareOpEXT);
@@ -146,25 +148,15 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkCmdSetDepthWriteEnableEXT);
X(vkCmdSetPrimitiveRestartEnableEXT);
X(vkCmdSetRasterizerDiscardEnableEXT);
- X(vkCmdSetAlphaToCoverageEnableEXT);
- X(vkCmdSetAlphaToOneEnableEXT);
- X(vkCmdSetConservativeRasterizationModeEXT);
- X(vkCmdSetLineRasterizationModeEXT);
- X(vkCmdSetLineStippleEnableEXT);
X(vkCmdSetDepthBiasEnableEXT);
- X(vkCmdSetLogicOpEnableEXT);
- X(vkCmdSetDepthClampEnableEXT);
X(vkCmdSetFrontFaceEXT);
X(vkCmdSetLogicOpEXT);
X(vkCmdSetPatchControlPointsEXT);
+ X(vkCmdSetLineStippleEXT);
X(vkCmdSetLineWidth);
X(vkCmdSetPrimitiveTopologyEXT);
X(vkCmdSetStencilOpEXT);
X(vkCmdSetStencilTestEnableEXT);
- X(vkCmdSetVertexInputEXT);
- X(vkCmdSetColorWriteMaskEXT);
- X(vkCmdSetColorBlendEnableEXT);
- X(vkCmdSetColorBlendEquationEXT);
X(vkCmdResolveImage);
X(vkCreateBuffer);
X(vkCreateBufferView);
@@ -254,6 +246,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
}
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 5c04132f7b..594194d788 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -200,7 +200,6 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdBindPipeline vkCmdBindPipeline{};
PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT{};
PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers{};
- PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT{};
PFN_vkCmdBlitImage vkCmdBlitImage{};
PFN_vkCmdClearAttachments vkCmdClearAttachments{};
PFN_vkCmdClearColorImage vkCmdClearColorImage{};
@@ -229,6 +228,7 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{};
PFN_vkCmdPushConstants vkCmdPushConstants{};
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{};
+ PFN_vkCmdResetQueryPool vkCmdResetQueryPool{};
PFN_vkCmdResolveImage vkCmdResolveImage{};
PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants{};
PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT{};
@@ -241,15 +241,8 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT{};
PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT{};
PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT{};
- PFN_vkCmdSetAlphaToCoverageEnableEXT vkCmdSetAlphaToCoverageEnableEXT{};
- PFN_vkCmdSetAlphaToOneEnableEXT vkCmdSetAlphaToOneEnableEXT{};
- PFN_vkCmdSetConservativeRasterizationModeEXT vkCmdSetConservativeRasterizationModeEXT{};
- PFN_vkCmdSetLineRasterizationModeEXT vkCmdSetLineRasterizationModeEXT{};
- PFN_vkCmdSetLineStippleEnableEXT vkCmdSetLineStippleEnableEXT{};
PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT{};
PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{};
- PFN_vkCmdSetLogicOpEnableEXT vkCmdSetLogicOpEnableEXT{};
- PFN_vkCmdSetDepthClampEnableEXT vkCmdSetDepthClampEnableEXT{};
PFN_vkCmdSetEvent vkCmdSetEvent{};
PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{};
PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT{};
@@ -257,16 +250,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_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT{};
PFN_vkCmdSetViewport vkCmdSetViewport{};
- PFN_vkCmdSetColorWriteMaskEXT vkCmdSetColorWriteMaskEXT{};
- PFN_vkCmdSetColorBlendEnableEXT vkCmdSetColorBlendEnableEXT{};
- PFN_vkCmdSetColorBlendEquationEXT vkCmdSetColorBlendEquationEXT{};
+ PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT{};
PFN_vkCmdWaitEvents vkCmdWaitEvents{};
PFN_vkCreateBuffer vkCreateBuffer{};
PFN_vkCreateBufferView vkCreateBufferView{};
@@ -1182,6 +1173,10 @@ public:
dld->vkCmdPushDescriptorSetWithTemplateKHR(handle, update_template, layout, set, data);
}
+ void ResetQueryPool(VkQueryPool query_pool, u32 first, u32 count) const noexcept {
+ dld->vkCmdResetQueryPool(handle, query_pool, first, count);
+ }
+
void BindPipeline(VkPipelineBindPoint bind_point, VkPipeline pipeline) const noexcept {
dld->vkCmdBindPipeline(handle, bind_point, pipeline);
}
@@ -1374,6 +1369,18 @@ public:
dld->vkCmdSetScissor(handle, first, scissors.size(), scissors.data());
}
+ void SetViewportWithCountEXT(Span viewports) const noexcept {
+ if (dld && dld->vkCmdSetViewportWithCountEXT) {
+ dld->vkCmdSetViewportWithCountEXT(handle, viewports.size(), viewports.data());
+ }
+ }
+
+ void SetScissorWithCountEXT(Span scissors) const noexcept {
+ if (dld && dld->vkCmdSetScissorWithCountEXT) {
+ dld->vkCmdSetScissorWithCountEXT(handle, scissors.size(), scissors.data());
+ }
+ }
+
void SetBlendConstants(const float blend_constants[4]) const noexcept {
dld->vkCmdSetBlendConstants(handle, blend_constants);
}
@@ -1403,7 +1410,9 @@ public:
.depthBiasClamp = clamp,
.depthBiasSlopeFactor = slope_factor,
};
- dld->vkCmdSetDepthBias2EXT(handle, &info);
+ if (dld && dld->vkCmdSetDepthBias2EXT) {
+ dld->vkCmdSetDepthBias2EXT(handle, &info);
+ }
}
void SetDepthBounds(float min_depth_bounds, float max_depth_bounds) const noexcept {
@@ -1423,104 +1432,76 @@ public:
buffer_barriers.data(), image_barriers.size(), image_barriers.data());
}
- void BindVertexBuffers2EXT(u32 first_binding, u32 binding_count, const VkBuffer* buffers,
- const VkDeviceSize* offsets, const VkDeviceSize* sizes,
- const VkDeviceSize* strides) const noexcept {
- dld->vkCmdBindVertexBuffers2EXT(handle, first_binding, binding_count, buffers, offsets,
- sizes, strides);
- }
-
void SetCullModeEXT(VkCullModeFlags cull_mode) const noexcept {
- dld->vkCmdSetCullModeEXT(handle, cull_mode);
+ if (dld && dld->vkCmdSetCullModeEXT) {
+ dld->vkCmdSetCullModeEXT(handle, cull_mode);
+ }
}
void SetDepthBoundsTestEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetDepthBoundsTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ if (dld && dld->vkCmdSetDepthBoundsTestEnableEXT) {
+ dld->vkCmdSetDepthBoundsTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
void SetDepthCompareOpEXT(VkCompareOp compare_op) const noexcept {
- dld->vkCmdSetDepthCompareOpEXT(handle, compare_op);
+ if (dld && dld->vkCmdSetDepthCompareOpEXT) {
+ dld->vkCmdSetDepthCompareOpEXT(handle, compare_op);
+ }
}
void SetDepthTestEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetDepthTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ if (dld && dld->vkCmdSetDepthTestEnableEXT) {
+ dld->vkCmdSetDepthTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
void SetDepthWriteEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetDepthWriteEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ if (dld && dld->vkCmdSetDepthWriteEnableEXT) {
+ dld->vkCmdSetDepthWriteEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
void SetPrimitiveRestartEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetPrimitiveRestartEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ if (dld && dld->vkCmdSetPrimitiveRestartEnableEXT) {
+ dld->vkCmdSetPrimitiveRestartEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
void SetRasterizerDiscardEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetRasterizerDiscardEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ if (dld && dld->vkCmdSetRasterizerDiscardEnableEXT) {
+ dld->vkCmdSetRasterizerDiscardEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
- void SetConservativeRasterizationModeEXT(VkConservativeRasterizationModeEXT mode) const noexcept
- {
- dld->vkCmdSetConservativeRasterizationModeEXT(handle, mode);
- }
-
- void SetLineRasterizationModeEXT(VkLineRasterizationModeEXT mode) const noexcept
- {
- dld->vkCmdSetLineRasterizationModeEXT(handle, mode);
- }
-
- void SetLineStippleEnableEXT(bool enable) const noexcept
- {
- dld->vkCmdSetLineStippleEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
- }
-
- void SetLineStippleEXT(u32 factor, u16 pattern) const noexcept
- {
- dld->vkCmdSetLineStippleEXT(handle, factor, pattern);
+ void SetLineStippleEXT(u32 factor, u16 pattern) const noexcept {
+ if (dld && dld->vkCmdSetLineStippleEXT) {
+ dld->vkCmdSetLineStippleEXT(handle, factor, pattern);
+ }
}
void SetDepthBiasEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
- }
-
- void SetLogicOpEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetLogicOpEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
- }
-
- void SetAlphaToCoverageEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetAlphaToCoverageEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
- }
-
- void SetAlphaToOneEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetAlphaToOneEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
- }
-
- void SetDepthClampEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetDepthClampEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ if (dld && dld->vkCmdSetDepthBiasEnableEXT) {
+ dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
void SetFrontFaceEXT(VkFrontFace front_face) const noexcept {
- dld->vkCmdSetFrontFaceEXT(handle, front_face);
+ if (dld && dld->vkCmdSetFrontFaceEXT) {
+ dld->vkCmdSetFrontFaceEXT(handle, front_face);
+ }
}
void SetLogicOpEXT(VkLogicOp logic_op) const noexcept {
- dld->vkCmdSetLogicOpEXT(handle, logic_op);
+ if (dld && dld->vkCmdSetLogicOpEXT) {
+ dld->vkCmdSetLogicOpEXT(handle, logic_op);
+ }
}
void SetPatchControlPointsEXT(uint32_t patch_control_points) const noexcept {
- dld->vkCmdSetPatchControlPointsEXT(handle, patch_control_points);
- }
-
- void SetColorWriteMaskEXT(u32 first, Span masks) const noexcept {
- dld->vkCmdSetColorWriteMaskEXT(handle, first, masks.size(), masks.data());
- }
-
- void SetColorBlendEnableEXT(u32 first, Span enables) const noexcept {
- dld->vkCmdSetColorBlendEnableEXT(handle, first, enables.size(), enables.data());
- }
-
- void SetColorBlendEquationEXT(u32 first,
- Span equations) const noexcept {
- dld->vkCmdSetColorBlendEquationEXT(handle, first, equations.size(), equations.data());
+ if (dld && dld->vkCmdSetPatchControlPointsEXT) {
+ dld->vkCmdSetPatchControlPointsEXT(handle, patch_control_points);
+ }
}
void SetLineWidth(float line_width) const noexcept {
@@ -1528,52 +1509,61 @@ public:
}
void SetPrimitiveTopologyEXT(VkPrimitiveTopology primitive_topology) const noexcept {
- dld->vkCmdSetPrimitiveTopologyEXT(handle, primitive_topology);
+ if (dld && dld->vkCmdSetPrimitiveTopologyEXT) {
+ dld->vkCmdSetPrimitiveTopologyEXT(handle, primitive_topology);
+ }
}
void SetStencilOpEXT(VkStencilFaceFlags face_mask, VkStencilOp fail_op, VkStencilOp pass_op,
VkStencilOp depth_fail_op, VkCompareOp compare_op) const noexcept {
- dld->vkCmdSetStencilOpEXT(handle, face_mask, fail_op, pass_op, depth_fail_op, compare_op);
+ if (dld && dld->vkCmdSetStencilOpEXT) {
+ dld->vkCmdSetStencilOpEXT(handle, face_mask, fail_op, pass_op, depth_fail_op, compare_op);
+ }
}
void SetStencilTestEnableEXT(bool enable) const noexcept {
- dld->vkCmdSetStencilTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
- }
-
- void SetVertexInputEXT(
- vk::Span bindings,
- vk::Span attributes) const noexcept {
- dld->vkCmdSetVertexInputEXT(handle, bindings.size(), bindings.data(), attributes.size(),
- attributes.data());
+ if (dld && dld->vkCmdSetStencilTestEnableEXT) {
+ dld->vkCmdSetStencilTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
+ }
}
void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers,
const VkDeviceSize* offsets,
const VkDeviceSize* sizes) const noexcept {
- dld->vkCmdBindTransformFeedbackBuffersEXT(handle, first, count, buffers, offsets, sizes);
+ if (dld && dld->vkCmdBindTransformFeedbackBuffersEXT) {
+ dld->vkCmdBindTransformFeedbackBuffersEXT(handle, first, count, buffers, offsets, sizes);
+ }
}
void BeginTransformFeedbackEXT(u32 first_counter_buffer, u32 counter_buffers_count,
const VkBuffer* counter_buffers,
const VkDeviceSize* counter_buffer_offsets) const noexcept {
- dld->vkCmdBeginTransformFeedbackEXT(handle, first_counter_buffer, counter_buffers_count,
- counter_buffers, counter_buffer_offsets);
+ if (dld && dld->vkCmdBeginTransformFeedbackEXT) {
+ dld->vkCmdBeginTransformFeedbackEXT(handle, first_counter_buffer, counter_buffers_count,
+ counter_buffers, counter_buffer_offsets);
+ }
}
void EndTransformFeedbackEXT(u32 first_counter_buffer, u32 counter_buffers_count,
const VkBuffer* counter_buffers,
const VkDeviceSize* counter_buffer_offsets) const noexcept {
- dld->vkCmdEndTransformFeedbackEXT(handle, first_counter_buffer, counter_buffers_count,
- counter_buffers, counter_buffer_offsets);
+ if (dld && dld->vkCmdEndTransformFeedbackEXT) {
+ dld->vkCmdEndTransformFeedbackEXT(handle, first_counter_buffer, counter_buffers_count,
+ counter_buffers, counter_buffer_offsets);
+ }
}
void BeginConditionalRenderingEXT(
const VkConditionalRenderingBeginInfoEXT& info) const noexcept {
- dld->vkCmdBeginConditionalRenderingEXT(handle, &info);
+ if (dld && dld->vkCmdBeginConditionalRenderingEXT) {
+ dld->vkCmdBeginConditionalRenderingEXT(handle, &info);
+ }
}
void EndConditionalRenderingEXT() const noexcept {
- dld->vkCmdEndConditionalRenderingEXT(handle);
+ if (dld && dld->vkCmdEndConditionalRenderingEXT) {
+ dld->vkCmdEndConditionalRenderingEXT(handle);
+ }
}
void BeginDebugUtilsLabelEXT(const char* label, std::span color) const noexcept {
@@ -1583,11 +1573,15 @@ public:
.pLabelName = label,
.color{color[0], color[1], color[2], color[3]},
};
- dld->vkCmdBeginDebugUtilsLabelEXT(handle, &label_info);
+ if (dld && dld->vkCmdBeginDebugUtilsLabelEXT) {
+ dld->vkCmdBeginDebugUtilsLabelEXT(handle, &label_info);
+ }
}
void EndDebugUtilsLabelEXT() const noexcept {
- dld->vkCmdEndDebugUtilsLabelEXT(handle);
+ if (dld && dld->vkCmdEndDebugUtilsLabelEXT) {
+ dld->vkCmdEndDebugUtilsLabelEXT(handle);
+ }
}
private: