VideoCore: Refactor fencing system.

This commit is contained in:
Fernando Sahmkow 2022-02-06 01:16:11 +01:00
parent 4d60410dd9
commit bc8b3d225e
20 changed files with 154 additions and 167 deletions

View file

@ -242,6 +242,9 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
return;
case MAXWELL3D_REG_INDEX(fragment_barrier):
return rasterizer->FragmentBarrier();
case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache):
rasterizer->InvalidateGPUCache();
return rasterizer->WaitForIdle();
case MAXWELL3D_REG_INDEX(tiled_cache_barrier):
return rasterizer->TiledCacheBarrier();
}
@ -472,10 +475,25 @@ void Maxwell3D::ProcessQueryGet() {
switch (regs.query.query_get.operation) {
case Regs::QueryOperation::Release:
if (regs.query.query_get.fence == 1) {
rasterizer->SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence);
if (regs.query.query_get.fence == 1 || regs.query.query_get.short_query != 0) {
const GPUVAddr sequence_address{regs.query.QueryAddress()};
const u32 payload = regs.query.query_sequence;
std::function<void()> operation([this, sequence_address, payload] {
memory_manager.Write<u32>(sequence_address, payload);
});
rasterizer->SignalFence(std::move(operation));
} else {
StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0);
struct LongQueryResult {
u64_le value;
u64_le timestamp;
};
const GPUVAddr sequence_address{regs.query.QueryAddress()};
const u32 payload = regs.query.query_sequence;
std::function<void()> operation([this, sequence_address, payload] {
LongQueryResult query_result{payload, system.GPU().GetTicks()};
memory_manager.WriteBlock(sequence_address, &query_result, sizeof(query_result));
});
rasterizer->SignalFence(std::move(operation));
}
break;
case Regs::QueryOperation::Acquire:

View file

@ -79,12 +79,15 @@ void Puller::ProcessSemaphoreTriggerMethod() {
u64 timestamp;
};
Block block{};
block.sequence = regs.semaphore_sequence;
// TODO(Kmather73): Generate a real GPU timestamp and write it here instead of
// CoreTiming
block.timestamp = gpu.GetTicks();
memory_manager.WriteBlock(regs.semaphore_address.SemaphoreAddress(), &block, sizeof(block));
const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()};
const u32 payload = regs.semaphore_sequence;
std::function<void()> operation([this, sequence_address, payload] {
Block block{};
block.sequence = payload;
block.timestamp = gpu.GetTicks();
memory_manager.WriteBlock(sequence_address, &block, sizeof(block));
});
rasterizer->SignalFence(std::move(operation));
} else {
do {
const u32 word{memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress())};
@ -94,6 +97,7 @@ void Puller::ProcessSemaphoreTriggerMethod() {
regs.acquire_active = true;
regs.acquire_mode = false;
if (word != regs.acquire_value) {
rasterizer->ReleaseFences();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
@ -101,11 +105,13 @@ void Puller::ProcessSemaphoreTriggerMethod() {
regs.acquire_active = true;
regs.acquire_mode = true;
if (word < regs.acquire_value) {
rasterizer->ReleaseFences();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
} else if (op == GpuSemaphoreOperation::AcquireMask) {
if (word & regs.semaphore_sequence == 0) {
if (word && regs.semaphore_sequence == 0) {
rasterizer->ReleaseFences();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
@ -117,16 +123,23 @@ void Puller::ProcessSemaphoreTriggerMethod() {
}
void Puller::ProcessSemaphoreRelease() {
rasterizer->SignalSemaphore(regs.semaphore_address.SemaphoreAddress(), regs.semaphore_release);
const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()};
const u32 payload = regs.semaphore_release;
std::function<void()> operation([this, sequence_address, payload] {
memory_manager.Write<u32>(sequence_address, payload);
});
rasterizer->SignalFence(std::move(operation));
}
void Puller::ProcessSemaphoreAcquire() {
const u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress());
u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress());
const auto value = regs.semaphore_acquire;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
if (word != value) {
while (word != value) {
regs.acquire_active = true;
regs.acquire_value = value;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
rasterizer->ReleaseFences();
word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress());
// TODO(kemathe73) figure out how to do the acquire_timeout
regs.acquire_mode = false;
regs.acquire_source = false;
@ -147,9 +160,9 @@ void Puller::CallPullerMethod(const MethodCall& method_call) {
case BufferMethods::SemaphoreAddressHigh:
case BufferMethods::SemaphoreAddressLow:
case BufferMethods::SemaphoreSequencePayload:
case BufferMethods::WrcacheFlush:
case BufferMethods::SyncpointPayload:
break;
case BufferMethods::WrcacheFlush:
case BufferMethods::RefCnt:
rasterizer->SignalReference();
break;
@ -173,7 +186,7 @@ void Puller::CallPullerMethod(const MethodCall& method_call) {
}
case BufferMethods::MemOpB: {
// Implement this better.
rasterizer->SyncGuestHost();
rasterizer->InvalidateGPUCache();
break;
}
case BufferMethods::MemOpC: