diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 7fb31634..0f6b5d80 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -10,6 +10,11 @@ namespace dxvk { : m_device (device), m_info (createInfo), m_memFlags (memoryType) { + // Align physical buffer slices to 256 bytes, which guarantees + // that we don't violate any Vulkan alignment requirements + m_physSliceLength = createInfo.size; + m_physSliceStride = align(createInfo.size, 256); + // Initialize a single backing bufer with one slice m_physBuffers[0] = this->allocPhysicalBuffer(1); m_physSlice = this->allocPhysicalSlice(); @@ -23,12 +28,11 @@ namespace dxvk { DxvkPhysicalBufferSlice DxvkBuffer::allocPhysicalSlice() { - if (m_physSliceId >= m_physBuffers[m_physBufferId]->sliceCount()) { + if (m_physSliceId >= m_physSliceCount) { m_physBufferId = (m_physBufferId + 1) % m_physBuffers.size(); m_physSliceId = 0; - if ((m_physBuffers[m_physBufferId] == nullptr) - || (m_physBuffers[m_physBufferId]->sliceCount() < m_physSliceCount)) { + if (m_physBuffers[m_physBufferId] == nullptr) { // Make sure that all buffers have the same size. If we don't do this, // one of the physical buffers may grow indefinitely while the others // remain small, depending on the usage pattern of the application. @@ -37,19 +41,26 @@ namespace dxvk { // Allocate a new physical buffer if the current one is still in use. // This also indicates that the buffer gets updated frequently, so we // will double the size of the physical buffers to accomodate for it. - if (m_physBufferId == 0) + if (m_physBufferId == 0) { + std::fill(m_physBuffers.begin(), m_physBuffers.end(), nullptr); m_physSliceCount *= 2; + } m_physBuffers[m_physBufferId] = this->allocPhysicalBuffer(m_physSliceCount); } } - return m_physBuffers[m_physBufferId]->slice(m_physSliceId++); + return m_physBuffers[m_physBufferId]->slice( + m_physSliceStride * m_physSliceId++, + m_physSliceLength); } Rc DxvkBuffer::allocPhysicalBuffer(VkDeviceSize sliceCount) const { - return m_device->allocPhysicalBuffer(m_info, sliceCount, m_memFlags); + DxvkBufferCreateInfo createInfo; + createInfo.size = sliceCount * m_physSliceStride; + + return m_device->allocPhysicalBuffer(createInfo, m_memFlags); } diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 9e892387..e0204bc1 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -129,9 +129,11 @@ namespace dxvk { // TODO maybe align this to a cache line in order // to avoid false sharing once CSMT is implemented - VkDeviceSize m_physBufferId = 0; - VkDeviceSize m_physSliceId = 0; - VkDeviceSize m_physSliceCount = 1; + VkDeviceSize m_physBufferId = 0; + VkDeviceSize m_physSliceId = 0; + VkDeviceSize m_physSliceCount = 1; + VkDeviceSize m_physSliceLength = 0; + VkDeviceSize m_physSliceStride = 0; std::array, 2> m_physBuffers; diff --git a/src/dxvk/dxvk_buffer_res.cpp b/src/dxvk/dxvk_buffer_res.cpp index fd69f103..7d48bc23 100644 --- a/src/dxvk/dxvk_buffer_res.cpp +++ b/src/dxvk/dxvk_buffer_res.cpp @@ -5,19 +5,15 @@ namespace dxvk { DxvkPhysicalBuffer::DxvkPhysicalBuffer( const Rc& vkd, const DxvkBufferCreateInfo& createInfo, - VkDeviceSize sliceCount, DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags) - : m_vkd (vkd), - m_sliceCount (sliceCount), - m_sliceLength (createInfo.size), - m_sliceStride (align(createInfo.size, 256)) { + : m_vkd(vkd) { VkBufferCreateInfo info; info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; info.pNext = nullptr; info.flags = 0; - info.size = m_sliceStride * sliceCount; + info.size = createInfo.size; info.usage = createInfo.usage; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.queueFamilyIndexCount = 0; @@ -43,9 +39,4 @@ namespace dxvk { 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 index 8d3703c4..86264e1e 100644 --- a/src/dxvk/dxvk_buffer_res.h +++ b/src/dxvk/dxvk_buffer_res.h @@ -64,7 +64,6 @@ namespace dxvk { DxvkPhysicalBuffer( const Rc& vkd, const DxvkBufferCreateInfo& createInfo, - VkDeviceSize sliceCount, DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags); @@ -78,14 +77,6 @@ namespace dxvk { return m_handle; } - /** - * \brief Number of slices - * \returns Total slice count - */ - VkDeviceSize sliceCount() const { - return m_sliceCount; - } - /** * \brief Map pointer * @@ -101,14 +92,13 @@ namespace dxvk { /** * \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 + * \param [in] offset Slice offset + * \param [in] length Slice length * \returns The physical slice */ - DxvkPhysicalBufferSlice slice(uint32_t id); + DxvkPhysicalBufferSlice slice( + VkDeviceSize offset, + VkDeviceSize length); private: @@ -116,10 +106,6 @@ namespace dxvk { DxvkMemory m_memory; VkBuffer m_handle; - VkDeviceSize m_sliceCount; - VkDeviceSize m_sliceLength; - VkDeviceSize m_sliceStride; - }; @@ -211,4 +197,10 @@ namespace dxvk { }; + inline DxvkPhysicalBufferSlice DxvkPhysicalBuffer::slice( + VkDeviceSize offset, + VkDeviceSize length) { + return DxvkPhysicalBufferSlice(this, offset, length); + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d1588f8d..c495b590 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1351,7 +1351,7 @@ namespace dxvk { void DxvkContext::updateShaderDescriptors( VkPipelineBindPoint bindPoint, const DxvkBindingState& bindingState, - const Rc& layout) { + const Rc& layout) { std::array writes; const VkDescriptorSet dset = diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index b9098f19..0b0f5aec 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -40,10 +40,9 @@ namespace dxvk { Rc DxvkDevice::allocPhysicalBuffer( const DxvkBufferCreateInfo& createInfo, - VkDeviceSize sliceCount, VkMemoryPropertyFlags memoryType) { return new DxvkPhysicalBuffer(m_vkd, - createInfo, sliceCount, *m_memory, memoryType); + createInfo, *m_memory, memoryType); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 955998ef..88b4e3bd 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -105,13 +105,11 @@ namespace dxvk { * \brief Allocates a physical buffer * * \param [in] createInfo Buffer create info - * \param [in] sliceCount Buffer slice count * \param [in] memoryType Memory property flags * \returns The buffer resource object */ Rc allocPhysicalBuffer( const DxvkBufferCreateInfo& createInfo, - VkDeviceSize sliceCount, VkMemoryPropertyFlags memoryType); /**