diff options
Diffstat (limited to 'src/video_core/engines/puller.cpp')
| -rw-r--r-- | src/video_core/engines/puller.cpp | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp index 3866c8746..8c17639e4 100644 --- a/src/video_core/engines/puller.cpp +++ b/src/video_core/engines/puller.cpp | |||
| @@ -68,11 +68,6 @@ void Puller::ProcessFenceActionMethod() { | |||
| 68 | } | 68 | } |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | void Puller::ProcessWaitForInterruptMethod() { | ||
| 72 | // TODO(bunnei) ImplementMe | ||
| 73 | LOG_WARNING(HW_GPU, "(STUBBED) called"); | ||
| 74 | } | ||
| 75 | |||
| 76 | void Puller::ProcessSemaphoreTriggerMethod() { | 71 | void Puller::ProcessSemaphoreTriggerMethod() { |
| 77 | const auto semaphoreOperationMask = 0xF; | 72 | const auto semaphoreOperationMask = 0xF; |
| 78 | const auto op = | 73 | const auto op = |
| @@ -91,29 +86,33 @@ void Puller::ProcessSemaphoreTriggerMethod() { | |||
| 91 | block.timestamp = gpu.GetTicks(); | 86 | block.timestamp = gpu.GetTicks(); |
| 92 | memory_manager.WriteBlock(regs.semaphore_address.SemaphoreAddress(), &block, sizeof(block)); | 87 | memory_manager.WriteBlock(regs.semaphore_address.SemaphoreAddress(), &block, sizeof(block)); |
| 93 | } else { | 88 | } else { |
| 94 | const u32 word{memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress())}; | 89 | do { |
| 95 | if ((op == GpuSemaphoreOperation::AcquireEqual && word == regs.semaphore_sequence) || | 90 | const u32 word{memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress())}; |
| 96 | (op == GpuSemaphoreOperation::AcquireGequal && | ||
| 97 | static_cast<s32>(word - regs.semaphore_sequence) > 0) || | ||
| 98 | (op == GpuSemaphoreOperation::AcquireMask && (word & regs.semaphore_sequence))) { | ||
| 99 | // Nothing to do in this case | ||
| 100 | } else { | ||
| 101 | regs.acquire_source = true; | 91 | regs.acquire_source = true; |
| 102 | regs.acquire_value = regs.semaphore_sequence; | 92 | regs.acquire_value = regs.semaphore_sequence; |
| 103 | if (op == GpuSemaphoreOperation::AcquireEqual) { | 93 | if (op == GpuSemaphoreOperation::AcquireEqual) { |
| 104 | regs.acquire_active = true; | 94 | regs.acquire_active = true; |
| 105 | regs.acquire_mode = false; | 95 | regs.acquire_mode = false; |
| 96 | if (word != regs.acquire_value) { | ||
| 97 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||
| 98 | continue; | ||
| 99 | } | ||
| 106 | } else if (op == GpuSemaphoreOperation::AcquireGequal) { | 100 | } else if (op == GpuSemaphoreOperation::AcquireGequal) { |
| 107 | regs.acquire_active = true; | 101 | regs.acquire_active = true; |
| 108 | regs.acquire_mode = true; | 102 | regs.acquire_mode = true; |
| 103 | if (word < regs.acquire_value) { | ||
| 104 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||
| 105 | continue; | ||
| 106 | } | ||
| 109 | } else if (op == GpuSemaphoreOperation::AcquireMask) { | 107 | } else if (op == GpuSemaphoreOperation::AcquireMask) { |
| 110 | // TODO(kemathe) The acquire mask operation waits for a value that, ANDed with | 108 | if (word & regs.semaphore_sequence == 0) { |
| 111 | // semaphore_sequence, gives a non-0 result | 109 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 112 | LOG_ERROR(HW_GPU, "Invalid semaphore operation AcquireMask not implemented"); | 110 | continue; |
| 111 | } | ||
| 113 | } else { | 112 | } else { |
| 114 | LOG_ERROR(HW_GPU, "Invalid semaphore operation"); | 113 | LOG_ERROR(HW_GPU, "Invalid semaphore operation"); |
| 115 | } | 114 | } |
| 116 | } | 115 | } while (false); |
| 117 | } | 116 | } |
| 118 | } | 117 | } |
| 119 | 118 | ||
| @@ -124,6 +123,7 @@ void Puller::ProcessSemaphoreRelease() { | |||
| 124 | void Puller::ProcessSemaphoreAcquire() { | 123 | void Puller::ProcessSemaphoreAcquire() { |
| 125 | const u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress()); | 124 | const u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress()); |
| 126 | const auto value = regs.semaphore_acquire; | 125 | const auto value = regs.semaphore_acquire; |
| 126 | std::this_thread::sleep_for(std::chrono::milliseconds(5)); | ||
| 127 | if (word != value) { | 127 | if (word != value) { |
| 128 | regs.acquire_active = true; | 128 | regs.acquire_active = true; |
| 129 | regs.acquire_value = value; | 129 | regs.acquire_value = value; |
| @@ -146,32 +146,39 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { | |||
| 146 | case BufferMethods::Nop: | 146 | case BufferMethods::Nop: |
| 147 | case BufferMethods::SemaphoreAddressHigh: | 147 | case BufferMethods::SemaphoreAddressHigh: |
| 148 | case BufferMethods::SemaphoreAddressLow: | 148 | case BufferMethods::SemaphoreAddressLow: |
| 149 | case BufferMethods::SemaphoreSequence: | 149 | case BufferMethods::SemaphoreSequencePayload: |
| 150 | case BufferMethods::UnkCacheFlush: | ||
| 151 | case BufferMethods::WrcacheFlush: | 150 | case BufferMethods::WrcacheFlush: |
| 152 | case BufferMethods::FenceValue: | 151 | case BufferMethods::SyncpointPayload: |
| 153 | break; | 152 | break; |
| 154 | case BufferMethods::RefCnt: | 153 | case BufferMethods::RefCnt: |
| 155 | rasterizer->SignalReference(); | 154 | rasterizer->SignalReference(); |
| 156 | break; | 155 | break; |
| 157 | case BufferMethods::FenceAction: | 156 | case BufferMethods::SyncpointOperation: |
| 158 | ProcessFenceActionMethod(); | 157 | ProcessFenceActionMethod(); |
| 159 | break; | 158 | break; |
| 160 | case BufferMethods::WaitForInterrupt: | 159 | case BufferMethods::WaitForIdle: |
| 161 | ProcessWaitForInterruptMethod(); | 160 | rasterizer->WaitForIdle(); |
| 162 | break; | 161 | break; |
| 163 | case BufferMethods::SemaphoreTrigger: { | 162 | case BufferMethods::SemaphoreOperation: { |
| 164 | ProcessSemaphoreTriggerMethod(); | 163 | ProcessSemaphoreTriggerMethod(); |
| 165 | break; | 164 | break; |
| 166 | } | 165 | } |
| 167 | case BufferMethods::NotifyIntr: { | 166 | case BufferMethods::NonStallInterrupt: { |
| 168 | // TODO(Kmather73): Research and implement this method. | 167 | LOG_ERROR(HW_GPU, "Special puller engine method NonStallInterrupt not implemented"); |
| 169 | LOG_ERROR(HW_GPU, "Special puller engine method NotifyIntr not implemented"); | ||
| 170 | break; | 168 | break; |
| 171 | } | 169 | } |
| 172 | case BufferMethods::Unk28: { | 170 | case BufferMethods::MemOpA: { |
| 173 | // TODO(Kmather73): Research and implement this method. | 171 | LOG_ERROR(HW_GPU, "Memory Operation A"); |
| 174 | LOG_ERROR(HW_GPU, "Special puller engine method Unk28 not implemented"); | 172 | break; |
| 173 | } | ||
| 174 | case BufferMethods::MemOpB: { | ||
| 175 | // Implement this better. | ||
| 176 | rasterizer->SyncGuestHost(); | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | case BufferMethods::MemOpC: | ||
| 180 | case BufferMethods::MemOpD: { | ||
| 181 | LOG_ERROR(HW_GPU, "Memory Operation C,D"); | ||
| 175 | break; | 182 | break; |
| 176 | } | 183 | } |
| 177 | case BufferMethods::SemaphoreAcquire: { | 184 | case BufferMethods::SemaphoreAcquire: { |