diff options
Diffstat (limited to 'src/core/hw/gpu.h')
-rw-r--r-- | src/core/hw/gpu.h | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 7de05523..75f52446 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -34,13 +34,6 @@ namespace GPU { // MMIO region 0x1EFxxxxx struct Regs { -// helper macro to properly align structure members. -// Calling INSERT_PADDING_WORDS will add a new member variable with a name like "pad121", -// depending on the current source line to make sure variable names are unique. -#define INSERT_PADDING_WORDS_HELPER1(x, y) x ## y -#define INSERT_PADDING_WORDS_HELPER2(x, y) INSERT_PADDING_WORDS_HELPER1(x, y) -#define INSERT_PADDING_WORDS(num_words) u32 INSERT_PADDING_WORDS_HELPER2(pad, __LINE__)[(num_words)] - // helper macro to make sure the defined structures are of the expected size. #if defined(_MSC_VER) // TODO: MSVC does not support using sizeof() on non-static data members even though this @@ -53,6 +46,7 @@ struct Regs { "Structure size and register block length don't match") #endif + // All of those formats are described in reverse byte order, since the 3DS is little-endian. enum class PixelFormat : u32 { RGBA8 = 0, RGB8 = 1, @@ -61,13 +55,57 @@ struct Regs { RGBA4 = 4, }; + /** + * Returns the number of bytes per pixel. + */ + static int BytesPerPixel(PixelFormat format) { + switch (format) { + case PixelFormat::RGBA8: + return 4; + case PixelFormat::RGB8: + return 3; + case PixelFormat::RGB565: + case PixelFormat::RGB5A1: + case PixelFormat::RGBA4: + return 2; + default: + UNIMPLEMENTED(); + } + } + INSERT_PADDING_WORDS(0x4); struct { u32 address_start; - u32 address_end; // ? - u32 size; - u32 value; // ? + u32 address_end; + + union { + u32 value_32bit; + + BitField<0, 16, u32> value_16bit; + + // TODO: Verify component order + BitField< 0, 8, u32> value_24bit_r; + BitField< 8, 8, u32> value_24bit_g; + BitField<16, 8, u32> value_24bit_b; + }; + + union { + u32 control; + + // Setting this field to 1 triggers the memory fill. + // This field also acts as a status flag, and gets reset to 0 upon completion. + BitField<0, 1, u32> trigger; + + // Set to 1 upon completion. + BitField<0, 1, u32> finished; + + // 0: fill with 16- or 32-bit wide values; 1: fill with 24-bit wide values + BitField<8, 1, u32> fill_24bit; + + // 0: fill with 16-bit wide values; 1: fill with 32-bit wide values + BitField<9, 1, u32> fill_32bit; + }; inline u32 GetStartAddress() const { return DecodeAddressRegister(address_start); @@ -193,10 +231,6 @@ struct Regs { INSERT_PADDING_WORDS(0x9c3); -#undef INSERT_PADDING_WORDS_HELPER1 -#undef INSERT_PADDING_WORDS_HELPER2 -#undef INSERT_PADDING_WORDS - static inline size_t NumIds() { return sizeof(Regs) / sizeof(u32); } @@ -252,9 +286,6 @@ void Read(T &var, const u32 addr); template <typename T> void Write(u32 addr, const T data); -/// Update hardware -void Update(); - /// Initialize hardware void Init(); |