From 210f4924875e1b9e49a87d8f522fa33e16b7e19e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 19 Jul 2025 00:39:59 +1000 Subject: [PATCH] MetalDevice: Remove pipeline cache It seems to be broken when appending using from-source created libraries. Similar issues have been described in: - https://bugreports.qt.io/browse/QTBUG-114338 - https://bugreports.qt.io/browse/QTBUG-108216 --- src/util/metal_device.h | 5 -- src/util/metal_device.mm | 115 ++------------------------------------- 2 files changed, 6 insertions(+), 114 deletions(-) diff --git a/src/util/metal_device.h b/src/util/metal_device.h index 1606343db..0a27fca2d 100644 --- a/src/util/metal_device.h +++ b/src/util/metal_device.h @@ -334,9 +334,6 @@ protected: const ExclusiveFullscreenMode* exclusive_fullscreen_mode, std::optional exclusive_fullscreen_control, Error* error) override; void DestroyDevice() override; - bool OpenPipelineCache(const std::string& path, Error* error) override; - bool CreatePipelineCache(const std::string& path, Error* error) override; - bool ClosePipelineCache(const std::string& path, Error* error) override; private: static constexpr u32 VERTEX_BUFFER_SIZE = 8 * 1024 * 1024; @@ -416,7 +413,6 @@ private: MetalStreamBuffer m_texture_upload_buffer; id m_shaders = nil; - id m_pipeline_archive = nil; std::vector, std::unique_ptr>> m_resolve_pipelines; std::vector>> m_clear_pipelines; @@ -450,5 +446,4 @@ private: double m_last_gpu_time_end = 0; id m_layer_drawable = nil; - bool m_pipeline_cache_modified = false; }; diff --git a/src/util/metal_device.mm b/src/util/metal_device.mm index cb0c98d04..d282a2899 100644 --- a/src/util/metal_device.mm +++ b/src/util/metal_device.mm @@ -140,7 +140,7 @@ MetalDevice::MetalDevice() : m_current_viewport(0, 0, 1, 1), m_current_scissor(0 MetalDevice::~MetalDevice() { - Assert(m_pipeline_archive == nil && m_layer_drawable == nil && m_device == nil); + Assert(m_layer_drawable == nil && m_device == nil); } MetalSwapChain::MetalSwapChain(const WindowInfo& wi, GPUVSyncMode vsync_mode, bool allow_present_throttle, @@ -392,19 +392,12 @@ void MetalDevice::SetFeatures(FeatureMask disabled_features) m_features.explicit_present = false; m_features.timed_present = true; m_features.shader_cache = true; - m_features.pipeline_cache = true; + m_features.pipeline_cache = false; m_features.prefer_unused_textures = true; // Same feature bit for both. m_features.dxt_textures = m_features.bptc_textures = !(disabled_features & FEATURE_MASK_COMPRESSED_TEXTURES) && m_device.supportsBCTextureCompression; - - // Disable pipeline cache on Intel, apparently it's buggy. - if ([[m_device name] containsString:@"Intel"]) - { - WARNING_LOG("Disabling Metal pipeline cache on Intel GPU."); - m_features.pipeline_cache = false; - } } bool MetalDevice::LoadShaders() @@ -439,76 +432,6 @@ bool MetalDevice::LoadShaders() } } -bool MetalDevice::OpenPipelineCache(const std::string& path, Error* error) -{ - @autoreleasepool - { - MTLBinaryArchiveDescriptor* archiveDescriptor = [[[MTLBinaryArchiveDescriptor alloc] init] autorelease]; - archiveDescriptor.url = [NSURL fileURLWithPath:CocoaTools::StringViewToNSString(path)]; - - NSError* nserror = nil; - m_pipeline_archive = [m_device newBinaryArchiveWithDescriptor:archiveDescriptor error:&nserror]; - if (m_pipeline_archive == nil) - { - CocoaTools::NSErrorToErrorObject(error, "newBinaryArchiveWithDescriptor failed: ", nserror); - return false; - } - - m_pipeline_cache_modified = false; - return true; - } -} - -bool MetalDevice::CreatePipelineCache(const std::string& path, Error* error) -{ - @autoreleasepool - { - MTLBinaryArchiveDescriptor* archiveDescriptor = [[[MTLBinaryArchiveDescriptor alloc] init] autorelease]; - archiveDescriptor.url = nil; - - NSError* nserror = nil; - m_pipeline_archive = [m_device newBinaryArchiveWithDescriptor:archiveDescriptor error:&nserror]; - if (m_pipeline_archive == nil) - { - CocoaTools::NSErrorToErrorObject(error, "newBinaryArchiveWithDescriptor failed: ", nserror); - return false; - } - - m_pipeline_cache_modified = false; - return true; - } -} - -bool MetalDevice::ClosePipelineCache(const std::string& path, Error* error) -{ - if (!m_pipeline_archive) - return false; - - const ScopedGuard closer = [this]() { - [m_pipeline_archive release]; - m_pipeline_archive = nil; - }; - - if (!m_pipeline_cache_modified) - { - INFO_LOG("Not saving pipeline cache, it has not been modified."); - return true; - } - - @autoreleasepool - { - NSURL* url = [NSURL fileURLWithPath:CocoaTools::StringViewToNSString(path)]; - NSError* nserror = nil; - if (![m_pipeline_archive serializeToURL:url error:&nserror]) - { - CocoaTools::NSErrorToErrorObject(error, "serializeToURL failed: ", nserror); - return false; - } - - return true; - } -} - id MetalDevice::GetFunctionFromLibrary(id library, NSString* name) { id function = [library newFunctionWithName:name]; @@ -938,38 +861,12 @@ std::unique_ptr MetalDevice::CreatePipeline(const GPUPipeline::Grap NSError* nserror = nil; // Try cached first. - id pipeline = nil; - if (m_pipeline_archive != nil) - { - desc.binaryArchives = [NSArray arrayWithObjects:m_pipeline_archive, nil]; - pipeline = [m_device newRenderPipelineStateWithDescriptor:desc - options:MTLPipelineOptionFailOnBinaryArchiveMiss - reflection:nil - error:&nserror]; - if (pipeline == nil) - { - // Add it to the cache. - if (![m_pipeline_archive addRenderPipelineFunctionsWithDescriptor:desc error:&nserror]) - { - LogNSError(nserror, "Failed to add render pipeline to binary archive"); - desc.binaryArchives = nil; - } - else - { - m_pipeline_cache_modified = true; - } - } - } - + id pipeline = [m_device newRenderPipelineStateWithDescriptor:desc error:&nserror]; if (pipeline == nil) { - pipeline = [m_device newRenderPipelineStateWithDescriptor:desc error:&nserror]; - if (pipeline == nil) - { - LogNSError(nserror, "Failed to create render pipeline state"); - CocoaTools::NSErrorToErrorObject(error, "newRenderPipelineStateWithDescriptor failed: ", nserror); - return {}; - } + LogNSError(nserror, "Failed to create render pipeline state"); + CocoaTools::NSErrorToErrorObject(error, "newRenderPipelineStateWithDescriptor failed: ", nserror); + return {}; } return std::unique_ptr(new MetalPipeline(pipeline, depth, cull_mode, primitive));