diff options
Diffstat (limited to 'src/core/hw/gpu.cpp')
| -rw-r--r-- | src/core/hw/gpu.cpp | 102 |
1 files changed, 51 insertions, 51 deletions
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 | } |