/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/ganesh/d3d/GrD3DAttachment.h"

#include "src/gpu/ganesh/d3d/GrD3DGpu.h"

GrD3DAttachment::GrD3DAttachment(GrD3DGpu* gpu,
                                 SkISize dimensions,
                                 UsageFlags supportedUsages,
                                 DXGI_FORMAT format,
                                 const D3D12_RESOURCE_DESC& desc,
                                 const GrD3DTextureResourceInfo& info,
                                 sk_sp<GrD3DResourceState> state,
                                 const GrD3DDescriptorHeap::CPUHandle& view,
                                 std::string_view label)
        : GrAttachment(gpu,
                       dimensions,
                       supportedUsages,
                       desc.SampleDesc.Count,
                       GrMipmapped::kNo,
                       GrProtected::kNo,
                       label)
        , GrD3DTextureResource(info, state)
        , fView(view)
        , fFormat(format) {
    this->registerWithCache(skgpu::Budgeted::kYes);
}

sk_sp<GrD3DAttachment> GrD3DAttachment::MakeStencil(GrD3DGpu* gpu,
                                                    SkISize dimensions,
                                                    int sampleCnt,
                                                    DXGI_FORMAT format) {
    D3D12_RESOURCE_DESC resourceDesc = {};
    resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resourceDesc.Alignment = 0;  // default alignment
    resourceDesc.Width = dimensions.width();
    resourceDesc.Height = dimensions.height();
    resourceDesc.DepthOrArraySize = 1;
    resourceDesc.MipLevels = 1;
    resourceDesc.Format = format;
    resourceDesc.SampleDesc.Count = sampleCnt;
    resourceDesc.SampleDesc.Quality = DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;  // use driver-selected swizzle
    resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;

    D3D12_CLEAR_VALUE clearValue = {};
    clearValue.Format = format;
    clearValue.DepthStencil.Depth = 0;
    clearValue.DepthStencil.Stencil = 0;

    GrD3DTextureResourceInfo info;
    if (!GrD3DTextureResource::InitTextureResourceInfo(gpu, resourceDesc,
                                                       D3D12_RESOURCE_STATE_DEPTH_WRITE,
                                                       GrProtected::kNo, &clearValue, &info)) {
        return nullptr;
    }

    GrD3DDescriptorHeap::CPUHandle view =
            gpu->resourceProvider().createDepthStencilView(info.fResource.get());

    sk_sp<GrD3DResourceState> state(new GrD3DResourceState(info.fResourceState));
    return sk_sp<GrD3DAttachment>(new GrD3DAttachment(gpu, dimensions,
                                                      UsageFlags::kStencilAttachment,
                                                      format, resourceDesc, info,
                                                      std::move(state),
                                                      view,
                                                      /*label=*/"D3DAttachment_MakeStencil"));
}

void GrD3DAttachment::onRelease() {
    GrD3DGpu* gpu = this->getD3DGpu();
    this->releaseResource(gpu);

    GrAttachment::onRelease();
}

void GrD3DAttachment::onAbandon() {
    GrD3DGpu* gpu = this->getD3DGpu();
    this->releaseResource(gpu);

    GrAttachment::onAbandon();
}

GrD3DGpu* GrD3DAttachment::getD3DGpu() const {
    SkASSERT(!this->wasDestroyed());
    return static_cast<GrD3DGpu*>(this->getGpu());
}

void GrD3DAttachment::onSetLabel() {
    SkASSERT(this->d3dResource());
    if (!this->getLabel().empty()) {
        const std::wstring label = L"_Skia_" + GrD3DMultiByteToWide(this->getLabel());
        this->d3dResource()->SetName(label.c_str());
    }
}
