diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index c116eb55..86cbffe5 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -3,44 +3,6 @@ namespace dxvk { - DxvkBufferResource::DxvkBufferResource( - const Rc& vkd, - const DxvkBufferCreateInfo& createInfo, - DxvkMemoryAllocator& memAlloc, - VkMemoryPropertyFlags memFlags) - : m_vkd(vkd) { - - VkBufferCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.size = createInfo.size; - info.usage = createInfo.usage; - info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - info.queueFamilyIndexCount = 0; - info.pQueueFamilyIndices = nullptr; - - if (m_vkd->vkCreateBuffer(m_vkd->device(), - &info, nullptr, &m_buffer) != VK_SUCCESS) - throw DxvkError("DxvkBuffer::DxvkBuffer: Failed to create buffer"); - - VkMemoryRequirements memReq; - m_vkd->vkGetBufferMemoryRequirements( - m_vkd->device(), m_buffer, &memReq); - m_memory = memAlloc.alloc(memReq, memFlags); - - if (m_vkd->vkBindBufferMemory(m_vkd->device(), - m_buffer, m_memory.memory(), m_memory.offset()) != VK_SUCCESS) - throw DxvkError("DxvkBuffer::DxvkBuffer: Failed to bind device memory"); - } - - - DxvkBufferResource::~DxvkBufferResource() { - if (m_buffer != VK_NULL_HANDLE) - m_vkd->vkDestroyBuffer(m_vkd->device(), m_buffer, nullptr); - } - - DxvkBuffer::DxvkBuffer( DxvkDevice* device, const DxvkBufferCreateInfo& createInfo, @@ -54,12 +16,12 @@ namespace dxvk { void DxvkBuffer::renameResource( - const Rc& resource) { + const Rc& resource) { m_resource = resource; } - Rc DxvkBuffer::allocateResource() { + Rc DxvkBuffer::allocateResource() { return m_device->allocBufferResource(m_info, m_memFlags); } diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index d18175c7..5d73c252 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -1,83 +1,9 @@ #pragma once -#include "dxvk_format.h" -#include "dxvk_memory.h" -#include "dxvk_resource.h" +#include "dxvk_buffer_res.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; - }; - - - /** - * \brief Physical buffer resource - */ - class DxvkBufferResource : public DxvkResource { - - public: - - DxvkBufferResource( - const Rc& vkd, - const DxvkBufferCreateInfo& createInfo, - DxvkMemoryAllocator& memAlloc, - VkMemoryPropertyFlags memFlags); - - ~DxvkBufferResource(); - - VkBuffer handle() const { - return m_buffer; - } - - void* mapPtr(VkDeviceSize offset) const { - return m_memory.mapPtr(offset); - } - - private: - - Rc m_vkd; - DxvkMemory m_memory; - VkBuffer m_buffer; - - }; - - /** * \brief Virtual buffer resource * @@ -167,13 +93,13 @@ namespace dxvk { * \param [in] resource The new backing resource */ void renameResource( - const Rc& resource); + const Rc& resource); /** * \brief Allocates new backing resource * \returns The new buffer */ - Rc allocateResource(); + Rc allocateResource(); private: @@ -181,7 +107,7 @@ namespace dxvk { DxvkBufferCreateInfo m_info; VkMemoryPropertyFlags m_memFlags; - Rc m_resource; + Rc m_resource; }; diff --git a/src/dxvk/dxvk_buffer_res.cpp b/src/dxvk/dxvk_buffer_res.cpp new file mode 100644 index 00000000..c666a5ba --- /dev/null +++ b/src/dxvk/dxvk_buffer_res.cpp @@ -0,0 +1,50 @@ +#include "dxvk_buffer_res.h" + +namespace dxvk { + + DxvkPhysicalBuffer::DxvkPhysicalBuffer( + const Rc& vkd, + const DxvkBufferCreateInfo& createInfo, + VkDeviceSize sliceCount, + DxvkMemoryAllocator& memAlloc, + VkMemoryPropertyFlags memFlags) + : m_vkd(vkd), + m_sliceLength(createInfo.size), + m_sliceStride(align(createInfo.size, 256)) { + + VkBufferCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.size = m_sliceStride * sliceCount; + info.usage = createInfo.usage; + info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + info.queueFamilyIndexCount = 0; + info.pQueueFamilyIndices = nullptr; + + if (m_vkd->vkCreateBuffer(m_vkd->device(), + &info, nullptr, &m_handle) != VK_SUCCESS) + throw DxvkError("DxvkPhysicalBuffer: Failed to create buffer"); + + VkMemoryRequirements memReq; + m_vkd->vkGetBufferMemoryRequirements( + m_vkd->device(), m_handle, &memReq); + m_memory = memAlloc.alloc(memReq, memFlags); + + if (m_vkd->vkBindBufferMemory(m_vkd->device(), + m_handle, m_memory.memory(), m_memory.offset()) != VK_SUCCESS) + throw DxvkError("DxvkPhysicalBuffer: Failed to bind device memory"); + } + + + DxvkPhysicalBuffer::~DxvkPhysicalBuffer() { + if (m_handle != VK_NULL_HANDLE) + m_vkd->vkDestroyBuffer(m_vkd->device(), m_handle, nullptr); + } + + + DxvkPhysicalBufferSlice DxvkPhysicalBuffer::slice(uint32_t id) { + return DxvkPhysicalBufferSlice(this, id * m_sliceStride, m_sliceLength); + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_buffer_res.h b/src/dxvk/dxvk_buffer_res.h new file mode 100644 index 00000000..36947c62 --- /dev/null +++ b/src/dxvk/dxvk_buffer_res.h @@ -0,0 +1,194 @@ +#pragma once + +#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, + VkDeviceSize sliceCount, + 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 + * + * Returns the buffer object and the offset of the + * given slice. Slices are always aligned to the + * highest required alignment of the device, so + * that they can be used for any purpose. + * \param [in] id Slice index + * \returns The physical slice + */ + DxvkPhysicalBufferSlice slice(uint32_t id); + + private: + + Rc m_vkd; + DxvkMemory m_memory; + VkBuffer m_handle; + + VkDeviceSize m_sliceLength; + VkDeviceSize m_sliceStride; + + }; + + + /** + * \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->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 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; + } + + private: + + Rc m_buffer; + VkDeviceSize m_offset; + VkDeviceSize m_length; + + }; + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index eafb38d6..fddbdc26 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -37,11 +37,11 @@ namespace dxvk { } - Rc DxvkDevice::allocBufferResource( + Rc DxvkDevice::allocBufferResource( const DxvkBufferCreateInfo& createInfo, VkMemoryPropertyFlags memoryType) { - return new DxvkBufferResource(m_vkd, - createInfo, *m_memory, memoryType); + return new DxvkPhysicalBuffer(m_vkd, + createInfo, 1, *m_memory, memoryType); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 7bc71d8c..04bcb2c3 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -107,7 +107,7 @@ namespace dxvk { * \param [in] memoryType Memory property flags * \returns The buffer resource object */ - Rc allocBufferResource( + Rc allocBufferResource( const DxvkBufferCreateInfo& createInfo, VkMemoryPropertyFlags memoryType); diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index ae49a983..6747d999 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -7,6 +7,7 @@ dxvk_src = files([ 'dxvk_adapter.cpp', 'dxvk_barrier.cpp', 'dxvk_buffer.cpp', + 'dxvk_buffer_res.cpp', 'dxvk_cmdlist.cpp', 'dxvk_compute.cpp', 'dxvk_context.cpp',