From 9992ba1a79a2302e7ce2499c1b157ad552bd395d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Aug 2018 15:14:26 +0200 Subject: [PATCH] [d3d11] Add more general counter buffer allocator We're going to need it for more than just UAV counters soon. --- src/d3d11/d3d11_counter_buffer.cpp | 52 ++++++++++++++++++++++++ src/d3d11/d3d11_counter_buffer.h | 63 ++++++++++++++++++++++++++++++ src/d3d11/meson.build | 1 + 3 files changed, 116 insertions(+) create mode 100644 src/d3d11/d3d11_counter_buffer.cpp create mode 100644 src/d3d11/d3d11_counter_buffer.h diff --git a/src/d3d11/d3d11_counter_buffer.cpp b/src/d3d11/d3d11_counter_buffer.cpp new file mode 100644 index 000000000..84a359c1a --- /dev/null +++ b/src/d3d11/d3d11_counter_buffer.cpp @@ -0,0 +1,52 @@ +#include "d3d11_counter_buffer.h" +#include "d3d11_device.h" + +namespace dxvk { + + D3D11CounterBuffer::D3D11CounterBuffer( + const Rc& Device, + const DxvkBufferCreateInfo& BufferInfo, + VkDeviceSize SliceLength) + : m_device (Device), + m_bufferInfo (BufferInfo), + m_sliceLength (SliceLength) { + + } + + + D3D11CounterBuffer::~D3D11CounterBuffer() { + + } + + + DxvkBufferSlice D3D11CounterBuffer::AllocSlice() { + std::lock_guard lock(m_mutex); + + if (m_freeSlices.size() == 0) + CreateBuffer(); + + DxvkBufferSlice slice = m_freeSlices.back(); + m_freeSlices.pop_back(); + return slice; + } + + + void D3D11CounterBuffer::FreeSlice(const DxvkBufferSlice& Slice) { + std::lock_guard lock(m_mutex); + m_freeSlices.push_back(Slice); + } + + + void D3D11CounterBuffer::CreateBuffer() { + Rc buffer = m_device->createBuffer( + m_bufferInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + VkDeviceSize sliceCount = m_bufferInfo.size / m_sliceLength; + + for (uint32_t i = 0; i < sliceCount; i++) { + m_freeSlices.push_back(DxvkBufferSlice( + buffer, m_sliceLength * i, m_sliceLength)); + } + } + +} \ No newline at end of file diff --git a/src/d3d11/d3d11_counter_buffer.h b/src/d3d11/d3d11_counter_buffer.h new file mode 100644 index 000000000..d22df1dfe --- /dev/null +++ b/src/d3d11/d3d11_counter_buffer.h @@ -0,0 +1,63 @@ +#pragma once + +#include "d3d11_include.h" + +#include "../dxvk/dxvk_buffer.h" +#include "../dxvk/dxvk_device.h" + +namespace dxvk { + + class D3D11Device; + + /** + * \brief D3D11 UAV counter slice allocator + * + * Thread safe allocator for buffer slices of + * the same size, which are typically used to + * store counters (such as UAV counters). + */ + class D3D11CounterBuffer : public RcObject { + + public: + + D3D11CounterBuffer( + const Rc& Device, + const DxvkBufferCreateInfo& BufferInfo, + VkDeviceSize SliceLength); + + ~D3D11CounterBuffer(); + + /** + * \brief Allocates a counter slice + * + * Picks a slice from the free list or + * creates a new buffer if necessary. + * \returns The counter slice + */ + DxvkBufferSlice AllocSlice(); + + /** + * \brief Frees a counter slice + * + * Adds the given slice back to the + * free list so that it can be reused. + * \param [in] Slice the slice to free + */ + void FreeSlice( + const DxvkBufferSlice& Slice); + + private: + + Rc m_device; + + DxvkBufferCreateInfo m_bufferInfo; + VkDeviceSize m_sliceLength; + + std::mutex m_mutex; + std::vector m_freeSlices; + + void CreateBuffer(); + + }; + +} \ No newline at end of file diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 4ce774444..f70815b00 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -23,6 +23,7 @@ d3d11_src = [ 'd3d11_context.cpp', 'd3d11_context_def.cpp', 'd3d11_context_imm.cpp', + 'd3d11_counter_buffer.cpp', 'd3d11_depth_stencil.cpp', 'd3d11_device.cpp', 'd3d11_enums.cpp',