mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-17 19:17:55 +03:00
Add move-assignment semantics to ActiveCommandBuffer
/MegaBuffer
We need move-assignment semantics to viably utilize these objects as class members, they cannot be replaced without move-assign (or copy-assign but that is undesirable here). This commit fixes that by introducing a move assignment operator to them while making the `slot` a pointer which has the necessary nullability semantics.
This commit is contained in:
parent
8991ccac65
commit
5129d2ae78
@ -91,18 +91,28 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
BufferManager::MegaBufferSlot::MegaBufferSlot(GPU &gpu) : backing(gpu.memory.AllocateBuffer(Size)) {}
|
BufferManager::MegaBufferSlot::MegaBufferSlot(GPU &gpu) : backing(gpu.memory.AllocateBuffer(Size)) {}
|
||||||
|
|
||||||
MegaBuffer::MegaBuffer(BufferManager::MegaBufferSlot &slot) : slot{slot}, freeRegion{slot.backing.subspan(PAGE_SIZE)} {}
|
MegaBuffer::MegaBuffer(BufferManager::MegaBufferSlot &slot) : slot{&slot}, freeRegion{slot.backing.subspan(PAGE_SIZE)} {}
|
||||||
|
|
||||||
MegaBuffer::~MegaBuffer() {
|
MegaBuffer::~MegaBuffer() {
|
||||||
slot.active.clear(std::memory_order_release);
|
if (slot)
|
||||||
|
slot->active.clear(std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
MegaBuffer &MegaBuffer::operator=(MegaBuffer &&other) {
|
||||||
|
if (slot)
|
||||||
|
slot->active.clear(std::memory_order_release);
|
||||||
|
slot = other.slot;
|
||||||
|
freeRegion = other.freeRegion;
|
||||||
|
other.slot = nullptr;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MegaBuffer::Reset() {
|
void MegaBuffer::Reset() {
|
||||||
freeRegion = slot.backing.subspan(PAGE_SIZE);
|
freeRegion = slot->backing.subspan(PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Buffer MegaBuffer::GetBacking() const {
|
vk::Buffer MegaBuffer::GetBacking() const {
|
||||||
return slot.backing.vkBuffer;
|
return slot->backing.vkBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::DeviceSize MegaBuffer::Push(span<u8> data, bool pageAlign) {
|
vk::DeviceSize MegaBuffer::Push(span<u8> data, bool pageAlign) {
|
||||||
@ -111,8 +121,8 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
if (pageAlign) {
|
if (pageAlign) {
|
||||||
// If page aligned data was requested then align the free
|
// If page aligned data was requested then align the free
|
||||||
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - slot.backing.data()), PAGE_SIZE)};
|
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - slot->backing.data()), PAGE_SIZE)};
|
||||||
freeRegion = slot.backing.subspan(alignedFreeBase);
|
freeRegion = slot->backing.subspan(alignedFreeBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate space for data from the free region
|
// Allocate space for data from the free region
|
||||||
@ -121,11 +131,11 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
// Move the free region along
|
// Move the free region along
|
||||||
freeRegion = freeRegion.subspan(data.size());
|
freeRegion = freeRegion.subspan(data.size());
|
||||||
return static_cast<vk::DeviceSize>(resultSpan.data() - slot.backing.data());
|
return static_cast<vk::DeviceSize>(resultSpan.data() - slot->backing.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
MegaBuffer BufferManager::AcquireMegaBuffer(const std::shared_ptr<FenceCycle> &cycle) {
|
MegaBuffer BufferManager::AcquireMegaBuffer(const std::shared_ptr<FenceCycle> &cycle) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{mutex};
|
||||||
|
|
||||||
for (auto &slot : megaBuffers) {
|
for (auto &slot : megaBuffers) {
|
||||||
if (!slot.active.test_and_set(std::memory_order_acq_rel)) {
|
if (!slot.active.test_and_set(std::memory_order_acq_rel)) {
|
||||||
|
@ -60,7 +60,7 @@ namespace skyline::gpu {
|
|||||||
*/
|
*/
|
||||||
class MegaBuffer {
|
class MegaBuffer {
|
||||||
private:
|
private:
|
||||||
BufferManager::MegaBufferSlot &slot;
|
BufferManager::MegaBufferSlot *slot;
|
||||||
span<u8> freeRegion; //!< The unallocated space in the megabuffer
|
span<u8> freeRegion; //!< The unallocated space in the megabuffer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -68,6 +68,8 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
~MegaBuffer();
|
~MegaBuffer();
|
||||||
|
|
||||||
|
MegaBuffer &operator=(MegaBuffer &&other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resets the free region of the megabuffer to its initial state, data is left intact but may be overwritten
|
* @brief Resets the free region of the megabuffer to its initial state, data is left intact but may be overwritten
|
||||||
*/
|
*/
|
||||||
|
@ -46,29 +46,38 @@ namespace skyline::gpu {
|
|||||||
*/
|
*/
|
||||||
class ActiveCommandBuffer {
|
class ActiveCommandBuffer {
|
||||||
private:
|
private:
|
||||||
CommandBufferSlot &slot;
|
CommandBufferSlot *slot;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr ActiveCommandBuffer(CommandBufferSlot &slot) : slot(slot) {}
|
constexpr ActiveCommandBuffer(CommandBufferSlot &slot) : slot{&slot} {}
|
||||||
|
|
||||||
|
constexpr ActiveCommandBuffer &operator=(ActiveCommandBuffer &&other) {
|
||||||
|
if (slot)
|
||||||
|
slot->active.clear(std::memory_order_release);
|
||||||
|
slot = other.slot;
|
||||||
|
other.slot = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
~ActiveCommandBuffer() {
|
~ActiveCommandBuffer() {
|
||||||
slot.active.clear(std::memory_order_release);
|
if (slot)
|
||||||
|
slot->active.clear(std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Fence GetFence() {
|
vk::Fence GetFence() {
|
||||||
return *slot.fence;
|
return *slot->fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FenceCycle> GetFenceCycle() {
|
std::shared_ptr<FenceCycle> GetFenceCycle() {
|
||||||
return slot.cycle;
|
return slot->cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::raii::CommandBuffer &operator*() {
|
vk::raii::CommandBuffer &operator*() {
|
||||||
return slot.commandBuffer;
|
return slot->commandBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::raii::CommandBuffer *operator->() {
|
vk::raii::CommandBuffer *operator->() {
|
||||||
return &slot.commandBuffer;
|
return &slot->commandBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,10 +85,10 @@ namespace skyline::gpu {
|
|||||||
* @note This should be used when a single allocated command buffer is used for all submissions from a component
|
* @note This should be used when a single allocated command buffer is used for all submissions from a component
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<FenceCycle> Reset() {
|
std::shared_ptr<FenceCycle> Reset() {
|
||||||
slot.cycle->Wait();
|
slot->cycle->Wait();
|
||||||
slot.cycle = std::make_shared<FenceCycle>(slot.device, *slot.fence);
|
slot->cycle = std::make_shared<FenceCycle>(slot->device, *slot->fence);
|
||||||
slot.commandBuffer.reset();
|
slot->commandBuffer.reset();
|
||||||
return slot.cycle;
|
return slot->cycle;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user