// Copyright 2017 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/d3d12/BindGroupD3D12.h"

#include "dawn/common/BitSetIterator.h"
#include "dawn/native/ExternalTexture.h"
#include "dawn/native/d3d12/BindGroupLayoutD3D12.h"
#include "dawn/native/d3d12/BufferD3D12.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/SamplerHeapCacheD3D12.h"
#include "dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h"
#include "dawn/native/d3d12/TextureD3D12.h"

namespace dawn::native::d3d12 {

    // static
    ResultOrError<Ref<BindGroup>> BindGroup::Create(Device* device,
                                                    const BindGroupDescriptor* descriptor) {
        return ToBackend(descriptor->layout)->AllocateBindGroup(device, descriptor);
    }

    BindGroup::BindGroup(Device* device,
                         const BindGroupDescriptor* descriptor,
                         uint32_t viewSizeIncrement,
                         const CPUDescriptorHeapAllocation& viewAllocation)
        : BindGroupBase(this, device, descriptor) {
        BindGroupLayout* bgl = ToBackend(GetLayout());

        mCPUViewAllocation = viewAllocation;

        const auto& descriptorHeapOffsets = bgl->GetDescriptorHeapOffsets();

        ID3D12Device* d3d12Device = device->GetD3D12Device();

        // It's not necessary to create descriptors in the descriptor heap for dynamic resources.
        // This is because they are created as root descriptors which are never heap allocated.
        // Since dynamic buffers are packed in the front, we can skip over these bindings by
        // starting from the dynamic buffer count.
        for (BindingIndex bindingIndex = bgl->GetDynamicBufferCount();
             bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
            const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);

            // Increment size does not need to be stored and is only used to get a handle
            // local to the allocation with OffsetFrom().
            switch (bindingInfo.bindingType) {
                case BindingInfoType::Buffer: {
                    BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);

                    ID3D12Resource* resource = ToBackend(binding.buffer)->GetD3D12Resource();
                    if (resource == nullptr) {
                        // The Buffer was destroyed. Skip creating buffer views since there is no
                        // resource. This bind group won't be used as it is an error to submit a
                        // command buffer that references destroyed resources.
                        continue;
                    }

                    switch (bindingInfo.buffer.type) {
                        case wgpu::BufferBindingType::Uniform: {
                            D3D12_CONSTANT_BUFFER_VIEW_DESC desc;
                            desc.SizeInBytes =
                                Align(binding.size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
                            desc.BufferLocation =
                                ToBackend(binding.buffer)->GetVA() + binding.offset;

                            d3d12Device->CreateConstantBufferView(
                                &desc, viewAllocation.OffsetFrom(
                                           viewSizeIncrement, descriptorHeapOffsets[bindingIndex]));
                            break;
                        }
                        case wgpu::BufferBindingType::Storage:
                        case kInternalStorageBufferBinding: {
                            // Since Tint outputs HLSL shaders with RWByteAddressBuffer,
                            // we must use D3D12_BUFFER_UAV_FLAG_RAW when making the
                            // UNORDERED_ACCESS_VIEW_DESC. Using D3D12_BUFFER_UAV_FLAG_RAW requires
                            // that we use DXGI_FORMAT_R32_TYPELESS as the format of the view.
                            // DXGI_FORMAT_R32_TYPELESS requires that the element size be 4
                            // byte aligned. Since binding.size and binding.offset are in bytes,
                            // we need to divide by 4 to obtain the element size.
                            D3D12_UNORDERED_ACCESS_VIEW_DESC desc;
                            desc.Buffer.NumElements = binding.size / 4;
                            desc.Format = DXGI_FORMAT_R32_TYPELESS;
                            desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
                            desc.Buffer.FirstElement = binding.offset / 4;
                            desc.Buffer.StructureByteStride = 0;
                            desc.Buffer.CounterOffsetInBytes = 0;
                            desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;

                            d3d12Device->CreateUnorderedAccessView(
                                resource, nullptr, &desc,
                                viewAllocation.OffsetFrom(viewSizeIncrement,
                                                          descriptorHeapOffsets[bindingIndex]));
                            break;
                        }
                        case wgpu::BufferBindingType::ReadOnlyStorage: {
                            // Like StorageBuffer, Tint outputs HLSL shaders for readonly
                            // storage buffer with ByteAddressBuffer. So we must use
                            // D3D12_BUFFER_SRV_FLAG_RAW when making the SRV descriptor. And it has
                            // similar requirement for format, element size, etc.
                            D3D12_SHADER_RESOURCE_VIEW_DESC desc;
                            desc.Format = DXGI_FORMAT_R32_TYPELESS;
                            desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
                            desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
                            desc.Buffer.FirstElement = binding.offset / 4;
                            desc.Buffer.NumElements = binding.size / 4;
                            desc.Buffer.StructureByteStride = 0;
                            desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
                            d3d12Device->CreateShaderResourceView(
                                resource, &desc,
                                viewAllocation.OffsetFrom(viewSizeIncrement,
                                                          descriptorHeapOffsets[bindingIndex]));
                            break;
                        }
                        case wgpu::BufferBindingType::Undefined:
                            UNREACHABLE();
                    }

                    break;
                }

                case BindingInfoType::Texture: {
                    auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
                    auto& srv = view->GetSRVDescriptor();

                    ID3D12Resource* resource = ToBackend(view->GetTexture())->GetD3D12Resource();
                    if (resource == nullptr) {
                        // The Texture was destroyed. Skip creating the SRV since there is no
                        // resource. This bind group won't be used as it is an error to submit a
                        // command buffer that references destroyed resources.
                        continue;
                    }

                    d3d12Device->CreateShaderResourceView(
                        resource, &srv,
                        viewAllocation.OffsetFrom(viewSizeIncrement,
                                                  descriptorHeapOffsets[bindingIndex]));
                    break;
                }

                case BindingInfoType::StorageTexture: {
                    TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));

                    ID3D12Resource* resource = ToBackend(view->GetTexture())->GetD3D12Resource();
                    if (resource == nullptr) {
                        // The Texture was destroyed. Skip creating the SRV/UAV since there is no
                        // resource. This bind group won't be used as it is an error to submit a
                        // command buffer that references destroyed resources.
                        continue;
                    }

                    switch (bindingInfo.storageTexture.access) {
                        case wgpu::StorageTextureAccess::WriteOnly: {
                            D3D12_UNORDERED_ACCESS_VIEW_DESC uav = view->GetUAVDescriptor();
                            d3d12Device->CreateUnorderedAccessView(
                                resource, nullptr, &uav,
                                viewAllocation.OffsetFrom(viewSizeIncrement,
                                                          descriptorHeapOffsets[bindingIndex]));
                            break;
                        }

                        case wgpu::StorageTextureAccess::Undefined:
                            UNREACHABLE();
                    }

                    break;
                }

