NVDRV: Further improvements.

This commit is contained in:
Fernando Sahmkow 2022-02-07 07:52:04 +01:00
parent b59ca4df0c
commit a9ca39f859
16 changed files with 280 additions and 161 deletions

View file

@ -453,18 +453,10 @@ void Maxwell3D::ProcessFirmwareCall4() {
}
void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
struct LongQueryResult {
u64_le value;
u64_le timestamp;
};
static_assert(sizeof(LongQueryResult) == 16, "LongQueryResult has wrong size");
const GPUVAddr sequence_address{regs.query.QueryAddress()};
if (long_query) {
// Write the 128-bit result structure in long mode. Note: We emulate an infinitely fast
// GPU, this command may actually take a while to complete in real hardware due to GPU
// wait queues.
LongQueryResult query_result{payload, system.GPU().GetTicks()};
memory_manager.WriteBlock(sequence_address, &query_result, sizeof(query_result));
memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
memory_manager.Write<u64>(sequence_address, payload);
} else {
memory_manager.Write<u32>(sequence_address, static_cast<u32>(payload));
}
@ -493,10 +485,10 @@ void Maxwell3D::ProcessQueryGet() {
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));
memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
memory_manager.Write<u64>(sequence_address, payload);
});
rasterizer->SignalFence(std::move(operation));
rasterizer->SyncOperation(std::move(operation));
}
break;
case Regs::QueryOperation::Acquire:

View file

@ -274,16 +274,24 @@ void MaxwellDMA::FastCopyBlockLinearToPitch() {
void MaxwellDMA::ReleaseSemaphore() {
const auto type = regs.launch_dma.semaphore_type;
const GPUVAddr address = regs.semaphore.address;
const u32 payload = regs.semaphore.payload;
switch (type) {
case LaunchDMA::SemaphoreType::NONE:
break;
case LaunchDMA::SemaphoreType::RELEASE_ONE_WORD_SEMAPHORE:
memory_manager.Write<u32>(address, regs.semaphore.payload);
case LaunchDMA::SemaphoreType::RELEASE_ONE_WORD_SEMAPHORE: {
std::function<void()> operation(
[this, address, payload] { memory_manager.Write<u32>(address, payload); });
rasterizer->SignalFence(std::move(operation));
break;
case LaunchDMA::SemaphoreType::RELEASE_FOUR_WORD_SEMAPHORE:
memory_manager.Write<u64>(address, static_cast<u64>(regs.semaphore.payload));
memory_manager.Write<u64>(address + 8, system.GPU().GetTicks());
}
case LaunchDMA::SemaphoreType::RELEASE_FOUR_WORD_SEMAPHORE: {
std::function<void()> operation([this, address, payload] {
memory_manager.Write<u64>(address + sizeof(u64), system.GPU().GetTicks());
memory_manager.Write<u64>(address, payload);
});
rasterizer->SignalFence(std::move(operation));
break;
}
default:
ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value()));
}

View file

@ -59,6 +59,7 @@ void Puller::ProcessFenceActionMethod() {
case Puller::FenceOperation::Acquire:
// UNIMPLEMENTED_MSG("Channel Scheduling pending.");
// WaitFence(regs.fence_action.syncpoint_id, regs.fence_value);
rasterizer->ReleaseFences();
break;
case Puller::FenceOperation::Increment:
rasterizer->SignalSyncPoint(regs.fence_action.syncpoint_id);
@ -73,19 +74,11 @@ void Puller::ProcessSemaphoreTriggerMethod() {
const auto op =
static_cast<GpuSemaphoreOperation>(regs.semaphore_trigger & semaphoreOperationMask);
if (op == GpuSemaphoreOperation::WriteLong) {
struct Block {
u32 sequence;
u32 zeros = 0;
u64 timestamp;
};
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));
memory_manager.Write<u64>(sequence_address + sizeof(u64), gpu.GetTicks());
memory_manager.Write<u64>(sequence_address, payload);
});
rasterizer->SignalFence(std::move(operation));
} else {
@ -98,7 +91,6 @@ void Puller::ProcessSemaphoreTriggerMethod() {
regs.acquire_mode = false;
if (word != regs.acquire_value) {
rasterizer->ReleaseFences();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
} else if (op == GpuSemaphoreOperation::AcquireGequal) {
@ -106,13 +98,11 @@ void Puller::ProcessSemaphoreTriggerMethod() {
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) {
rasterizer->ReleaseFences();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
} else {
@ -128,7 +118,7 @@ void Puller::ProcessSemaphoreRelease() {
std::function<void()> operation([this, sequence_address, payload] {
memory_manager.Write<u32>(sequence_address, payload);
});
rasterizer->SignalFence(std::move(operation));
rasterizer->SyncOperation(std::move(operation));
}
void Puller::ProcessSemaphoreAcquire() {