From cb7c3602e7bd795d321f9e6bc625a97f4665e9f9 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Sat, 9 Jul 2022 19:49:09 +0530 Subject: [PATCH] Attach `TextureView` to `FenceCycle` The lifetime of `TextureView` objects wasn't correctly managed as they weren't being attached the the `FenceCycle` in `AttachTexture`, this led to them getting deleted and causing all sorts of UB. --- .../main/cpp/skyline/gpu/interconnect/command_executor.cpp | 6 ++++-- app/src/main/cpp/skyline/gpu/texture/texture.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) 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 42a0b621..5116a609 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp @@ -46,7 +46,7 @@ namespace skyline::gpu::interconnect { lastSubpassDepthStencilAttachment = depthStencilAttachment; }}; - if (renderPass == nullptr || (renderPass && (renderPass->renderArea != renderArea || subpassCount >= gpu.traits.quirks.maxSubpassCount))) { + if (renderPass == nullptr || renderPass->renderArea != renderArea || subpassCount >= gpu.traits.quirks.maxSubpassCount) { // We need to create a render pass if one doesn't already exist or the current one isn't compatible if (renderPass != nullptr) nodes.emplace_back(std::in_place_type_t()); @@ -101,6 +101,8 @@ namespace skyline::gpu::interconnect { // Avoids a potential deadlock with this resource being locked while acquiring the TextureManager lock while the thread owning it tries to acquire a lock on this texture textureManagerLock.emplace(gpu.texture); + cycle->AttachObject(view->shared_from_this()); + bool didLock{view->LockWithTag(tag)}; if (didLock) attachedTextures.emplace_back(view->texture); @@ -286,7 +288,7 @@ namespace skyline::gpu::interconnect { nodes.clear(); for (const auto &attachedTexture : attachedTextures) { - cycle->AttachObject(attachedTexture.texture); + // We don't need to attach the Texture to the cycle as a TextureView will already be attached cycle->ChainCycle(attachedTexture->cycle); attachedTexture->cycle = cycle; } diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index c8900ca2..f144c092 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -809,7 +809,7 @@ namespace skyline::gpu { if (source->layout != vk::ImageLayout::eTransferSrcOptimal) { commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, vk::ImageMemoryBarrier{ .image = sourceBacking, - .srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite, + .srcAccessMask = vk::AccessFlagBits::eMemoryWrite, .dstAccessMask = vk::AccessFlagBits::eTransferRead, .oldLayout = source->layout, .newLayout = vk::ImageLayout::eTransferSrcOptimal, @@ -823,7 +823,7 @@ namespace skyline::gpu { if (layout != vk::ImageLayout::eTransferDstOptimal) { commandBuffer.pipelineBarrier(layout != vk::ImageLayout::eUndefined ? vk::PipelineStageFlagBits::eTopOfPipe : vk::PipelineStageFlagBits::eBottomOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, vk::ImageMemoryBarrier{ .image = destinationBacking, - .srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite, + .srcAccessMask = vk::AccessFlagBits::eMemoryRead, .dstAccessMask = vk::AccessFlagBits::eTransferWrite, .oldLayout = layout, .newLayout = vk::ImageLayout::eTransferDstOptimal,