summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-01-29 17:43:09 -0800
committerGravatar Yuri Kunde Schlesner2017-02-12 18:11:03 -0800
commite1ad7d69b981c7ed249ba7efd4287d712db3747d (patch)
tree813232650da323b708faef9ad8a7db7a50d3f287 /src
parentVideoCore: Move software rasterizer files to sub-directory (diff)
downloadyuzu-e1ad7d69b981c7ed249ba7efd4287d712db3747d.tar.gz
yuzu-e1ad7d69b981c7ed249ba7efd4287d712db3747d.tar.xz
yuzu-e1ad7d69b981c7ed249ba7efd4287d712db3747d.zip
SWRasterizer: Move framebuffer operation functions to their own file
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/swrasterizer/framebuffer.cpp259
-rw-r--r--src/video_core/swrasterizer/framebuffer.h23
-rw-r--r--src/video_core/swrasterizer/rasterizer.cpp237
4 files changed, 285 insertions, 236 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 962228680..479edfff4 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -14,6 +14,7 @@ set(SRCS
14 shader/shader.cpp 14 shader/shader.cpp
15 shader/shader_interpreter.cpp 15 shader/shader_interpreter.cpp
16 swrasterizer/clipper.cpp 16 swrasterizer/clipper.cpp
17 swrasterizer/framebuffer.cpp
17 swrasterizer/rasterizer.cpp 18 swrasterizer/rasterizer.cpp
18 swrasterizer/swrasterizer.cpp 19 swrasterizer/swrasterizer.cpp
19 texture/etc1.cpp 20 texture/etc1.cpp
@@ -51,6 +52,7 @@ set(HEADERS
51 shader/shader.h 52 shader/shader.h
52 shader/shader_interpreter.h 53 shader/shader_interpreter.h
53 swrasterizer/clipper.h 54 swrasterizer/clipper.h
55 swrasterizer/framebuffer.h
54 swrasterizer/rasterizer.h 56 swrasterizer/rasterizer.h
55 swrasterizer/swrasterizer.h 57 swrasterizer/swrasterizer.h
56 texture/etc1.h 58 texture/etc1.h
diff --git a/src/video_core/swrasterizer/framebuffer.cpp b/src/video_core/swrasterizer/framebuffer.cpp
new file mode 100644
index 000000000..4b31eda89
--- /dev/null
+++ b/src/video_core/swrasterizer/framebuffer.cpp
@@ -0,0 +1,259 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6
7#include "common/assert.h"
8#include "common/color.h"
9#include "common/common_types.h"
10#include "common/logging/log.h"
11#include "common/vector_math.h"
12#include "core/hw/gpu.h"
13#include "core/memory.h"
14#include "video_core/pica_state.h"
15#include "video_core/regs_framebuffer.h"
16#include "video_core/swrasterizer/framebuffer.h"
17#include "video_core/utils.h"
18
19namespace Pica {
20namespace Rasterizer {
21
22void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
23 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
24 const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
25
26 // Similarly to textures, the render framebuffer is laid out from bottom to top, too.
27 // NOTE: The framebuffer height register contains the actual FB height minus one.
28 y = framebuffer.height - y;
29
30 const u32 coarse_y = y & ~7;
31 u32 bytes_per_pixel =
32 GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value()));
33 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) +
34 coarse_y * framebuffer.width * bytes_per_pixel;
35 u8* dst_pixel = Memory::GetPhysicalPointer(addr) + dst_offset;
36
37 switch (framebuffer.color_format) {
38 case FramebufferRegs::ColorFormat::RGBA8:
39 Color::EncodeRGBA8(color, dst_pixel);
40 break;
41
42 case FramebufferRegs::ColorFormat::RGB8:
43 Color::EncodeRGB8(color, dst_pixel);
44 break;
45
46 case FramebufferRegs::ColorFormat::RGB5A1:
47 Color::EncodeRGB5A1(color, dst_pixel);
48 break;
49
50 case FramebufferRegs::ColorFormat::RGB565:
51 Color::EncodeRGB565(color, dst_pixel);
52 break;
53
54 case FramebufferRegs::ColorFormat::RGBA4:
55 Color::EncodeRGBA4(color, dst_pixel);
56 break;
57
58 default:
59 LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x",
60 framebuffer.color_format.Value());
61 UNIMPLEMENTED();
62 }
63}
64
65const Math::Vec4<u8> GetPixel(int x, int y) {
66 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
67 const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
68
69 y = framebuffer.height - y;
70
71 const u32 coarse_y = y & ~7;
72 u32 bytes_per_pixel =
73 GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value()));
74 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) +
75 coarse_y * framebuffer.width * bytes_per_pixel;
76 u8* src_pixel = Memory::GetPhysicalPointer(addr) + src_offset;
77
78 switch (framebuffer.color_format) {
79 case FramebufferRegs::ColorFormat::RGBA8:
80 return Color::DecodeRGBA8(src_pixel);
81
82 case FramebufferRegs::ColorFormat::RGB8:
83 return Color::DecodeRGB8(src_pixel);
84
85 case FramebufferRegs::ColorFormat::RGB5A1:
86 return Color::DecodeRGB5A1(src_pixel);
87
88 case FramebufferRegs::ColorFormat::RGB565:
89 return Color::DecodeRGB565(src_pixel);
90
91 case FramebufferRegs::ColorFormat::RGBA4:
92 return Color::DecodeRGBA4(src_pixel);
93
94 default:
95 LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x",
96 framebuffer.color_format.Value());
97 UNIMPLEMENTED();
98 }
99
100 return {0, 0, 0, 0};
101}
102
103u32 GetDepth(int x, int y) {
104 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
105 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
106 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
107
108 y = framebuffer.height - y;
109
110 const u32 coarse_y = y & ~7;
111 u32 bytes_per_pixel = FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
112 u32 stride = framebuffer.width * bytes_per_pixel;
113
114 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
115 u8* src_pixel = depth_buffer + src_offset;
116
117 switch (framebuffer.depth_format) {
118 case FramebufferRegs::DepthFormat::D16:
119 return Color::DecodeD16(src_pixel);
120 case FramebufferRegs::DepthFormat::D24:
121 return Color::DecodeD24(src_pixel);
122 case FramebufferRegs::DepthFormat::D24S8:
123 return Color::DecodeD24S8(src_pixel).x;
124 default:
125 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format);
126 UNIMPLEMENTED();
127 return 0;
128 }
129}
130
131u8 GetStencil(int x, int y) {
132 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
133 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
134 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
135
136 y = framebuffer.height - y;
137
138 const u32 coarse_y = y & ~7;
139 u32 bytes_per_pixel = Pica::FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
140 u32 stride = framebuffer.width * bytes_per_pixel;
141
142 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
143 u8* src_pixel = depth_buffer + src_offset;
144
145 switch (framebuffer.depth_format) {
146 case FramebufferRegs::DepthFormat::D24S8:
147 return Color::DecodeD24S8(src_pixel).y;
148
149 default:
150 LOG_WARNING(
151 HW_GPU,
152 "GetStencil called for function which doesn't have a stencil component (format %u)",
153 framebuffer.depth_format);
154 return 0;
155 }
156}
157
158void SetDepth(int x, int y, u32 value) {
159 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
160 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
161 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
162
163 y = framebuffer.height - y;
164
165 const u32 coarse_y = y & ~7;
166 u32 bytes_per_pixel = FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
167 u32 stride = framebuffer.width * bytes_per_pixel;
168
169 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
170 u8* dst_pixel = depth_buffer + dst_offset;
171
172 switch (framebuffer.depth_format) {
173 case FramebufferRegs::DepthFormat::D16:
174 Color::EncodeD16(value, dst_pixel);
175 break;
176
177 case FramebufferRegs::DepthFormat::D24:
178 Color::EncodeD24(value, dst_pixel);
179 break;
180
181 case FramebufferRegs::DepthFormat::D24S8:
182 Color::EncodeD24X8(value, dst_pixel);
183 break;
184
185 default:
186 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format);
187 UNIMPLEMENTED();
188 break;
189 }
190}
191
192void SetStencil(int x, int y, u8 value) {
193 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
194 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
195 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
196
197 y = framebuffer.height - y;
198
199 const u32 coarse_y = y & ~7;
200 u32 bytes_per_pixel = Pica::FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
201 u32 stride = framebuffer.width * bytes_per_pixel;
202
203 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
204 u8* dst_pixel = depth_buffer + dst_offset;
205
206 switch (framebuffer.depth_format) {
207 case Pica::FramebufferRegs::DepthFormat::D16:
208 case Pica::FramebufferRegs::DepthFormat::D24:
209 // Nothing to do
210 break;
211
212 case Pica::FramebufferRegs::DepthFormat::D24S8:
213 Color::EncodeX24S8(value, dst_pixel);
214 break;
215
216 default:
217 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format);
218 UNIMPLEMENTED();
219 break;
220 }
221}
222
223u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref) {
224 switch (action) {
225 case FramebufferRegs::StencilAction::Keep:
226 return old_stencil;
227
228 case FramebufferRegs::StencilAction::Zero:
229 return 0;
230
231 case FramebufferRegs::StencilAction::Replace:
232 return ref;
233
234 case FramebufferRegs::StencilAction::Increment:
235 // Saturated increment
236 return std::min<u8>(old_stencil, 254) + 1;
237
238 case FramebufferRegs::StencilAction::Decrement:
239 // Saturated decrement
240 return std::max<u8>(old_stencil, 1) - 1;
241
242 case FramebufferRegs::StencilAction::Invert:
243 return ~old_stencil;
244
245 case FramebufferRegs::StencilAction::IncrementWrap:
246 return old_stencil + 1;
247
248 case FramebufferRegs::StencilAction::DecrementWrap:
249 return old_stencil - 1;
250
251 default:
252 LOG_CRITICAL(HW_GPU, "Unknown stencil action %x", (int)action);
253 UNIMPLEMENTED();
254 return 0;
255 }
256}
257
258} // namespace Rasterizer
259} // namespace Pica
diff --git a/src/video_core/swrasterizer/framebuffer.h b/src/video_core/swrasterizer/framebuffer.h
new file mode 100644
index 000000000..220f7013b
--- /dev/null
+++ b/src/video_core/swrasterizer/framebuffer.h
@@ -0,0 +1,23 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "common/vector_math.h"
9#include "video_core/regs_framebuffer.h"
10
11namespace Pica {
12namespace Rasterizer {
13
14void DrawPixel(int x, int y, const Math::Vec4<u8>& color);
15const Math::Vec4<u8> GetPixel(int x, int y);
16u32 GetDepth(int x, int y);
17u8 GetStencil(int x, int y);
18void SetDepth(int x, int y, u32 value);
19void SetStencil(int x, int y, u8 value);
20u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref);
21
22} // namespace Rasterizer
23} // namespace Pica
diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp
index 17ba59144..cb11338b7 100644
--- a/src/video_core/swrasterizer/rasterizer.cpp
+++ b/src/video_core/swrasterizer/rasterizer.cpp
@@ -22,6 +22,7 @@
22#include "video_core/regs_rasterizer.h" 22#include "video_core/regs_rasterizer.h"
23#include "video_core/regs_texturing.h" 23#include "video_core/regs_texturing.h"
24#include "video_core/shader/shader.h" 24#include "video_core/shader/shader.h"
25#include "video_core/swrasterizer/framebuffer.h"
25#include "video_core/swrasterizer/rasterizer.h" 26#include "video_core/swrasterizer/rasterizer.h"
26#include "video_core/texture/texture_decode.h" 27#include "video_core/texture/texture_decode.h"
27#include "video_core/utils.h" 28#include "video_core/utils.h"
@@ -30,242 +31,6 @@ namespace Pica {
30 31
31namespace Rasterizer { 32namespace Rasterizer {
32 33
33static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
34 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
35 const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
36
37 // Similarly to textures, the render framebuffer is laid out from bottom to top, too.
38 // NOTE: The framebuffer height register contains the actual FB height minus one.
39 y = framebuffer.height - y;
40
41 const u32 coarse_y = y & ~7;
42 u32 bytes_per_pixel =
43 GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value()));
44 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) +
45 coarse_y * framebuffer.width * bytes_per_pixel;
46 u8* dst_pixel = Memory::GetPhysicalPointer(addr) + dst_offset;
47
48 switch (framebuffer.color_format) {
49 case FramebufferRegs::ColorFormat::RGBA8:
50 Color::EncodeRGBA8(color, dst_pixel);
51 break;
52
53 case FramebufferRegs::ColorFormat::RGB8:
54 Color::EncodeRGB8(color, dst_pixel);
55 break;
56
57 case FramebufferRegs::ColorFormat::RGB5A1:
58 Color::EncodeRGB5A1(color, dst_pixel);
59 break;
60
61 case FramebufferRegs::ColorFormat::RGB565:
62 Color::EncodeRGB565(color, dst_pixel);
63 break;
64
65 case FramebufferRegs::ColorFormat::RGBA4:
66 Color::EncodeRGBA4(color, dst_pixel);
67 break;
68
69 default:
70 LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x",
71 framebuffer.color_format.Value());
72 UNIMPLEMENTED();
73 }
74}
75
76static const Math::Vec4<u8> GetPixel(int x, int y) {
77 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
78 const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
79
80 y = framebuffer.height - y;
81
82 const u32 coarse_y = y & ~7;
83 u32 bytes_per_pixel =
84 GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value()));
85 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) +
86 coarse_y * framebuffer.width * bytes_per_pixel;
87 u8* src_pixel = Memory::GetPhysicalPointer(addr) + src_offset;
88
89 switch (framebuffer.color_format) {
90 case FramebufferRegs::ColorFormat::RGBA8:
91 return Color::DecodeRGBA8(src_pixel);
92
93 case FramebufferRegs::ColorFormat::RGB8:
94 return Color::DecodeRGB8(src_pixel);
95
96 case FramebufferRegs::ColorFormat::RGB5A1:
97 return Color::DecodeRGB5A1(src_pixel);
98
99 case FramebufferRegs::ColorFormat::RGB565:
100 return Color::DecodeRGB565(src_pixel);
101
102 case FramebufferRegs::ColorFormat::RGBA4:
103 return Color::DecodeRGBA4(src_pixel);
104
105 default:
106 LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x",
107 framebuffer.color_format.Value());
108 UNIMPLEMENTED();
109 }
110
111 return {0, 0, 0, 0};
112}
113
114static u32 GetDepth(int x, int y) {
115 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
116 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
117 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
118
119 y = framebuffer.height - y;
120
121 const u32 coarse_y = y & ~7;
122 u32 bytes_per_pixel = FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
123 u32 stride = framebuffer.width * bytes_per_pixel;
124
125 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
126 u8* src_pixel = depth_buffer + src_offset;
127
128 switch (framebuffer.depth_format) {
129 case FramebufferRegs::DepthFormat::D16:
130 return Color::DecodeD16(src_pixel);
131 case FramebufferRegs::DepthFormat::D24:
132 return Color::DecodeD24(src_pixel);
133 case FramebufferRegs::DepthFormat::D24S8:
134 return Color::DecodeD24S8(src_pixel).x;
135 default:
136 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format);
137 UNIMPLEMENTED();
138 return 0;
139 }
140}
141
142static u8 GetStencil(int x, int y) {
143 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
144 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
145 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
146
147 y = framebuffer.height - y;
148
149 const u32 coarse_y = y & ~7;
150 u32 bytes_per_pixel = Pica::FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
151 u32 stride = framebuffer.width * bytes_per_pixel;
152
153 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
154 u8* src_pixel = depth_buffer + src_offset;
155
156 switch (framebuffer.depth_format) {
157 case FramebufferRegs::DepthFormat::D24S8:
158 return Color::DecodeD24S8(src_pixel).y;
159
160 default:
161 LOG_WARNING(
162 HW_GPU,
163 "GetStencil called for function which doesn't have a stencil component (format %u)",
164 framebuffer.depth_format);
165 return 0;
166 }
167}
168
169static void SetDepth(int x, int y, u32 value) {
170 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
171 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
172 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
173
174 y = framebuffer.height - y;
175
176 const u32 coarse_y = y & ~7;
177 u32 bytes_per_pixel = FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
178 u32 stride = framebuffer.width * bytes_per_pixel;
179
180 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
181 u8* dst_pixel = depth_buffer + dst_offset;
182
183 switch (framebuffer.depth_format) {
184 case FramebufferRegs::DepthFormat::D16:
185 Color::EncodeD16(value, dst_pixel);
186 break;
187
188 case FramebufferRegs::DepthFormat::D24:
189 Color::EncodeD24(value, dst_pixel);
190 break;
191
192 case FramebufferRegs::DepthFormat::D24S8:
193 Color::EncodeD24X8(value, dst_pixel);
194 break;
195
196 default:
197 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format);
198 UNIMPLEMENTED();
199 break;
200 }
201}
202
203static void SetStencil(int x, int y, u8 value) {
204 const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
205 const PAddr addr = framebuffer.GetDepthBufferPhysicalAddress();
206 u8* depth_buffer = Memory::GetPhysicalPointer(addr);
207
208 y = framebuffer.height - y;
209
210 const u32 coarse_y = y & ~7;
211 u32 bytes_per_pixel = Pica::FramebufferRegs::BytesPerDepthPixel(framebuffer.depth_format);
212 u32 stride = framebuffer.width * bytes_per_pixel;
213
214 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
215 u8* dst_pixel = depth_buffer + dst_offset;
216
217 switch (framebuffer.depth_format) {
218 case Pica::FramebufferRegs::DepthFormat::D16:
219 case Pica::FramebufferRegs::DepthFormat::D24:
220 // Nothing to do
221 break;
222
223 case Pica::FramebufferRegs::DepthFormat::D24S8:
224 Color::EncodeX24S8(value, dst_pixel);
225 break;
226
227 default:
228 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format);
229 UNIMPLEMENTED();
230 break;
231 }
232}
233
234static u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref) {
235 switch (action) {
236 case FramebufferRegs::StencilAction::Keep:
237 return old_stencil;
238
239 case FramebufferRegs::StencilAction::Zero:
240 return 0;
241
242 case FramebufferRegs::StencilAction::Replace:
243 return ref;
244
245 case FramebufferRegs::StencilAction::Increment:
246 // Saturated increment
247 return std::min<u8>(old_stencil, 254) + 1;
248
249 case FramebufferRegs::StencilAction::Decrement:
250 // Saturated decrement
251 return std::max<u8>(old_stencil, 1) - 1;
252
253 case FramebufferRegs::StencilAction::Invert:
254 return ~old_stencil;
255
256 case FramebufferRegs::StencilAction::IncrementWrap:
257 return old_stencil + 1;
258
259 case FramebufferRegs::StencilAction::DecrementWrap:
260 return old_stencil - 1;
261
262 default:
263 LOG_CRITICAL(HW_GPU, "Unknown stencil action %x", (int)action);
264 UNIMPLEMENTED();
265 return 0;
266 }
267}
268
269// NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values 34// NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values
270struct Fix12P4 { 35struct Fix12P4 {
271 Fix12P4() {} 36 Fix12P4() {}