diff options
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 24dc37856..a7bb0612f 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -7,13 +7,14 @@ | |||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/math_util.h" | 8 | #include "common/math_util.h" |
| 9 | 9 | ||
| 10 | #include "core/hw/gpu.h" | ||
| 11 | #include "debug_utils/debug_utils.h" | ||
| 10 | #include "math.h" | 12 | #include "math.h" |
| 11 | #include "color.h" | 13 | #include "color.h" |
| 12 | #include "pica.h" | 14 | #include "pica.h" |
| 13 | #include "rasterizer.h" | 15 | #include "rasterizer.h" |
| 14 | #include "vertex_shader.h" | 16 | #include "vertex_shader.h" |
| 15 | 17 | #include "video_core/utils.h" | |
| 16 | #include "debug_utils/debug_utils.h" | ||
| 17 | 18 | ||
| 18 | namespace Pica { | 19 | namespace Pica { |
| 19 | 20 | ||
| @@ -27,10 +28,14 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { | |||
| 27 | // NOTE: The framebuffer height register contains the actual FB height minus one. | 28 | // NOTE: The framebuffer height register contains the actual FB height minus one. |
| 28 | y = (registers.framebuffer.height - y); | 29 | y = (registers.framebuffer.height - y); |
| 29 | 30 | ||
| 31 | const u32 coarse_y = y & ~7; | ||
| 32 | u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); | ||
| 33 | u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel; | ||
| 34 | |||
| 30 | switch (registers.framebuffer.color_format) { | 35 | switch (registers.framebuffer.color_format) { |
| 31 | case registers.framebuffer.RGBA8: | 36 | case registers.framebuffer.RGBA8: |
| 32 | { | 37 | { |
| 33 | u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 4; | 38 | u8* pixel = color_buffer + dst_offset; |
| 34 | pixel[3] = color.r(); | 39 | pixel[3] = color.r(); |
| 35 | pixel[2] = color.g(); | 40 | pixel[2] = color.g(); |
| 36 | pixel[1] = color.b(); | 41 | pixel[1] = color.b(); |
| @@ -40,14 +45,14 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { | |||
| 40 | 45 | ||
| 41 | case registers.framebuffer.RGBA4: | 46 | case registers.framebuffer.RGBA4: |
| 42 | { | 47 | { |
| 43 | u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 2; | 48 | u8* pixel = color_buffer + dst_offset; |
| 44 | pixel[1] = (color.r() & 0xF0) | (color.g() >> 4); | 49 | pixel[1] = (color.r() & 0xF0) | (color.g() >> 4); |
| 45 | pixel[0] = (color.b() & 0xF0) | (color.a() >> 4); | 50 | pixel[0] = (color.b() & 0xF0) | (color.a() >> 4); |
| 46 | break; | 51 | break; |
| 47 | } | 52 | } |
| 48 | 53 | ||
| 49 | default: | 54 | default: |
| 50 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); | 55 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); |
| 51 | UNIMPLEMENTED(); | 56 | UNIMPLEMENTED(); |
| 52 | } | 57 | } |
| 53 | } | 58 | } |
| @@ -58,11 +63,15 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 58 | 63 | ||
| 59 | y = (registers.framebuffer.height - y); | 64 | y = (registers.framebuffer.height - y); |
| 60 | 65 | ||
| 66 | const u32 coarse_y = y & ~7; | ||
| 67 | u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); | ||
| 68 | u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel; | ||
| 69 | |||
| 61 | switch (registers.framebuffer.color_format) { | 70 | switch (registers.framebuffer.color_format) { |
| 62 | case registers.framebuffer.RGBA8: | 71 | case registers.framebuffer.RGBA8: |
| 63 | { | 72 | { |
| 64 | Math::Vec4<u8> ret; | 73 | Math::Vec4<u8> ret; |
| 65 | u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 4; | 74 | u8* pixel = color_buffer + src_offset; |
| 66 | ret.r() = pixel[3]; | 75 | ret.r() = pixel[3]; |
| 67 | ret.g() = pixel[2]; | 76 | ret.g() = pixel[2]; |
| 68 | ret.b() = pixel[1]; | 77 | ret.b() = pixel[1]; |
| @@ -73,7 +82,7 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 73 | case registers.framebuffer.RGBA4: | 82 | case registers.framebuffer.RGBA4: |
| 74 | { | 83 | { |
| 75 | Math::Vec4<u8> ret; | 84 | Math::Vec4<u8> ret; |
| 76 | u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 2; | 85 | u8* pixel = color_buffer + src_offset; |
| 77 | ret.r() = Color::Convert4To8(pixel[1] >> 4); | 86 | ret.r() = Color::Convert4To8(pixel[1] >> 4); |
| 78 | ret.g() = Color::Convert4To8(pixel[1] & 0x0F); | 87 | ret.g() = Color::Convert4To8(pixel[1] & 0x0F); |
| 79 | ret.b() = Color::Convert4To8(pixel[0] >> 4); | 88 | ret.b() = Color::Convert4To8(pixel[0] >> 4); |
| @@ -82,7 +91,7 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 82 | } | 91 | } |
| 83 | 92 | ||
| 84 | default: | 93 | default: |
| 85 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); | 94 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); |
| 86 | UNIMPLEMENTED(); | 95 | UNIMPLEMENTED(); |
| 87 | } | 96 | } |
| 88 | 97 | ||
| @@ -91,22 +100,28 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 91 | 100 | ||
| 92 | static u32 GetDepth(int x, int y) { | 101 | static u32 GetDepth(int x, int y) { |
| 93 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); | 102 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); |
| 94 | u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(addr))); | 103 | u8* depth_buffer = Memory::GetPointer(PAddrToVAddr(addr)); |
| 95 | 104 | ||
| 96 | y = (registers.framebuffer.height - y); | 105 | y = (registers.framebuffer.height - y); |
| 106 | |||
| 107 | const u32 coarse_y = y & ~7; | ||
| 108 | u32 stride = registers.framebuffer.width * 2; | ||
| 97 | 109 | ||
| 98 | // Assuming 16-bit depth buffer format until actual format handling is implemented | 110 | // Assuming 16-bit depth buffer format until actual format handling is implemented |
| 99 | return *(depth_buffer + x + y * registers.framebuffer.GetWidth()); | 111 | return *(u16*)(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride); |
| 100 | } | 112 | } |
| 101 | 113 | ||
| 102 | static void SetDepth(int x, int y, u16 value) { | 114 | static void SetDepth(int x, int y, u16 value) { |
| 103 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); | 115 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); |
| 104 | u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(addr))); | 116 | u8* depth_buffer = Memory::GetPointer(PAddrToVAddr(addr)); |
| 105 | 117 | ||
| 106 | y = (registers.framebuffer.height - y); | 118 | y = (registers.framebuffer.height - y); |
| 107 | 119 | ||
| 120 | const u32 coarse_y = y & ~7; | ||
| 121 | u32 stride = registers.framebuffer.width * 2; | ||
| 122 | |||
| 108 | // Assuming 16-bit depth buffer format until actual format handling is implemented | 123 | // Assuming 16-bit depth buffer format until actual format handling is implemented |
| 109 | *(depth_buffer + x + y * registers.framebuffer.GetWidth()) = value; | 124 | *(u16*)(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride) = value; |
| 110 | } | 125 | } |
| 111 | 126 | ||
| 112 | // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values | 127 | // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values |