BufferVk.h#
The PVRVk class, an object wrapping memory that is directly(non-image) accessible to the shaders.
Includes#
PVRVk/DeviceMemoryVk.h
PVRVk/DeviceVk.h
Included By#
Namespaces#
Classes#
Source Code#
#pragma once
#include "PVRVk/DeviceVk.h"
#include "PVRVk/DeviceMemoryVk.h"
namespace pvrvk {
struct BufferCreateInfo
{
public:
BufferCreateInfo()
: _flags(BufferCreateFlags::e_NONE), _size(0), _sharingMode(SharingMode::e_EXCLUSIVE), _usageFlags(BufferUsageFlags::e_NONE), _numQueueFamilyIndices(0),
_queueFamilyIndices(nullptr)
{}
BufferCreateInfo(pvrvk::DeviceSize size, pvrvk::BufferUsageFlags usageFlags, pvrvk::BufferCreateFlags flags = pvrvk::BufferCreateFlags::e_NONE,
SharingMode sharingMode = SharingMode::e_EXCLUSIVE, const uint32_t* queueFamilyIndices = nullptr, uint32_t numQueueFamilyIndices = 0)
: _flags(flags), _size(size), _sharingMode(sharingMode), _usageFlags(usageFlags), _numQueueFamilyIndices(numQueueFamilyIndices), _queueFamilyIndices(queueFamilyIndices)
{}
inline BufferCreateFlags getFlags() const { return _flags; }
inline void setFlags(BufferCreateFlags flags) { this->_flags = flags; }
inline DeviceSize getSize() const { return _size; }
inline void setSize(DeviceSize size) { this->_size = size; }
inline SharingMode getSharingMode() const { return _sharingMode; }
inline void setSharingMode(SharingMode sharingMode) { this->_sharingMode = sharingMode; }
inline BufferUsageFlags getUsageFlags() const { return _usageFlags; }
inline void setUsageFlags(BufferUsageFlags usageFlags) { this->_usageFlags = usageFlags; }
inline uint32_t getNumQueueFamilyIndices() const { return _numQueueFamilyIndices; }
inline void setNumQueueFamilyIndices(uint32_t numQueueFamilyIndices) { this->_numQueueFamilyIndices = numQueueFamilyIndices; }
inline const uint32_t* getQueueFamilyIndices() const { return _queueFamilyIndices; }
private:
BufferCreateFlags _flags;
DeviceSize _size;
SharingMode _sharingMode;
BufferUsageFlags _usageFlags;
uint32_t _numQueueFamilyIndices;
const uint32_t* _queueFamilyIndices;
};
namespace impl {
class Buffer_ : public PVRVkDeviceObjectBase<VkBuffer, ObjectType::e_BUFFER>, public DeviceObjectDebugUtils<Buffer_>
{
private:
friend class Device_;
class make_shared_enabler
{
protected:
make_shared_enabler() {}
friend class Buffer_;
};
static Buffer constructShared(const DeviceWeakPtr& device, const BufferCreateInfo& createInfo) { return std::make_shared<Buffer_>(make_shared_enabler{}, device, createInfo); }
BufferCreateInfo _createInfo;
MemoryRequirements _memRequirements;
VkDeviceSize _memoryOffset;
DeviceMemory _deviceMemory;
public:
DECLARE_NO_COPY_SEMANTICS(Buffer_)
Buffer_(make_shared_enabler, const DeviceWeakPtr& device, const BufferCreateInfo& createInfo);
~Buffer_();
DeviceMemory& getDeviceMemory() { return _deviceMemory; }
inline BufferCreateFlags getFlags() const { return _createInfo.getFlags(); }
inline bool hasCreateFlag(pvrvk::BufferCreateFlags flags) const { return (_createInfo.getFlags() & flags) == flags; }
inline bool hasUsageFlag(pvrvk::BufferUsageFlags flags) const { return (_createInfo.getUsageFlags() & flags) == flags; }
inline DeviceSize getSize() const { return _createInfo.getSize(); }
inline SharingMode getSharingMode() const { return _createInfo.getSharingMode(); }
inline BufferUsageFlags getUsageFlags() const { return _createInfo.getUsageFlags(); }
inline uint32_t getNumQueueFamilyIndices() const { return _createInfo.getNumQueueFamilyIndices(); }
inline const uint32_t* getQueueFamilyIndices() const { return _createInfo.getQueueFamilyIndices(); }
void bindMemory(DeviceMemory deviceMemory, VkDeviceSize offset)
{
if (isSparseBuffer()) { throw ErrorValidationFailedEXT("Cannot call bindMemory on a sparse buffer"); }
if (_deviceMemory) { throw ErrorValidationFailedEXT("Cannot bind a memory block as Buffer already has a memory block bound"); }
_memoryOffset = offset;
_deviceMemory = deviceMemory;
vkThrowIfFailed(static_cast<Result>(getDevice()->getVkBindings().vkBindBufferMemory(getDevice()->getVkHandle(), getVkHandle(), _deviceMemory->getVkHandle(), offset)),
"Failed to bind memory to buffer");
}
BufferCreateInfo getCreateInfo() const { return _createInfo; }
bool isSparseBuffer() const
{
return (_createInfo.getFlags() & (BufferCreateFlags::e_SPARSE_ALIASED_BIT | BufferCreateFlags::e_SPARSE_BINDING_BIT | BufferCreateFlags::e_SPARSE_RESIDENCY_BIT)) != 0;
}
const MemoryRequirements& getMemoryRequirement() const { return _memRequirements; }
VkDeviceAddress getDeviceAddress(const Device device)
{
VkBufferDeviceAddressInfo bufferDeviceAddressInfo = { static_cast<VkStructureType>(StructureType::e_BUFFER_DEVICE_ADDRESS_INFO_KHR), nullptr, getVkHandle() };
// Depending on the instance version, use the extension version or the core version
if (device->getPhysicalDevice()->getInstance()->getCreateInfo().getApplicationInfo().getApiVersion() >= VK_MAKE_VERSION(1, 2, 0))
{
return device->getVkBindings().vkGetBufferDeviceAddress(device->getVkHandle(), &bufferDeviceAddressInfo);
}
else if (device->getEnabledExtensionTable().khrBufferDeviceAddressEnabled)
{
return device->getVkBindings().vkGetBufferDeviceAddressKHR(device->getVkHandle(), &bufferDeviceAddressInfo);
}
else if (device->getEnabledExtensionTable().extBufferDeviceAddressEnabled)
{
return device->getVkBindings().vkGetBufferDeviceAddressEXT(device->getVkHandle(), &bufferDeviceAddressInfo);
}
assert(false && "Cannot retrieve device address");
return 0;
}
};
} // namespace impl
struct BufferViewCreateInfo
{
public:
BufferViewCreateInfo() : _format(Format::e_UNDEFINED), _offset(0), _range(VK_WHOLE_SIZE), _flags(BufferViewCreateFlags::e_NONE) {}
BufferViewCreateInfo(const Buffer& buffer, Format format, DeviceSize offset = 0, DeviceSize range = VK_WHOLE_SIZE, BufferViewCreateFlags flags = BufferViewCreateFlags::e_NONE)
: _buffer(buffer), _format(format), _offset(offset), _range(range), _flags(flags)
{
assert(range <= buffer->getSize() - offset);
}
inline BufferViewCreateFlags getFlags() const { return _flags; }
inline void setFlags(BufferViewCreateFlags flags) { this->_flags = flags; }
inline const Buffer& getBuffer() const { return _buffer; }
inline void setBuffer(const Buffer& buffer) { this->_buffer = buffer; }
inline Format getFormat() const { return _format; }
inline void setFormat(Format format) { this->_format = format; }
inline DeviceSize getOffset() const { return _offset; }
inline void setOffset(DeviceSize offset) { this->_offset = offset; }
inline DeviceSize getRange() const { return _range; }
inline void setRange(DeviceSize range) { this->_range = range; }
private:
Buffer _buffer;
Format _format;
DeviceSize _offset;
DeviceSize _range;
BufferViewCreateFlags _flags;
};
namespace impl {
class BufferView_ : public PVRVkDeviceObjectBase<VkBufferView, ObjectType::e_BUFFER_VIEW>, public DeviceObjectDebugUtils<BufferView_>
{
private:
friend class Device_;
class make_shared_enabler
{
protected:
make_shared_enabler() {}
friend class BufferView_;
};
static BufferView constructShared(const DeviceWeakPtr& device, const BufferViewCreateInfo& createInfo)
{
return std::make_shared<BufferView_>(make_shared_enabler{}, device, createInfo);
}
BufferViewCreateInfo _createInfo;
public:
DECLARE_NO_COPY_SEMANTICS(BufferView_)
BufferView_(make_shared_enabler, const DeviceWeakPtr& device, const BufferViewCreateInfo& createInfo);
~BufferView_();
inline BufferViewCreateFlags getFlags() const { return _createInfo.getFlags(); }
inline const Buffer& getBuffer() const { return _createInfo.getBuffer(); }
inline Format getFormat() const { return _createInfo.getFormat(); }
inline DeviceSize getOffset() const { return _createInfo.getOffset(); }
inline DeviceSize getRange() const { return _createInfo.getRange(); }
const BufferViewCreateInfo& getCreateInfo() const { return _createInfo; }
};
} // namespace impl
} // namespace pvrvk