diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index bc9ef571b..d385b1efe 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -358,6 +358,10 @@ GraphicsPipeline::GraphicsPipeline( .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f}, }; + // Required by spec unless VK_EXT_extended_dynamic_state3 is supported. + // In practice, we use dynamic state for all of it. + constexpr vk::PipelineDepthStencilStateCreateInfo depth_stencil_info = {}; + const vk::GraphicsPipelineCreateInfo pipeline_info = { .pNext = &pipeline_rendering_ci, .stageCount = static_cast(shader_stages.size()), @@ -368,6 +372,8 @@ GraphicsPipeline::GraphicsPipeline( .pViewportState = &viewport_info, .pRasterizationState = &raster_chain.get(), .pMultisampleState = &sdata.multisampling, + .pDepthStencilState = + !instance.IsExtendedDynamicState3Supported() ? &depth_stencil_info : nullptr, .pColorBlendState = &color_blending, .pDynamicState = &dynamic_info, .layout = *pipeline_layout, diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 8bd2b19d6..886ea8e75 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -158,29 +158,8 @@ Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index, CreateDevice(); CollectPhysicalMemoryInfo(); + CollectImageFormatInfo(); CollectToolingInfo(); - - // Check and log format support details. - for (const auto& format : LiverpoolToVK::SurfaceFormats()) { - if (!IsFormatSupported(format.vk_format, format.flags)) { - LOG_WARNING(Render_Vulkan, - "Surface format data_format={}, number_format={} is not fully supported " - "(vk_format={}, missing features={})", - static_cast(format.data_format), - static_cast(format.number_format), vk::to_string(format.vk_format), - vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format))); - } - } - for (const auto& format : LiverpoolToVK::DepthFormats()) { - if (!IsFormatSupported(format.vk_format, format.flags)) { - LOG_WARNING(Render_Vulkan, - "Depth format z_format={}, stencil_format={} is not fully supported " - "(vk_format={}, missing features={})", - static_cast(format.z_format), static_cast(format.stencil_format), - vk::to_string(format.vk_format), - vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format))); - } - } } Instance::~Instance() { @@ -331,10 +310,12 @@ bool Instance::CreateDevice() { TRACY_GPU_ENABLED ? add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME) : false; #ifdef __APPLE__ - // Required by Vulkan spec if supported. - portability_subset = add_extension(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); - if (portability_subset) { - portability_features = feature_chain.get(); + if (driver_id == vk::DriverId::eMoltenvk) { + portability_subset = add_extension(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); + if (portability_subset) { + portability_features = + feature_chain.get(); + } } #endif @@ -705,6 +686,44 @@ void Instance::CollectPhysicalMemoryInfo() { static_cast(std::max(available_memory - 8_GB, static_cast(local_memory))); } +void Instance::CollectImageFormatInfo() { + // Check for block texel view support using basic image format info. + const vk::PhysicalDeviceImageFormatInfo2 block_texel_view_info{ + .format = vk::Format::eBc1RgbaUnormBlock, + .type = vk::ImageType::e2D, + .tiling = vk::ImageTiling::eOptimal, + .usage = vk::ImageUsageFlagBits::eSampled, + .flags = vk::ImageCreateFlagBits::eBlockTexelViewCompatible, + }; + const auto block_texel_view_props = + physical_device.getImageFormatProperties2(block_texel_view_info); + supports_block_texel_view = block_texel_view_props.result == vk::Result::eSuccess; + LOG_INFO(Render_Vulkan, "Block Texel View support: {}", + supports_block_texel_view ? "Yes" : "No"); + + // Check and log format support details. + for (const auto& format : LiverpoolToVK::SurfaceFormats()) { + if (!IsFormatSupported(format.vk_format, format.flags)) { + LOG_WARNING(Render_Vulkan, + "Surface format data_format={}, number_format={} is not fully supported " + "(vk_format={}, missing features={})", + static_cast(format.data_format), + static_cast(format.number_format), vk::to_string(format.vk_format), + vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format))); + } + } + for (const auto& format : LiverpoolToVK::DepthFormats()) { + if (!IsFormatSupported(format.vk_format, format.flags)) { + LOG_WARNING(Render_Vulkan, + "Depth format z_format={}, stencil_format={} is not fully supported " + "(vk_format={}, missing features={})", + static_cast(format.z_format), static_cast(format.stencil_format), + vk::to_string(format.vk_format), + vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format))); + } + } +} + void Instance::CollectToolingInfo() const { if (driver_id == vk::DriverId::eAmdProprietary || driver_id == vk::DriverId::eIntelProprietaryWindows) { diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 7a8a906d5..11bb57d17 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -149,7 +149,12 @@ public: return depth_range_unrestricted; } - /// Returns true when the extendedDynamicState3ColorWriteMask feature o + /// Returns true when VK_EXT_extended_dynamic_state3 is supported + bool IsExtendedDynamicState3Supported() const { + return dynamic_state_3; + } + + /// Returns true when the extendedDynamicState3ColorWriteMask feature of /// VK_EXT_extended_dynamic_state3 is supported. bool IsDynamicColorWriteMaskSupported() const { return dynamic_state_3 && dynamic_state_3_features.extendedDynamicState3ColorWriteMask; @@ -421,6 +426,12 @@ public: return features.logicOp; } + /// Returns whether VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT is supported on compressed + /// images. + bool IsBlockTexelViewSupported() const { + return supports_block_texel_view; + } + /// Returns whether the device can report memory usage. bool CanReportMemoryUsage() const { return supports_memory_budget; @@ -447,6 +458,7 @@ private: /// Collects various information from the device. void CollectDeviceParameters(); void CollectPhysicalMemoryInfo(); + void CollectImageFormatInfo(); void CollectToolingInfo() const; /// Gets the supported feature flags for a format. @@ -507,6 +519,7 @@ private: bool maintenance_8{}; bool attachment_feedback_loop{}; bool supports_memory_budget{}; + bool supports_block_texel_view{}; u64 total_memory_budget{}; std::vector valid_heaps; }; diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 44ddd55c6..0293d912a 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -127,7 +127,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, if (info.props.is_volume) { flags |= vk::ImageCreateFlagBits::e2DArrayCompatible; } - if (info.props.is_block) { + if (info.props.is_block && instance->IsBlockTexelViewSupported()) { flags |= vk::ImageCreateFlagBits::eBlockTexelViewCompatible; }