mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-22 22:11:49 +01:00
Add subpass limit quirk to fix Adreno driver bug
Older Adreno proprietary drivers (5xx and below) will segfault while destroying the renderpass and associated objects if more than 64 subpasses are within a renderpass due to internal driver implementation details. This commit introduces checks to automatically break up a renderpass when that limit is hit.
This commit is contained in:
parent
65d5a3bce5
commit
e294fa8c91
2
.idea/scopes/ShaderCompiler.xml
generated
2
.idea/scopes/ShaderCompiler.xml
generated
@ -1,3 +1,3 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="ShaderCompiler" pattern="file[skyline.app]:libraries/shader-compiler//*" />
|
||||
<scope name="ShaderCompiler" pattern="file[skyline.app.main]:shader-compiler//*" />
|
||||
</component>
|
@ -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<node::RenderPassEndNode>());
|
||||
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<node::RenderPassNode>(nodes.emplace_back(std::in_place_type_t<node::RenderPassNode>(), renderArea));
|
||||
else
|
||||
subpassCount++;
|
||||
|
||||
return newRenderPass;
|
||||
}
|
||||
@ -119,6 +122,7 @@ namespace skyline::gpu::interconnect {
|
||||
if (renderPass) {
|
||||
nodes.emplace_back(std::in_place_type_t<node::RenderPassEndNode>());
|
||||
renderPass = nullptr;
|
||||
subpassCount = 0;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -18,6 +18,7 @@ namespace skyline::gpu::interconnect {
|
||||
CommandScheduler::ActiveCommandBuffer activeCommandBuffer;
|
||||
boost::container::stable_vector<node::NodeVariant> nodes;
|
||||
node::RenderPassNode *renderPass{};
|
||||
size_t subpassCount{}; //!< The number of subpasses in the current render pass
|
||||
std::unordered_set<Texture *> syncTextures; //!< All textures that need to be synced prior to and after execution
|
||||
|
||||
using SharedBufferDelegate = std::shared_ptr<Buffer::BufferDelegate>;
|
||||
|
@ -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<TextureView>(shared_from_this(), type, range, pFormat, mapping)};
|
||||
views.push_back(view);
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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<u32>::max()}; //!< The maximum amount of subpasses within a renderpass, this is limited to 64 on older Adreno proprietary drivers
|
||||
|
||||
QuirkManager() = default;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user