From 6fce1414c3a899c3694fd05518101a82ff8060ce Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 11 Feb 2018 19:03:31 -0500 Subject: [PATCH] vi: Parse IGBPQueueBufferRequestParcel params and expose buffer flip vertical. --- .../service/nvdrv/devices/nvdisp_disp0.cpp | 6 +++-- .../hle/service/nvdrv/devices/nvdisp_disp0.h | 4 ++- .../hle/service/nvflinger/buffer_queue.cpp | 3 ++- src/core/hle/service/nvflinger/buffer_queue.h | 16 +++++++++++- src/core/hle/service/nvflinger/nvflinger.cpp | 2 +- src/core/hle/service/vi/vi.cpp | 26 +++++++++++++++---- 6 files changed, 46 insertions(+), 11 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& input, std::vector } void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, - u32 stride) { + u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); LOG_WARNING(Service, "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", addr, offset, width, height, stride, format); using PixelFormat = RendererBase::FramebufferInfo::PixelFormat; + using Flags = NVFlinger::BufferQueue::BufferTransformFlags; + const bool flip_vertical = static_cast(transform) & static_cast(Flags::FlipV); const RendererBase::FramebufferInfo framebuffer_info{ - addr, offset, width, height, stride, static_cast(format)}; + addr, offset, width, height, stride, static_cast(format), flip_vertical}; Core::System::GetInstance().perf_stats.EndGameFrame(); 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 @@ #include #include "common/common_types.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" +#include "core/hle/service/nvflinger/buffer_queue.h" namespace Service { namespace Nvidia { @@ -23,7 +24,8 @@ public: u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; /// Performs a screen flip, drawing the buffer pointed to by the handle. - void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride); + void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, + NVFlinger::BufferQueue::BufferTransformFlags transform); private: std::shared_ptr 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 { return itr->igbp_buffer; } -void BufferQueue::QueueBuffer(u32 slot) { +void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform) { auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { return buffer.slot == slot; }); ASSERT(itr != queue.end()); ASSERT(itr->status == Buffer::Status::Dequeued); itr->status = Buffer::Status::Queued; + itr->transform = transform; } boost::optional 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: BufferQueue(u32 id, u64 layer_id); ~BufferQueue() = default; + enum class BufferTransformFlags : u32 { + /// Flip source image horizontally (around the vertical axis) + FlipH = 0x01, + /// Flip source image vertically (around the horizontal axis) + FlipV = 0x02, + /// Rotate source image 90 degrees clockwise + Rotate90 = 0x04, + /// Rotate source image 180 degrees + Roate180 = 0x03, + /// Rotate source image 270 degrees clockwise + Roate270 = 0x07, + }; + struct Buffer { enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 }; u32 slot; Status status = Status::Free; IGBPBuffer igbp_buffer; + BufferTransformFlags transform; }; void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); u32 DequeueBuffer(u32 pixel_format, u32 width, u32 height); const IGBPBuffer& RequestBuffer(u32 slot) const; - void QueueBuffer(u32 slot); + void QueueBuffer(u32 slot, BufferTransformFlags transform); boost::optional AcquireBuffer(); void ReleaseBuffer(u32 slot); 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() { ASSERT(nvdisp); nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, - igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride); + igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform); buffer_queue->ReleaseBuffer(buffer->slot); } diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 0262e830b..dd4d3e517 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include - +#include #include "common/alignment.h" #include "common/scope_exit.h" #include "core/core_timing.h" @@ -325,13 +325,29 @@ public: data = Read(); } + struct Fence { + u32_le id; + u32_le value; + }; + static_assert(sizeof(Fence) == 8, "Fence has wrong size"); + struct Data { u32_le slot; - INSERT_PADDING_WORDS(2); + INSERT_PADDING_WORDS(3); u32_le timestamp; - INSERT_PADDING_WORDS(20); + s32_le is_auto_timestamp; + s32_le crop_left; + s32_le crop_top; + s32_le crop_right; + s32_le crop_bottom; + s32_le scaling_mode; + NVFlinger::BufferQueue::BufferTransformFlags transform; + u32_le sticky_transform; + INSERT_PADDING_WORDS(2); + u32_le fence_is_valid; + std::array fences; }; - static_assert(sizeof(Data) == 96, "ParcelData has wrong size"); + static_assert(sizeof(Data) == 80, "ParcelData has wrong size"); Data data; }; @@ -456,7 +472,7 @@ private: } else if (transaction == TransactionId::QueueBuffer) { IGBPQueueBufferRequestParcel request{input_data}; - buffer_queue->QueueBuffer(request.data.slot); + buffer_queue->QueueBuffer(request.data.slot, request.data.transform); IGBPQueueBufferResponseParcel response{1280, 720}; response_buffer = response.Serialize();