diff options
Diffstat (limited to 'src/video_core/engines')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/engines/puller.cpp | 39 |
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 | |||
| 242 | return; | 242 | return; |
| 243 | case MAXWELL3D_REG_INDEX(fragment_barrier): | 243 | case MAXWELL3D_REG_INDEX(fragment_barrier): |
| 244 | return rasterizer->FragmentBarrier(); | 244 | return rasterizer->FragmentBarrier(); |
| 245 | case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache): | ||
| 246 | rasterizer->InvalidateGPUCache(); | ||
| 247 | return rasterizer->WaitForIdle(); | ||
| 245 | case MAXWELL3D_REG_INDEX(tiled_cache_barrier): | 248 | case MAXWELL3D_REG_INDEX(tiled_cache_barrier): |
| 246 | return rasterizer->TiledCacheBarrier(); | 249 | return rasterizer->TiledCacheBarrier(); |
| 247 | } | 250 | } |
| @@ -472,10 +475,25 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 472 | 475 | ||
| 473 | switch (regs.query.query_get.operation) { | 476 | switch (regs.query.query_get.operation) { |
| 474 | case Regs::QueryOperation::Release: | 477 | case Regs::QueryOperation::Release: |
| 475 | if (regs.query.query_get.fence == 1) { | 478 | if (regs.query.query_get.fence == 1 || regs.query.query_get.short_query != 0) { |
| 476 | rasterizer->SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence); | 479 | const GPUVAddr sequence_address{regs.query.QueryAddress()}; |
| 480 | const u32 payload = regs.query.query_sequence; | ||
| 481 | std::function<void()> operation([this, sequence_address, payload] { | ||
| 482 | memory_manager.Write<u32>(sequence_address, payload); | ||
| 483 | }); | ||
| 484 | rasterizer->SignalFence(std::move(operation)); | ||
| 477 | } else { | 485 | } else { |
| 478 | StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); | 486 | struct LongQueryResult { |
| 487 | u64_le value; | ||
| 488 | u64_le timestamp; | ||
| 489 | }; | ||
| 490 | const GPUVAddr sequence_address{regs.query.QueryAddress()}; | ||
| 491 | const u32 payload = regs.query.query_sequence; | ||
| 492 | std::function<void()> operation([this, sequence_address, payload] { | ||
| 493 | LongQueryResult query_result{payload, system.GPU().GetTicks()}; | ||
| 494 | memory_manager.WriteBlock(sequence_address, &query_result, sizeof(query_result)); | ||
| 495 | }); | ||
| 496 | rasterizer->SignalFence(std::move(operation)); | ||
| 479 | } | 497 | } |
| 480 | break; | 498 | break; |
| 481 | case Regs::QueryOperation::Acquire: | 499 | 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() { | |||
| 79 | u64 timestamp; | 79 | u64 timestamp; |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | Block block{}; | 82 | const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()}; |
| 83 | block.sequence = regs.semaphore_sequence; | 83 | const u32 payload = regs.semaphore_sequence; |
| 84 | // TODO(Kmather73): Generate a real GPU timestamp and write it here instead of | 84 | std::function<void()> operation([this, sequence_address, payload] { |
| 85 | // CoreTiming | 85 | Block block{}; |
| 86 | block.timestamp = gpu.GetTicks(); | 86 | block.sequence = payload; |
| 87 | memory_manager.WriteBlock(regs.semaphore_address.SemaphoreAddress(), &block, sizeof(block)); | 87 | block.timestamp = gpu.GetTicks(); |
| 88 | memory_manager.WriteBlock(sequence_address, &block, sizeof(block)); | ||
| 89 | }); | ||
| 90 | rasterizer->SignalFence(std::move(operation)); | ||
| 88 | } else { | 91 | } else { |
| 89 | do { | 92 | do { |
| 90 | const u32 word{memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress())}; | 93 | const u32 word{memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress())}; |
| @@ -94,6 +97,7 @@ void Puller::ProcessSemaphoreTriggerMethod() { | |||
| 94 | regs.acquire_active = true; | 97 | regs.acquire_active = true; |
| 95 | regs.acquire_mode = false; | 98 | regs.acquire_mode = false; |
| 96 | if (word != regs.acquire_value) { | 99 | if (word != regs.acquire_value) { |
| 100 | rasterizer->ReleaseFences(); | ||
| 97 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | 101 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 98 | continue; | 102 | continue; |
| 99 | } | 103 | } |
| @@ -101,11 +105,13 @@ void Puller::ProcessSemaphoreTriggerMethod() { | |||
| 101 | regs.acquire_active = true; | 105 | regs.acquire_active = true; |
| 102 | regs.acquire_mode = true; | 106 | regs.acquire_mode = true; |
| 103 | if (word < regs.acquire_value) { | 107 | if (word < regs.acquire_value) { |
| 108 | rasterizer->ReleaseFences(); | ||
| 104 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | 109 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 105 | continue; | 110 | continue; |
| 106 | } | 111 | } |
| 107 | } else if (op == GpuSemaphoreOperation::AcquireMask) { | 112 | } else if (op == GpuSemaphoreOperation::AcquireMask) { |
| 108 | if (word & regs.semaphore_sequence == 0) { | 113 | if (word && regs.semaphore_sequence == 0) { |
| 114 | rasterizer->ReleaseFences(); | ||
| 109 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | 115 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 110 | continue; | 116 | continue; |
| 111 | } | 117 | } |
| @@ -117,16 +123,23 @@ void Puller::ProcessSemaphoreTriggerMethod() { | |||
| 117 | } | 123 | } |
| 118 | 124 | ||
| 119 | void Puller::ProcessSemaphoreRelease() { | 125 | void Puller::ProcessSemaphoreRelease() { |
| 120 | rasterizer->SignalSemaphore(regs.semaphore_address.SemaphoreAddress(), regs.semaphore_release); | 126 | const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()}; |
| 127 | const u32 payload = regs.semaphore_release; | ||
| 128 | std::function<void()> operation([this, sequence_address, payload] { | ||
| 129 | memory_manager.Write<u32>(sequence_address, payload); | ||
| 130 | }); | ||
| 131 | rasterizer->SignalFence(std::move(operation)); | ||
| 121 | } | 132 | } |
| 122 | 133 | ||
| 123 | void Puller::ProcessSemaphoreAcquire() { | 134 | void Puller::ProcessSemaphoreAcquire() { |
| 124 | const u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress()); | 135 | u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress()); |
| 125 | const auto value = regs.semaphore_acquire; | 136 | const auto value = regs.semaphore_acquire; |
| 126 | std::this_thread::sleep_for(std::chrono::milliseconds(5)); | 137 | while (word != value) { |
| 127 | if (word != value) { | ||
| 128 | regs.acquire_active = true; | 138 | regs.acquire_active = true; |
| 129 | regs.acquire_value = value; | 139 | regs.acquire_value = value; |
| 140 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||
| 141 | rasterizer->ReleaseFences(); | ||
| 142 | word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress()); | ||
| 130 | // TODO(kemathe73) figure out how to do the acquire_timeout | 143 | // TODO(kemathe73) figure out how to do the acquire_timeout |
| 131 | regs.acquire_mode = false; | 144 | regs.acquire_mode = false; |
| 132 | regs.acquire_source = false; | 145 | regs.acquire_source = false; |
| @@ -147,9 +160,9 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { | |||
| 147 | case BufferMethods::SemaphoreAddressHigh: | 160 | case BufferMethods::SemaphoreAddressHigh: |
| 148 | case BufferMethods::SemaphoreAddressLow: | 161 | case BufferMethods::SemaphoreAddressLow: |
| 149 | case BufferMethods::SemaphoreSequencePayload: | 162 | case BufferMethods::SemaphoreSequencePayload: |
| 150 | case BufferMethods::WrcacheFlush: | ||
| 151 | case BufferMethods::SyncpointPayload: | 163 | case BufferMethods::SyncpointPayload: |
| 152 | break; | 164 | break; |
| 165 | case BufferMethods::WrcacheFlush: | ||
| 153 | case BufferMethods::RefCnt: | 166 | case BufferMethods::RefCnt: |
| 154 | rasterizer->SignalReference(); | 167 | rasterizer->SignalReference(); |
| 155 | break; | 168 | break; |
| @@ -173,7 +186,7 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { | |||
| 173 | } | 186 | } |
| 174 | case BufferMethods::MemOpB: { | 187 | case BufferMethods::MemOpB: { |
| 175 | // Implement this better. | 188 | // Implement this better. |
| 176 | rasterizer->SyncGuestHost(); | 189 | rasterizer->InvalidateGPUCache(); |
| 177 | break; | 190 | break; |
| 178 | } | 191 | } |
| 179 | case BufferMethods::MemOpC: | 192 | case BufferMethods::MemOpC: |