// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/native/RenderPassWorkaroundsHelper.h"

#include <utility>
#include <vector>

#include "absl/container/inlined_vector.h"
#include "dawn/common/Assert.h"
#include "dawn/native/AttachmentState.h"
#include "dawn/native/BlitColorToColorWithDraw.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
#include "dawn/native/Texture.h"

namespace dawn::native {

namespace {
// Tracks the temporary resolve attachments used when the AlwaysResolveIntoZeroLevelAndLayer toggle
// is active so that the results can be copied from the temporary resolve attachment into the
// intended target after the render pass is complete. Also used by the
// ResolveMultipleAttachmentInSeparatePasses toggle to track resolves that need to be done in their
// own passes.
struct TemporaryResolveAttachment {
    TemporaryResolveAttachment(Ref<TextureViewBase> src,
                               Ref<TextureViewBase> dst,
                               wgpu::StoreOp storeOp = wgpu::StoreOp::Store)
        : copySrc(std::move(src)), copyDst(std::move(dst)), storeOp(storeOp) {}

    Ref<TextureViewBase> copySrc;
    Ref<TextureViewBase> copyDst;
    wgpu::StoreOp storeOp;
};

void CopyTextureView(CommandEncoder* encoder, TextureViewBase* src, TextureViewBase* dst) {
    TexelCopyTextureInfo srcTexelCopyTextureInfo = {};
    srcTexelCopyTextureInfo.texture = src->GetTexture();
    srcTexelCopyTextureInfo.aspect = wgpu::TextureAspect::All;
    srcTexelCopyTextureInfo.mipLevel = src->GetBaseMipLevel();
    srcTexelCopyTextureInfo.origin = {0, 0, src->GetBaseArrayLayer()};

    TexelCopyTextureInfo dstTexelCopyTextureInfo = {};
    dstTexelCopyTextureInfo.texture = dst->GetTexture();
    dstTexelCopyTextureInfo.aspect = wgpu::TextureAspect::All;
    dstTexelCopyTextureInfo.mipLevel = dst->GetBaseMipLevel();
    dstTexelCopyTextureInfo.origin = {0, 0, dst->GetBaseArrayLayer()};

    Extent3D extent3D = src->GetSingleSubresourceVirtualSize();

    auto internalUsageScope = encoder->MakeInternalUsageScope();
    encoder->APICopyTextureToTexture(&srcTexelCopyTextureInfo, &dstTexelCopyTextureInfo, &extent3D);
}

void ResolveWithRenderPass(CommandEncoder* encoder,
                           TextureViewBase* src,
                           TextureViewBase* dst,
                           wgpu::StoreOp storeOp) {
    RenderPassColorAttachment attachment = {};
    attachment.view = src;
    attachment.resolveTarget = dst;
    attachment.loadOp = wgpu::LoadOp::Load;
    attachment.storeOp = storeOp;

    RenderPassDescriptor resolvePass = {};
    resolvePass.colorAttachmentCount = 1;
    resolvePass.colorAttachments = &attachment;

    // Begin and end an empty render pass to force the resolve.
    Ref<RenderPassEncoder> rpEncoder = encoder->BeginRenderPass(&resolvePass);
    rpEncoder->End();
}

void DiscardWithRenderPass(CommandEncoder* encoder, TextureViewBase* view) {
    ResolveWithRenderPass(encoder, view, nullptr, wgpu::StoreOp::Discard);
}

}  // namespace

RenderPassWorkaroundsHelper::RenderPassWorkaroundsHelper() = default;
RenderPassWorkaroundsHelper::~RenderPassWorkaroundsHelper() = default;

MaybeError RenderPassWorkaroundsHelper::Initialize(
    CommandEncoder* encoder,
    const UnpackedPtr<RenderPassDescriptor>& renderPassDescriptor) {
    DeviceBase* device = encoder->GetDevice();

    // dawn:56, dawn:1569
    // Handle Toggle AlwaysResolveIntoZeroLevelAndLayer. This swaps out the given resolve attachment
    // for a temporary one that has no layers or mip levels. The results are copied from the
    // temporary attachment into the given attachment when the render pass ends. (Handled in
    // Apply())
    if (device->IsToggleEnabled(Toggle::AlwaysResolveIntoZeroLevelAndLayer)) {
        for (uint8_t i = 0; i < renderPassDescriptor->colorAttachmentCount; ++i) {
            ColorAttachmentIndex colorIdx(i);
            const auto& colorAttachment = renderPassDescriptor->colorAttachments[i];
            TextureViewBase* resolveTarget = colorAttachment.resolveTarget;

            if (resolveTarget != nullptr && (resolveTarget->GetBaseMipLevel() != 0 ||
                                             resolveTarget->GetBaseArrayLayer() != 0)) {
                DAWN_ASSERT(colorAttachment.view);
                // Create a temporary texture to resolve into
                // TODO(dawn:1618): Defer allocation of temporary textures till submit time.
                TextureDescriptor descriptor = {};
                descriptor.usage = wgpu::TextureUsage::RenderAttachment |
                                   wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
                                   wgpu::TextureUsage::TextureBinding;
                descriptor.format = resolveTarget->GetFormat().format;
                descriptor.size = resolveTarget->GetSingleSubresourceVirtualSize();
                descriptor.dimension = wgpu::TextureDimension::e2D;
                descriptor.mipLevelCount = 1;

                // We are creating new resources. Device must already be locked via
                // APIBeginRenderPass.
                // TODO(crbug.com/dawn/1618): In future, all temp resources should be created at
                // Command Submit time, so the locking would be removed from here at that point.
                Ref<TextureBase> temporaryResolveTexture;
                Ref<TextureViewBase> temporaryResolveView;
                {
                    DAWN_ASSERT(device->IsLockedByCurrentThreadIfNeeded());

                    DAWN_TRY_ASSIGN(temporaryResolveTexture, device->CreateTexture(&descriptor));

                    TextureViewDescriptor viewDescriptor = {};
                    DAWN_TRY_ASSIGN(
                        temporaryResolveView,
                        device->CreateTextureView(temporaryResolveTexture.Get(), &viewDescriptor));

                    if (colorAttachment.loadOp == wgpu::LoadOp::ExpandResolveTexture) {
                        // Since we want to load the original resolve target, we need to copy it to
                        // the temp resolve target.
                        CopyTextureView(encoder, resolveTarget, temporaryResolveView.Get());
                    }
                }

                mTempResolveTargets[colorIdx] = {std::move(temporaryResolveTexture),
                                                 std::move(temporaryResolveView)};

                mTempResolveTargetsMask.set(colorIdx);
            }
        }
    }

    return {};
}

MaybeError RenderPassWorkaroundsHelper::ApplyOnPostEncoding(
    CommandEncoder* encoder,
    const UnpackedPtr<RenderPassDescriptor>& renderPassDescriptor,
    RenderPassResourceUsageTracker* usageTracker,
    BeginRenderPassCmd* cmd,
    RenderPassEncoder::EndCallback* passEndCallbackOut) {
    auto device = encoder->GetDevice();

    // List of operations to perform on render pass end.
    absl::InlinedVector<RenderPassEncoder::EndCallback, 1> passEndOperations;

    // dawn:56, dawn:1569
    // swap the resolve targets for the temp resolve textures.
    if (mTempResolveTargetsMask.any()) {
        std::vector<TemporaryResolveAttachment> temporaryResolveAttachments;

        for (auto index : mTempResolveTargetsMask) {
            TextureViewBase* resolveTarget = cmd->colorAttachments[index].resolveTarget.Get();
            TextureViewBase* temporaryResolveView = mTempResolveTargets[index].view.Get();

            DAWN_ASSERT(resolveTarget);

            // Save the temporary and given render targets together for copying after
            // the render pass ends.
            temporaryResolveAttachments.emplace_back(temporaryResolveView, resolveTarget);

            // Replace the given resolve attachment with the temporary one.
            usageTracker->TextureViewUsedAs(temporaryResolveView,
                                            wgpu::TextureUsage::RenderAttachment);
            cmd->colorAttachments[index].resolveTarget = temporaryResolveView;
        }

        passEndOperations.emplace_back([encoder, temporaryResolveAttachments = std::move(
                                                     temporaryResolveAttachments)]() -> MaybeError {
            // Called once the render pass has been ended.
            // Handle any copies needed for the AlwaysResolveIntoZeroLevelAndLayer
            // workaround immediately after the render pass ends and before any additional
            // commands are recorded.
            for (auto& copyTarget : temporaryResolveAttachments) {
                CopyTextureView(encoder, copyTarget.copySrc.Get(), copyTarget.copyDst.Get());
            }
            return {};
        });
    }

    mShouldApplyExpandResolveEmulation =
        cmd->attachmentState->GetExpandResolveInfo().attachmentsToExpandResolve.any() &&
        device->CanTextureLoadResolveTargetInTheSameRenderpass();

    std::optional<RenderPassDescriptorResolveRect> expandResolveRect;
    if (auto* legacyResolveRect =
            renderPassDescriptor.Get<RenderPassDescriptorExpandResolveRect>()) {
        RenderPassDescriptorResolveRect rect;
        rect.colorOffsetX = legacyResolveRect->x;
        rect.colorOffsetY = legacyResolveRect->y;
        rect.resolveOffsetX = legacyResolveRect->x;
        rect.resolveOffsetY = legacyResolveRect->y;
        rect.width = legacyResolveRect->width;
        rect.height = legacyResolveRect->height;
        expandResolveRect = rect;

    } else if (auto* resolveRect = renderPassDescriptor.Get<RenderPassDescriptorResolveRect>()) {
        expandResolveRect = *resolveRect;
    }
    // Handle partial resolve. This identifies passes where there are MSAA color attachments with
    // wgpu::LoadOp::ExpandResolveTexture. If that's the case then the resolves are deferred by
    // removing the resolve targets and forcing the storeOp to Store. After the pass has ended an
    // new pass is recorded for each resolve target that resolves it separately.
    if (expandResolveRect) {
        std::vector<TemporaryResolveAttachment> temporaryResolveAttachments;

        for (auto i : cmd->attachmentState->GetColorAttachmentsMask()) {
            auto& attachmentInfo = cmd->colorAttachments[i];
            TextureViewBase* resolveTarget = attachmentInfo.resolveTarget.Get();
            if (!resolveTarget) {
                continue;
            }
            // Save the color and resolve targets together for an explicit resolve pass
            // after this one ends, then remove the resolve target from this pass and
            // force the storeOp to Store.
            temporaryResolveAttachments.emplace_back(attachmentInfo.view.Get(), resolveTarget,
                                                     attachmentInfo.storeOp);
            attachmentInfo.storeOp = wgpu::StoreOp::Store;
            attachmentInfo.resolveTarget = nullptr;
        }
        for (auto& deferredResolve : temporaryResolveAttachments) {
            passEndOperations.emplace_back([device, encoder, resolveRect = *expandResolveRect,
                                            deferredResolve]() -> MaybeError {
                // Do partial resolve first in one render pass.
                DAWN_TRY(ResolveMultisampleWithDraw(device, encoder, resolveRect,
                                                    deferredResolve.copySrc.Get(),
                                                    deferredResolve.copyDst.Get()));

                switch (deferredResolve.storeOp) {
                    case wgpu::StoreOp::Store:
                        // 'Store' has been handled in the main render pass already.
                        break;
                    case wgpu::StoreOp::Discard:
                        // Handle 'Discard', tagging the subresource as uninitialized.
                        DiscardWithRenderPass(encoder, deferredResolve.copySrc.Get());
                        break;
                    default:
                        DAWN_UNREACHABLE();
                }
                return {};
            });
        }
    }

    // dawn:1550
    // Handle toggle ResolveMultipleAttachmentInSeparatePasses. This identifies passes where there
    // are multiple MSAA color targets and at least one of them has a resolve target. If that's the
    // case then the resolves are deferred by removing the resolve targets and forcing the storeOp
    // to Store. After the pass has ended an new pass is recorded for each resolve target that
    // resolves it separately.
    if (device->IsToggleEnabled(Toggle::ResolveMultipleAttachmentInSeparatePasses) &&
        cmd->attachmentState->GetColorAttachmentsMask().count() > 1) {
        bool splitResolvesIntoSeparatePasses = false;

        // This workaround needs to apply if there are multiple MSAA color targets (checked above)
        // and at least one resolve target.
        for (auto i : cmd->attachmentState->GetColorAttachmentsMask()) {
            if (cmd->colorAttachments[i].resolveTarget.Get() != nullptr) {
                splitResolvesIntoSeparatePasses = true;
                break;
            }
        }

        if (splitResolvesIntoSeparatePasses) {
            std::vector<TemporaryResolveAttachment> temporaryResolveAttachments;

            for (auto i : cmd->attachmentState->GetColorAttachmentsMask()) {
                auto& attachmentInfo = cmd->colorAttachments[i];
                TextureViewBase* resolveTarget = attachmentInfo.resolveTarget.Get();
                if (resolveTarget != nullptr) {
                    // Save the color and resolve targets together for an explicit resolve pass
                    // after this one ends, then remove the resolve target from this pass and
                    // force the storeOp to Store.
                    temporaryResolveAttachments.emplace_back(attachmentInfo.view.Get(),
                                                             resolveTarget, attachmentInfo.storeOp);
                    attachmentInfo.storeOp = wgpu::StoreOp::Store;
                    attachmentInfo.resolveTarget = nullptr;
                }
            }

            passEndOperations.emplace_back(
                [encoder, temporaryResolveAttachments =
                              std::move(temporaryResolveAttachments)]() -> MaybeError {
                    // Called once the render pass has been ended.
                    // Handles any separate resolve passes needed for the
                    // ResolveMultipleAttachmentInSeparatePasses workaround immediately after the
                    // render pass ends and before any additional commands are recorded.
                    for (auto& deferredResolve : temporaryResolveAttachments) {
                        ResolveWithRenderPass(encoder, deferredResolve.copySrc.Get(),
                                              deferredResolve.copyDst.Get(),
                                              deferredResolve.storeOp);
                    }
                    return {};
                });
        }
    }

    *passEndCallbackOut = [passEndOperations = std::move(passEndOperations)]() -> MaybeError {
        // Apply the operations in reverse order. Typically they can be:
        //   1.a) Full resolve pass.
        //   1.b) Partial resolve pass, and conditionally followed with a MSAA texture Discard pass.
        //   2) Copy from temp resolve to the actual resolve target.
        for (auto opIte = passEndOperations.rbegin(); opIte != passEndOperations.rend(); ++opIte) {
            DAWN_TRY((*opIte)());
        }
        return {};
    };

    return {};
}

MaybeError RenderPassWorkaroundsHelper::ApplyOnRenderPassStart(
    RenderPassEncoder* rpEncoder,
    const UnpackedPtr<RenderPassDescriptor>& rpDesc) {
    DeviceBase* device = rpEncoder->GetDevice();
    if (mShouldApplyExpandResolveEmulation) {
        // Perform ExpandResolveTexture load op's emulation after the render pass starts.
        // Backend that doesn't support CanTextureLoadResolveTargetInTheSameRenderpass() can
        // implement this load op internally.
        DAWN_TRY(ExpandResolveTextureWithDraw(device, rpEncoder, rpDesc));
    }

    return {};
}

}  // namespace dawn::native
