1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[dxvk] Introduce DxvkBufferAllocation

For now, this is merely a wrapper around the existing buffer slice
struct in order to allow easier refactoring.
This commit is contained in:
Philip Rebohle 2024-09-22 11:27:14 +02:00 committed by Philip Rebohle
parent d0832f8431
commit 5c2f56c9cc
3 changed files with 105 additions and 12 deletions

View File

@ -100,10 +100,10 @@ namespace dxvk {
* to the mapped region..
*/
struct DxvkBufferSliceHandle {
VkBuffer handle;
VkDeviceSize offset;
VkDeviceSize length;
void* mapPtr;
VkBuffer handle = VK_NULL_HANDLE;
VkDeviceSize offset = 0u;
VkDeviceSize length = 0u;
void* mapPtr = nullptr;
bool eq(const DxvkBufferSliceHandle& other) const {
return handle == other.handle
@ -121,6 +121,61 @@ namespace dxvk {
};
/**
* \brief Buffer allocation
*
* References a buffer allocation and stores
* the offset. Used when renaming a buffer.
*/
class DxvkBufferAllocation {
friend class DxvkBuffer;
friend class DxvkContext; /* TODO remove */
public:
DxvkBufferAllocation() = default;
explicit DxvkBufferAllocation(DxvkBufferSliceHandle slice)
: m_slice(slice) { }
DxvkBufferAllocation(const DxvkBufferAllocation&) = default;
DxvkBufferAllocation& operator = (const DxvkBufferAllocation&) = default;
DxvkBufferAllocation(DxvkBufferAllocation&& other)
: m_slice(other.m_slice) {
other.m_slice = DxvkBufferSliceHandle();
}
DxvkBufferAllocation& operator = (DxvkBufferAllocation&& other) {
m_slice = other.m_slice;
other.m_slice = DxvkBufferSliceHandle();
return *this;
}
~DxvkBufferAllocation() = default;
/**
* \brief Retrieves CPU pointer
* \returns Pointer to the mapped buffer slice
*/
void* mapPtr() const {
return m_slice.mapPtr;
}
/**
* \brief Checks whether the slice is valid
* \returns \c true if the slice is valid
*/
explicit operator bool () const {
return m_slice.handle != VK_NULL_HANDLE;
}
private:
DxvkBufferSliceHandle m_slice = { };
};
/**
* \brief Virtual buffer resource
*
@ -247,7 +302,7 @@ namespace dxvk {
DxvkBufferSliceHandle rename(const DxvkBufferSliceHandle& slice) {
return std::exchange(m_physSlice, slice);
}
/**
* \brief Transform feedback vertex stride
*
@ -269,7 +324,7 @@ namespace dxvk {
void setXfbVertexStride(uint32_t stride) {
m_vertexStride = stride;
}
/**
* \brief Allocates new buffer slice
* \returns The new buffer slice
@ -309,7 +364,34 @@ namespace dxvk {
m_freeSlices.pop_back();
return result;
}
/**
* \brief Allocates a new buffer slice
* \returns New buffer slice
*/
DxvkBufferAllocation allocateSlice() {
return DxvkBufferAllocation(allocSlice());
}
/**
* \brief Replaces backing storage
*
* Implicitly invalidates all views created for the buffer.
* \param [in] slice New buffer slice
* \returns Previous buffer allocation for lifetime tracking.
*/
DxvkBufferAllocation assignSlice(DxvkBufferAllocation&& slice) {
return DxvkBufferAllocation(rename(slice.m_slice));
}
/**
* \brief Retrieves current backing storage
* \returns Current buffer allocation
*/
DxvkBufferAllocation getAllocation() const {
return DxvkBufferAllocation(m_physSlice);
}
/**
* \brief Frees a buffer slice
*

View File

@ -1828,10 +1828,10 @@ namespace dxvk {
void DxvkContext::invalidateBuffer(
const Rc<DxvkBuffer>& buffer,
const DxvkBufferSliceHandle& slice) {
DxvkBufferAllocation&& slice) {
// Allocate new backing resource
DxvkBufferSliceHandle prevSlice = buffer->rename(slice);
m_cmd->freeBufferSlice(buffer, prevSlice);
DxvkBufferAllocation prevSlice = buffer->assignSlice(std::move(slice));
m_cmd->freeBufferSlice(buffer, prevSlice.m_slice);
// We also need to update all bindings that the buffer
// may be bound to either directly or through views.
@ -1865,6 +1865,13 @@ namespace dxvk {
}
void DxvkContext::invalidateBuffer(
const Rc<DxvkBuffer>& buffer,
const DxvkBufferSliceHandle& slice) {
invalidateBuffer(buffer, DxvkBufferAllocation(slice));
}
void DxvkContext::resolveImage(
const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage,
@ -6385,10 +6392,10 @@ namespace dxvk {
&& (m_flags.test(DxvkContextFlag::GpXfbActive)))
this->spillRenderPass(true);
this->invalidateBuffer(buffer, buffer->allocSlice());
this->invalidateBuffer(buffer, buffer->allocateSlice());
return true;
}
DxvkGraphicsPipeline* DxvkContext::lookupGraphicsPipeline(
const DxvkGraphicsPipelineShaders& shaders) {

View File

@ -959,8 +959,12 @@ namespace dxvk {
* \warning If the buffer is used by another context,
* invalidating it will result in undefined behaviour.
* \param [in] buffer The buffer to invalidate
* \param [in] slice New buffer slice handle
* \param [in] slice New buffer slice
*/
void invalidateBuffer(
const Rc<DxvkBuffer>& buffer,
DxvkBufferAllocation&& slice);
void invalidateBuffer(
const Rc<DxvkBuffer>& buffer,
const DxvkBufferSliceHandle& slice);