diff options
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 5861c1926..dc32128c6 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -91,7 +91,7 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | return {}; | 93 | return {}; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static u32 GetDepth(int x, int y) { | 96 | static u32 GetDepth(int x, int y) { |
| 97 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); | 97 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); |
| @@ -100,23 +100,65 @@ static u32 GetDepth(int x, int y) { | |||
| 100 | y = (registers.framebuffer.height - y); | 100 | y = (registers.framebuffer.height - y); |
| 101 | 101 | ||
| 102 | const u32 coarse_y = y & ~7; | 102 | const u32 coarse_y = y & ~7; |
| 103 | u32 stride = registers.framebuffer.width * 2; | ||
| 104 | 103 | ||
| 105 | // Assuming 16-bit depth buffer format until actual format handling is implemented | 104 | switch (registers.framebuffer.depth_format) { |
| 106 | return *(u16*)(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride); | 105 | case registers.framebuffer.D16: |
| 106 | { | ||
| 107 | u32 stride = registers.framebuffer.width * 2; | ||
| 108 | return Color::DecodeD16(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride); | ||
| 109 | } | ||
| 110 | case registers.framebuffer.D24: | ||
| 111 | { | ||
| 112 | u32 stride = registers.framebuffer.width * 3; | ||
| 113 | u8* address = depth_buffer + VideoCore::GetMortonOffset(x, y, 3) + coarse_y * stride; | ||
| 114 | return Color::DecodeD24(address); | ||
| 115 | } | ||
| 116 | case registers.framebuffer.D24S8: | ||
| 117 | { | ||
| 118 | u32 stride = registers.framebuffer.width * 4; | ||
| 119 | return Color::DecodeD24S8(depth_buffer + VideoCore::GetMortonOffset(x, y, 4) + coarse_y * stride).x; | ||
| 120 | } | ||
| 121 | default: | ||
| 122 | LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", registers.framebuffer.depth_format); | ||
| 123 | UNIMPLEMENTED(); | ||
| 124 | return 0; | ||
| 125 | } | ||
| 107 | } | 126 | } |
| 108 | 127 | ||
| 109 | static void SetDepth(int x, int y, u16 value) { | 128 | static void SetDepth(int x, int y, u32 value) { |
| 110 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); | 129 | const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); |
| 111 | u8* depth_buffer = Memory::GetPointer(PAddrToVAddr(addr)); | 130 | u8* depth_buffer = Memory::GetPointer(PAddrToVAddr(addr)); |
| 112 | 131 | ||
| 113 | y = (registers.framebuffer.height - y); | 132 | y = (registers.framebuffer.height - y); |
| 114 | 133 | ||
| 115 | const u32 coarse_y = y & ~7; | 134 | const u32 coarse_y = y & ~7; |
| 116 | u32 stride = registers.framebuffer.width * 2; | ||
| 117 | 135 | ||
| 118 | // Assuming 16-bit depth buffer format until actual format handling is implemented | 136 | switch (registers.framebuffer.depth_format) { |
| 119 | *(u16*)(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride) = value; | 137 | case registers.framebuffer.D16: |
| 138 | { | ||
| 139 | u32 stride = registers.framebuffer.width * 2; | ||
| 140 | Color::EncodeD16(value, depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride); | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | case registers.framebuffer.D24: | ||
| 144 | { | ||
| 145 | u32 stride = registers.framebuffer.width * 3; | ||
| 146 | u8* address = depth_buffer + VideoCore::GetMortonOffset(x, y, 3) + coarse_y * stride; | ||
| 147 | Color::EncodeD24(value, address); | ||
| 148 | break; | ||
| 149 | } | ||
| 150 | case registers.framebuffer.D24S8: | ||
| 151 | { | ||
| 152 | u32 stride = registers.framebuffer.width * 4; | ||
| 153 | // TODO(Subv): Implement the stencil buffer | ||
| 154 | Color::EncodeD24S8(value, 0, depth_buffer + VideoCore::GetMortonOffset(x, y, 4) + coarse_y * stride); | ||
| 155 | break; | ||
| 156 | } | ||
| 157 | default: | ||
| 158 | LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", registers.framebuffer.depth_format); | ||
| 159 | UNIMPLEMENTED(); | ||
| 160 | break; | ||
| 161 | } | ||
| 120 | } | 162 | } |
| 121 | 163 | ||
| 122 | // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values | 164 | // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values |
| @@ -595,7 +637,7 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0, | |||
| 595 | u16 z = (u16)((v0.screenpos[2].ToFloat32() * w0 + | 637 | u16 z = (u16)((v0.screenpos[2].ToFloat32() * w0 + |
| 596 | v1.screenpos[2].ToFloat32() * w1 + | 638 | v1.screenpos[2].ToFloat32() * w1 + |
| 597 | v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); | 639 | v2.screenpos[2].ToFloat32() * w2) * 65535.f / wsum); |
| 598 | u16 ref_z = GetDepth(x >> 4, y >> 4); | 640 | u32 ref_z = GetDepth(x >> 4, y >> 4); |
| 599 | 641 | ||
| 600 | bool pass = false; | 642 | bool pass = false; |
| 601 | 643 | ||