// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #if GRAPHICS_API_VULKAN #include "Engine/Graphics/Shaders/GPUShader.h" #include "Engine/Graphics/Shaders/GPUConstantBuffer.h" #include "GPUDeviceVulkan.h" #include "ResourceOwnerVulkan.h" /// /// The shared ring buffer for uniform buffers uploading for Vulkan backend. /// /// /// class UniformBufferUploaderVulkan : public GPUResourceVulkan, public ResourceOwnerVulkan { public: struct Allocation { /// /// The allocation offset from the GPU buffer begin (in bytes). /// uint64 Offset; /// /// The allocation size (in bytes). /// uint64 Size; /// /// The GPU buffer. /// VkBuffer Buffer; /// /// The CPU memory address to the mapped buffer data. Can be used to write the uniform buffer contents to upload them to GPU. /// byte* CPUAddress; }; private: VkBuffer _buffer; VmaAllocation _allocation; uint64 _size; uint64 _offset; uint32 _minAlignment; byte* _mapped; CmdBufferVulkan* _fenceCmdBuffer; uint64 _fenceCounter; public: /// /// Initializes a new instance of the class. /// /// The graphics device. UniformBufferUploaderVulkan(GPUDeviceVulkan* device); public: Allocation Allocate(uint64 size, uint32 alignment, GPUContextVulkan* context); public: // [GPUResourceVulkan] GPUResourceType GetResourceType() const final override { return GPUResourceType::Buffer; } // [ResourceOwnerVulkan] GPUResource* AsGPUResource() const override { return (GPUResource*)this; } protected: // [GPUResourceVulkan] void OnReleaseGPU() override; }; /// /// Constant Buffer for Vulkan backend. /// class GPUConstantBufferVulkan : public GPUResourceVulkan, public DescriptorOwnerResourceVulkan { public: /// /// Initializes a new instance of the class. /// /// The graphics device. /// The buffer size (in bytes). GPUConstantBufferVulkan(GPUDeviceVulkan* device, uint32 size) noexcept : GPUResourceVulkan(device, String::Empty) { _size = size; } public: /// /// The last uploaded data inside the shared uniforms uploading ring buffer. /// UniformBufferUploaderVulkan::Allocation Allocation; public: // [DescriptorOwnerResourceVulkan] void DescriptorAsDynamicUniformBuffer(GPUContextVulkan* context, VkBuffer& buffer, VkDeviceSize& offset, VkDeviceSize& range, uint32& dynamicOffset) override { buffer = Allocation.Buffer; offset = 0; range = Allocation.Size; dynamicOffset = (uint32)Allocation.Offset; } }; /// /// Shader for Vulkan backend. /// class GPUShaderVulkan : public GPUResourceVulkan { public: /// /// Initializes a new instance of the class. /// /// The device. /// The resource name. GPUShaderVulkan(GPUDeviceVulkan* device, const StringView& name) : GPUResourceVulkan(device, name) { } protected: // [GPUShader] GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, byte* cacheBytes, uint32 cacheSize, MemoryReadStream& stream) override; }; #endif