diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index cd1bfd77e8..473cc58bfc 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -338,9 +338,8 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; if (limit_dynamic_storage_buffers) { max_dynamic_storage_buffers = device.GetMaxDescriptorSetStorageBuffersDynamic(); - } - if (device.GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY) { - // TODO: FixMe: Uint8Pass compute shader does not build on some Qualcomm drivers. + } + if (device.SupportsUint8Indices()) { uint8_pass = std::make_unique(device, scheduler, descriptor_pool, staging_pool, compute_pass_descriptor_queue); } @@ -518,6 +517,10 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat vk_index_type = VK_INDEX_TYPE_UINT16; if (uint8_pass) { std::tie(vk_buffer, vk_offset) = uint8_pass->Assemble(num_indices, buffer, offset); + } else if (device.GetDriverID() == VK_DRIVER_ID_QUALCOMM_PROPRIETARY) { + ReserveNullBuffer(); + vk_buffer = *null_buffer; + vk_offset = 0; } } if (vk_buffer == VK_NULL_HANDLE) { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 32fa825455..ffc345fe48 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -654,16 +654,11 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im } void TryTransformSwizzleIfNeeded(PixelFormat format, std::array& swizzle, - bool emulate_bgr565, bool emulate_a4b4g4r4) { + bool emulate_a4b4g4r4) { switch (format) { case PixelFormat::A1B5G5R5_UNORM: std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); break; - case PixelFormat::B5G6R5_UNORM: - if (emulate_bgr565) { - std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); - } - break; case PixelFormat::A5B5G5R1_UNORM: std::ranges::transform(swizzle, swizzle.begin(), SwapSpecial); break; @@ -2119,7 +2114,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI }; if (!info.IsRenderTarget()) { swizzle = info.Swizzle(); - TryTransformSwizzleIfNeeded(format, swizzle, device->MustEmulateBGR565(), + TryTransformSwizzleIfNeeded(format, swizzle, !device->IsExt4444FormatsSupported()); if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) { std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 2ae5052640..92ef997849 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -432,7 +432,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; - const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; if (!is_suitable) LOG_WARNING(Render_Vulkan, "Unsuitable driver - continuing anyways"); @@ -601,10 +600,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (is_qualcomm) { - const u32 version = (properties.properties.driverVersion << 3) >> 3; - if (version < VK_MAKE_API_VERSION(0, 255, 615, 512)) { - has_broken_parallel_compiling = true; - } const size_t sampler_limit = properties.properties.limits.maxSamplerAllocationCount; if (sampler_limit > 0) { constexpr size_t MIN_SAMPLER_BUDGET = 1024U; @@ -645,20 +640,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR has_broken_compute = CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && !Settings::values.enable_compute_pipelines.GetValue(); - must_emulate_bgr565 = false; // Default: assume emulation isn't required - - if (is_intel_anv) { - LOG_WARNING(Render_Vulkan, "Intel ANV driver does not support native BGR format"); - must_emulate_bgr565 = true; - } else if (is_qualcomm) { - LOG_WARNING(Render_Vulkan, - "Qualcomm driver mishandles BGR5 formats even with VK_KHR_maintenance5, forcing emulation"); - must_emulate_bgr565 = true; - } else if (is_arm) { - LOG_WARNING(Render_Vulkan, - "ARM Mali driver mishandles BGR5 formats even with VK_KHR_maintenance5, forcing emulation"); - must_emulate_bgr565 = true; - } if (is_mvk) { LOG_WARNING(Render_Vulkan, @@ -936,11 +917,7 @@ bool Device::ShouldBoostClocks() const { } bool Device::HasTimelineSemaphore() const { - if (GetDriverID() == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || - GetDriverID() == VK_DRIVER_ID_MESA_TURNIP) { - // Timeline semaphores do not work properly on all Qualcomm drivers. - // They generally work properly with Turnip drivers, but are problematic on some devices - // (e.g. ZTE handsets with Snapdragon 870). + if (GetDriverID() == VK_DRIVER_ID_MESA_TURNIP) { return false; } return features.timeline_semaphore.timelineSemaphore; @@ -1092,9 +1069,14 @@ bool Device::GetSuitability(bool requires_swapchain) { LOG_INFO(Render_Vulkan, "Device doesn't support feature {}", #name); \ } +// Optional features are enabled silently without any logging +#define OPTIONAL_FEATURE(feature, name) (void)features.feature.name; + + FOR_EACH_VK_OPTIONAL_FEATURE(OPTIONAL_FEATURE); FOR_EACH_VK_RECOMMENDED_FEATURE(LOG_FEATURE); FOR_EACH_VK_MANDATORY_FEATURE(CHECK_FEATURE); +#undef OPTIONAL_FEATURE #undef LOG_FEATURE #undef CHECK_FEATURE diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 9b08dc2926..a6de3d6022 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -135,10 +135,6 @@ VK_DEFINE_HANDLE(VmaAllocator) // Define features which must be supported. #define FOR_EACH_VK_MANDATORY_FEATURE(FEATURE_NAME) \ - FEATURE_NAME(bit16_storage, storageBuffer16BitAccess) \ - FEATURE_NAME(bit16_storage, uniformAndStorageBuffer16BitAccess) \ - FEATURE_NAME(bit8_storage, storageBuffer8BitAccess) \ - FEATURE_NAME(bit8_storage, uniformAndStorageBuffer8BitAccess) \ FEATURE_NAME(features, depthBiasClamp) \ FEATURE_NAME(features, depthClamp) \ FEATURE_NAME(features, drawIndirectFirstInstance) \ @@ -171,6 +167,8 @@ VK_DEFINE_HANDLE(VmaAllocator) // Define features where the absence of the feature may result in a degraded experience. #define FOR_EACH_VK_RECOMMENDED_FEATURE(FEATURE_NAME) \ + FEATURE_NAME(bit16_storage, storageBuffer16BitAccess) \ + FEATURE_NAME(bit8_storage, storageBuffer8BitAccess) \ FEATURE_NAME(custom_border_color, customBorderColors) \ FEATURE_NAME(depth_bias_control, depthBiasControl) \ FEATURE_NAME(depth_bias_control, leastRepresentableValueForceUnormRepresentation) \ @@ -191,6 +189,11 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE_NAME(uniform_buffer_standard_layout, uniformBufferStandardLayout) \ FEATURE_NAME(vertex_input_dynamic_state, vertexInputDynamicState) +// These features are not required but can be helpful for drivers that can use it. +#define FOR_EACH_VK_OPTIONAL_FEATURE(FEATURE_NAME) \ + FEATURE_NAME(bit16_storage, uniformAndStorageBuffer16BitAccess) \ + FEATURE_NAME(bit8_storage, uniformAndStorageBuffer8BitAccess) + namespace Vulkan { class NsightAftermathTracker; @@ -793,10 +796,6 @@ public: return must_emulate_scaled_formats; } - bool MustEmulateBGR565() const { - return must_emulate_bgr565; - } - bool HasNullDescriptor() const { return features.robustness2.nullDescriptor; } @@ -896,6 +895,12 @@ public: return extensions.maintenance9; } + /// Returns true if the device supports UINT8 index buffer conversion via compute shader. + bool SupportsUint8Indices() const { + return features.bit8_storage.storageBuffer8BitAccess && + features.bit16_storage.storageBuffer16BitAccess; + } + [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, u32 driver_version) { if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { @@ -1042,7 +1047,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 must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format. 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{};