// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #if GRAPHICS_API_VULKAN #include "Engine/Core/Collections/Array.h" #include "Engine/Graphics/Textures/GPUTexture.h" #include "GPUDeviceVulkan.h" #include "ResourceOwnerVulkan.h" /// /// The texture view for Vulkan backend. /// class GPUTextureViewVulkan : public GPUTextureView, public DescriptorOwnerResourceVulkan { public: GPUTextureViewVulkan() { } GPUTextureViewVulkan(const GPUTextureViewVulkan& other) : GPUTextureViewVulkan() { #if !BUILD_RELEASE CRASH; // Not used #endif } GPUTextureViewVulkan& operator=(const GPUTextureViewVulkan& other) { #if !BUILD_RELEASE CRASH; // Not used #endif return *this; } #if !BUILD_RELEASE ~GPUTextureViewVulkan() { ASSERT(View == VK_NULL_HANDLE); } #endif public: GPUDeviceVulkan* Device = nullptr; ResourceOwnerVulkan* Owner = nullptr; VkImage Image = VK_NULL_HANDLE; VkImageView View = VK_NULL_HANDLE; VkImageView ViewFramebuffer = VK_NULL_HANDLE; VkExtent3D Extent; uint32 Layers; VkImageViewCreateInfo Info; int32 SubresourceIndex; VkImageLayout LayoutRTV; VkImageLayout LayoutSRV; public: void Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* owner, VkImage image, int32 totalMipLevels, PixelFormat format, MSAALevel msaa, VkExtent3D extent, VkImageViewType viewType, int32 mipLevels = 1, int32 firstMipIndex = 0, int32 arraySize = 1, int32 firstArraySlice = 0, bool readOnlyDepth = false); VkImageView GetFramebufferView(); void Release(); public: // [GPUResourceView] void* GetNativePtr() const override { return (void*)(DescriptorOwnerResourceVulkan*)this; } // [DescriptorOwnerResourceVulkan] void DescriptorAsImage(GPUContextVulkan* context, VkImageView& imageView, VkImageLayout& layout) override; void DescriptorAsStorageImage(GPUContextVulkan* context, VkImageView& imageView, VkImageLayout& layout) override; }; /// /// Texture object for Vulkan backend. /// class GPUTextureVulkan : public GPUResourceVulkan, public ResourceOwnerVulkan, public DescriptorOwnerResourceVulkan { private: VkImage _image = VK_NULL_HANDLE; VmaAllocation _allocation = VK_NULL_HANDLE; GPUTextureViewVulkan _handleArray; GPUTextureViewVulkan _handleVolume; GPUTextureViewVulkan _handleUAV; GPUTextureViewVulkan _handleReadOnlyDepth; Array _handlesPerSlice; // [slice] Array> _handlesPerMip; // [slice][mip] public: /// /// Initializes a new instance of the class. /// /// The device. /// The resource name. GPUTextureVulkan(GPUDeviceVulkan* device, const StringView& name) : GPUResourceVulkan(device, name) { } public: /// /// Gets the Vulkan image handle. /// FORCE_INLINE VkImage GetHandle() const { return _image; } /// /// The Vulkan staging buffer (used by the staging textures for memory transfers). /// GPUBufferVulkan* StagingBuffer = nullptr; /// /// The default aspect mask flags for the texture (all planes). /// VkImageAspectFlags DefaultAspectMask; 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*)_image; } bool GetData(int32 arrayOrDepthSliceIndex, int32 mipMapIndex, TextureMipData& data, uint32 mipRowPitch) override; // [ResourceOwnerVulkan] GPUResource* AsGPUResource() const override { return (GPUResource*)this; } // [DescriptorOwnerResourceVulkan] void DescriptorAsStorageImage(GPUContextVulkan* context, VkImageView& imageView, VkImageLayout& layout) override; protected: // [GPUTexture] bool OnInit() override; void OnResidentMipsChanged() override; void OnReleaseGPU() override; }; #endif