diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index e69de29b..5f13f330 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -0,0 +1,38 @@ +#include "dxvk_buffer.h" + +namespace dxvk { + + DxvkBuffer::DxvkBuffer( + const Rc& vkd, + const DxvkBufferCreateInfo& createInfo, + DxvkMemoryAllocator& memAlloc, + VkMemoryPropertyFlags memFlags) + : m_vkd(vkd), m_info(createInfo) { + + 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); + } + + + DxvkBuffer::~DxvkBuffer() { + if (m_buffer != VK_NULL_HANDLE) + m_vkd->vkDestroyBuffer(m_vkd->device(), m_buffer, nullptr); + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 47983f6a..6c993610 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -1,5 +1,6 @@ #pragma once +#include "dxvk_memory.h" #include "dxvk_resource.h" namespace dxvk { @@ -13,7 +14,10 @@ namespace dxvk { struct DxvkBufferCreateInfo { /// Size of the buffer, in bytes - VkDeviceSize bufferSize; + VkDeviceSize size; + + /// Buffer usage flags + VkBufferUsageFlags usage; }; @@ -21,17 +25,55 @@ namespace dxvk { /** * \brief DXVK buffer * - * A simple buffer resource that stores linear data. + * A simple buffer resource that stores + * linear data. Can be mapped to host + * memory. */ class DxvkBuffer : public DxvkResource { public: + DxvkBuffer( + const Rc& vkd, + const DxvkBufferCreateInfo& createInfo, + DxvkMemoryAllocator& memAlloc, + VkMemoryPropertyFlags memFlags); + ~DxvkBuffer(); + /** + * \brief Buffer handle + * \returns Buffer handle + */ + VkBuffer handle() const { + return m_buffer; + } + + /** + * \brief Buffer properties + * \returns Buffer properties + */ + const DxvkBufferCreateInfo& info() const { + return m_info; + } + + /** + * \brief Map pointer + * + * If the buffer has been created on a host-visible + * memory type, the buffer memory is mapped and can + * be accessed by the host. + * \returns Pointer to mapped memory region + */ + void* mapPtr() const { + return m_memory.mapPtr(); + } private: - + Rc m_vkd; + DxvkBufferCreateInfo m_info; + DxvkMemory m_memory; + VkBuffer m_buffer = VK_NULL_HANDLE; }; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 0f43266f..7bc3109d 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -47,6 +47,14 @@ namespace dxvk { } + Rc DxvkDevice::createBuffer( + const DxvkBufferCreateInfo& createInfo, + VkMemoryPropertyFlags memoryType) { + return new DxvkBuffer(m_vkd, + createInfo, m_memory, memoryType); + } + + Rc DxvkDevice::createImage( const DxvkImageCreateInfo& createInfo, VkMemoryPropertyFlags memoryType) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 66c9dd37..e8a73f50 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -85,6 +85,17 @@ namespace dxvk { Rc createFramebuffer( const DxvkRenderTargets& renderTargets); + /** + * \brief Creates a buffer object + * + * \param [in] createInfo Buffer create info + * \param [in] memoryType Memory type flags + * \returns The buffer object + */ + Rc createBuffer( + const DxvkBufferCreateInfo& createInfo, + VkMemoryPropertyFlags memoryType); + /** * \brief Creates an image object * diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 01e3fa7e..f0a49921 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -1,5 +1,6 @@ dxvk_src = files([ 'dxvk_adapter.cpp', + 'dxvk_buffer.cpp', 'dxvk_cmdlist.cpp', 'dxvk_compute.cpp', 'dxvk_context.cpp',