diff options
| author | 2018-02-13 19:17:27 -0500 | |
|---|---|---|
| committer | 2018-02-13 19:17:27 -0500 | |
| commit | 826e9c9782be5a364540b21421550055da77ba32 (patch) | |
| tree | 1afebf4e48be1f6174d15e3efe75005b9322015c /src | |
| parent | Merge pull request #184 from mailwl/lm (diff) | |
| parent | vi: Add FENCE_HACK, which is useful for booting BOTW. (diff) | |
| download | yuzu-826e9c9782be5a364540b21421550055da77ba32.tar.gz yuzu-826e9c9782be5a364540b21421550055da77ba32.tar.xz yuzu-826e9c9782be5a364540b21421550055da77ba32.zip | |
Merge pull request #181 from bunnei/vi-fixes-2
VI cleanup and add a hack for booting games
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index dd4d3e517..8b4ed30d2 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -262,6 +262,11 @@ public: | |||
| 262 | Data data; | 262 | Data data; |
| 263 | }; | 263 | }; |
| 264 | 264 | ||
| 265 | // TODO(bunnei): Remove this. When set to 1, games will think a fence is valid and boot further. | ||
| 266 | // This will break libnx and potentially other apps that more stringently check this. This is here | ||
| 267 | // purely as a convenience, and should go away once we implement fences. | ||
| 268 | static constexpr u32 FENCE_HACK = 0; | ||
| 269 | |||
| 265 | class IGBPDequeueBufferResponseParcel : public Parcel { | 270 | class IGBPDequeueBufferResponseParcel : public Parcel { |
| 266 | public: | 271 | public: |
| 267 | explicit IGBPDequeueBufferResponseParcel(u32 slot) : Parcel(), slot(slot) {} | 272 | explicit IGBPDequeueBufferResponseParcel(u32 slot) : Parcel(), slot(slot) {} |
| @@ -269,11 +274,20 @@ public: | |||
| 269 | 274 | ||
| 270 | protected: | 275 | protected: |
| 271 | void SerializeData() override { | 276 | void SerializeData() override { |
| 272 | Write(slot); | 277 | // TODO(bunnei): Find out what this all means. Writing anything non-zero here breaks libnx. |
| 273 | // TODO(Subv): Find out how this Fence is used. | 278 | Write<u32>(0); |
| 274 | std::array<u32_le, 11> fence = {}; | 279 | Write<u32>(FENCE_HACK); |
| 275 | Write(fence); | 280 | Write<u32>(0); |
| 276 | Write<u32_le>(0); | 281 | Write<u32>(0); |
| 282 | Write<u32>(0); | ||
| 283 | Write<u32>(0); | ||
| 284 | Write<u32>(0); | ||
| 285 | Write<u32>(0); | ||
| 286 | Write<u32>(0); | ||
| 287 | Write<u32>(0); | ||
| 288 | Write<u32>(0); | ||
| 289 | Write<u32>(0); | ||
| 290 | Write<u32>(0); | ||
| 277 | } | 291 | } |
| 278 | 292 | ||
| 279 | u32_le slot; | 293 | u32_le slot; |
| @@ -304,7 +318,7 @@ protected: | |||
| 304 | void SerializeData() override { | 318 | void SerializeData() override { |
| 305 | // TODO(bunnei): Find out what this all means. Writing anything non-zero here breaks libnx. | 319 | // TODO(bunnei): Find out what this all means. Writing anything non-zero here breaks libnx. |
| 306 | Write<u32_le>(0); | 320 | Write<u32_le>(0); |
| 307 | Write<u32_le>(0); | 321 | Write<u32_le>(FENCE_HACK); |
| 308 | Write<u32_le>(0); | 322 | Write<u32_le>(0); |
| 309 | Write(buffer); | 323 | Write(buffer); |
| 310 | Write<u32_le>(0); | 324 | Write<u32_le>(0); |
| @@ -442,18 +456,20 @@ private: | |||
| 442 | void TransactParcel(u32 id, TransactionId transaction, const std::vector<u8>& input_data, | 456 | void TransactParcel(u32 id, TransactionId transaction, const std::vector<u8>& input_data, |
| 443 | VAddr output_addr, u64 output_size) { | 457 | VAddr output_addr, u64 output_size) { |
| 444 | auto buffer_queue = nv_flinger->GetBufferQueue(id); | 458 | auto buffer_queue = nv_flinger->GetBufferQueue(id); |
| 445 | std::vector<u8> response_buffer; | 459 | |
| 446 | if (transaction == TransactionId::Connect) { | 460 | if (transaction == TransactionId::Connect) { |
| 447 | IGBPConnectRequestParcel request{input_data}; | 461 | IGBPConnectRequestParcel request{input_data}; |
| 448 | IGBPConnectResponseParcel response{1280, 720}; | 462 | IGBPConnectResponseParcel response{1280, 720}; |
| 449 | response_buffer = response.Serialize(); | 463 | std::vector<u8> response_buffer = response.Serialize(); |
| 464 | Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size()); | ||
| 450 | } else if (transaction == TransactionId::SetPreallocatedBuffer) { | 465 | } else if (transaction == TransactionId::SetPreallocatedBuffer) { |
| 451 | IGBPSetPreallocatedBufferRequestParcel request{input_data}; | 466 | IGBPSetPreallocatedBufferRequestParcel request{input_data}; |
| 452 | 467 | ||
| 453 | buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer); | 468 | buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer); |
| 454 | 469 | ||
| 455 | IGBPSetPreallocatedBufferResponseParcel response{}; | 470 | IGBPSetPreallocatedBufferResponseParcel response{}; |
| 456 | response_buffer = response.Serialize(); | 471 | std::vector<u8> response_buffer = response.Serialize(); |
| 472 | Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size()); | ||
| 457 | } else if (transaction == TransactionId::DequeueBuffer) { | 473 | } else if (transaction == TransactionId::DequeueBuffer) { |
| 458 | IGBPDequeueBufferRequestParcel request{input_data}; | 474 | IGBPDequeueBufferRequestParcel request{input_data}; |
| 459 | 475 | ||
| @@ -461,21 +477,24 @@ private: | |||
| 461 | request.data.height); | 477 | request.data.height); |
| 462 | 478 | ||
| 463 | IGBPDequeueBufferResponseParcel response{slot}; | 479 | IGBPDequeueBufferResponseParcel response{slot}; |
| 464 | response_buffer = response.Serialize(); | 480 | std::vector<u8> response_buffer = response.Serialize(); |
| 481 | Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size()); | ||
| 465 | } else if (transaction == TransactionId::RequestBuffer) { | 482 | } else if (transaction == TransactionId::RequestBuffer) { |
| 466 | IGBPRequestBufferRequestParcel request{input_data}; | 483 | IGBPRequestBufferRequestParcel request{input_data}; |
| 467 | 484 | ||
| 468 | auto& buffer = buffer_queue->RequestBuffer(request.slot); | 485 | auto& buffer = buffer_queue->RequestBuffer(request.slot); |
| 469 | 486 | ||
| 470 | IGBPRequestBufferResponseParcel response{buffer}; | 487 | IGBPRequestBufferResponseParcel response{buffer}; |
| 471 | response_buffer = response.Serialize(); | 488 | std::vector<u8> response_buffer = response.Serialize(); |
| 489 | Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size()); | ||
| 472 | } else if (transaction == TransactionId::QueueBuffer) { | 490 | } else if (transaction == TransactionId::QueueBuffer) { |
| 473 | IGBPQueueBufferRequestParcel request{input_data}; | 491 | IGBPQueueBufferRequestParcel request{input_data}; |
| 474 | 492 | ||
| 475 | buffer_queue->QueueBuffer(request.data.slot, request.data.transform); | 493 | buffer_queue->QueueBuffer(request.data.slot, request.data.transform); |
| 476 | 494 | ||
| 477 | IGBPQueueBufferResponseParcel response{1280, 720}; | 495 | IGBPQueueBufferResponseParcel response{1280, 720}; |
| 478 | response_buffer = response.Serialize(); | 496 | std::vector<u8> response_buffer = response.Serialize(); |
| 497 | Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size()); | ||
| 479 | } else if (transaction == TransactionId::Query) { | 498 | } else if (transaction == TransactionId::Query) { |
| 480 | IGBPQueryRequestParcel request{input_data}; | 499 | IGBPQueryRequestParcel request{input_data}; |
| 481 | 500 | ||
| @@ -483,13 +502,13 @@ private: | |||
| 483 | buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); | 502 | buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); |
| 484 | 503 | ||
| 485 | IGBPQueryResponseParcel response{value}; | 504 | IGBPQueryResponseParcel response{value}; |
| 486 | response_buffer = response.Serialize(); | 505 | std::vector<u8> response_buffer = response.Serialize(); |
| 487 | 506 | Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size()); | |
| 507 | } else if (transaction == TransactionId::CancelBuffer) { | ||
| 508 | LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); | ||
| 488 | } else { | 509 | } else { |
| 489 | ASSERT_MSG(false, "Unimplemented"); | 510 | ASSERT_MSG(false, "Unimplemented"); |
| 490 | } | 511 | } |
| 491 | |||
| 492 | Memory::WriteBlock(output_addr, response_buffer.data(), output_size); | ||
| 493 | } | 512 | } |
| 494 | 513 | ||
| 495 | void TransactParcel(Kernel::HLERequestContext& ctx) { | 514 | void TransactParcel(Kernel::HLERequestContext& ctx) { |
| @@ -555,7 +574,7 @@ private: | |||
| 555 | } | 574 | } |
| 556 | 575 | ||
| 557 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; | 576 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; |
| 558 | }; | 577 | }; // namespace VI |
| 559 | 578 | ||
| 560 | class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { | 579 | class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { |
| 561 | public: | 580 | public: |