mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[dxvk] Refactored physical buffer
Class is now much more generic, which should make things easier for the upcomping deferred context implementation
This commit is contained in:
parent
7e5a511fa0
commit
d74be35e8c
@ -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<DxvkPhysicalBuffer> 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Rc<DxvkPhysicalBuffer>, 2> m_physBuffers;
|
||||
|
||||
|
@ -5,19 +5,15 @@ namespace dxvk {
|
||||
DxvkPhysicalBuffer::DxvkPhysicalBuffer(
|
||||
const Rc<vk::DeviceFn>& 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);
|
||||
}
|
||||
|
||||
}
|
@ -64,7 +64,6 @@ namespace dxvk {
|
||||
DxvkPhysicalBuffer(
|
||||
const Rc<vk::DeviceFn>& 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);
|
||||
}
|
||||
|
||||
}
|
@ -1351,7 +1351,7 @@ namespace dxvk {
|
||||
void DxvkContext::updateShaderDescriptors(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
const DxvkBindingState& bindingState,
|
||||
const Rc<DxvkPipelineLayout>& layout) {
|
||||
const Rc<DxvkPipelineLayout>& layout) {
|
||||
std::array<VkWriteDescriptorSet, MaxNumResourceSlots> writes;
|
||||
|
||||
const VkDescriptorSet dset =
|
||||
|
@ -40,10 +40,9 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkPhysicalBuffer> DxvkDevice::allocPhysicalBuffer(
|
||||
const DxvkBufferCreateInfo& createInfo,
|
||||
VkDeviceSize sliceCount,
|
||||
VkMemoryPropertyFlags memoryType) {
|
||||
return new DxvkPhysicalBuffer(m_vkd,
|
||||
createInfo, sliceCount, *m_memory, memoryType);
|
||||
createInfo, *m_memory, memoryType);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<DxvkPhysicalBuffer> allocPhysicalBuffer(
|
||||
const DxvkBufferCreateInfo& createInfo,
|
||||
VkDeviceSize sliceCount,
|
||||
VkMemoryPropertyFlags memoryType);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user