diff options
| author | 2018-02-09 22:50:29 -0500 | |
|---|---|---|
| committer | 2018-02-09 23:33:49 -0500 | |
| commit | c83a1b232028ae4d84eb255e8c04154e9b6e8930 (patch) | |
| tree | fb8771cb86b9ae84bab9b65d064feb2bb4c3f7a1 /src | |
| parent | nvflinger: (Hack) Use first available buffer if none are found. (diff) | |
| download | yuzu-c83a1b232028ae4d84eb255e8c04154e9b6e8930.tar.gz yuzu-c83a1b232028ae4d84eb255e8c04154e9b6e8930.tar.xz yuzu-c83a1b232028ae4d84eb255e8c04154e9b6e8930.zip | |
vi: Implement TransactParcelAuto.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index a0eee9e4b..69ac2fe07 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -397,7 +397,7 @@ public: | |||
| 397 | {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, | 397 | {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, |
| 398 | {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, | 398 | {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, |
| 399 | {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, | 399 | {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, |
| 400 | {3, nullptr, "TransactParcelAuto"}, | 400 | {3, &IHOSBinderDriver::TransactParcelAuto, "TransactParcelAuto"}, |
| 401 | }; | 401 | }; |
| 402 | RegisterHandlers(functions); | 402 | RegisterHandlers(functions); |
| 403 | } | 403 | } |
| @@ -421,35 +421,21 @@ private: | |||
| 421 | SetPreallocatedBuffer = 14 | 421 | SetPreallocatedBuffer = 14 |
| 422 | }; | 422 | }; |
| 423 | 423 | ||
| 424 | void TransactParcel(Kernel::HLERequestContext& ctx) { | 424 | void TransactParcel(u32 id, TransactionId transaction, const std::vector<u8>& input_data, |
| 425 | IPC::RequestParser rp{ctx}; | 425 | VAddr output_addr, u64 output_size) { |
| 426 | u32 id = rp.Pop<u32>(); | ||
| 427 | auto transaction = static_cast<TransactionId>(rp.Pop<u32>()); | ||
| 428 | u32 flags = rp.Pop<u32>(); | ||
| 429 | |||
| 430 | auto& input_buffer = ctx.BufferDescriptorA()[0]; | ||
| 431 | std::vector<u8> input_data(input_buffer.Size()); | ||
| 432 | Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.Size()); | ||
| 433 | |||
| 434 | auto& output_buffer = ctx.BufferDescriptorB()[0]; | ||
| 435 | |||
| 436 | auto buffer_queue = nv_flinger->GetBufferQueue(id); | 426 | auto buffer_queue = nv_flinger->GetBufferQueue(id); |
| 437 | LOG_WARNING(Service_VI, "(STUBBED) called, transaction=%x", transaction); | 427 | std::vector<u8> response_buffer; |
| 438 | if (transaction == TransactionId::Connect) { | 428 | if (transaction == TransactionId::Connect) { |
| 439 | IGBPConnectRequestParcel request{input_data}; | 429 | IGBPConnectRequestParcel request{input_data}; |
| 440 | IGBPConnectResponseParcel response{1280, 720}; | 430 | IGBPConnectResponseParcel response{1280, 720}; |
| 441 | auto response_buffer = response.Serialize(); | 431 | response_buffer = response.Serialize(); |
| 442 | Memory::WriteBlock(output_buffer.Address(), response_buffer.data(), | ||
| 443 | output_buffer.Size()); | ||
| 444 | } else if (transaction == TransactionId::SetPreallocatedBuffer) { | 432 | } else if (transaction == TransactionId::SetPreallocatedBuffer) { |
| 445 | IGBPSetPreallocatedBufferRequestParcel request{input_data}; | 433 | IGBPSetPreallocatedBufferRequestParcel request{input_data}; |
| 446 | 434 | ||
| 447 | buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer); | 435 | buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer); |
| 448 | 436 | ||
| 449 | IGBPSetPreallocatedBufferResponseParcel response{}; | 437 | IGBPSetPreallocatedBufferResponseParcel response{}; |
| 450 | auto response_buffer = response.Serialize(); | 438 | response_buffer = response.Serialize(); |
| 451 | Memory::WriteBlock(output_buffer.Address(), response_buffer.data(), | ||
| 452 | output_buffer.Size()); | ||
| 453 | } else if (transaction == TransactionId::DequeueBuffer) { | 439 | } else if (transaction == TransactionId::DequeueBuffer) { |
| 454 | IGBPDequeueBufferRequestParcel request{input_data}; | 440 | IGBPDequeueBufferRequestParcel request{input_data}; |
| 455 | 441 | ||
| @@ -457,27 +443,21 @@ private: | |||
| 457 | request.data.height); | 443 | request.data.height); |
| 458 | 444 | ||
| 459 | IGBPDequeueBufferResponseParcel response{slot}; | 445 | IGBPDequeueBufferResponseParcel response{slot}; |
| 460 | auto response_buffer = response.Serialize(); | 446 | response_buffer = response.Serialize(); |
| 461 | Memory::WriteBlock(output_buffer.Address(), response_buffer.data(), | ||
| 462 | output_buffer.Size()); | ||
| 463 | } else if (transaction == TransactionId::RequestBuffer) { | 447 | } else if (transaction == TransactionId::RequestBuffer) { |
| 464 | IGBPRequestBufferRequestParcel request{input_data}; | 448 | IGBPRequestBufferRequestParcel request{input_data}; |
| 465 | 449 | ||
| 466 | auto& buffer = buffer_queue->RequestBuffer(request.slot); | 450 | auto& buffer = buffer_queue->RequestBuffer(request.slot); |
| 467 | 451 | ||
| 468 | IGBPRequestBufferResponseParcel response{buffer}; | 452 | IGBPRequestBufferResponseParcel response{buffer}; |
| 469 | auto response_buffer = response.Serialize(); | 453 | response_buffer = response.Serialize(); |
| 470 | Memory::WriteBlock(output_buffer.Address(), response_buffer.data(), | ||
| 471 | output_buffer.Size()); | ||
| 472 | } else if (transaction == TransactionId::QueueBuffer) { | 454 | } else if (transaction == TransactionId::QueueBuffer) { |
| 473 | IGBPQueueBufferRequestParcel request{input_data}; | 455 | IGBPQueueBufferRequestParcel request{input_data}; |
| 474 | 456 | ||
| 475 | buffer_queue->QueueBuffer(request.data.slot); | 457 | buffer_queue->QueueBuffer(request.data.slot); |
| 476 | 458 | ||
| 477 | IGBPQueueBufferResponseParcel response{1280, 720}; | 459 | IGBPQueueBufferResponseParcel response{1280, 720}; |
| 478 | auto response_buffer = response.Serialize(); | 460 | response_buffer = response.Serialize(); |
| 479 | Memory::WriteBlock(output_buffer.Address(), response_buffer.data(), | ||
| 480 | output_buffer.Size()); | ||
| 481 | } else if (transaction == TransactionId::Query) { | 461 | } else if (transaction == TransactionId::Query) { |
| 482 | IGBPQueryRequestParcel request{input_data}; | 462 | IGBPQueryRequestParcel request{input_data}; |
| 483 | 463 | ||
| @@ -485,13 +465,47 @@ private: | |||
| 485 | buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); | 465 | buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); |
| 486 | 466 | ||
| 487 | IGBPQueryResponseParcel response{value}; | 467 | IGBPQueryResponseParcel response{value}; |
| 488 | auto response_buffer = response.Serialize(); | 468 | response_buffer = response.Serialize(); |
| 489 | Memory::WriteBlock(output_buffer.Address(), response_buffer.data(), | 469 | |
| 490 | output_buffer.Size()); | ||
| 491 | } else { | 470 | } else { |
| 492 | ASSERT_MSG(false, "Unimplemented"); | 471 | ASSERT_MSG(false, "Unimplemented"); |
| 493 | } | 472 | } |
| 494 | 473 | ||
| 474 | Memory::WriteBlock(output_addr, response_buffer.data(), output_size); | ||
| 475 | } | ||
| 476 | |||
| 477 | void TransactParcel(Kernel::HLERequestContext& ctx) { | ||
| 478 | IPC::RequestParser rp{ctx}; | ||
| 479 | u32 id = rp.Pop<u32>(); | ||
| 480 | auto transaction = static_cast<TransactionId>(rp.Pop<u32>()); | ||
| 481 | u32 flags = rp.Pop<u32>(); | ||
| 482 | LOG_DEBUG(Service_VI, "called, transaction=%x", transaction); | ||
| 483 | |||
| 484 | auto& input_buffer = ctx.BufferDescriptorA()[0]; | ||
| 485 | auto& output_buffer = ctx.BufferDescriptorB()[0]; | ||
| 486 | std::vector<u8> input_data(input_buffer.Size()); | ||
| 487 | Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.Size()); | ||
| 488 | |||
| 489 | TransactParcel(id, transaction, input_data, output_buffer.Address(), output_buffer.Size()); | ||
| 490 | |||
| 491 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 492 | rb.Push(RESULT_SUCCESS); | ||
| 493 | } | ||
| 494 | |||
| 495 | void TransactParcelAuto(Kernel::HLERequestContext& ctx) { | ||
| 496 | IPC::RequestParser rp{ctx}; | ||
| 497 | u32 id = rp.Pop<u32>(); | ||
| 498 | auto transaction = static_cast<TransactionId>(rp.Pop<u32>()); | ||
| 499 | u32 flags = rp.Pop<u32>(); | ||
| 500 | LOG_DEBUG(Service_VI, "called, transaction=%x", transaction); | ||
| 501 | |||
| 502 | auto& input_buffer = ctx.BufferDescriptorX()[0]; | ||
| 503 | auto& output_buffer = ctx.BufferDescriptorC()[0]; | ||
| 504 | std::vector<u8> input_data(input_buffer.size); | ||
| 505 | Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.size); | ||
| 506 | |||
| 507 | TransactParcel(id, transaction, input_data, output_buffer.Address(), output_buffer.Size()); | ||
| 508 | |||
| 495 | IPC::ResponseBuilder rb{ctx, 2}; | 509 | IPC::ResponseBuilder rb{ctx, 2}; |
| 496 | rb.Push(RESULT_SUCCESS); | 510 | rb.Push(RESULT_SUCCESS); |
| 497 | } | 511 | } |