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