Browse Source

[vulkan] bump to vk 1.4 and some features to 1.4 tree

gpuopts
CamilleLaVey 3 weeks ago
parent
commit
59444d5c48
  1. 9
      src/video_core/renderer_vulkan/present/util.cpp
  2. 45
      src/video_core/renderer_vulkan/vk_texture_cache.cpp
  3. 43
      src/video_core/vulkan_common/vulkan_device.cpp
  4. 5
      src/video_core/vulkan_common/vulkan_device.h
  5. 16
      src/video_core/vulkan_common/vulkan_wrapper.cpp

9
src/video_core/renderer_vulkan/present/util.cpp

@ -112,12 +112,15 @@ void UploadImage(const Device& device, MemoryAllocator& allocator, Scheduler& sc
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([&](vk::CommandBuffer cmdbuf) { scheduler.Record([&](vk::CommandBuffer cmdbuf) {
TransitionImageLayout(cmdbuf, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
const VkImageLayout transfer_dst_layout = device.IsKhrUnifiedImageLayoutsSupported()
? VK_IMAGE_LAYOUT_GENERAL
: VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
TransitionImageLayout(cmdbuf, *image, transfer_dst_layout,
VK_IMAGE_LAYOUT_UNDEFINED); VK_IMAGE_LAYOUT_UNDEFINED);
cmdbuf.CopyBufferToImage(*upload_buffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
cmdbuf.CopyBufferToImage(*upload_buffer, *image, transfer_dst_layout,
regions); regions);
TransitionImageLayout(cmdbuf, *image, VK_IMAGE_LAYOUT_GENERAL, TransitionImageLayout(cmdbuf, *image, VK_IMAGE_LAYOUT_GENERAL,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
transfer_dst_layout);
}); });
scheduler.Finish(); scheduler.Finish();
} }

