// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Collections/Array.h" #include "Engine/Graphics/Textures/GPUTexture.h" #include "GPUDeviceDX12.h" #include "IShaderResourceDX12.h" #if GRAPHICS_API_DIRECTX12 /// /// The texture view for DirectX 12 backend. /// class GPUTextureViewDX12 : public GPUTextureView, public IShaderResourceDX12 { private: GPUDeviceDX12* _device = nullptr; ResourceOwnerDX12* _owner = nullptr; DescriptorHeapWithSlotsDX12::Slot _rtv, _srv, _dsv, _uav; public: GPUTextureViewDX12() { } GPUTextureViewDX12(const GPUTextureViewDX12& other) : GPUTextureViewDX12() { #if !BUILD_RELEASE CRASH; // Not used #endif } GPUTextureViewDX12& operator=(const GPUTextureViewDX12& other) { #if !BUILD_RELEASE CRASH; // Not used #endif return *this; } ~GPUTextureViewDX12() { Release(); } public: /// /// Init /// /// Parent resource /// Graphics Device /// Resource owner /// Parent texture format /// Parent texture multi-sample level /// Used subresource index or -1 to cover whole resource. void Init(GPUResource* parent, GPUDeviceDX12* device, ResourceOwnerDX12* owner, PixelFormat format, MSAALevel msaa, int32 subresourceIndex = -1) { GPUTextureView::Init(parent, format, msaa); SubresourceIndex = subresourceIndex; _device = device; _owner = owner; } /// /// Releases the view. /// void Release(); public: bool ReadOnlyDepthView = false; void SetRTV(D3D12_RENDER_TARGET_VIEW_DESC& rtvDesc); void SetSRV(D3D12_SHADER_RESOURCE_VIEW_DESC& srvDesc); void SetDSV(D3D12_DEPTH_STENCIL_VIEW_DESC& dsvDesc); void SetUAV(D3D12_UNORDERED_ACCESS_VIEW_DESC& uavDesc, ID3D12Resource* counterResource = nullptr); public: /// /// Gets the CPU handle to the render target view descriptor. /// FORCE_INLINE D3D12_CPU_DESCRIPTOR_HANDLE RTV() const { return _rtv.CPU(); } /// /// Gets the CPU handle to the depth stencil view descriptor. /// FORCE_INLINE D3D12_CPU_DESCRIPTOR_HANDLE DSV() const { return _dsv.CPU(); } public: // [GPUResourceView] void* GetNativePtr() const override { return (void*)(IShaderResourceDX12*)this; } // [IShaderResourceDX12] bool IsDepthStencilResource() const override { return _dsv.IsValid(); } D3D12_CPU_DESCRIPTOR_HANDLE SRV() const override { return _srv.CPU(); } D3D12_CPU_DESCRIPTOR_HANDLE UAV() const override { return _uav.CPU(); } ResourceOwnerDX12* GetResourceOwner() const override { return _owner; } }; /// /// Texture object for DirectX 12 backend. /// class GPUTextureDX12 : public GPUResourceDX12, public ResourceOwnerDX12, public IShaderResourceDX12 { private: GPUTextureViewDX12 _handleArray; GPUTextureViewDX12 _handleVolume; GPUTextureViewDX12 _handleReadOnlyDepth; Array _handlesPerSlice; // [slice] Array> _handlesPerMip; // [slice][mip] DescriptorHeapWithSlotsDX12::Slot _srv; DescriptorHeapWithSlotsDX12::Slot _uav; DXGI_FORMAT _dxgiFormatDSV; DXGI_FORMAT _dxgiFormatSRV; DXGI_FORMAT _dxgiFormatRTV; DXGI_FORMAT _dxgiFormatUAV; public: GPUTextureDX12(GPUDeviceDX12* device, const StringView& name) : GPUResourceDX12(device, name) { } private: void initHandles(); 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 (void*)_resource; } bool GetData(int32 arrayIndex, int32 mipMapIndex, TextureMipData& data, uint32 mipRowPitch) override; // [ResourceOwnerDX12] GPUResource* AsGPUResource() const override { return (GPUResource*)this; } // [IShaderResourceDX12] bool IsDepthStencilResource() const override { return (_desc.Flags & GPUTextureFlags::DepthStencil) != GPUTextureFlags::None; } D3D12_CPU_DESCRIPTOR_HANDLE SRV() const override { return _srv.CPU(); } D3D12_CPU_DESCRIPTOR_HANDLE UAV() const override { return _uav.CPU(); } ResourceOwnerDX12* GetResourceOwner() const override { return (ResourceOwnerDX12*)this; } protected: // [GPUTexture] bool OnInit() override; void OnResidentMipsChanged() override; void OnReleaseGPU() override; }; #endif