diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index f8cf7bfa..3ba08741 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -176,7 +176,6 @@ namespace skyline::gpu { return false; texture->SynchronizeGuest(false, true); // We can skip trapping since the caller will do it - texture->WaitOnFence(); return true; }, [weakThis] { TRACE_EVENT("gpu", "Texture::WriteTrap"); @@ -198,7 +197,6 @@ namespace skyline::gpu { if (!lock) return false; texture->SynchronizeGuest(true, true); // We need to assume the texture is dirty since we don't know what the guest is writing - texture->WaitOnFence(); return true; }); } @@ -455,13 +453,6 @@ namespace skyline::gpu { } } - Texture::TextureBufferCopy::TextureBufferCopy(std::shared_ptr texture, std::shared_ptr stagingBuffer) : texture(std::move(texture)), stagingBuffer(std::move(stagingBuffer)) {} - - Texture::TextureBufferCopy::~TextureBufferCopy() { - TRACE_EVENT("gpu", "Texture::TextureBufferCopy"); - texture->CopyToGuest(stagingBuffer ? stagingBuffer->data() : std::get(texture->backing).data()); - } - Texture::Texture(GPU &gpu, BackingType &&backing, texture::Dimensions dimensions, texture::Format format, vk::ImageLayout layout, vk::ImageTiling tiling, vk::ImageCreateFlags flags, vk::ImageUsageFlags usage, u32 levelCount, u32 layerCount, vk::SampleCountFlagBits sampleCount) : gpu(gpu), backing(std::move(backing)), @@ -596,7 +587,6 @@ namespace skyline::gpu { gpu.state.nce->DeleteTrap(*trapHandle); if (alignedMirror.valid()) munmap(alignedMirror.data(), alignedMirror.size()); - WaitOnFence(); } void Texture::lock() { @@ -780,12 +770,13 @@ namespace skyline::gpu { if (tiling == vk::ImageTiling::eOptimal || !std::holds_alternative(backing)) { auto stagingBuffer{gpu.memory.AllocateStagingBuffer(surfaceSize)}; + WaitOnFence(); auto lCycle{gpu.scheduler.Submit([&](vk::raii::CommandBuffer &commandBuffer) { CopyIntoStagingBuffer(commandBuffer, stagingBuffer); })}; - lCycle->AttachObject(std::make_shared(shared_from_this(), stagingBuffer)); - lCycle->ChainCycle(cycle); - cycle = lCycle; + lCycle->Wait(); // We block till the copy is complete + + CopyToGuest(stagingBuffer->data()); } else if (tiling == vk::ImageTiling::eLinear) { // We can optimize linear texture sync on a UMA by mapping the texture onto the CPU and copying directly from it rather than using a staging buffer WaitOnFence(); diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.h b/app/src/main/cpp/skyline/gpu/texture/texture.h index a0173f4e..1e6ab27e 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.h +++ b/app/src/main/cpp/skyline/gpu/texture/texture.h @@ -416,18 +416,6 @@ namespace skyline::gpu { */ void CopyToGuest(u8 *hostBuffer); - /** - * @brief A fence cycle dependency that copies the contents of a staging buffer or mapped image backing the texture to the guest texture - */ - struct TextureBufferCopy { - std::shared_ptr texture; - std::shared_ptr stagingBuffer; - - TextureBufferCopy(std::shared_ptr texture, std::shared_ptr stagingBuffer = {}); - - ~TextureBufferCopy(); - }; - /** * @return A vector of all the buffer image copies that need to be done for every aspect of every level of every layer of the texture */ @@ -547,7 +535,7 @@ namespace skyline::gpu { * @brief Synchronizes the guest texture with the host texture after it has been modified * @param cpuDirty If true, the texture will be transitioned to being CpuDirty by this call * @param skipTrap If true, trapping/untrapping the guest mappings will be skipped and has to be handled by the caller - * @note This function is not blocking and the synchronization will not be complete until the associated fence is signalled, it can be waited on with WaitOnFence() + * @note This function is blocking and waiting on the fence is not required * @note The texture **must** be locked prior to calling this */ void SynchronizeGuest(bool cpuDirty = false, bool skipTrap = false);