// Copyright 2019 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/AttachmentState.h"

#include "dawn/common/BitSetIterator.h"
#include "dawn/common/Enumerator.h"
#include "dawn/common/ityp_span.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/Device.h"
#include "dawn/native/ObjectContentHasher.h"
#include "dawn/native/PipelineLayout.h"
#include "dawn/native/Texture.h"

namespace dawn::native {

AttachmentState::AttachmentState(DeviceBase* device,
                                 const RenderBundleEncoderDescriptor* descriptor)
    : ObjectBase(device), mSampleCount(descriptor->sampleCount) {
    DAWN_ASSERT(descriptor->colorFormatCount <= kMaxColorAttachments);
    auto colorFormats = ityp::SpanFromUntyped<ColorAttachmentIndex>(descriptor->colorFormats,
                                                                    descriptor->colorFormatCount);

    for (auto [i, format] : Enumerate(colorFormats)) {
        if (format != wgpu::TextureFormat::Undefined) {
            mColorAttachmentsSet.set(i);
            mColorFormats[i] = format;
        }
    }
    mDepthStencilFormat = descriptor->depthStencilFormat;

    // TODO(dawn:1710): support MSAA render to single sampled in render bundles.
    // TODO(dawn:1704): support PLS in render bundles.

    SetContentHash(ComputeContentHash());
}

AttachmentState::AttachmentState(DeviceBase* device,
                                 const UnpackedPtr<RenderPipelineDescriptor>& descriptor,
                                 const PipelineLayoutBase* layout)
    : ObjectBase(device), mSampleCount(descriptor->multisample.count) {
    UnpackedPtr<MultisampleState> unpackedMultisampleState = Unpack(&descriptor->multisample);
    if (auto* msaaRenderToSingleSampledDesc =
            unpackedMultisampleState.Get<DawnMultisampleStateRenderToSingleSampled>()) {
        mIsMSAARenderToSingleSampledEnabled = msaaRenderToSingleSampledDesc->enabled;
    }

    if (descriptor->fragment != nullptr) {
        DAWN_ASSERT(descriptor->fragment->targetCount <= kMaxColorAttachments);
        auto targets = ityp::SpanFromUntyped<ColorAttachmentIndex>(
            descriptor->fragment->targets, descriptor->fragment->targetCount);

        for (auto [i, target] : Enumerate(targets)) {
            wgpu::TextureFormat format = target.format;
            if (format != wgpu::TextureFormat::Undefined) {
                mColorAttachmentsSet.set(i);
                mColorFormats[i] = format;
            }
        }
    }
    if (descriptor->depthStencil != nullptr) {
        mDepthStencilFormat = descriptor->depthStencil->format;
    }

    mHasPLS = layout->HasPixelLocalStorage();
    mStorageAttachmentSlots = layout->GetStorageAttachmentSlots();

    SetContentHash(ComputeContentHash());
}

AttachmentState::AttachmentState(DeviceBase* device,
                                 const UnpackedPtr<RenderPassDescriptor>& descriptor)
    : ObjectBase(device) {
    auto colorAttachments = ityp::SpanFromUntyped<ColorAttachmentIndex>(
        descriptor->colorAttachments, descriptor->colorAttachmentCount);
    for (auto [i, colorAttachment] : Enumerate(colorAttachments)) {
        TextureViewBase* attachment = colorAttachment.view;
        if (attachment == nullptr) {
            continue;
        }
        mColorAttachmentsSet.set(i);
        mColorFormats[i] = attachment->GetFormat().format;

        UnpackedPtr<RenderPassColorAttachment> unpackedColorAttachment = Unpack(&colorAttachment);
        auto* msaaRenderToSingleSampledDesc =
            unpackedColorAttachment.Get<DawnRenderPassColorAttachmentRenderToSingleSampled>();
        uint32_t attachmentSampleCount;
        if (msaaRenderToSingleSampledDesc != nullptr &&
            msaaRenderToSingleSampledDesc->implicitSampleCount > 1) {
            attachmentSampleCount = msaaRenderToSingleSampledDesc->implicitSampleCount;
            mIsMSAARenderToSingleSampledEnabled = true;
        } else {
            attachmentSampleCount = attachment->GetTexture()->GetSampleCount();
        }

        if (mSampleCount == 0) {
            mSampleCount = attachmentSampleCount;
        } else {
            DAWN_ASSERT(mSampleCount == attachmentSampleCount);
        }
    }

    // Gather the depth-stencil information.
    if (descriptor->depthStencilAttachment != nullptr) {
        TextureViewBase* attachment = descriptor->depthStencilAttachment->view;
        mDepthStencilFormat = attachment->GetFormat().format;
        if (mSampleCount == 0) {
            mSampleCount = attachment->GetTexture()->GetSampleCount();
        } else {
            DAWN_ASSERT(mSampleCount == attachment->GetTexture()->GetSampleCount());
        }
    }

    // Gather the PLS information.
    if (auto* pls = descriptor.Get<RenderPassPixelLocalStorage>()) {
        mHasPLS = true;
        mStorageAttachmentSlots = std::vector<wgpu::TextureFormat>(
            pls->totalPixelLocalStorageSize / kPLSSlotByteSize, wgpu::TextureFormat::Undefined);
        for (size_t i = 0; i < pls->storageAttachmentCount; i++) {
            size_t slot = pls->storageAttachments[i].offset / kPLSSlotByteSize;
            const TextureViewBase* attachment = pls->storageAttachments[i].storage;
            mStorageAttachmentSlots[slot] = attachment->GetFormat().format;

            if (mSampleCount == 0) {
                mSampleCount = attachment->GetTexture()->GetSampleCount();
            } else {
                DAWN_ASSERT(mSampleCount == attachment->GetTexture()->GetSampleCount());
            }
        }
    }

    DAWN_ASSERT(mSampleCount > 0);
    SetContentHash(ComputeContentHash());
}

AttachmentState::AttachmentState(const AttachmentState& blueprint)
    : ObjectBase(blueprint.GetDevice()) {
    mColorAttachmentsSet = blueprint.mColorAttachmentsSet;
    mColorFormats = blueprint.mColorFormats;
    mDepthStencilFormat = blueprint.mDepthStencilFormat;
    mSampleCount = blueprint.mSampleCount;
    mIsMSAARenderToSingleSampledEnabled = blueprint.mIsMSAARenderToSingleSampledEnabled;
    mHasPLS = blueprint.mHasPLS;
    mStorageAttachmentSlots = blueprint.mStorageAttachmentSlots;
    SetContentHash(blueprint.GetContentHash());
}

void AttachmentState::DeleteThis() {
    Uncache();
    RefCounted::DeleteThis();
}

bool AttachmentState::EqualityFunc::operator()(const AttachmentState* a,
                                               const AttachmentState* b) const {
    // Check set attachments
    if (a->mColorAttachmentsSet != b->mColorAttachmentsSet) {
        return false;
    }

    // Check color formats
    for (auto i : IterateBitSet(a->mColorAttachmentsSet)) {
        if (a->mColorFormats[i] != b->mColorFormats[i]) {
            return false;
        }
    }

    // Check depth stencil format
    if (a->mDepthStencilFormat != b->mDepthStencilFormat) {
        return false;
    }

    // Check sample count
    if (a->mSampleCount != b->mSampleCount) {
        return false;
    }

    // Both attachment state must either enable MSAA render to single sampled or disable it.
    if (a->mIsMSAARenderToSingleSampledEnabled != b->mIsMSAARenderToSingleSampledEnabled) {
        return false;
    }

    // Check PLS
    if (a->mHasPLS != b->mHasPLS) {
        return false;
    }
    if (a->mStorageAttachmentSlots.size() != b->mStorageAttachmentSlots.size()) {
        return false;
    }
    for (size_t i = 0; i < a->mStorageAttachmentSlots.size(); i++) {
        if (a->mStorageAttachmentSlots[i] != b->mStorageAttachmentSlots[i]) {
            return false;
        }
    }

    return true;
}

size_t AttachmentState::ComputeContentHash() {
    size_t hash = 0;

    // Hash color formats
    HashCombine(&hash, mColorAttachmentsSet);
    for (auto i : IterateBitSet(mColorAttachmentsSet)) {
        HashCombine(&hash, mColorFormats[i]);
    }

    // Hash depth stencil attachment
    HashCombine(&hash, mDepthStencilFormat);

    // Hash sample count
    HashCombine(&hash, mSampleCount);

    // Hash MSAA render to single sampled flag
    HashCombine(&hash, mIsMSAARenderToSingleSampledEnabled);

    // Hash the PLS state
    HashCombine(&hash, mHasPLS);
    for (wgpu::TextureFormat slotFormat : mStorageAttachmentSlots) {
        HashCombine(&hash, slotFormat);
    }

    return hash;
}

ColorAttachmentMask AttachmentState::GetColorAttachmentsMask() const {
    return mColorAttachmentsSet;
}

wgpu::TextureFormat AttachmentState::GetColorAttachmentFormat(ColorAttachmentIndex index) const {
    DAWN_ASSERT(mColorAttachmentsSet[index]);
    return mColorFormats[index];
}

bool AttachmentState::HasDepthStencilAttachment() const {
    return mDepthStencilFormat != wgpu::TextureFormat::Undefined;
}

wgpu::TextureFormat AttachmentState::GetDepthStencilFormat() const {
    DAWN_ASSERT(HasDepthStencilAttachment());
    return mDepthStencilFormat;
}

uint32_t AttachmentState::GetSampleCount() const {
    return mSampleCount;
}

bool AttachmentState::IsMSAARenderToSingleSampledEnabled() const {
    return mIsMSAARenderToSingleSampledEnabled;
}

bool AttachmentState::HasPixelLocalStorage() const {
    return mHasPLS;
}

const std::vector<wgpu::TextureFormat>& AttachmentState::GetStorageAttachmentSlots() const {
    return mStorageAttachmentSlots;
}

std::vector<ColorAttachmentIndex>
AttachmentState::ComputeStorageAttachmentPackingInColorAttachments() const {
    // TODO(dawn:1704): Consider caching this on AttachmentState creation, but does it become part
    // of the hashing and comparison operators? Fill with garbage data to more easily detect cases
    // where an incorrect slot is accessed.
    std::vector<ColorAttachmentIndex> result(mStorageAttachmentSlots.size(),
                                             ityp::PlusOne(kMaxColorAttachmentsTyped));

    // Iterate over the empty bits of mColorAttachmentsSet to pack storage attachment in them.
    auto availableSlots = ~mColorAttachmentsSet;
    for (size_t i = 0; i < mStorageAttachmentSlots.size(); i++) {
        DAWN_ASSERT(!availableSlots.none());
        auto slot = ColorAttachmentIndex(uint8_t(ScanForward(availableSlots.to_ulong())));
        availableSlots.reset(slot);
        result[i] = slot;
    }

    return result;
}

}  // namespace dawn::native
