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;