#pragma once #include "dxvk_descriptor.h" #include "dxvk_format.h" #include "dxvk_memory.h" #include "dxvk_resource.h" namespace dxvk { /** * \brief Buffer create info * * The properties of a buffer that are * passed to \ref DxvkDevice::createBuffer */ struct DxvkBufferCreateInfo { /// Size of the buffer, in bytes VkDeviceSize size; /// Buffer usage flags VkBufferUsageFlags usage; /// Pipeline stages that can access /// the contents of the buffer. VkPipelineStageFlags stages; /// Allowed access patterns VkAccessFlags access; }; /** * \brief Buffer view create info * * The properties of a buffer view that * are to \ref DxvkDevice::createBufferView */ struct DxvkBufferViewCreateInfo { /// Buffer data format, like image data VkFormat format; /// Offset of the buffer region to include in the view VkDeviceSize rangeOffset; /// Size of the buffer region to include in the view VkDeviceSize rangeLength; }; class DxvkPhysicalBuffer; class DxvkPhysicalBufferSlice; /** * \brief Physical buffer * * A physical buffer is used as a backing resource for * a virtual buffer. See \ref DxvkBuffer as for why * this separation is necessary. */ class DxvkPhysicalBuffer : public DxvkResource { public: DxvkPhysicalBuffer( const Rc& vkd, const DxvkBufferCreateInfo& createInfo, DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags); ~DxvkPhysicalBuffer(); /** * \brief Vulkan buffer handle * \returns Vulkan buffer handle */ VkBuffer handle() const { return m_handle; } /** * \brief Map pointer * * Retrieves a pointer into the mapped memory region * of the buffer, relative to the start of the buffer. * \param [in] offset Offset into the buffer * \returns Pointer into the mapped memory region */ void* mapPtr(VkDeviceSize offset) const { return m_memory.mapPtr(offset); } /** * \brief Retrieves a physical buffer slice * * \param [in] offset Slice offset * \param [in] length Slice length * \returns The physical slice */ DxvkPhysicalBufferSlice slice( VkDeviceSize offset, VkDeviceSize length); private: Rc m_vkd; DxvkMemory m_memory; VkBuffer m_handle; }; /** * \brief Physical buffer slice * * A slice into a physical buffer, which stores * the buffer and the offset into the buffer. */ class DxvkPhysicalBufferSlice { public: DxvkPhysicalBufferSlice() { } DxvkPhysicalBufferSlice( const Rc& buffer, VkDeviceSize offset, VkDeviceSize length) : m_buffer(buffer), m_offset(offset), m_length(length) { } /** * \brief Buffer handle * \returns Buffer handle */ VkBuffer handle() const { return m_buffer != nullptr ? m_buffer->handle() : VK_NULL_HANDLE; } /** * \brief Slice offset * * Offset of the slice into * the underlying buffer. * \returns Slice offset */ VkDeviceSize offset() const { return m_offset; } /** * \brief Slice length * * Number of bytes in the slice. * \returns Slice length, in bytes */ VkDeviceSize length() const { return m_length; } /** * \brief Sub slice into the physical buffer * * \param [in] offset Offset, relative to this slice * \param [in] length Number of bytes of the sub slice * \returns The sub slice */ DxvkPhysicalBufferSlice subSlice(VkDeviceSize offset, VkDeviceSize length) const { return DxvkPhysicalBufferSlice(m_buffer, m_offset + offset, length); } /** * \brief Map pointer * * Retrieves a pointer into the mapped memory * region of the underlying buffer, relative * to the slice's offset. * \param [in] offset Offset into the slice * \returns Pointer to the mapped memory region */ void* mapPtr(VkDeviceSize offset) const { return m_buffer->mapPtr(m_offset + offset); } /** * \brief The buffer resource * \returns Buffer resource */ Rc resource() const { return m_buffer; } /** * \brief Checks whether this slice overlaps with another * * \param [in] other The buffer slice to check * \returns \c true if the two slices overlap */ bool overlaps(const DxvkPhysicalBufferSlice& other) const { return this->m_buffer == other.m_buffer && this->m_offset + this->m_length > other.m_offset && this->m_offset < other.m_offset + other.m_length; } private: Rc m_buffer = nullptr; VkDeviceSize m_offset = 0; VkDeviceSize m_length = 0; }; inline DxvkPhysicalBufferSlice DxvkPhysicalBuffer::slice( VkDeviceSize offset, VkDeviceSize length) { return DxvkPhysicalBufferSlice(this, offset, length); } /** * \brief Physical buffer view * * Manages a texel buffer view for a physical * buffer slice, which is used as the backing * resource of a \c DxvkBufferView. */ class DxvkPhysicalBufferView : public DxvkResource { public: DxvkPhysicalBufferView( const Rc& vkd, const DxvkPhysicalBufferSlice& slice, const DxvkBufferViewCreateInfo& info); ~DxvkPhysicalBufferView(); /** * \brief Vulkan buffer view handle * \returns Vulkan buffer view handle */ VkBufferView handle() const { return m_view; } /** * \brief Physical buffer slice * * The slice backing this buffer view. * \returns Physical buffer slice */ DxvkPhysicalBufferSlice slice() const { return m_slice; } /** * \brief Physical buffer resource * \returns Resource pointer */ Rc bufferResource() const { return m_slice.resource(); } private: Rc m_vkd; DxvkPhysicalBufferSlice m_slice; VkBufferView m_view = VK_NULL_HANDLE; }; }