diff options
| author | 2014-07-16 11:27:58 +0200 | |
|---|---|---|
| committer | 2014-07-23 00:33:08 +0200 | |
| commit | 246cb75584af281596b938f898e8a3aedbcdb62a (patch) | |
| tree | e87322b8dbcf7e7d2975bc6874f0fd3487a46eb7 /src | |
| parent | GPU: Make use of RegisterSet. (diff) | |
| download | yuzu-246cb75584af281596b938f898e8a3aedbcdb62a.tar.gz yuzu-246cb75584af281596b938f898e8a3aedbcdb62a.tar.xz yuzu-246cb75584af281596b938f898e8a3aedbcdb62a.zip | |
RegisterSet: Simplify code by using structs for register definition instead of unions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/register_set.h | 14 | ||||
| -rw-r--r-- | src/core/hw/gpu.cpp | 102 | ||||
| -rw-r--r-- | src/core/hw/gpu.h | 154 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 18 |
4 files changed, 140 insertions, 148 deletions
diff --git a/src/common/register_set.h b/src/common/register_set.h index 0418551b3..ba19a2614 100644 --- a/src/common/register_set.h +++ b/src/common/register_set.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | /* | 34 | /* |
| 35 | * Standardized way to define a group of registers and corresponding data structures. To define | 35 | * Standardized way to define a group of registers and corresponding data structures. To define |
| 36 | * a new register set, first define struct containing an enumeration called "Id" containing | 36 | * a new register set, first define struct containing an enumeration called "Id" containing |
| 37 | * all register IDs and a template union called "Struct". Specialize the Struct union for any | 37 | * all register IDs and a template struct called "Struct". Specialize the Struct struct for any |
| 38 | * register ID which needs to be accessed in a specialized way. You can then declare the object | 38 | * register ID which needs to be accessed in a specialized way. You can then declare the object |
| 39 | * containing all register values using the RegisterSet<BaseType, DefiningStruct> type, where | 39 | * containing all register values using the RegisterSet<BaseType, DefiningStruct> type, where |
| 40 | * BaseType is the underlying type of each register (e.g. u32). | 40 | * BaseType is the underlying type of each register (e.g. u32). |
| @@ -54,7 +54,7 @@ | |||
| 54 | * | 54 | * |
| 55 | * // declare register definition structures | 55 | * // declare register definition structures |
| 56 | * template<Id id> | 56 | * template<Id id> |
| 57 | * union Struct; | 57 | * struct Struct; |
| 58 | * }; | 58 | * }; |
| 59 | * | 59 | * |
| 60 | * // Define register set object | 60 | * // Define register set object |
| @@ -62,9 +62,11 @@ | |||
| 62 | * | 62 | * |
| 63 | * // define register definition structures | 63 | * // define register definition structures |
| 64 | * template<> | 64 | * template<> |
| 65 | * union Regs::Struct<Regs::Value1> { | 65 | * struct Regs::Struct<Regs::Value1> { |
| 66 | * BitField<0, 4, u32> some_field; | 66 | * union { |
| 67 | * BitField<4, 3, u32> some_other_field; | 67 | * BitField<0, 4, u32> some_field; |
| 68 | * BitField<4, 3, u32> some_other_field; | ||
| 69 | * }; | ||
| 68 | * }; | 70 | * }; |
| 69 | * | 71 | * |
| 70 | * Usage in external code (within SomeNamespace scope): | 72 | * Usage in external code (within SomeNamespace scope): |
| @@ -77,7 +79,7 @@ | |||
| 77 | * | 79 | * |
| 78 | * | 80 | * |
| 79 | * @tparam BaseType Base type used for storing individual registers, e.g. u32 | 81 | * @tparam BaseType Base type used for storing individual registers, e.g. u32 |
| 80 | * @tparam RegDefinition Class defining an enumeration called "Id" and a template<Id id> union, as described above. | 82 | * @tparam RegDefinition Class defining an enumeration called "Id" and a template<Id id> struct, as described above. |
| 81 | * @note RegDefinition::Id needs to have an enum value called NumIds defining the number of registers to be allocated. | 83 | * @note RegDefinition::Id needs to have an enum value called NumIds defining the number of registers to be allocated. |
| 82 | */ | 84 | */ |
| 83 | template<typename BaseType, typename RegDefinition> | 85 | template<typename BaseType, typename RegDefinition> |
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 372e4f4cc..edffa25c5 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -30,14 +30,14 @@ void SetFramebufferLocation(const FramebufferLocation mode) { | |||
| 30 | auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); | 30 | auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); |
| 31 | auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); | 31 | auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); |
| 32 | 32 | ||
| 33 | framebuffer_top.data.address_left1 = PADDR_TOP_LEFT_FRAME1; | 33 | framebuffer_top.address_left1 = PADDR_TOP_LEFT_FRAME1; |
| 34 | framebuffer_top.data.address_left2 = PADDR_TOP_LEFT_FRAME2; | 34 | framebuffer_top.address_left2 = PADDR_TOP_LEFT_FRAME2; |
| 35 | framebuffer_top.data.address_right1 = PADDR_TOP_RIGHT_FRAME1; | 35 | framebuffer_top.address_right1 = PADDR_TOP_RIGHT_FRAME1; |
| 36 | framebuffer_top.data.address_right2 = PADDR_TOP_RIGHT_FRAME2; | 36 | framebuffer_top.address_right2 = PADDR_TOP_RIGHT_FRAME2; |
| 37 | framebuffer_sub.data.address_left1 = PADDR_SUB_FRAME1; | 37 | framebuffer_sub.address_left1 = PADDR_SUB_FRAME1; |
| 38 | //framebuffer_sub.data.address_left2 = unknown; | 38 | //framebuffer_sub.address_left2 = unknown; |
| 39 | framebuffer_sub.data.address_right1 = PADDR_SUB_FRAME2; | 39 | framebuffer_sub.address_right1 = PADDR_SUB_FRAME2; |
| 40 | //framebuffer_sub.data.address_right2 = unknown; | 40 | //framebuffer_sub.address_right2 = unknown; |
| 41 | break; | 41 | break; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| @@ -46,14 +46,14 @@ void SetFramebufferLocation(const FramebufferLocation mode) { | |||
| 46 | auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); | 46 | auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); |
| 47 | auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); | 47 | auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); |
| 48 | 48 | ||
| 49 | framebuffer_top.data.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1; | 49 | framebuffer_top.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1; |
| 50 | framebuffer_top.data.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2; | 50 | framebuffer_top.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2; |
| 51 | framebuffer_top.data.address_right1 = PADDR_VRAM_TOP_RIGHT_FRAME1; | 51 | framebuffer_top.address_right1 = PADDR_VRAM_TOP_RIGHT_FRAME1; |
| 52 | framebuffer_top.data.address_right2 = PADDR_VRAM_TOP_RIGHT_FRAME2; | 52 | framebuffer_top.address_right2 = PADDR_VRAM_TOP_RIGHT_FRAME2; |
| 53 | framebuffer_sub.data.address_left1 = PADDR_VRAM_SUB_FRAME1; | 53 | framebuffer_sub.address_left1 = PADDR_VRAM_SUB_FRAME1; |
| 54 | //framebuffer_sub.data.address_left2 = unknown; | 54 | //framebuffer_sub.address_left2 = unknown; |
| 55 | framebuffer_sub.data.address_right1 = PADDR_VRAM_SUB_FRAME2; | 55 | framebuffer_sub.address_right1 = PADDR_VRAM_SUB_FRAME2; |
| 56 | //framebuffer_sub.data.address_right2 = unknown; | 56 | //framebuffer_sub.address_right2 = unknown; |
| 57 | break; | 57 | break; |
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| @@ -135,14 +135,14 @@ inline void Write(u32 addr, const T data) { | |||
| 135 | const auto& config = g_regs.Get<Regs::MemoryFill>(static_cast<Regs::Id>(index - 3)); | 135 | const auto& config = g_regs.Get<Regs::MemoryFill>(static_cast<Regs::Id>(index - 3)); |
| 136 | 136 | ||
| 137 | // TODO: Not sure if this check should be done at GSP level instead | 137 | // TODO: Not sure if this check should be done at GSP level instead |
| 138 | if (config.data.address_start) { | 138 | if (config.address_start) { |
| 139 | // TODO: Not sure if this algorithm is correct, particularly because it doesn't use the size member at all | 139 | // TODO: Not sure if this algorithm is correct, particularly because it doesn't use the size member at all |
| 140 | u32* start = (u32*)Memory::GetPointer(config.data.GetStartAddress()); | 140 | u32* start = (u32*)Memory::GetPointer(config.GetStartAddress()); |
| 141 | u32* end = (u32*)Memory::GetPointer(config.data.GetEndAddress()); | 141 | u32* end = (u32*)Memory::GetPointer(config.GetEndAddress()); |
| 142 | for (u32* ptr = start; ptr < end; ++ptr) | 142 | for (u32* ptr = start; ptr < end; ++ptr) |
| 143 | *ptr = bswap32(config.data.value); // TODO: This is just a workaround to missing framebuffer format emulation | 143 | *ptr = bswap32(config.value); // TODO: This is just a workaround to missing framebuffer format emulation |
| 144 | 144 | ||
| 145 | DEBUG_LOG(GPU, "MemoryFill from %x to %x", config.data.GetStartAddress(), config.data.GetEndAddress()); | 145 | DEBUG_LOG(GPU, "MemoryFill from %x to %x", config.GetStartAddress(), config.GetEndAddress()); |
| 146 | } | 146 | } |
| 147 | break; | 147 | break; |
| 148 | } | 148 | } |
| @@ -150,20 +150,20 @@ inline void Write(u32 addr, const T data) { | |||
| 150 | case Regs::DisplayTransfer + 6: | 150 | case Regs::DisplayTransfer + 6: |
| 151 | { | 151 | { |
| 152 | const auto& config = g_regs.Get<Regs::DisplayTransfer>(); | 152 | const auto& config = g_regs.Get<Regs::DisplayTransfer>(); |
| 153 | if (config.data.trigger & 1) { | 153 | if (config.trigger & 1) { |
| 154 | u8* source_pointer = Memory::GetPointer(config.data.GetPhysicalInputAddress()); | 154 | u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress()); |
| 155 | u8* dest_pointer = Memory::GetPointer(config.data.GetPhysicalOutputAddress()); | 155 | u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress()); |
| 156 | 156 | ||
| 157 | for (int y = 0; y < config.data.output_height; ++y) { | 157 | for (int y = 0; y < config.output_height; ++y) { |
| 158 | // TODO: Why does the register seem to hold twice the framebuffer width? | 158 | // TODO: Why does the register seem to hold twice the framebuffer width? |
| 159 | for (int x = 0; x < config.data.output_width / 2; ++x) { | 159 | for (int x = 0; x < config.output_width / 2; ++x) { |
| 160 | int source[4] = { 0, 0, 0, 0}; // rgba; | 160 | int source[4] = { 0, 0, 0, 0}; // rgba; |
| 161 | 161 | ||
| 162 | switch (config.data.input_format) { | 162 | switch (config.input_format) { |
| 163 | case Regs::FramebufferFormat::RGBA8: | 163 | case Regs::FramebufferFormat::RGBA8: |
| 164 | { | 164 | { |
| 165 | // TODO: Most likely got the component order messed up. | 165 | // TODO: Most likely got the component order messed up. |
| 166 | u8* srcptr = source_pointer + x * 4 + y * config.data.input_width * 4 / 2; | 166 | u8* srcptr = source_pointer + x * 4 + y * config.input_width * 4 / 2; |
| 167 | source[0] = srcptr[0]; // blue | 167 | source[0] = srcptr[0]; // blue |
| 168 | source[1] = srcptr[1]; // green | 168 | source[1] = srcptr[1]; // green |
| 169 | source[2] = srcptr[2]; // red | 169 | source[2] = srcptr[2]; // red |
| @@ -172,15 +172,15 @@ inline void Write(u32 addr, const T data) { | |||
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | default: | 174 | default: |
| 175 | ERROR_LOG(GPU, "Unknown source framebuffer format %x", config.data.input_format.Value()); | 175 | ERROR_LOG(GPU, "Unknown source framebuffer format %x", config.input_format.Value()); |
| 176 | break; | 176 | break; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | switch (config.data.output_format) { | 179 | switch (config.output_format) { |
| 180 | /*case Regs::FramebufferFormat::RGBA8: | 180 | /*case Regs::FramebufferFormat::RGBA8: |
| 181 | { | 181 | { |
| 182 | // TODO: Untested | 182 | // TODO: Untested |
| 183 | u8* dstptr = (u32*)(dest_pointer + x * 4 + y * config.data.output_width * 4); | 183 | u8* dstptr = (u32*)(dest_pointer + x * 4 + y * config.output_width * 4); |
| 184 | dstptr[0] = source[0]; | 184 | dstptr[0] = source[0]; |
| 185 | dstptr[1] = source[1]; | 185 | dstptr[1] = source[1]; |
| 186 | dstptr[2] = source[2]; | 186 | dstptr[2] = source[2]; |
| @@ -190,7 +190,7 @@ inline void Write(u32 addr, const T data) { | |||
| 190 | 190 | ||
| 191 | case Regs::FramebufferFormat::RGB8: | 191 | case Regs::FramebufferFormat::RGB8: |
| 192 | { | 192 | { |
| 193 | u8* dstptr = dest_pointer + x * 3 + y * config.data.output_width * 3 / 2; | 193 | u8* dstptr = dest_pointer + x * 3 + y * config.output_width * 3 / 2; |
| 194 | dstptr[0] = source[0]; // blue | 194 | dstptr[0] = source[0]; // blue |
| 195 | dstptr[1] = source[1]; // green | 195 | dstptr[1] = source[1]; // green |
| 196 | dstptr[2] = source[2]; // red | 196 | dstptr[2] = source[2]; // red |
| @@ -198,17 +198,17 @@ inline void Write(u32 addr, const T data) { | |||
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | default: | 200 | default: |
| 201 | ERROR_LOG(GPU, "Unknown destination framebuffer format %x", config.data.output_format.Value()); | 201 | ERROR_LOG(GPU, "Unknown destination framebuffer format %x", config.output_format.Value()); |
| 202 | break; | 202 | break; |
| 203 | } | 203 | } |
| 204 | } | 204 | } |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | DEBUG_LOG(GPU, "DisplayTriggerTransfer: %x bytes from %x(%xx%x)-> %x(%xx%x), dst format %x", | 207 | DEBUG_LOG(GPU, "DisplayTriggerTransfer: %x bytes from %x(%xx%x)-> %x(%xx%x), dst format %x", |
| 208 | config.data.output_height * config.data.output_width * 4, | 208 | config.output_height * config.output_width * 4, |
| 209 | config.data.GetPhysicalInputAddress(), (int)config.data.input_width, (int)config.data.input_height, | 209 | config.GetPhysicalInputAddress(), (int)config.input_width, (int)config.input_height, |
| 210 | config.data.GetPhysicalOutputAddress(), (int)config.data.output_width, (int)config.data.output_height, | 210 | config.GetPhysicalOutputAddress(), (int)config.output_width, (int)config.output_height, |
| 211 | config.data.output_format.Value()); | 211 | config.output_format.Value()); |
| 212 | } | 212 | } |
| 213 | break; | 213 | break; |
| 214 | } | 214 | } |
| @@ -216,10 +216,10 @@ inline void Write(u32 addr, const T data) { | |||
| 216 | case Regs::CommandProcessor + 4: | 216 | case Regs::CommandProcessor + 4: |
| 217 | { | 217 | { |
| 218 | const auto& config = g_regs.Get<Regs::CommandProcessor>(); | 218 | const auto& config = g_regs.Get<Regs::CommandProcessor>(); |
| 219 | if (config.data.trigger & 1) | 219 | if (config.trigger & 1) |
| 220 | { | 220 | { |
| 221 | // u32* buffer = (u32*)Memory::GetPointer(config.data.address << 3); | 221 | // u32* buffer = (u32*)Memory::GetPointer(config.address << 3); |
| 222 | ERROR_LOG(GPU, "Beginning %x bytes of commands from address %x", config.data.size, config.data.address << 3); | 222 | ERROR_LOG(GPU, "Beginning %x bytes of commands from address %x", config.size, config.address << 3); |
| 223 | // TODO: Process command list! | 223 | // TODO: Process command list! |
| 224 | } | 224 | } |
| 225 | break; | 225 | break; |
| @@ -263,17 +263,17 @@ void Init() { | |||
| 263 | auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); | 263 | auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); |
| 264 | auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); | 264 | auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); |
| 265 | // TODO: Width should be 240 instead? | 265 | // TODO: Width should be 240 instead? |
| 266 | framebuffer_top.data.width = 480; | 266 | framebuffer_top.width = 480; |
| 267 | framebuffer_top.data.height = 400; | 267 | framebuffer_top.height = 400; |
| 268 | framebuffer_top.data.stride = 480*3; | 268 | framebuffer_top.stride = 480*3; |
| 269 | framebuffer_top.data.color_format = Regs::FramebufferFormat::RGB8; | 269 | framebuffer_top.color_format = Regs::FramebufferFormat::RGB8; |
| 270 | framebuffer_top.data.active_fb = 0; | 270 | framebuffer_top.active_fb = 0; |
| 271 | 271 | ||
| 272 | framebuffer_sub.data.width = 480; | 272 | framebuffer_sub.width = 480; |
| 273 | framebuffer_sub.data.height = 400; | 273 | framebuffer_sub.height = 400; |
| 274 | framebuffer_sub.data.stride = 480*3; | 274 | framebuffer_sub.stride = 480*3; |
| 275 | framebuffer_sub.data.color_format = Regs::FramebufferFormat::RGB8; | 275 | framebuffer_sub.color_format = Regs::FramebufferFormat::RGB8; |
| 276 | framebuffer_sub.data.active_fb = 0; | 276 | framebuffer_sub.active_fb = 0; |
| 277 | 277 | ||
| 278 | NOTICE_LOG(GPU, "initialized OK"); | 278 | NOTICE_LOG(GPU, "initialized OK"); |
| 279 | } | 279 | } |
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index ce524bd02..4ef0a047f 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h | |||
| @@ -29,7 +29,7 @@ struct Regs { | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | template<Id id> | 31 | template<Id id> |
| 32 | union Struct; | 32 | struct Struct; |
| 33 | 33 | ||
| 34 | enum class FramebufferFormat : u32 { | 34 | enum class FramebufferFormat : u32 { |
| 35 | RGBA8 = 0, | 35 | RGBA8 = 0, |
| @@ -38,128 +38,118 @@ struct Regs { | |||
| 38 | RGB5A1 = 3, | 38 | RGB5A1 = 3, |
| 39 | RGBA4 = 4, | 39 | RGBA4 = 4, |
| 40 | }; | 40 | }; |
| 41 | |||
| 42 | }; | 41 | }; |
| 43 | 42 | ||
| 44 | template<> | 43 | template<> |
| 45 | union Regs::Struct<Regs::MemoryFill> { | 44 | struct Regs::Struct<Regs::MemoryFill> { |
| 46 | struct { | 45 | u32 address_start; |
| 47 | u32 address_start; | 46 | u32 address_end; // ? |
| 48 | u32 address_end; // ? | 47 | u32 size; |
| 49 | u32 size; | 48 | u32 value; // ? |
| 50 | u32 value; // ? | 49 | |
| 51 | 50 | inline u32 GetStartAddress() const { | |
| 52 | inline u32 GetStartAddress() const { | 51 | return address_start * 8; |
| 53 | return address_start * 8; | 52 | } |
| 54 | } | 53 | |
| 55 | 54 | inline u32 GetEndAddress() const { | |
| 56 | inline u32 GetEndAddress() const { | 55 | return address_end * 8; |
| 57 | return address_end * 8; | 56 | } |
| 58 | } | ||
| 59 | } data; | ||
| 60 | }; | 57 | }; |
| 61 | static_assert(sizeof(Regs::Struct<Regs::MemoryFill>) == 0x10, "Structure size and register block length don't match"); | 58 | static_assert(sizeof(Regs::Struct<Regs::MemoryFill>) == 0x10, "Structure size and register block length don't match"); |
| 62 | 59 | ||
| 63 | template<> | 60 | template<> |
| 64 | union Regs::Struct<Regs::FramebufferTop> { | 61 | struct Regs::Struct<Regs::FramebufferTop> { |
| 65 | using Format = Regs::FramebufferFormat; | 62 | using Format = Regs::FramebufferFormat; |
| 66 | 63 | ||
| 67 | struct { | 64 | union { |
| 68 | union { | 65 | u32 size; |
| 69 | u32 size; | ||
| 70 | 66 | ||
| 71 | BitField< 0, 16, u32> width; | 67 | BitField< 0, 16, u32> width; |
| 72 | BitField<16, 16, u32> height; | 68 | BitField<16, 16, u32> height; |
| 73 | }; | 69 | }; |
| 74 | 70 | ||
| 75 | u32 pad0[2]; | 71 | u32 pad0[2]; |
| 76 | 72 | ||
| 77 | u32 address_left1; | 73 | u32 address_left1; |
| 78 | u32 address_left2; | 74 | u32 address_left2; |
| 79 | 75 | ||
| 80 | union { | 76 | union { |
| 81 | u32 format; | 77 | u32 format; |
| 82 | 78 | ||
| 83 | BitField< 0, 3, Format> color_format; | 79 | BitField< 0, 3, Format> color_format; |
| 84 | }; | 80 | }; |
| 85 | 81 | ||
| 86 | u32 pad1; | 82 | u32 pad1; |
| 87 | 83 | ||
| 88 | union { | 84 | union { |
| 89 | u32 active_fb; | 85 | u32 active_fb; |
| 90 | 86 | ||
| 91 | BitField<0, 1, u32> second_fb_active; | 87 | BitField<0, 1, u32> second_fb_active; |
| 92 | }; | 88 | }; |
| 93 | 89 | ||
| 94 | u32 pad2[5]; | 90 | u32 pad2[5]; |
| 95 | 91 | ||
| 96 | u32 stride; | 92 | u32 stride; |
| 97 | 93 | ||
| 98 | u32 address_right1; | 94 | u32 address_right1; |
| 99 | u32 address_right2; | 95 | u32 address_right2; |
| 100 | } data; | ||
| 101 | }; | 96 | }; |
| 97 | |||
| 102 | template<> | 98 | template<> |
| 103 | union Regs::Struct<Regs::FramebufferBottom> { | 99 | struct Regs::Struct<Regs::FramebufferBottom> : public Regs::Struct<Regs::FramebufferTop> { |
| 104 | using Type = decltype(Regs::Struct<Regs::FramebufferTop>::data); | ||
| 105 | Type data; | ||
| 106 | }; | 100 | }; |
| 107 | static_assert(sizeof(Regs::Struct<Regs::FramebufferTop>) == 0x40, "Structure size and register block length don't match"); | 101 | static_assert(sizeof(Regs::Struct<Regs::FramebufferTop>) == 0x40, "Structure size and register block length don't match"); |
| 108 | 102 | ||
| 109 | template<> | 103 | template<> |
| 110 | union Regs::Struct<Regs::DisplayTransfer> { | 104 | struct Regs::Struct<Regs::DisplayTransfer> { |
| 111 | using Format = Regs::FramebufferFormat; | 105 | using Format = Regs::FramebufferFormat; |
| 112 | 106 | ||
| 113 | struct { | 107 | u32 input_address; |
| 114 | u32 input_address; | 108 | u32 output_address; |
| 115 | u32 output_address; | ||
| 116 | 109 | ||
| 117 | inline u32 GetPhysicalInputAddress() const { | 110 | inline u32 GetPhysicalInputAddress() const { |
| 118 | return input_address * 8; | 111 | return input_address * 8; |
| 119 | } | 112 | } |
| 120 | 113 | ||
| 121 | inline u32 GetPhysicalOutputAddress() const { | 114 | inline u32 GetPhysicalOutputAddress() const { |
| 122 | return output_address * 8; | 115 | return output_address * 8; |
| 123 | } | 116 | } |
| 124 | 117 | ||
| 125 | union { | 118 | union { |
| 126 | u32 output_size; | 119 | u32 output_size; |
| 127 | 120 | ||
| 128 | BitField< 0, 16, u32> output_width; | 121 | BitField< 0, 16, u32> output_width; |
| 129 | BitField<16, 16, u32> output_height; | 122 | BitField<16, 16, u32> output_height; |
| 130 | }; | 123 | }; |
| 131 | 124 | ||
| 132 | union { | 125 | union { |
| 133 | u32 input_size; | 126 | u32 input_size; |
| 134 | 127 | ||
| 135 | BitField< 0, 16, u32> input_width; | 128 | BitField< 0, 16, u32> input_width; |
| 136 | BitField<16, 16, u32> input_height; | 129 | BitField<16, 16, u32> input_height; |
| 137 | }; | 130 | }; |
| 138 | 131 | ||
| 139 | union { | 132 | union { |
| 140 | u32 flags; | 133 | u32 flags; |
| 141 | 134 | ||
| 142 | BitField< 0, 1, u32> flip_data; | 135 | BitField< 0, 1, u32> flip_data; |
| 143 | BitField< 8, 3, Format> input_format; | 136 | BitField< 8, 3, Format> input_format; |
| 144 | BitField<12, 3, Format> output_format; | 137 | BitField<12, 3, Format> output_format; |
| 145 | BitField<16, 1, u32> output_tiled; | 138 | BitField<16, 1, u32> output_tiled; |
| 146 | }; | 139 | }; |
| 147 | 140 | ||
| 148 | u32 unknown; | 141 | u32 unknown; |
| 149 | u32 trigger; | 142 | u32 trigger; |
| 150 | } data; | ||
| 151 | }; | 143 | }; |
| 152 | static_assert(sizeof(Regs::Struct<Regs::DisplayTransfer>) == 0x1C, "Structure size and register block length don't match"); | 144 | static_assert(sizeof(Regs::Struct<Regs::DisplayTransfer>) == 0x1C, "Structure size and register block length don't match"); |
| 153 | 145 | ||
| 154 | template<> | 146 | template<> |
| 155 | union Regs::Struct<Regs::CommandProcessor> { | 147 | struct Regs::Struct<Regs::CommandProcessor> { |
| 156 | struct { | 148 | u32 size; |
| 157 | u32 size; | 149 | u32 pad0; |
| 158 | u32 pad0; | 150 | u32 address; |
| 159 | u32 address; | 151 | u32 pad1; |
| 160 | u32 pad1; | 152 | u32 trigger; |
| 161 | u32 trigger; | ||
| 162 | } data; | ||
| 163 | }; | 153 | }; |
| 164 | static_assert(sizeof(Regs::Struct<Regs::CommandProcessor>) == 0x14, "Structure size and register block length don't match"); | 154 | static_assert(sizeof(Regs::Struct<Regs::CommandProcessor>) == 0x14, "Structure size and register block length don't match"); |
| 165 | 155 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8d9d61ae8..50f820e4a 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -80,17 +80,17 @@ void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect& | |||
| 80 | 80 | ||
| 81 | const auto& framebuffer_top = GPU::g_regs.Get<GPU::Regs::FramebufferTop>(); | 81 | const auto& framebuffer_top = GPU::g_regs.Get<GPU::Regs::FramebufferTop>(); |
| 82 | const auto& framebuffer_sub = GPU::g_regs.Get<GPU::Regs::FramebufferBottom>(); | 82 | const auto& framebuffer_sub = GPU::g_regs.Get<GPU::Regs::FramebufferBottom>(); |
| 83 | const u32 active_fb_top = (framebuffer_top.data.active_fb == 1) | 83 | const u32 active_fb_top = (framebuffer_top.active_fb == 1) |
| 84 | ? framebuffer_top.data.address_left2 | 84 | ? framebuffer_top.address_left2 |
| 85 | : framebuffer_top.data.address_left1; | 85 | : framebuffer_top.address_left1; |
| 86 | const u32 active_fb_sub = (framebuffer_sub.data.active_fb == 1) | 86 | const u32 active_fb_sub = (framebuffer_sub.active_fb == 1) |
| 87 | ? framebuffer_sub.data.address_left2 | 87 | ? framebuffer_sub.address_left2 |
| 88 | : framebuffer_sub.data.address_left1; | 88 | : framebuffer_sub.address_left1; |
| 89 | 89 | ||
| 90 | DEBUG_LOG(GPU, "RenderXFB: %x bytes from %x(%xx%x), fmt %x", | 90 | DEBUG_LOG(GPU, "RenderXFB: %x bytes from %x(%xx%x), fmt %x", |
| 91 | framebuffer_top.data.stride * framebuffer_top.data.height, | 91 | framebuffer_top.stride * framebuffer_top.height, |
| 92 | GPU::GetFramebufferAddr(active_fb_top), (int)framebuffer_top.data.width, | 92 | GPU::GetFramebufferAddr(active_fb_top), (int)framebuffer_top.width, |
| 93 | (int)framebuffer_top.data.height, (int)framebuffer_top.data.format); | 93 | (int)framebuffer_top.height, (int)framebuffer_top.format); |
| 94 | 94 | ||
| 95 | // TODO: This should consider the GPU registers for framebuffer width, height and stride. | 95 | // TODO: This should consider the GPU registers for framebuffer width, height and stride. |
| 96 | FlipFramebuffer(GPU::GetFramebufferPointer(active_fb_top), m_xfb_top_flipped); | 96 | FlipFramebuffer(GPU::GetFramebufferPointer(active_fb_top), m_xfb_top_flipped); |