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