// 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.

#ifndef DAWNNATIVE_D3D12_TEXTURED3D12_H_
#define DAWNNATIVE_D3D12_TEXTURED3D12_H_

#include "dawn_native/Texture.h"

#include "dawn_native/DawnNative.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PassResourceUsage.h"
#include "dawn_native/d3d12/IntegerTypes.h"
#include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
#include "dawn_native/d3d12/d3d12_platform.h"

namespace dawn_native { namespace d3d12 {

    class CommandRecordingContext;
    class Device;

    DXGI_FORMAT D3D12TextureFormat(wgpu::TextureFormat format);
    MaybeError ValidateD3D12TextureCanBeWrapped(ID3D12Resource* d3d12Resource,
                                                const TextureDescriptor* descriptor);
    MaybeError ValidateTextureDescriptorCanBeWrapped(const TextureDescriptor* descriptor);

    class Texture final : public TextureBase {
      public:
        static ResultOrError<Ref<TextureBase>> Create(Device* device,
                                                      const TextureDescriptor* descriptor);
        static ResultOrError<Ref<TextureBase>> Create(Device* device,
                                                      const ExternalImageDescriptor* descriptor,
                                                      HANDLE sharedHandle,
                                                      ExternalMutexSerial acquireMutexKey,
                                                      bool isSwapChainTexture);
        Texture(Device* device,
                const TextureDescriptor* descriptor,
                ComPtr<ID3D12Resource> d3d12Texture);

        DXGI_FORMAT GetD3D12Format() const;
        ID3D12Resource* GetD3D12Resource() const;
        DXGI_FORMAT GetD3D12CopyableSubresourceFormat(Aspect aspect) const;

        D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t mipLevel,
                                                       uint32_t baseArrayLayer,
                                                       uint32_t layerCount) const;
        D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor(uint32_t mipLevel,
                                                       uint32_t baseArrayLayer,
                                                       uint32_t layerCount) const;
        void EnsureSubresourceContentInitialized(CommandRecordingContext* commandContext,
                                                 const SubresourceRange& range);

        void TrackUsageAndGetResourceBarrierForPass(CommandRecordingContext* commandContext,
                                                    std::vector<D3D12_RESOURCE_BARRIER>* barrier,
                                                    const PassTextureUsage& textureUsages);
        void TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
                                                  std::vector<D3D12_RESOURCE_BARRIER>* barrier,
                                                  wgpu::TextureUsage usage,
                                                  const SubresourceRange& range);
        void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                        wgpu::TextureUsage usage,
                                        const SubresourceRange& range);
        void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                        D3D12_RESOURCE_STATES newState,
                                        const SubresourceRange& range);
        void TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                           wgpu::TextureUsage usage);
        void TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                           D3D12_RESOURCE_STATES newState);

      private:
        Texture(Device* device, const TextureDescriptor* descriptor, TextureState state);
        ~Texture() override;
        using TextureBase::TextureBase;

        MaybeError InitializeAsInternalTexture();
        MaybeError InitializeAsExternalTexture(const TextureDescriptor* descriptor,
                                               HANDLE sharedHandle,
                                               ExternalMutexSerial acquireMutexKey,
                                               bool isSwapChainTexture);

        // Dawn API
        void DestroyImpl() override;
        MaybeError ClearTexture(CommandRecordingContext* commandContext,
                                const SubresourceRange& range,
                                TextureBase::ClearValue clearValue);

        void TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
                                                  std::vector<D3D12_RESOURCE_BARRIER>* barrier,
                                                  D3D12_RESOURCE_STATES newState,
                                                  const SubresourceRange& range);

        void TransitionSingleOrAllSubresources(std::vector<D3D12_RESOURCE_BARRIER>* barriers,
                                               uint32_t index,
                                               D3D12_RESOURCE_STATES subresourceNewState,
                                               ExecutionSerial pendingCommandSerial,
                                               bool allSubresources);
        void HandleTransitionSpecialCases(CommandRecordingContext* commandContext);

        bool mSameLastUsagesAcrossSubresources = true;

        struct StateAndDecay {
            D3D12_RESOURCE_STATES lastState;
            ExecutionSerial lastDecaySerial;
            bool isValidToDecay;
        };
        std::vector<StateAndDecay> mSubresourceStateAndDecay;

        ResourceHeapAllocation mResourceAllocation;
        bool mSwapChainTexture = false;

        ExternalMutexSerial mAcquireMutexKey = ExternalMutexSerial(0);
        ComPtr<IDXGIKeyedMutex> mDxgiKeyedMutex;
    };

    class TextureView final : public TextureViewBase {
      public:
        TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);

        DXGI_FORMAT GetD3D12Format() const;

        const D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDescriptor() const;
        D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor() const;
        D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor() const;
        D3D12_UNORDERED_ACCESS_VIEW_DESC GetUAVDescriptor() const;

      private:
        D3D12_SHADER_RESOURCE_VIEW_DESC mSrvDesc;
    };
}}  // namespace dawn_native::d3d12

#endif  // DAWNNATIVE_D3D12_TEXTURED3D12_H_
