diff options
| author | bunnei <bunneidev@gmail.com> | 2018-02-11 21:47:35 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-02-11 21:47:35 -0500 | 
| commit | 890e98a33e4afa3d7374c7951ee2bde7cc8849c5 (patch) | |
| tree | d5e62426c3a2ed38dcc6929a1e7066f0d0dd9933 | |
| parent | b26cdf1fe5e07d161bdb8542744b26c8e50f94c9 (diff) | |
| parent | deadcb39c2914d77734907daf7ce304872265798 (diff) | |
Merge pull request #177 from bunnei/vi-fixes
Several misc. VI fixes
| -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 | ||||
| -rw-r--r-- | src/video_core/renderer_base.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 3 | 
9 files changed, 67 insertions, 22 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  }  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); 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 <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; 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<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:      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); 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 69ac2fe07..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 <algorithm> - +#include <array>  #include "common/alignment.h"  #include "common/scope_exit.h"  #include "core/core_timing.h" @@ -101,8 +101,10 @@ public:          SerializeData();          Header header{}; -        header.data_offset = sizeof(Header);          header.data_size = static_cast<u32_le>(write_index - sizeof(Header)); +        header.data_offset = sizeof(Header); +        header.objects_size = 4; +        header.objects_offset = sizeof(Header) + header.data_size;          std::memcpy(buffer.data(), &header, sizeof(Header));          return buffer; @@ -142,11 +144,11 @@ protected:  private:      struct Data {          u32_le magic = 2; -        u32_le process_id; +        u32_le process_id = 1;          u32_le id; -        INSERT_PADDING_BYTES(0xC); +        INSERT_PADDING_WORDS(3);          std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; -        INSERT_PADDING_BYTES(8); +        INSERT_PADDING_WORDS(2);      };      static_assert(sizeof(Data) == 0x28, "ParcelData has wrong size"); @@ -323,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;  }; @@ -454,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(); @@ -672,7 +690,7 @@ void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) {  }  void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { -    LOG_WARNING(Service_VI, "(STUBBED) called"); +    LOG_DEBUG(Service_VI, "called");      IPC::RequestParser rp{ctx};      auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();      auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); @@ -697,7 +715,7 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) {  }  void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { -    LOG_WARNING(Service, "(STUBBED) called"); +    LOG_DEBUG(Service_VI, "called");      IPC::RequestParser rp{ctx};      u32 flags = rp.Pop<u32>(); diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 28893b181..2aba50eda 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -43,6 +43,7 @@ public:          u32 height;          u32 stride;          PixelFormat pixel_format; +        bool flip_vertical;      };      virtual ~RendererBase() {} diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8c23128ae..7f921fa32 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -262,6 +262,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const FramebufferInfo& framebuffer_info,      // only allows rows to have a memory alignement of 4.      ASSERT(framebuffer_info.stride % 4 == 0); +    framebuffer_flip_vertical = framebuffer_info.flip_vertical; +      // Reset the screen info's display texture to its own permanent texture      screen_info.display_texture = screen_info.texture.resource.handle;      screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f); @@ -401,13 +403,15 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,  void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float x, float y, float w,                                        float h) { -    auto& texcoords = screen_info.display_texcoords; +    const auto& texcoords = screen_info.display_texcoords; +    const auto& left = framebuffer_flip_vertical ? texcoords.right : texcoords.left; +    const auto& right = framebuffer_flip_vertical ? texcoords.left : texcoords.right;      std::array<ScreenRectVertex, 4> vertices = {{ -        ScreenRectVertex(x, y, texcoords.top, texcoords.right), -        ScreenRectVertex(x + w, y, texcoords.bottom, texcoords.right), -        ScreenRectVertex(x, y + h, texcoords.top, texcoords.left), -        ScreenRectVertex(x + w, y + h, texcoords.bottom, texcoords.left), +        ScreenRectVertex(x, y, texcoords.top, right), +        ScreenRectVertex(x + w, y, texcoords.bottom, right), +        ScreenRectVertex(x, y + h, texcoords.top, left), +        ScreenRectVertex(x + w, y + h, texcoords.bottom, left),      }};      state.texture_units[0].texture_2d = screen_info.display_texture; diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index db6c355a5..05bb3c5cf 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -86,4 +86,7 @@ private:      // Shader attribute input indices      GLuint attrib_position;      GLuint attrib_tex_coord; + +    /// Flips the framebuffer vertically when true +    bool framebuffer_flip_vertical;  }; | 
