summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-02-13 19:17:27 -0500
committerGravatar GitHub2018-02-13 19:17:27 -0500
commit826e9c9782be5a364540b21421550055da77ba32 (patch)
tree1afebf4e48be1f6174d15e3efe75005b9322015c /src
parentMerge pull request #184 from mailwl/lm (diff)
parentvi: Add FENCE_HACK, which is useful for booting BOTW. (diff)
downloadyuzu-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.cpp53
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.
268static constexpr u32 FENCE_HACK = 0;
269
265class IGBPDequeueBufferResponseParcel : public Parcel { 270class IGBPDequeueBufferResponseParcel : public Parcel {
266public: 271public:
267 explicit IGBPDequeueBufferResponseParcel(u32 slot) : Parcel(), slot(slot) {} 272 explicit IGBPDequeueBufferResponseParcel(u32 slot) : Parcel(), slot(slot) {}
@@ -269,11 +274,20 @@ public:
269 274
270protected: 275protected:
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
560class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { 579class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
561public: 580public: