summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp24
-rw-r--r--src/video_core/engines/puller.cpp39
2 files changed, 47 insertions, 16 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 3a4646289..950c70dcd 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -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:
diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp
index 8c17639e4..dd9494efa 100644
--- a/src/video_core/engines/puller.cpp
+++ b/src/video_core/engines/puller.cpp
@@ -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: