// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Graphics/Textures/GPUTexture.h"
#include "GPUDeviceDX11.h"
#include "IShaderResourceDX11.h"
#if GRAPHICS_API_DIRECTX11
///
/// The texture view for DirectX 11 backend.
///
///
///
class GPUTextureViewDX11 : public GPUTextureView, public IShaderResourceDX11
{
private:
ID3D11RenderTargetView* _rtv = nullptr;
ID3D11ShaderResourceView* _srv = nullptr;
ID3D11DepthStencilView* _dsv = nullptr;
ID3D11UnorderedAccessView* _uav = nullptr;
public:
///
/// Initializes a new instance of the class.
///
GPUTextureViewDX11()
{
}
GPUTextureViewDX11(const GPUTextureViewDX11& other)
: GPUTextureViewDX11()
{
#if !BUILD_RELEASE
CRASH; // Not used
#endif
}
GPUTextureViewDX11& operator=(const GPUTextureViewDX11& other)
{
#if !BUILD_RELEASE
CRASH; // Not used
#endif
return *this;
}
///
/// Finalizes an instance of the class.
///
~GPUTextureViewDX11()
{
Release();
}
public:
///
/// Init
///
/// Resource that owns that handle
/// Render Target View
/// Shader Resource view
/// Depth Stencil View
/// Unordered Access View
/// Parent texture format
/// Parent texture multi-sample level
void Init(GPUResource* parent, ID3D11RenderTargetView* rtv, ID3D11ShaderResourceView* srv, ID3D11DepthStencilView* dsv, ID3D11UnorderedAccessView* uav, PixelFormat format, MSAALevel msaa)
{
GPUTextureView::Init(parent, format, msaa);
_rtv = rtv;
_srv = srv;
_dsv = dsv;
_uav = uav;
}
///
/// Release the view.
///
void Release()
{
DX_SAFE_RELEASE_CHECK(_rtv, 0);
DX_SAFE_RELEASE_CHECK(_srv, 0);
DX_SAFE_RELEASE_CHECK(_dsv, 0);
DX_SAFE_RELEASE_CHECK(_uav, 0);
}
public:
///
/// Sets new render target view.
///
/// A new render target view.
void SetRTV(ID3D11RenderTargetView* rtv)
{
DX_SAFE_RELEASE_CHECK(_rtv, 0);
_rtv = rtv;
}
///
/// Sets new shader resource view.
///
/// A new shader resource view.
void SetSRV(ID3D11ShaderResourceView* srv)
{
DX_SAFE_RELEASE_CHECK(_srv, 0);
_srv = srv;
}
///
/// Sets new depth stencil view.
///
/// A new depth stencil view.
void SetDSV(ID3D11DepthStencilView* dsv)
{
DX_SAFE_RELEASE_CHECK(_dsv, 0);
_dsv = dsv;
}
///
/// Sets new unordered access view.
///
/// A new unordered access view.
void SetUAV(ID3D11UnorderedAccessView* uav)
{
DX_SAFE_RELEASE_CHECK(_uav, 0);
_uav = uav;
}
public:
///
/// Gets the render target view.
///
/// The render target view.
ID3D11RenderTargetView* RTV() const
{
return _rtv;
}
///
/// Gets the depth stencil view.
///
/// The depth stencil view.
ID3D11DepthStencilView* DSV() const
{
return _dsv;
}
public:
// [GPUResourceView]
void* GetNativePtr() const override
{
return (void*)(IShaderResourceDX11*)this;
}
// [IShaderResourceDX11]
ID3D11ShaderResourceView* SRV() const override
{
return _srv;
}
ID3D11UnorderedAccessView* UAV() const override
{
return _uav;
}
};
///
/// Texture object for DirectX 11 backend.
///
class GPUTextureDX11 : public GPUResourceDX11
{
private:
ID3D11Resource* _resource = nullptr;
GPUTextureViewDX11 _handleArray;
GPUTextureViewDX11 _handleVolume;
GPUTextureViewDX11 _handleReadOnlyDepth;
Array _handlesPerSlice; // [slice]
Array> _handlesPerMip; // [slice][mip]
DXGI_FORMAT _dxgiFormatDSV;
DXGI_FORMAT _dxgiFormatSRV;
DXGI_FORMAT _dxgiFormatRTV;
DXGI_FORMAT _dxgiFormatUAV;
public:
///
/// Initializes a new instance of the class.
///
/// The device.
/// The name.
GPUTextureDX11(GPUDeviceDX11* device, const StringView& name)
: GPUResourceDX11(device, name)
{
}
public:
///
/// Gets DX11 texture resource.
///
/// DX11 texture resource.
FORCE_INLINE ID3D11Resource* GetResource() const
{
return _resource;
}
private:
void initHandles();
ID3D11Texture2D* GetTexture2D() const
{
ASSERT(_desc.Dimensions == TextureDimensions::Texture || _desc.Dimensions == TextureDimensions::CubeTexture);
return (ID3D11Texture2D*)_resource;
}
ID3D11Texture3D* GetTexture3D() const
{
ASSERT(_desc.Dimensions == TextureDimensions::VolumeTexture);
return (ID3D11Texture3D*)_resource;
}
public:
// [GPUTexture]
GPUTextureView* View(int32 arrayOrDepthIndex) const override
{
return (GPUTextureView*)&_handlesPerSlice[arrayOrDepthIndex];
}
GPUTextureView* View(int32 arrayOrDepthIndex, int32 mipMapIndex) const override
{
return (GPUTextureView*)&_handlesPerMip[arrayOrDepthIndex][mipMapIndex];
}
GPUTextureView* ViewArray() const override
{
ASSERT(ArraySize() > 1);
return (GPUTextureView*)&_handleArray;
}
GPUTextureView* ViewVolume() const override
{
ASSERT(IsVolume());
return (GPUTextureView*)&_handleVolume;
}
GPUTextureView* ViewReadOnlyDepth() const override
{
ASSERT(_desc.Flags & GPUTextureFlags::ReadOnlyDepthView);
return (GPUTextureView*)&_handleReadOnlyDepth;
}
void* GetNativePtr() const override
{
return static_cast(_resource);
}
bool GetData(int32 arrayOrDepthSliceIndex, int32 mipMapIndex, TextureMipData& data, uint32 mipRowPitch) override;
// [GPUResourceDX11]
ID3D11Resource* GetResource() override
{
return _resource;
}
protected:
// [GPUTexture]
bool OnInit() override;
void OnResidentMipsChanged() override;
void OnReleaseGPU() override;
};
#endif