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

GPU: Add display transfer configuration.

Tony Wasserka 12 лет назад
Родитель
Сommit
16bbc4f81b
2 измененных файлов с 92 добавлено и 0 удалено
  1. 52 0
      src/core/hw/gpu.cpp
  2. 40 0
      src/core/hw/gpu.h

+ 52 - 0
src/core/hw/gpu.cpp

@@ -108,6 +108,31 @@ inline void Read(T &var, const u32 addr) {
         var = g_regs.framebuffer_sub_right_1;
         break;
 
+    case Registers::DisplayInputBufferAddr:
+        var = g_regs.display_transfer.input_address;
+        break;
+
+    case Registers::DisplayOutputBufferAddr:
+        var = g_regs.display_transfer.output_address;
+        break;
+
+    case Registers::DisplayOutputBufferSize:
+        var = g_regs.display_transfer.output_size;
+        break;
+
+    case Registers::DisplayInputBufferSize:
+        var = g_regs.display_transfer.input_size;
+        break;
+
+    case Registers::DisplayTransferFlags:
+        var = g_regs.display_transfer.flags;
+        break;
+
+    // Not sure if this is supposed to be readable
+    case Registers::DisplayTriggerTransfer:
+        var = g_regs.display_transfer.trigger;
+        break;
+
     case Registers::CommandListSize:
         var = g_regs.command_list_size;
         break;
@@ -129,6 +154,33 @@ inline void Read(T &var, const u32 addr) {
 template <typename T>
 inline void Write(u32 addr, const T data) {
     switch (static_cast<Registers::Id>(addr)) {
+    case Registers::DisplayInputBufferAddr:
+        g_regs.display_transfer.input_address = data;
+        break;
+
+    case Registers::DisplayOutputBufferAddr:
+        g_regs.display_transfer.output_address = data;
+        break;
+
+    case Registers::DisplayOutputBufferSize:
+        g_regs.display_transfer.output_size = data;
+        break;
+
+    case Registers::DisplayInputBufferSize:
+        g_regs.display_transfer.input_size = data;
+        break;
+
+    case Registers::DisplayTransferFlags:
+        g_regs.display_transfer.flags = data;
+        break;
+
+    case Registers::DisplayTriggerTransfer:
+        g_regs.display_transfer.trigger = data;
+        if (g_regs.display_transfer.trigger & 1) {
+            // TODO: Perform display transfer!
+        }
+        break;
+
     case Registers::CommandListSize:
         g_regs.command_list_size = data;
         break;

+ 40 - 0
src/core/hw/gpu.h

@@ -5,6 +5,7 @@
 #pragma once
 
 #include "common/common_types.h"
+#include "common/bit_field.h"
 
 namespace GPU {
 
@@ -44,6 +45,45 @@ struct Registers {
     u32 framebuffer_sub_right_1;
     u32 framebuffer_sub_right_2;
 
+    struct {
+        u32 input_address;
+        u32 output_address;
+
+        inline u32 GetPhysicalInputAddress() const {
+            return input_address * 8;
+        }
+
+        inline u32 GetPhysicalOutputAddress() const {
+            return output_address * 8;
+        }
+
+        union {
+            u32 output_size;
+
+            BitField< 0, 16, u32> output_width;
+            BitField<16, 16, u32> output_height;
+        };
+
+        union {
+            u32 input_size;
+
+            BitField< 0, 16, u32> input_width;
+            BitField<16, 16, u32> input_height;
+        };
+
+        union {
+            u32 flags;
+
+            BitField< 0, 1, u32> flip_data;
+            BitField< 8, 3, u32> input_format;
+            BitField<12, 3, u32> output_format;
+            BitField<16, 1, u32> output_tiled;
+        };
+
+        u32 unknown;
+        u32 trigger;
+    } display_transfer;
+
     u32 command_list_size;
     u32 command_list_address;
     u32 command_processing_enabled;