                case BindingInfoType::ExternalTexture: {
                    UNREACHABLE();
                }

                case BindingInfoType::Sampler: {
                    // No-op as samplers will be later initialized by CreateSamplers().
                    break;
                }
            }
        }

        // Loop through the dynamic storage buffers and build a flat map from the index of the
        // dynamic storage buffer to its binding size. The index |dynamicStorageBufferIndex|
        // means that it is the i'th buffer that is both dynamic and storage, in increasing order
        // of BindingNumber.
        mDynamicStorageBufferLengths.resize(bgl->GetBindingCountInfo().dynamicStorageBufferCount);
        uint32_t dynamicStorageBufferIndex = 0;
        for (BindingIndex bindingIndex(0); bindingIndex < bgl->GetDynamicBufferCount();
             ++bindingIndex) {
            if (bgl->IsStorageBufferBinding(bindingIndex)) {
                mDynamicStorageBufferLengths[dynamicStorageBufferIndex++] =
                    GetBindingAsBufferBinding(bindingIndex).size;
            }
        }
    }

    BindGroup::~BindGroup() = default;

    void BindGroup::DestroyImpl() {
        BindGroupBase::DestroyImpl();
        ToBackend(GetLayout())->DeallocateBindGroup(this, &mCPUViewAllocation);
        ASSERT(!mCPUViewAllocation.IsValid());
    }

    bool BindGroup::PopulateViews(ShaderVisibleDescriptorAllocator* viewAllocator) {
        const BindGroupLayout* bgl = ToBackend(GetLayout());

        const uint32_t descriptorCount = bgl->GetCbvUavSrvDescriptorCount();
        if (descriptorCount == 0 || viewAllocator->IsAllocationStillValid(mGPUViewAllocation)) {
            return true;
        }

        // Attempt to allocate descriptors for the currently bound shader-visible heaps.
        // If either failed, return early to re-allocate and switch the heaps.
        Device* device = ToBackend(GetDevice());

        D3D12_CPU_DESCRIPTOR_HANDLE baseCPUDescriptor;
        if (!viewAllocator->AllocateGPUDescriptors(descriptorCount,
                                                   device->GetPendingCommandSerial(),
                                                   &baseCPUDescriptor, &mGPUViewAllocation)) {
            return false;
        }

        // CPU bindgroups are sparsely allocated across CPU heaps. Instead of doing
        // simple copies per bindgroup, a single non-simple copy could be issued.
        // TODO(dawn:155): Consider doing this optimization.
        device->GetD3D12Device()->CopyDescriptorsSimple(descriptorCount, baseCPUDescriptor,
                                                        mCPUViewAllocation.GetBaseDescriptor(),
                                                        D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

        return true;
    }

    D3D12_GPU_DESCRIPTOR_HANDLE BindGroup::GetBaseViewDescriptor() const {
        return mGPUViewAllocation.GetBaseDescriptor();
    }

    D3D12_GPU_DESCRIPTOR_HANDLE BindGroup::GetBaseSamplerDescriptor() const {
        ASSERT(mSamplerAllocationEntry != nullptr);
        return mSamplerAllocationEntry->GetBaseDescriptor();
    }

    bool BindGroup::PopulateSamplers(Device* device,
                                     ShaderVisibleDescriptorAllocator* samplerAllocator) {
        if (mSamplerAllocationEntry == nullptr) {
            return true;
        }
        return mSamplerAllocationEntry->Populate(device, samplerAllocator);
    }

    void BindGroup::SetSamplerAllocationEntry(Ref<SamplerHeapCacheEntry> entry) {
        mSamplerAllocationEntry = std::move(entry);
    }

    const BindGroup::DynamicStorageBufferLengths& BindGroup::GetDynamicStorageBufferLengths()
        const {
        return mDynamicStorageBufferLengths;
    }

}  // namespace dawn::native::d3d12
