summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2015-03-08 21:31:15 -0500
committerGravatar Subv2015-03-09 20:13:21 -0500
commit1248e291f0c9a29734b0f5175df8fa675cce930c (patch)
tree18218cbe496e5a2f42022a5e6741fa0665218874 /src
parentFrontend/Qt: Allow the framebuffer widget to inspect the depth buffer (diff)
downloadyuzu-1248e291f0c9a29734b0f5175df8fa675cce930c.tar.gz
yuzu-1248e291f0c9a29734b0f5175df8fa675cce930c.tar.xz
yuzu-1248e291f0c9a29734b0f5175df8fa675cce930c.zip
GPU: Added the stencil test structure to the Pica Regs struct.
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/graphics_framebuffer.cpp6
-rw-r--r--src/citra_qt/debugger/graphics_framebuffer.h6
-rw-r--r--src/core/hw/gpu.cpp4
-rw-r--r--src/core/hw/gpu.h6
-rw-r--r--src/video_core/color.h18
-rw-r--r--src/video_core/pica.h43
-rw-r--r--src/video_core/rasterizer.cpp54
7 files changed, 76 insertions, 61 deletions
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp
index 2985cadb1..d621d7204 100644
--- a/src/citra_qt/debugger/graphics_framebuffer.cpp
+++ b/src/citra_qt/debugger/graphics_framebuffer.cpp
@@ -176,7 +176,7 @@ void GraphicsFramebufferWidget::OnUpdate()
176 { 176 {
177 // TODO: Store a reference to the registers in the debug context instead of accessing them directly... 177 // TODO: Store a reference to the registers in the debug context instead of accessing them directly...
178 178
179 auto framebuffer = Pica::registers.framebuffer; 179 const auto& framebuffer = Pica::registers.framebuffer;
180 180
181 framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); 181 framebuffer_address = framebuffer.GetColorBufferPhysicalAddress();
182 framebuffer_width = framebuffer.GetWidth(); 182 framebuffer_width = framebuffer.GetWidth();
@@ -189,7 +189,7 @@ void GraphicsFramebufferWidget::OnUpdate()
189 189
190 case Source::DepthBuffer: 190 case Source::DepthBuffer:
191 { 191 {
192 auto framebuffer = Pica::registers.framebuffer; 192 const auto& framebuffer = Pica::registers.framebuffer;
193 193
194 framebuffer_address = framebuffer.GetDepthBufferPhysicalAddress(); 194 framebuffer_address = framebuffer.GetDepthBufferPhysicalAddress();
195 framebuffer_width = framebuffer.GetWidth(); 195 framebuffer_width = framebuffer.GetWidth();
@@ -294,4 +294,4 @@ u32 GraphicsFramebufferWidget::BytesPerPixel(GraphicsFramebufferWidget::Format f
294 case Format::D16: 294 case Format::D16:
295 return 2; 295 return 2;
296 } 296 }
297} \ No newline at end of file 297}
diff --git a/src/citra_qt/debugger/graphics_framebuffer.h b/src/citra_qt/debugger/graphics_framebuffer.h
index dff91d131..4cb396ffe 100644
--- a/src/citra_qt/debugger/graphics_framebuffer.h
+++ b/src/citra_qt/debugger/graphics_framebuffer.h
@@ -20,9 +20,9 @@ class GraphicsFramebufferWidget : public BreakPointObserverDock {
20 using Event = Pica::DebugContext::Event; 20 using Event = Pica::DebugContext::Event;
21 21
22 enum class Source { 22 enum class Source {
23 PicaTarget = 0, 23 PicaTarget = 0,
24 DepthBuffer = 1, 24 DepthBuffer = 1,
25 Custom = 2, 25 Custom = 2,
26 26
27 // TODO: Add GPU framebuffer sources! 27 // TODO: Add GPU framebuffer sources!
28 }; 28 };
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index b7102b874..424ce2ca7 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -81,9 +81,9 @@ inline void Write(u32 addr, const T data) {
81 if (config.fill_24bit) { 81 if (config.fill_24bit) {
82 // fill with 24-bit values 82 // fill with 24-bit values
83 for (u8* ptr = start; ptr < end; ptr += 3) { 83 for (u8* ptr = start; ptr < end; ptr += 3) {
84 ptr[0] = config.value_24bit_r; 84 ptr[0] = config.value_24bit_b;
85 ptr[1] = config.value_24bit_g; 85 ptr[1] = config.value_24bit_g;
86 ptr[2] = config.value_24bit_b; 86 ptr[2] = config.value_24bit_r;
87 } 87 }
88 } else if (config.fill_32bit) { 88 } else if (config.fill_32bit) {
89 // fill with 32-bit values 89 // fill with 32-bit values
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 5ca4a5450..737b1e968 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -100,10 +100,10 @@ struct Regs {
100 // Set to 1 upon completion. 100 // Set to 1 upon completion.
101 BitField<0, 1, u32> finished; 101 BitField<0, 1, u32> finished;
102 102
103 // If both of these bits are unset, then it will fill the memory with a 16 bit value 103 // 0: fill with 16- or 32-bit wide values; 1: fill with 24-bit wide values
104 // 1: fill with 24-bit wide values
105 BitField<8, 1, u32> fill_24bit; 104 BitField<8, 1, u32> fill_24bit;
106 // 1: fill with 32-bit wide values 105
106 // 0: fill with 16-bit wide values; 1: fill with 32-bit wide values
107 BitField<9, 1, u32> fill_32bit; 107 BitField<9, 1, u32> fill_32bit;
108 }; 108 };
109 109
diff --git a/src/video_core/color.h b/src/video_core/color.h
index 35b56efc0..14ade74f2 100644
--- a/src/video_core/color.h
+++ b/src/video_core/color.h
@@ -105,7 +105,7 @@ inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) {
105 * @param bytes Pointer to encoded source value 105 * @param bytes Pointer to encoded source value
106 * @return Depth value as an u32 106 * @return Depth value as an u32
107 */ 107 */
108inline const u32 DecodeD16(const u8* bytes) { 108inline u32 DecodeD16(const u8* bytes) {
109 return *reinterpret_cast<const u16_le*>(bytes); 109 return *reinterpret_cast<const u16_le*>(bytes);
110} 110}
111 111
@@ -114,7 +114,7 @@ inline const u32 DecodeD16(const u8* bytes) {
114 * @param bytes Pointer to encoded source value 114 * @param bytes Pointer to encoded source value
115 * @return Depth value as an u32 115 * @return Depth value as an u32
116 */ 116 */
117inline const u32 DecodeD24(const u8* bytes) { 117inline u32 DecodeD24(const u8* bytes) {
118 return (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; 118 return (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
119} 119}
120 120
@@ -181,8 +181,8 @@ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) {
181} 181}
182 182
183/** 183/**
184 * Encode a depth value as D16 format 184 * Encode a 16 bit depth value as D16 format
185 * @param value Source depth value to encode 185 * @param value 16 bit source depth value to encode
186 * @param bytes Pointer where to store the encoded value 186 * @param bytes Pointer where to store the encoded value
187 */ 187 */
188inline void EncodeD16(u32 value, u8* bytes) { 188inline void EncodeD16(u32 value, u8* bytes) {
@@ -190,8 +190,8 @@ inline void EncodeD16(u32 value, u8* bytes) {
190} 190}
191 191
192/** 192/**
193 * Encode a depth value as D24 format 193 * Encode a 24 bit depth value as D24 format
194 * @param value Source depth value to encode 194 * @param value 24 bit source depth value to encode
195 * @param bytes Pointer where to store the encoded value 195 * @param bytes Pointer where to store the encoded value
196 */ 196 */
197inline void EncodeD24(u32 value, u8* bytes) { 197inline void EncodeD24(u32 value, u8* bytes) {
@@ -201,9 +201,9 @@ inline void EncodeD24(u32 value, u8* bytes) {
201} 201}
202 202
203/** 203/**
204 * Encode depth and stencil values as D24S8 format 204 * Encode a 24 bit depth and 8 bit stencil values as D24S8 format
205 * @param depth Source depth values to encode 205 * @param depth 24 bit source depth value to encode
206 * @param stencil Source stencil value to encode 206 * @param stencil 8 bit source stencil value to encode
207 * @param bytes Pointer where to store the encoded value 207 * @param bytes Pointer where to store the encoded value
208 */ 208 */
209inline void EncodeD24S8(u32 depth, u8 stencil, u8* bytes) { 209inline void EncodeD24S8(u32 depth, u8 stencil, u8* bytes) {
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 6549693f5..fe20cd77d 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -393,7 +393,15 @@ struct Regs {
393 BitField< 8, 8, u32> ref; 393 BitField< 8, 8, u32> ref;
394 } alpha_test; 394 } alpha_test;
395 395
396 INSERT_PADDING_WORDS(0x2); 396 union {
397 BitField< 0, 1, u32> stencil_test_enable;
398 BitField< 4, 3, CompareFunc> stencil_test_func;
399 BitField< 8, 8, u32> stencil_replacement_value;
400 BitField<16, 8, u32> stencil_reference_value;
401 BitField<24, 8, u32> stencil_mask;
402 } stencil_test;
403
404 INSERT_PADDING_WORDS(0x1);
397 405
398 union { 406 union {
399 BitField< 0, 1, u32> depth_test_enable; 407 BitField< 0, 1, u32> depth_test_enable;
@@ -408,6 +416,30 @@ struct Regs {
408 INSERT_PADDING_WORDS(0x8); 416 INSERT_PADDING_WORDS(0x8);
409 } output_merger; 417 } output_merger;
410 418
419 enum DepthFormat : u32 {
420 D16 = 0,
421
422 D24 = 2,
423 D24S8 = 3
424 };
425
426 /*
427 * Returns the number of bytes in the specified depth format
428 */
429 static u32 BytesPerDepthPixel(DepthFormat format) {
430 switch (format) {
431 case DepthFormat::D16:
432 return 2;
433 case DepthFormat::D24:
434 return 3;
435 case DepthFormat::D24S8:
436 return 4;
437 default:
438 LOG_CRITICAL(HW_GPU, "Unknown depth format %u", format);
439 UNIMPLEMENTED();
440 }
441 }
442
411 struct { 443 struct {
412 // Components are laid out in reverse byte order, most significant bits first. 444 // Components are laid out in reverse byte order, most significant bits first.
413 enum ColorFormat : u32 { 445 enum ColorFormat : u32 {
@@ -418,16 +450,9 @@ struct Regs {
418 RGBA4 = 4, 450 RGBA4 = 4,
419 }; 451 };
420 452
421 enum DepthFormat : u32 {
422 D16 = 0,
423
424 D24 = 2,
425 D24S8 = 3
426 };
427
428 INSERT_PADDING_WORDS(0x6); 453 INSERT_PADDING_WORDS(0x6);
429 454
430 u32 depth_format; 455 DepthFormat depth_format;
431 BitField<16, 3, u32> color_format; 456 BitField<16, 3, u32> color_format;
432 457
433 INSERT_PADDING_WORDS(0x4); 458 INSERT_PADDING_WORDS(0x4);
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index dc32128c6..dd46f0ec3 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -100,24 +100,19 @@ 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 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(registers.framebuffer.depth_format);
104 u32 stride = registers.framebuffer.width * bytes_per_pixel;
105
106 u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
107 u8* src_pixel = depth_buffer + src_offset;
103 108
104 switch (registers.framebuffer.depth_format) { 109 switch (registers.framebuffer.depth_format) {
105 case registers.framebuffer.D16: 110 case Pica::Regs::DepthFormat::D16:
106 { 111 return Color::DecodeD16(src_pixel);
107 u32 stride = registers.framebuffer.width * 2; 112 case Pica::Regs::DepthFormat::D24:
108 return Color::DecodeD16(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride); 113 return Color::DecodeD24(src_pixel);
109 } 114 case Pica::Regs::DepthFormat::D24S8:
110 case registers.framebuffer.D24: 115 return Color::DecodeD24S8(src_pixel).x;
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: 116 default:
122 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", registers.framebuffer.depth_format); 117 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", registers.framebuffer.depth_format);
123 UNIMPLEMENTED(); 118 UNIMPLEMENTED();
@@ -132,28 +127,23 @@ static void SetDepth(int x, int y, u32 value) {
132 y = (registers.framebuffer.height - y); 127 y = (registers.framebuffer.height - y);
133 128
134 const u32 coarse_y = y & ~7; 129 const u32 coarse_y = y & ~7;
130 u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(registers.framebuffer.depth_format);
131 u32 stride = registers.framebuffer.width * bytes_per_pixel;
132
133 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
134 u8* dst_pixel = depth_buffer + dst_offset;
135 135
136 switch (registers.framebuffer.depth_format) { 136 switch (registers.framebuffer.depth_format) {
137 case registers.framebuffer.D16: 137 case Pica::Regs::DepthFormat::D16:
138 { 138 Color::EncodeD16(value, dst_pixel);
139 u32 stride = registers.framebuffer.width * 2;
140 Color::EncodeD16(value, depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride);
141 break; 139 break;
142 } 140 case Pica::Regs::DepthFormat::D24:
143 case registers.framebuffer.D24: 141 Color::EncodeD24(value, dst_pixel);
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; 142 break;
149 } 143 case Pica::Regs::DepthFormat::D24S8:
150 case registers.framebuffer.D24S8:
151 {
152 u32 stride = registers.framebuffer.width * 4;
153 // TODO(Subv): Implement the stencil buffer 144 // TODO(Subv): Implement the stencil buffer
154 Color::EncodeD24S8(value, 0, depth_buffer + VideoCore::GetMortonOffset(x, y, 4) + coarse_y * stride); 145 Color::EncodeD24S8(value, 0, dst_pixel);
155 break; 146 break;
156 }
157 default: 147 default:
158 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", registers.framebuffer.depth_format); 148 LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", registers.framebuffer.depth_format);
159 UNIMPLEMENTED(); 149 UNIMPLEMENTED();