diff --git a/.idea/scopes/ShaderCompiler.xml b/.idea/scopes/ShaderCompiler.xml index 0077ad7f..54e6e2d6 100644 --- a/.idea/scopes/ShaderCompiler.xml +++ b/.idea/scopes/ShaderCompiler.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp index 099bb8a1..29ba9b54 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp @@ -12,15 +12,18 @@ namespace skyline::gpu::interconnect { } bool CommandExecutor::CreateRenderPass(vk::Rect2D renderArea) { - if (renderPass && renderPass->renderArea != renderArea) { + if (renderPass && (renderPass->renderArea != renderArea || subpassCount > gpu.traits.quirks.maxSubpassCount)) { nodes.emplace_back(std::in_place_type_t()); renderPass = nullptr; + subpassCount = 0; } bool newRenderPass{renderPass == nullptr}; if (newRenderPass) // We need to create a render pass if one doesn't already exist or the current one isn't compatible renderPass = &std::get(nodes.emplace_back(std::in_place_type_t(), renderArea)); + else + subpassCount++; return newRenderPass; } @@ -119,6 +122,7 @@ namespace skyline::gpu::interconnect { if (renderPass) { nodes.emplace_back(std::in_place_type_t()); renderPass = nullptr; + subpassCount = 0; } { diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h index 88fea99a..3388cd7b 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h @@ -18,6 +18,7 @@ namespace skyline::gpu::interconnect { CommandScheduler::ActiveCommandBuffer activeCommandBuffer; boost::container::stable_vector nodes; node::RenderPassNode *renderPass{}; + size_t subpassCount{}; //!< The number of subpasses in the current render pass std::unordered_set syncTextures; //!< All textures that need to be synced prior to and after execution using SharedBufferDelegate = std::shared_ptr; diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index 6058a983..31155aa8 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -529,7 +529,7 @@ namespace skyline::gpu { } if (gpu.traits.quirks.vkImageMutableFormatCostly && pFormat->vkFormat != format->vkFormat) - Logger::Warn("Creating a view of a texture with a different format without mutable format"); + Logger::Warn("Creating a view of a texture with a different format without mutable format: {} - {}", vk::to_string(pFormat->vkFormat), vk::to_string(format->vkFormat)); auto view{std::make_shared(shared_from_this(), type, range, pFormat, mapping)}; views.push_back(view); diff --git a/app/src/main/cpp/skyline/gpu/trait_manager.cpp b/app/src/main/cpp/skyline/gpu/trait_manager.cpp index a39651aa..b3475c53 100644 --- a/app/src/main/cpp/skyline/gpu/trait_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/trait_manager.cpp @@ -133,6 +133,8 @@ namespace skyline::gpu { needsIndividualTextureBindingWrites = true; vkImageMutableFormatCostly = true; // Disables UBWC brokenDescriptorAliasing = true; + 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 break; } @@ -148,8 +150,8 @@ namespace skyline::gpu { std::string TraitManager::QuirkManager::Summary() { return fmt::format( - "\n* Needs Individual Texture Binding Writes: {}\n* VkImage Mutable Format is costly: {}", - needsIndividualTextureBindingWrites, vkImageMutableFormatCostly + "\n* Needs Individual Texture Binding Writes: {}\n* VkImage Mutable Format is costly: {}\n* Broken Descriptor Aliasing: {}\n* Max Subpass Count: {}", + needsIndividualTextureBindingWrites, vkImageMutableFormatCostly, brokenDescriptorAliasing, maxSubpassCount ); } diff --git a/app/src/main/cpp/skyline/gpu/trait_manager.h b/app/src/main/cpp/skyline/gpu/trait_manager.h index 41a19c9f..5a23aa3e 100644 --- a/app/src/main/cpp/skyline/gpu/trait_manager.h +++ b/app/src/main/cpp/skyline/gpu/trait_manager.h @@ -42,6 +42,7 @@ namespace skyline::gpu { bool needsIndividualTextureBindingWrites{}; //!< [Adreno Proprietary] A bug that requires descriptor set writes for VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER to be done individually with descriptorCount = 1 rather than batched bool vkImageMutableFormatCostly{}; //!< [Adreno Proprietary/Freedreno] An indication that VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is costly and should not be enabled unless absolutely necessary (Disables UBWC on Adreno GPUs) bool brokenDescriptorAliasing{}; //!< [Adreno Proprietary] A bug that causes alised descriptor sets to be incorrectly interpreted by the shader compiler leading to it buggering up LLVM function argument types and crashing + u32 maxSubpassCount{std::numeric_limits::max()}; //!< The maximum amount of subpasses within a renderpass, this is limited to 64 on older Adreno proprietary drivers QuirkManager() = default;