45
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -536,6 +536,7 @@ struct RangedBarrierRange {
}; };
void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image, void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image,
VkImageAspectFlags aspect_mask, bool is_initialized, VkImageAspectFlags aspect_mask, bool is_initialized,
bool use_unified_layouts,
std::span<const VkBufferImageCopy> copies) { std::span<const VkBufferImageCopy> copies) {
static constexpr VkAccessFlags WRITE_ACCESS_FLAGS = static constexpr VkAccessFlags WRITE_ACCESS_FLAGS =
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
@ -550,6 +551,8 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
range.AddLayers(region.imageSubresource); range.AddLayers(region.imageSubresource);
} }
const VkImageSubresourceRange subresource_range = range.SubresourceRange(aspect_mask); const VkImageSubresourceRange subresource_range = range.SubresourceRange(aspect_mask);
const VkImageLayout transfer_dst_layout =
use_unified_layouts ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
const VkImageMemoryBarrier read_barrier{ const VkImageMemoryBarrier read_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@ -557,7 +560,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
.srcAccessMask = WRITE_ACCESS_FLAGS, .srcAccessMask = WRITE_ACCESS_FLAGS,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = transfer_dst_layout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image, .image = image,
@ -569,7 +572,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS, .dstAccessMask = WRITE_ACCESS_FLAGS | READ_ACCESS_FLAGS,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.oldLayout = transfer_dst_layout,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@ -581,7 +584,7 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
read_barrier); read_barrier);
cmdbuf.CopyBufferToImage(src_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copies);
cmdbuf.CopyBufferToImage(src_buffer, image, transfer_dst_layout, copies);
// TODO: Move this to another API // TODO: Move this to another API
cmdbuf.PipelineBarrier( cmdbuf.PipelineBarrier(
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
@ -703,7 +706,7 @@ void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4
void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info,
VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution, VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution,
bool up_scaling = true) {
bool use_unified_layouts, bool up_scaling = true) {
const bool is_2d = info.type == ImageType::e2D; const bool is_2d = info.type == ImageType::e2D;
const auto resources = info.resources; const auto resources = info.resources;
const VkExtent2D extent{ const VkExtent2D extent{
@ -777,6 +780,10 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.baseArrayLayer = 0, .baseArrayLayer = 0,
.layerCount = VK_REMAINING_ARRAY_LAYERS, .layerCount = VK_REMAINING_ARRAY_LAYERS,
}; };
const VkImageLayout transfer_src_layout =
use_unified_layouts ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
const VkImageLayout transfer_dst_layout =
use_unified_layouts ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
const std::array read_barriers{ const std::array read_barriers{
VkImageMemoryBarrier{ VkImageMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@ -784,7 +791,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.newLayout = transfer_src_layout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = src_image, .image = src_image,
@ -798,7 +805,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, // Discard contents .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, // Discard contents
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = transfer_dst_layout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = dst_image, .image = dst_image,
@ -812,7 +819,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.srcAccessMask = 0, .srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.oldLayout = transfer_src_layout,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@ -825,7 +832,7 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.oldLayout = transfer_dst_layout,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@ -843,8 +850,8 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
VK_PIPELINE_STAGE_TRANSFER_BIT; VK_PIPELINE_STAGE_TRANSFER_BIT;
cmdbuf.PipelineBarrier(src_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, cmdbuf.PipelineBarrier(src_stages, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, nullptr, nullptr, read_barriers); 0, nullptr, nullptr, read_barriers);
cmdbuf.BlitImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions, vk_filter);
cmdbuf.BlitImage(src_image, transfer_src_layout, dst_image,
transfer_dst_layout, regions, vk_filter);
// After transfer, images may be used in graphics, compute, or as attachments // After transfer, images may be used in graphics, compute, or as attachments
const VkPipelineStageFlags dst_stages = const VkPipelineStageFlags dst_stages =
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
@ -1743,9 +1750,11 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
const VkImage temp_vk_image = *temp_wrapper->original_image; const VkImage temp_vk_image = *temp_wrapper->original_image;
const VkImageAspectFlags vk_aspect_mask = temp_wrapper->aspect_mask; const VkImageAspectFlags vk_aspect_mask = temp_wrapper->aspect_mask;
scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies,
const bool use_unified_layouts = runtime->device.IsKhrUnifiedImageLayoutsSupported();
scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies, use_unified_layouts,
keep = temp_wrapper](vk::CommandBuffer cmdbuf) { 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,
use_unified_layouts, VideoCommon::FixSmallVectorADL(vk_copies));
}); });
// Use MSAACopyPass to convert from non-MSAA to MSAA // Use MSAACopyPass to convert from non-MSAA to MSAA
@ -1782,9 +1791,11 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
const VkImageAspectFlags vk_aspect_mask = aspect_mask; const VkImageAspectFlags vk_aspect_mask = aspect_mask;
const bool was_initialized = std::exchange(initialized, true); const bool was_initialized = std::exchange(initialized, true);
const bool use_unified_layouts = runtime->device.IsKhrUnifiedImageLayoutsSupported();
scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized, scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized,
vk_copies](vk::CommandBuffer cmdbuf) {
CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized, VideoCommon::FixSmallVectorADL(vk_copies));
vk_copies, use_unified_layouts](vk::CommandBuffer cmdbuf) {
CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized,
use_unified_layouts, VideoCommon::FixSmallVectorADL(vk_copies));
}); });
if (is_rescaled) { if (is_rescaled) {
@ -2071,7 +2082,8 @@ bool Image::ScaleUp(bool ignore) {
if (NeedsScaleHelper()) { if (NeedsScaleHelper()) {
return BlitScaleHelper(true); return BlitScaleHelper(true);
} else { } else {
BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution);
BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution,
runtime->device.IsKhrUnifiedImageLayoutsSupported());
} }
return true; return true;
} }
@ -2096,7 +2108,8 @@ bool Image::ScaleDown(bool ignore) {
if (NeedsScaleHelper()) { if (NeedsScaleHelper()) {
return BlitScaleHelper(false); return BlitScaleHelper(false);
} else { } else {
BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, false);
BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution,
runtime->device.IsKhrUnifiedImageLayoutsSupported(), false);
} }
return true; return true;
} }

