diff options
| -rw-r--r-- | src/video_core/dma_pusher.h | 25 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 48 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 25 |
3 files changed, 70 insertions, 28 deletions
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index efa90d170..2026b7857 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h | |||
| @@ -27,6 +27,31 @@ enum class SubmissionMode : u32 { | |||
| 27 | IncreaseOnce = 5 | 27 | IncreaseOnce = 5 |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence | ||
| 31 | // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. | ||
| 32 | // So the values you see in docs might be multiplied by 4. | ||
| 33 | enum class BufferMethods : u32 { | ||
| 34 | BindObject = 0x0, | ||
| 35 | Nop = 0x2, | ||
| 36 | SemaphoreAddressHigh = 0x4, | ||
| 37 | SemaphoreAddressLow = 0x5, | ||
| 38 | SemaphoreSequence = 0x6, | ||
| 39 | SemaphoreTrigger = 0x7, | ||
| 40 | NotifyIntr = 0x8, | ||
| 41 | WrcacheFlush = 0x9, | ||
| 42 | Unk28 = 0xA, | ||
| 43 | UnkCacheFlush = 0xB, | ||
| 44 | RefCnt = 0x14, | ||
| 45 | SemaphoreAcquire = 0x1A, | ||
| 46 | SemaphoreRelease = 0x1B, | ||
| 47 | FenceValue = 0x1C, | ||
| 48 | FenceAction = 0x1D, | ||
| 49 | WaitForInterrupt = 0x1E, | ||
| 50 | Unk7c = 0x1F, | ||
| 51 | Yield = 0x20, | ||
| 52 | NonPullerMethods = 0x40, | ||
| 53 | }; | ||
| 54 | |||
| 30 | struct CommandListHeader { | 55 | struct CommandListHeader { |
| 31 | union { | 56 | union { |
| 32 | u64 raw; | 57 | u64 raw; |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 171f78183..ebd149c3a 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -194,30 +194,6 @@ void GPU::SyncGuestHost() { | |||
| 194 | void GPU::OnCommandListEnd() { | 194 | void GPU::OnCommandListEnd() { |
| 195 | renderer->Rasterizer().ReleaseFences(); | 195 | renderer->Rasterizer().ReleaseFences(); |
| 196 | } | 196 | } |
| 197 | // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence | ||
| 198 | // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. | ||
| 199 | // So the values you see in docs might be multiplied by 4. | ||
| 200 | enum class BufferMethods { | ||
| 201 | BindObject = 0x0, | ||
| 202 | Nop = 0x2, | ||
| 203 | SemaphoreAddressHigh = 0x4, | ||
| 204 | SemaphoreAddressLow = 0x5, | ||
| 205 | SemaphoreSequence = 0x6, | ||
| 206 | SemaphoreTrigger = 0x7, | ||
| 207 | NotifyIntr = 0x8, | ||
| 208 | WrcacheFlush = 0x9, | ||
| 209 | Unk28 = 0xA, | ||
| 210 | UnkCacheFlush = 0xB, | ||
| 211 | RefCnt = 0x14, | ||
| 212 | SemaphoreAcquire = 0x1A, | ||
| 213 | SemaphoreRelease = 0x1B, | ||
| 214 | FenceValue = 0x1C, | ||
| 215 | FenceAction = 0x1D, | ||
| 216 | Unk78 = 0x1E, | ||
| 217 | Unk7c = 0x1F, | ||
| 218 | Yield = 0x20, | ||
| 219 | NonPullerMethods = 0x40, | ||
| 220 | }; | ||
| 221 | 197 | ||
| 222 | enum class GpuSemaphoreOperation { | 198 | enum class GpuSemaphoreOperation { |
| 223 | AcquireEqual = 0x1, | 199 | AcquireEqual = 0x1, |
| @@ -277,7 +253,12 @@ void GPU::CallPullerMethod(const MethodCall& method_call) { | |||
| 277 | case BufferMethods::UnkCacheFlush: | 253 | case BufferMethods::UnkCacheFlush: |
| 278 | case BufferMethods::WrcacheFlush: | 254 | case BufferMethods::WrcacheFlush: |
| 279 | case BufferMethods::FenceValue: | 255 | case BufferMethods::FenceValue: |
| 256 | break; | ||
| 280 | case BufferMethods::FenceAction: | 257 | case BufferMethods::FenceAction: |
| 258 | ProcessFenceActionMethod(); | ||
| 259 | break; | ||
| 260 | case BufferMethods::WaitForInterrupt: | ||
| 261 | ProcessWaitForInterruptMethod(); | ||
| 281 | break; | 262 | break; |
| 282 | case BufferMethods::SemaphoreTrigger: { | 263 | case BufferMethods::SemaphoreTrigger: { |
| 283 | ProcessSemaphoreTriggerMethod(); | 264 | ProcessSemaphoreTriggerMethod(); |
| @@ -391,6 +372,25 @@ void GPU::ProcessBindMethod(const MethodCall& method_call) { | |||
| 391 | } | 372 | } |
| 392 | } | 373 | } |
| 393 | 374 | ||
| 375 | void GPU::ProcessFenceActionMethod() { | ||
| 376 | switch (regs.fence_action.op) { | ||
| 377 | case FenceOperation::Acquire: | ||
| 378 | WaitFence(regs.fence_action.syncpoint_id, regs.fence_value); | ||
| 379 | break; | ||
| 380 | case FenceOperation::Increment: | ||
| 381 | IncrementSyncPoint(regs.fence_action.syncpoint_id); | ||
| 382 | break; | ||
| 383 | default: | ||
| 384 | UNIMPLEMENTED_MSG("Unimplemented operation {}", | ||
| 385 | static_cast<u32>(regs.fence_action.op.Value())); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | void GPU::ProcessWaitForInterruptMethod() { | ||
| 390 | // TODO(bunnei) ImplementMe | ||
| 391 | LOG_WARNING(HW_GPU, "(STUBBED) called"); | ||
| 392 | } | ||
| 393 | |||
| 394 | void GPU::ProcessSemaphoreTriggerMethod() { | 394 | void GPU::ProcessSemaphoreTriggerMethod() { |
| 395 | const auto semaphoreOperationMask = 0xF; | 395 | const auto semaphoreOperationMask = 0xF; |
| 396 | const auto op = | 396 | const auto op = |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index b8c613b11..5444b49f3 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -263,6 +263,24 @@ public: | |||
| 263 | return use_nvdec; | 263 | return use_nvdec; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | enum class FenceOperation : u32 { | ||
| 267 | Acquire = 0, | ||
| 268 | Increment = 1, | ||
| 269 | }; | ||
| 270 | |||
| 271 | union FenceAction { | ||
| 272 | u32 raw; | ||
| 273 | BitField<0, 1, FenceOperation> op; | ||
| 274 | BitField<8, 24, u32> syncpoint_id; | ||
| 275 | |||
| 276 | static constexpr CommandHeader Build(FenceOperation op, u32 syncpoint_id) { | ||
| 277 | FenceAction result{}; | ||
| 278 | result.op.Assign(op); | ||
| 279 | result.syncpoint_id.Assign(syncpoint_id); | ||
| 280 | return {result.raw}; | ||
| 281 | } | ||
| 282 | }; | ||
| 283 | |||
| 266 | struct Regs { | 284 | struct Regs { |
| 267 | static constexpr size_t NUM_REGS = 0x40; | 285 | static constexpr size_t NUM_REGS = 0x40; |
| 268 | 286 | ||
| @@ -291,10 +309,7 @@ public: | |||
| 291 | u32 semaphore_acquire; | 309 | u32 semaphore_acquire; |
| 292 | u32 semaphore_release; | 310 | u32 semaphore_release; |
| 293 | u32 fence_value; | 311 | u32 fence_value; |
| 294 | union { | 312 | FenceAction fence_action; |
| 295 | BitField<4, 4, u32> operation; | ||
| 296 | BitField<8, 8, u32> id; | ||
| 297 | } fence_action; | ||
| 298 | INSERT_UNION_PADDING_WORDS(0xE2); | 313 | INSERT_UNION_PADDING_WORDS(0xE2); |
| 299 | 314 | ||
| 300 | // Puller state | 315 | // Puller state |
| @@ -342,6 +357,8 @@ protected: | |||
| 342 | 357 | ||
| 343 | private: | 358 | private: |
| 344 | void ProcessBindMethod(const MethodCall& method_call); | 359 | void ProcessBindMethod(const MethodCall& method_call); |
| 360 | void ProcessFenceActionMethod(); | ||
| 361 | void ProcessWaitForInterruptMethod(); | ||
| 345 | void ProcessSemaphoreTriggerMethod(); | 362 | void ProcessSemaphoreTriggerMethod(); |
| 346 | void ProcessSemaphoreRelease(); | 363 | void ProcessSemaphoreRelease(); |
| 347 | void ProcessSemaphoreAcquire(); | 364 | void ProcessSemaphoreAcquire(); |