diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 40 |
6 files changed, 54 insertions, 17 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 4d0ab844c..7674d332d 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -20,15 +20,17 @@ u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | 22 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, |
| 23 | u32 stride) { | 23 | u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { |
| 24 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | 24 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); |
| 25 | LOG_WARNING(Service, | 25 | LOG_WARNING(Service, |
| 26 | "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", | 26 | "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", |
| 27 | addr, offset, width, height, stride, format); | 27 | addr, offset, width, height, stride, format); |
| 28 | 28 | ||
| 29 | using PixelFormat = RendererBase::FramebufferInfo::PixelFormat; | 29 | using PixelFormat = RendererBase::FramebufferInfo::PixelFormat; |
| 30 | using Flags = NVFlinger::BufferQueue::BufferTransformFlags; | ||
| 31 | const bool flip_vertical = static_cast<u32>(transform) & static_cast<u32>(Flags::FlipV); | ||
| 30 | const RendererBase::FramebufferInfo framebuffer_info{ | 32 | const RendererBase::FramebufferInfo framebuffer_info{ |
| 31 | addr, offset, width, height, stride, static_cast<PixelFormat>(format)}; | 33 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), flip_vertical}; |
| 32 | 34 | ||
| 33 | Core::System::GetInstance().perf_stats.EndGameFrame(); | 35 | Core::System::GetInstance().perf_stats.EndGameFrame(); |
| 34 | VideoCore::g_renderer->SwapBuffers(framebuffer_info); | 36 | VideoCore::g_renderer->SwapBuffers(framebuffer_info); |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index f3cfc9925..66f56f23d 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 11 | #include "core/hle/service/nvflinger/buffer_queue.h" | ||
| 11 | 12 | ||
| 12 | namespace Service { | 13 | namespace Service { |
| 13 | namespace Nvidia { | 14 | namespace Nvidia { |
| @@ -23,7 +24,8 @@ public: | |||
| 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 24 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 24 | 25 | ||
| 25 | /// Performs a screen flip, drawing the buffer pointed to by the handle. | 26 | /// Performs a screen flip, drawing the buffer pointed to by the handle. |
| 26 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride); | 27 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, |
| 28 | NVFlinger::BufferQueue::BufferTransformFlags transform); | ||
| 27 | 29 | ||
| 28 | private: | 30 | private: |
| 29 | std::shared_ptr<nvmap> nvmap_dev; | 31 | std::shared_ptr<nvmap> nvmap_dev; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index f90c7ca51..ff7b6b039 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -58,12 +58,13 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { | |||
| 58 | return itr->igbp_buffer; | 58 | return itr->igbp_buffer; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | void BufferQueue::QueueBuffer(u32 slot) { | 61 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform) { |
| 62 | auto itr = std::find_if(queue.begin(), queue.end(), | 62 | auto itr = std::find_if(queue.begin(), queue.end(), |
| 63 | [&](const Buffer& buffer) { return buffer.slot == slot; }); | 63 | [&](const Buffer& buffer) { return buffer.slot == slot; }); |
| 64 | ASSERT(itr != queue.end()); | 64 | ASSERT(itr != queue.end()); |
| 65 | ASSERT(itr->status == Buffer::Status::Dequeued); | 65 | ASSERT(itr->status == Buffer::Status::Dequeued); |
| 66 | itr->status = Buffer::Status::Queued; | 66 | itr->status = Buffer::Status::Queued; |
| 67 | itr->transform = transform; | ||
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() { | 70 | boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() { |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 5c6719407..ef9732769 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -46,18 +46,32 @@ public: | |||
| 46 | BufferQueue(u32 id, u64 layer_id); | 46 | BufferQueue(u32 id, u64 layer_id); |
| 47 | ~BufferQueue() = default; | 47 | ~BufferQueue() = default; |
| 48 | 48 | ||
| 49 | enum class BufferTransformFlags : u32 { | ||
| 50 | /// Flip source image horizontally (around the vertical axis) | ||
| 51 | FlipH = 0x01, | ||
| 52 | /// Flip source image vertically (around the horizontal axis) | ||
| 53 | FlipV = 0x02, | ||
| 54 | /// Rotate source image 90 degrees clockwise | ||
| 55 | Rotate90 = 0x04, | ||
| 56 | /// Rotate source image 180 degrees | ||
| 57 | Roate180 = 0x03, | ||
| 58 | /// Rotate source image 270 degrees clockwise | ||
| 59 | Roate270 = 0x07, | ||
| 60 | }; | ||
| 61 | |||
| 49 | struct Buffer { | 62 | struct Buffer { |
| 50 | enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 }; | 63 | enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 }; |
| 51 | 64 | ||
| 52 | u32 slot; | 65 | u32 slot; |
| 53 | Status status = Status::Free; | 66 | Status status = Status::Free; |
| 54 | IGBPBuffer igbp_buffer; | 67 | IGBPBuffer igbp_buffer; |
| 68 | BufferTransformFlags transform; | ||
| 55 | }; | 69 | }; |
| 56 | 70 | ||
| 57 | void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); | 71 | void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); |
| 58 | u32 DequeueBuffer(u32 pixel_format, u32 width, u32 height); | 72 | u32 DequeueBuffer(u32 pixel_format, u32 width, u32 height); |
| 59 | const IGBPBuffer& RequestBuffer(u32 slot) const; | 73 | const IGBPBuffer& RequestBuffer(u32 slot) const; |
| 60 | void QueueBuffer(u32 slot); | 74 | void QueueBuffer(u32 slot, BufferTransformFlags transform); |
| 61 | boost::optional<const Buffer&> AcquireBuffer(); | 75 | boost::optional<const Buffer&> AcquireBuffer(); |
| 62 | void ReleaseBuffer(u32 slot); | 76 | void ReleaseBuffer(u32 slot); |
| 63 | u32 Query(QueryType type); | 77 | u32 Query(QueryType type); |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index fe622b986..2089462b7 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -145,7 +145,7 @@ void NVFlinger::Compose() { | |||
| 145 | ASSERT(nvdisp); | 145 | ASSERT(nvdisp); |
| 146 | 146 | ||
| 147 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, | 147 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, |
| 148 | igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride); | 148 | igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform); |
| 149 | 149 | ||
| 150 | buffer_queue->ReleaseBuffer(buffer->slot); | 150 | buffer_queue->ReleaseBuffer(buffer->slot); |
| 151 | } | 151 | } |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 69ac2fe07..dd4d3e517 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | 6 | #include <array> | |
| 7 | #include "common/alignment.h" | 7 | #include "common/alignment.h" |
| 8 | #include "common/scope_exit.h" | 8 | #include "common/scope_exit.h" |
| 9 | #include "core/core_timing.h" | 9 | #include "core/core_timing.h" |
| @@ -101,8 +101,10 @@ public: | |||
| 101 | SerializeData(); | 101 | SerializeData(); |
| 102 | 102 | ||
| 103 | Header header{}; | 103 | Header header{}; |
| 104 | header.data_offset = sizeof(Header); | ||
| 105 | header.data_size = static_cast<u32_le>(write_index - sizeof(Header)); | 104 | header.data_size = static_cast<u32_le>(write_index - sizeof(Header)); |
| 105 | header.data_offset = sizeof(Header); | ||
| 106 | header.objects_size = 4; | ||
| 107 | header.objects_offset = sizeof(Header) + header.data_size; | ||
| 106 | std::memcpy(buffer.data(), &header, sizeof(Header)); | 108 | std::memcpy(buffer.data(), &header, sizeof(Header)); |
| 107 | 109 | ||
| 108 | return buffer; | 110 | return buffer; |
| @@ -142,11 +144,11 @@ protected: | |||
| 142 | private: | 144 | private: |
| 143 | struct Data { | 145 | struct Data { |
| 144 | u32_le magic = 2; | 146 | u32_le magic = 2; |
| 145 | u32_le process_id; | 147 | u32_le process_id = 1; |
| 146 | u32_le id; | 148 | u32_le id; |
| 147 | INSERT_PADDING_BYTES(0xC); | 149 | INSERT_PADDING_WORDS(3); |
| 148 | std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; | 150 | std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; |
| 149 | INSERT_PADDING_BYTES(8); | 151 | INSERT_PADDING_WORDS(2); |
| 150 | }; | 152 | }; |
| 151 | static_assert(sizeof(Data) == 0x28, "ParcelData has wrong size"); | 153 | static_assert(sizeof(Data) == 0x28, "ParcelData has wrong size"); |
| 152 | 154 | ||
| @@ -323,13 +325,29 @@ public: | |||
| 323 | data = Read<Data>(); | 325 | data = Read<Data>(); |
| 324 | } | 326 | } |
| 325 | 327 | ||
| 328 | struct Fence { | ||
| 329 | u32_le id; | ||
| 330 | u32_le value; | ||
| 331 | }; | ||
| 332 | static_assert(sizeof(Fence) == 8, "Fence has wrong size"); | ||
| 333 | |||
| 326 | struct Data { | 334 | struct Data { |
| 327 | u32_le slot; | 335 | u32_le slot; |
| 328 | INSERT_PADDING_WORDS(2); | 336 | INSERT_PADDING_WORDS(3); |
| 329 | u32_le timestamp; | 337 | u32_le timestamp; |
| 330 | INSERT_PADDING_WORDS(20); | 338 | s32_le is_auto_timestamp; |
| 339 | s32_le crop_left; | ||
| 340 | s32_le crop_top; | ||
| 341 | s32_le crop_right; | ||
| 342 | s32_le crop_bottom; | ||
| 343 | s32_le scaling_mode; | ||
| 344 | NVFlinger::BufferQueue::BufferTransformFlags transform; | ||
| 345 | u32_le sticky_transform; | ||
| 346 | INSERT_PADDING_WORDS(2); | ||
| 347 | u32_le fence_is_valid; | ||
| 348 | std::array<Fence, 2> fences; | ||
| 331 | }; | 349 | }; |
| 332 | static_assert(sizeof(Data) == 96, "ParcelData has wrong size"); | 350 | static_assert(sizeof(Data) == 80, "ParcelData has wrong size"); |
| 333 | 351 | ||
| 334 | Data data; | 352 | Data data; |
| 335 | }; | 353 | }; |
| @@ -454,7 +472,7 @@ private: | |||
| 454 | } else if (transaction == TransactionId::QueueBuffer) { | 472 | } else if (transaction == TransactionId::QueueBuffer) { |
| 455 | IGBPQueueBufferRequestParcel request{input_data}; | 473 | IGBPQueueBufferRequestParcel request{input_data}; |
| 456 | 474 | ||
| 457 | buffer_queue->QueueBuffer(request.data.slot); | 475 | buffer_queue->QueueBuffer(request.data.slot, request.data.transform); |
| 458 | 476 | ||
| 459 | IGBPQueueBufferResponseParcel response{1280, 720}; | 477 | IGBPQueueBufferResponseParcel response{1280, 720}; |
| 460 | response_buffer = response.Serialize(); | 478 | response_buffer = response.Serialize(); |
| @@ -672,7 +690,7 @@ void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) { | |||
| 672 | } | 690 | } |
| 673 | 691 | ||
| 674 | void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { | 692 | void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { |
| 675 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 693 | LOG_DEBUG(Service_VI, "called"); |
| 676 | IPC::RequestParser rp{ctx}; | 694 | IPC::RequestParser rp{ctx}; |
| 677 | auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); | 695 | auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); |
| 678 | auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); | 696 | auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); |
| @@ -697,7 +715,7 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { | |||
| 697 | } | 715 | } |
| 698 | 716 | ||
| 699 | void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { | 717 | void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { |
| 700 | LOG_WARNING(Service, "(STUBBED) called"); | 718 | LOG_DEBUG(Service_VI, "called"); |
| 701 | 719 | ||
| 702 | IPC::RequestParser rp{ctx}; | 720 | IPC::RequestParser rp{ctx}; |
| 703 | u32 flags = rp.Pop<u32>(); | 721 | u32 flags = rp.Pop<u32>(); |