summaryrefslogtreecommitdiff
path: root/src/video_core/rasterizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/rasterizer.cpp')
-rw-r--r--src/video_core/rasterizer.cpp39
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
18namespace Pica { 19namespace 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
92static u32 GetDepth(int x, int y) { 101static 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
102static void SetDepth(int x, int y, u16 value) { 114static 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