Просмотр исходного кода

vi: Parse IGBPQueueBufferRequestParcel params and expose buffer flip vertical.

bunnei 8 лет назад
Родитель
Сommit
6fce1414c3

+ 4 - 2
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
 }
 
 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<u32>(transform) & static_cast<u32>(Flags::FlipV);
     const RendererBase::FramebufferInfo framebuffer_info{
-        addr, offset, width, height, stride, static_cast<PixelFormat>(format)};
+        addr, offset, width, height, stride, static_cast<PixelFormat>(format), flip_vertical};
 
     Core::System::GetInstance().perf_stats.EndGameFrame();
     VideoCore::g_renderer->SwapBuffers(framebuffer_info);

+ 3 - 1
src/core/hle/service/nvdrv/devices/nvdisp_disp0.h

@@ -8,6 +8,7 @@
 #include <vector>
 #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<u8>& input, std::vector<u8>& 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> nvmap_dev;

+ 2 - 1
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<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() {

+ 15 - 1
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<const Buffer&> AcquireBuffer();
     void ReleaseBuffer(u32 slot);
     u32 Query(QueryType type);

+ 1 - 1
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);
     }

+ 21 - 5
src/core/hle/service/vi/vi.cpp

@@ -3,7 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <algorithm>
-
+#include <array>
 #include "common/alignment.h"
 #include "common/scope_exit.h"
 #include "core/core_timing.h"
@@ -325,13 +325,29 @@ public:
         data = Read<Data>();
     }
 
+    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<Fence, 2> 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();