yuzu-emu
/
yuzu
Archived
1
0
Fork 0

nvnflinger: mark buffer as acquired when acquired

This commit is contained in:
Liam 2023-12-07 17:45:42 -05:00
parent 462ba1b360
commit fcc85abe27
3 changed files with 37 additions and 3 deletions

View File

@ -90,6 +90,18 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
LOG_DEBUG(Service_Nvnflinger, "acquiring slot={}", slot); LOG_DEBUG(Service_Nvnflinger, "acquiring slot={}", slot);
// If the front buffer is still being tracked, update its slot state
if (core->StillTracking(*front)) {
slots[slot].acquire_called = true;
slots[slot].needs_cleanup_on_release = false;
slots[slot].buffer_state = BufferState::Acquired;
// TODO: for now, avoid resetting the fence, so that when we next return this
// slot to the producer, it will wait for the fence to pass. We should fix this
// by properly waiting for the fence in the BufferItemConsumer.
// slots[slot].fence = Fence::NoFence();
}
// If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to // If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to
// avoid unnecessarily remapping this buffer on the consumer side. // avoid unnecessarily remapping this buffer on the consumer side.
if (out_buffer->acquire_called) { if (out_buffer->acquire_called) {
@ -132,11 +144,28 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
++current; ++current;
} }
if (slots[slot].buffer_state == BufferState::Acquired) {
// TODO: for now, avoid resetting the fence, so that when we next return this
// slot to the producer, it can wait for its own fence to pass. We should fix this
// by properly waiting for the fence in the BufferItemConsumer.
// slots[slot].fence = release_fence;
slots[slot].buffer_state = BufferState::Free; slots[slot].buffer_state = BufferState::Free;
listener = core->connected_producer_listener; listener = core->connected_producer_listener;
LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot); LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot);
} else if (slots[slot].needs_cleanup_on_release) {
LOG_DEBUG(Service_Nvnflinger, "releasing a stale buffer slot {} (state = {})", slot,
slots[slot].buffer_state);
slots[slot].needs_cleanup_on_release = false;
return Status::StaleBufferSlot;
} else {
LOG_ERROR(Service_Nvnflinger,
"attempted to release buffer slot {} but its state was {}", slot,
slots[slot].buffer_state);
return Status::BadValue;
}
core->SignalDequeueCondition(); core->SignalDequeueCondition();
} }

View File

@ -74,6 +74,10 @@ void BufferQueueCore::FreeBufferLocked(s32 slot) {
slots[slot].graphic_buffer.reset(); slots[slot].graphic_buffer.reset();
if (slots[slot].buffer_state == BufferState::Acquired) {
slots[slot].needs_cleanup_on_release = true;
}
slots[slot].buffer_state = BufferState::Free; slots[slot].buffer_state = BufferState::Free;
slots[slot].frame_number = UINT32_MAX; slots[slot].frame_number = UINT32_MAX;
slots[slot].acquire_called = false; slots[slot].acquire_called = false;

View File

@ -31,6 +31,7 @@ struct BufferSlot final {
u64 frame_number{}; u64 frame_number{};
Fence fence; Fence fence;
bool acquire_called{}; bool acquire_called{};
bool needs_cleanup_on_release{};
bool attached_by_consumer{}; bool attached_by_consumer{};
bool is_preallocated{}; bool is_preallocated{};
}; };