43
src/video_core/vulkan_common/vulkan_device.cpp

@ -941,6 +941,9 @@ bool Device::GetSuitability(bool requires_swapchain) {
VkPhysicalDeviceVulkan12Features features_1_2{}; VkPhysicalDeviceVulkan12Features features_1_2{};
VkPhysicalDeviceVulkan13Features features_1_3{}; VkPhysicalDeviceVulkan13Features features_1_3{};
#ifdef VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES
VkPhysicalDeviceVulkan14Features features_1_4{};
#endif
// Configure properties. // Configure properties.
properties.properties = physical.GetProperties(); properties.properties = physical.GetProperties();
@ -980,6 +983,11 @@ bool Device::GetSuitability(bool requires_swapchain) {
if (instance_version < VK_API_VERSION_1_3) { if (instance_version < VK_API_VERSION_1_3) {
FOR_EACH_VK_FEATURE_1_3(FEATURE_EXTENSION); FOR_EACH_VK_FEATURE_1_3(FEATURE_EXTENSION);
} }
#ifdef VK_API_VERSION_1_4
if (instance_version < VK_API_VERSION_1_4) {
FOR_EACH_VK_FEATURE_1_4(FEATURE_EXTENSION);
}
#endif
FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION); FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION);
FOR_EACH_VK_EXTENSION(EXTENSION); FOR_EACH_VK_EXTENSION(EXTENSION);
@ -1015,11 +1023,16 @@ bool Device::GetSuitability(bool requires_swapchain) {
// Set next pointer. // Set next pointer.
void** next = &features2.pNext; void** next = &features2.pNext;
// Vulkan 1.2 and 1.3 features
// Vulkan 1.2, 1.3 and 1.4 features
if (instance_version >= VK_API_VERSION_1_2) { if (instance_version >= VK_API_VERSION_1_2) {
features_1_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; features_1_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
features_1_3.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; features_1_3.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
#ifdef VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES
features_1_4.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES;
features_1_3.pNext = &features_1_4;
#endif
features_1_2.pNext = &features_1_3; features_1_2.pNext = &features_1_3;
*next = &features_1_2; *next = &features_1_2;
@ -1051,6 +1064,13 @@ bool Device::GetSuitability(bool requires_swapchain) {
} else { } else {
FOR_EACH_VK_FEATURE_1_3(EXT_FEATURE); FOR_EACH_VK_FEATURE_1_3(EXT_FEATURE);
} }
#ifdef VK_API_VERSION_1_4
if (instance_version >= VK_API_VERSION_1_4) {
FOR_EACH_VK_FEATURE_1_4(FEATURE);
} else {
FOR_EACH_VK_FEATURE_1_4(EXT_FEATURE);
}
#endif
#undef EXT_FEATURE #undef EXT_FEATURE
#undef FEATURE #undef FEATURE
@ -1488,16 +1508,31 @@ void Device::RemoveUnsuitableExtensions() {
RemoveExtensionFeatureIfUnsuitable(extensions.maintenance6, features.maintenance6, RemoveExtensionFeatureIfUnsuitable(extensions.maintenance6, features.maintenance6,
VK_KHR_MAINTENANCE_6_EXTENSION_NAME); VK_KHR_MAINTENANCE_6_EXTENSION_NAME);
// VK_KHR_maintenance7 (proposed for Vulkan 1.4, no features)
// VK_KHR_maintenance7
#ifdef VK_API_VERSION_1_4
extensions.maintenance7 = instance_version >= VK_API_VERSION_1_4 ||
loaded_extensions.contains(VK_KHR_MAINTENANCE_7_EXTENSION_NAME);
#else
extensions.maintenance7 = loaded_extensions.contains(VK_KHR_MAINTENANCE_7_EXTENSION_NAME); extensions.maintenance7 = loaded_extensions.contains(VK_KHR_MAINTENANCE_7_EXTENSION_NAME);
#endif
RemoveExtensionIfUnsuitable(extensions.maintenance7, 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
#ifdef VK_API_VERSION_1_4
extensions.maintenance8 = instance_version >= VK_API_VERSION_1_4 ||
loaded_extensions.contains(VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
#else
extensions.maintenance8 = loaded_extensions.contains(VK_KHR_MAINTENANCE_8_EXTENSION_NAME); extensions.maintenance8 = loaded_extensions.contains(VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
#endif
RemoveExtensionIfUnsuitable(extensions.maintenance8, 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
#ifdef VK_API_VERSION_1_4
extensions.maintenance9 = instance_version >= VK_API_VERSION_1_4 ||
loaded_extensions.contains(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
#else
extensions.maintenance9 = loaded_extensions.contains(VK_KHR_MAINTENANCE_9_EXTENSION_NAME); extensions.maintenance9 = loaded_extensions.contains(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
#endif
RemoveExtensionIfUnsuitable(extensions.maintenance9, VK_KHR_MAINTENANCE_9_EXTENSION_NAME); RemoveExtensionIfUnsuitable(extensions.maintenance9, VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
} }

5
src/video_core/vulkan_common/vulkan_device.h

@ -487,6 +487,11 @@ public:
return extensions.workgroup_memory_explicit_layout; return extensions.workgroup_memory_explicit_layout;
} }
/// Returns true if the device supports VK_KHR_unified_image_layouts.
bool IsKhrUnifiedImageLayoutsSupported() const {
return extensions.unified_image_layouts;
}
/// Returns true if the device supports VK_KHR_image_format_list. /// Returns true if the device supports VK_KHR_image_format_list.
bool IsKhrImageFormatListSupported() const { bool IsKhrImageFormatListSupported() const {
return extensions.image_format_list || instance_version >= VK_API_VERSION_1_2; return extensions.image_format_list || instance_version >= VK_API_VERSION_1_2;

16
src/video_core/vulkan_common/vulkan_wrapper.cpp

@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
@ -47,6 +47,14 @@ bool IsMicrosoftDozen(const char* device_name) {
return std::strstr(device_name, "Microsoft") != nullptr; return std::strstr(device_name, "Microsoft") != nullptr;
} }
constexpr u32 MaxInstanceApiVersion() {
#ifdef VK_API_VERSION_1_4
return VK_API_VERSION_1_4;
#else
return VK_API_VERSION_1_3;
#endif
}
void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) { void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) {
// Sort by name, this will set a base and make GPUs with higher numbers appear first // Sort by name, this will set a base and make GPUs with higher numbers appear first
// (e.g. GTX 1650 will intentionally be listed before a GTX 1080). // (e.g. GTX 1650 will intentionally be listed before a GTX 1080).
@ -437,8 +445,8 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
#else #else
constexpr VkFlags ci_flags{}; constexpr VkFlags ci_flags{};
#endif #endif
// DO NOT TOUCH, breaks RNDA3!!
// Don't know why, but gloom + yellow line glitch appears
// Keep application and engine tags stable for driver behavior compatibility.
const u32 api_version = std::min(version, MaxInstanceApiVersion());
const VkApplicationInfo application_info{ const VkApplicationInfo application_info{
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr, .pNext = nullptr,
@ -446,7 +454,7 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
.applicationVersion = VK_MAKE_VERSION(1, 3, 0), .applicationVersion = VK_MAKE_VERSION(1, 3, 0),
.pEngineName = "yuzu Emulator", .pEngineName = "yuzu Emulator",
.engineVersion = VK_MAKE_VERSION(1, 3, 0), .engineVersion = VK_MAKE_VERSION(1, 3, 0),
.apiVersion = VK_API_VERSION_1_3,
.apiVersion = api_version,
}; };
const VkInstanceCreateInfo ci{ const VkInstanceCreateInfo ci{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,

Loading…
Cancel
Save