1
0
Fork 0
Univerxel/src/client/render/vk/api/Buffers.hpp

97 lines
2.9 KiB
C++

#pragma once
#include "../../api/Buffers.hpp"
#include "Memory.hpp"
#include <vector>
namespace render::vk {
/// Self-container Vulkan buffer
class Buffer: public render::Buffer {
public:
~Buffer();
VkBuffer getRef() const { return ref; }
static void MakeDefault();
struct info {
VkBuffer ref = NULL;
VkDeviceSize offset = 0;
};
protected:
Buffer(VkBuffer ref, memory::ptr mem):
ref(ref), memory(std::move(mem)) { }
VkBuffer ref;
memory::ptr memory;
};
/// Writable (aka Host visible) vulkan buffer
class WritableBuffer: public render::WritableBuffer, public Buffer {
public:
static std::unique_ptr<WritableBuffer> Create(size_t size, Usage usage = Usage::TRANSFER_SRC, const data_view write = data_view());
void write(const data_view, size_t offset) override;
void read(data_ref, size_t offset) override;
explicit operator bool() const { return ref && memory->ptr; }
protected:
WritableBuffer(VkBuffer ref, memory::ptr mem, VkDeviceSize memOffset = 0):
vk::Buffer(ref, std::move(mem)), memOffset(memOffset) { }
const VkDeviceSize memOffset;
};
/// Fast (aka Device local local) vulkan buffer
class FastBuffer: public render::FastBuffer, public Buffer {
public:
protected:
FastBuffer(VkBuffer ref, memory::ptr mem):
vk::Buffer(ref, std::move(mem)) { }
};
class ShortIndexedVertexBuffer: public render::ShortIndexedVertexBuffer {
public:
static std::unique_ptr<ShortIndexedVertexBuffer> Create(const data_view vertices, const data_view indices);
~ShortIndexedVertexBuffer();
static void ClearUnused(uint32_t image);
VkBuffer getVertex() const { return vertex; }
VkBuffer getIndex() const { return index; }
void setLastUse(uint32_t image) { lastUseImage = image; }
explicit operator bool() const { return vertex && index; }
protected:
ShortIndexedVertexBuffer(VkBuffer vertex, VkBuffer index, memory::ptr mem):
vertex(vertex), index(index), memory(std::move(mem)), lastUseImage(UINT32_MAX) { }
VkBuffer vertex;
VkBuffer index;
memory::ptr memory;
uint32_t lastUseImage;
};
class BufferGroup {
public:
BufferGroup(): memory(memory::GetNull()) { }
~BufferGroup();
void allocate(const std::vector<Buffer::requirement> &, bool writable);
VkBuffer at(size_t i) const { return refs.at(i).ref; }
/// Requires last allocate to be writable
void write(size_t, const data_view);
explicit operator bool() const { return memory && !refs.empty(); }
private:
void free();
std::vector<Buffer::info> refs;
memory::ptr memory;
};
memory::ptr createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, const render::data_view view, Buffer::info &out);
memory::ptr createBuffers(const std::vector<Buffer::requirement> &requirements, VkMemoryPropertyFlags properties, std::vector<Buffer::info> &out);
}