diff --git a/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp b/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp index e55fa68b..322276ef 100644 --- a/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp +++ b/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp @@ -6,7 +6,10 @@ #include "graphics_pipeline_cache.h" namespace skyline::gpu::cache { - GraphicsPipelineCache::GraphicsPipelineCache(GPU &gpu) : gpu(gpu), vkPipelineCache(gpu.vkDevice, vk::PipelineCacheCreateInfo{}) {} + GraphicsPipelineCache::GraphicsPipelineCache(GPU &gpu) + : gpu{gpu}, + vkPipelineCache{gpu.vkDevice, vk::PipelineCacheCreateInfo{}}, + pool{gpu.traits.quirks.brokenMultithreadedPipelineCompilation ? 1U : 0U} {} #define VEC_CPY(pointer, size) state.pointer, state.pointer + state.size @@ -396,4 +399,8 @@ namespace skyline::gpu::cache { pipelineEntryIt.first->second.pipeline = pipelineFuture.share(); return CompiledPipeline{pipelineEntryIt.first->second}; } + + void GraphicsPipelineCache::WaitIdle() { + pool.wait_for_tasks(); + } } diff --git a/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.h b/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.h index 828fecbb..d9de930f 100644 --- a/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.h +++ b/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.h @@ -165,5 +165,10 @@ namespace skyline::gpu::cache { * @note Input/Resolve attachments are **not** supported and using them with the supplied pipeline will result in UB */ CompiledPipeline GetCompiledPipeline(const PipelineState& state, span layoutBindings, span pushConstantRanges = {}, bool noPushDescriptors = false); + + /** + * @brief Waits until the pipeline compilation thread pool is idle and all pipelines have been compiled + */ + void WaitIdle(); }; } diff --git a/app/src/main/cpp/skyline/gpu/interconnect/kepler_compute/pipeline_manager.cpp b/app/src/main/cpp/skyline/gpu/interconnect/kepler_compute/pipeline_manager.cpp index 766c3951..b1c22f25 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/kepler_compute/pipeline_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/kepler_compute/pipeline_manager.cpp @@ -90,6 +90,10 @@ namespace skyline::gpu::interconnect::kepler_compute { .layout = *pipelineLayout, }; + + if (ctx.gpu.traits.quirks.brokenMultithreadedPipelineCompilation) + ctx.gpu.graphicsPipelineCache.WaitIdle(); + vk::raii::Pipeline pipeline{ctx.gpu.vkDevice, nullptr, pipelineInfo}; return Pipeline::CompiledPipeline{ diff --git a/app/src/main/cpp/skyline/gpu/trait_manager.cpp b/app/src/main/cpp/skyline/gpu/trait_manager.cpp index 5fd3945a..3e93a6cb 100644 --- a/app/src/main/cpp/skyline/gpu/trait_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/trait_manager.cpp @@ -227,6 +227,10 @@ namespace skyline::gpu { if (deviceProperties.driverVersion < VK_MAKE_VERSION(512, 600, 0)) maxSubpassCount = 64; // Driver will segfault while destroying the renderpass and associated objects if this is exceeded on all 5xx and below drivers + + if (deviceProperties.driverVersion >= VK_MAKE_VERSION(512, 615, 0) && deviceProperties.driverVersion <= VK_MAKE_VERSION(512, 615, 512)) + brokenMultithreadedPipelineCompilation = true; + maxGlobalPriority = vk::QueueGlobalPriorityEXT::eHigh; break; } diff --git a/app/src/main/cpp/skyline/gpu/trait_manager.h b/app/src/main/cpp/skyline/gpu/trait_manager.h index 227fbac8..31e9b247 100644 --- a/app/src/main/cpp/skyline/gpu/trait_manager.h +++ b/app/src/main/cpp/skyline/gpu/trait_manager.h @@ -65,6 +65,7 @@ namespace skyline::gpu { bool brokenPushDescriptors{}; //!< [Adreno Proprietary] A bug that causes push descriptor updates to ignored by the driver in certain situations bool brokenSpirvPositionInput{}; //!< [Adreno Proprietary] A bug that causes the shader compiler to fail on shaders with vertex position inputs not contained within a struct bool brokenComputeShaders{}; //!< [ARM Proprietary] A bug that causes compute shaders in some games to crash the GPU + bool brokenMultithreadedPipelineCompilation{}; //!< [Qualcomm Proprietary] A bug that causes the shader compiler to crash when compiling pipelines on multiple threads simultaneously u32 maxSubpassCount{std::numeric_limits::max()}; //!< The maximum amount of subpasses within a renderpass, this is limited to 64 on older Adreno proprietary drivers vk::QueueGlobalPriorityEXT maxGlobalPriority{vk::QueueGlobalPriorityEXT::eMedium}; //!< The highest allowed global priority of the queue, drivers will not allow higher priorities to be set on queues