early-access version 3528
This commit is contained in:
parent
a6e49bc8f4
commit
b31b4e3caa
6 changed files with 22 additions and 41 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3527.
|
This is the source code for early-access 3528.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -92,14 +92,6 @@ 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;
|
|
||||||
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) {
|
||||||
|
@ -142,29 +134,13 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
|
||||||
++current;
|
++current;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slots[slot].buffer_state == BufferState::Acquired) {
|
slots[slot].buffer_state = BufferState::Free;
|
||||||
slots[slot].fence = release_fence;
|
|
||||||
slots[slot].buffer_state = BufferState::Free;
|
|
||||||
|
|
||||||
nvmap.FreeHandle(slots[slot].graphic_buffer->BufferId(), true);
|
nvmap.FreeHandle(slots[slot].graphic_buffer->BufferId(), true);
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,10 +86,6 @@ 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;
|
||||||
|
|
|
@ -31,7 +31,6 @@ 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{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,8 +46,11 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) {
|
||||||
vsync_signal.wait(false);
|
vsync_signal.wait(false);
|
||||||
vsync_signal.store(false);
|
vsync_signal.store(false);
|
||||||
|
|
||||||
const auto lock_guard = Lock();
|
guard->lock();
|
||||||
|
|
||||||
Compose();
|
Compose();
|
||||||
|
|
||||||
|
guard->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +70,8 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
|
||||||
[this](std::uintptr_t, s64 time,
|
[this](std::uintptr_t, s64 time,
|
||||||
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
|
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
|
||||||
vsync_signal.store(true);
|
vsync_signal.store(true);
|
||||||
const auto lock_guard = Lock();
|
{ const auto lock_guard = Lock(); }
|
||||||
vsync_signal.notify_one();
|
vsync_signal.notify_one();
|
||||||
|
|
||||||
return std::chrono::nanoseconds(GetNextTicks());
|
return std::chrono::nanoseconds(GetNextTicks());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -266,9 +268,8 @@ void Nvnflinger::Compose() {
|
||||||
SCOPE_EXIT({ display.SignalVSyncEvent(); });
|
SCOPE_EXIT({ display.SignalVSyncEvent(); });
|
||||||
|
|
||||||
// Don't do anything for displays without layers.
|
// Don't do anything for displays without layers.
|
||||||
if (!display.HasLayers()) {
|
if (!display.HasLayers())
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(Subv): Support more than 1 layer.
|
// TODO(Subv): Support more than 1 layer.
|
||||||
VI::Layer& layer = display.GetLayer(0);
|
VI::Layer& layer = display.GetLayer(0);
|
||||||
|
|
|
@ -137,7 +137,7 @@ public:
|
||||||
query = Register(type, *cpu_addr, host_ptr, timestamp.has_value());
|
query = Register(type, *cpu_addr, host_ptr, timestamp.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = query->BindCounter(Stream(type).Current());
|
auto result = query->BindCounter(Stream(type).Current(), timestamp);
|
||||||
if (result) {
|
if (result) {
|
||||||
auto async_job_id = query->GetAsyncJob();
|
auto async_job_id = query->GetAsyncJob();
|
||||||
auto& async_job = slot_async_jobs[async_job_id];
|
auto& async_job = slot_async_jobs[async_job_id];
|
||||||
|
@ -411,11 +411,19 @@ public:
|
||||||
// When counter is nullptr it means that it's just been reset. We are supposed to write a
|
// When counter is nullptr it means that it's just been reset. We are supposed to write a
|
||||||
// zero in these cases.
|
// zero in these cases.
|
||||||
const u64 value = counter ? counter->Query(async) : 0;
|
const u64 value = counter ? counter->Query(async) : 0;
|
||||||
|
if (async) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
std::memcpy(host_ptr, &value, sizeof(u64));
|
||||||
|
|
||||||
|
if (timestamp) {
|
||||||
|
std::memcpy(host_ptr + TIMESTAMP_OFFSET, &*timestamp, sizeof(u64));
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Binds a counter to this query.
|
/// Binds a counter to this query.
|
||||||
std::optional<u64> BindCounter(std::shared_ptr<HostCounter> counter_) {
|
std::optional<u64> BindCounter(std::shared_ptr<HostCounter> counter_, std::optional<u64> timestamp_) {
|
||||||
std::optional<u64> result{};
|
std::optional<u64> result{};
|
||||||
if (counter) {
|
if (counter) {
|
||||||
// If there's an old counter set it means the query is being rewritten by the game.
|
// If there's an old counter set it means the query is being rewritten by the game.
|
||||||
|
@ -423,6 +431,7 @@ public:
|
||||||
result = std::make_optional(Flush());
|
result = std::make_optional(Flush());
|
||||||
}
|
}
|
||||||
counter = std::move(counter_);
|
counter = std::move(counter_);
|
||||||
|
timestamp = timestamp_;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue