summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.h56
-rw-r--r--src/video_core/gpu.h9
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp49
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h47
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h50
-rw-r--r--src/video_core/textures/decoders.cpp31
-rw-r--r--src/video_core/textures/decoders.h6
9 files changed, 246 insertions, 32 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 58db81222..ff67f2a58 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -280,6 +280,34 @@ public:
280 UnsignedInt = 0x2, 280 UnsignedInt = 0x2,
281 }; 281 };
282 282
283 enum class ComparisonOp : u32 {
284 Never = 0x200,
285 Less = 0x201,
286 Equal = 0x202,
287 LessEqual = 0x203,
288 Greater = 0x204,
289 NotEqual = 0x205,
290 GreaterEqual = 0x206,
291 Always = 0x207,
292 };
293
294 struct Cull {
295 enum class FrontFace : u32 {
296 ClockWise = 0x0900,
297 CounterClockWise = 0x0901,
298 };
299
300 enum class CullFace : u32 {
301 Front = 0x0404,
302 Back = 0x0405,
303 FrontAndBack = 0x0408,
304 };
305
306 u32 enabled;
307 FrontFace front_face;
308 CullFace cull_face;
309 };
310
283 struct Blend { 311 struct Blend {
284 enum class Equation : u32 { 312 enum class Equation : u32 {
285 Add = 1, 313 Add = 1,
@@ -413,7 +441,7 @@ public:
413 struct { 441 struct {
414 u32 address_high; 442 u32 address_high;
415 u32 address_low; 443 u32 address_low;
416 u32 format; 444 Tegra::DepthFormat format;
417 u32 block_dimensions; 445 u32 block_dimensions;
418 u32 layer_stride; 446 u32 layer_stride;
419 447
@@ -435,11 +463,21 @@ public:
435 }; 463 };
436 } rt_control; 464 } rt_control;
437 465
438 INSERT_PADDING_WORDS(0x31); 466 INSERT_PADDING_WORDS(0x2B);
467
468 u32 depth_test_enable;
469
470 INSERT_PADDING_WORDS(0x5);
439 471
440 u32 independent_blend_enable; 472 u32 independent_blend_enable;
441 473
442 INSERT_PADDING_WORDS(0x15); 474 u32 depth_write_enabled;
475
476 INSERT_PADDING_WORDS(0x8);
477
478 ComparisonOp depth_test_func;
479
480 INSERT_PADDING_WORDS(0xB);
443 481
444 struct { 482 struct {
445 u32 separate_alpha; 483 u32 separate_alpha;
@@ -540,7 +578,13 @@ public:
540 } 578 }
541 } index_array; 579 } index_array;
542 580
543 INSERT_PADDING_WORDS(0xC7); 581 INSERT_PADDING_WORDS(0x7);
582
583 INSERT_PADDING_WORDS(0x46);
584
585 Cull cull;
586
587 INSERT_PADDING_WORDS(0x77);
544 588
545 struct { 589 struct {
546 u32 query_address_high; 590 u32 query_address_high;
@@ -747,7 +791,10 @@ ASSERT_REG_POSITION(vertex_buffer, 0x35D);
747ASSERT_REG_POSITION(zeta, 0x3F8); 791ASSERT_REG_POSITION(zeta, 0x3F8);
748ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); 792ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458);
749ASSERT_REG_POSITION(rt_control, 0x487); 793ASSERT_REG_POSITION(rt_control, 0x487);
794ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
750ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); 795ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
796ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
797ASSERT_REG_POSITION(depth_test_func, 0x4C3);
751ASSERT_REG_POSITION(blend, 0x4CF); 798ASSERT_REG_POSITION(blend, 0x4CF);
752ASSERT_REG_POSITION(vb_element_base, 0x50D); 799ASSERT_REG_POSITION(vb_element_base, 0x50D);
753ASSERT_REG_POSITION(tsc, 0x557); 800ASSERT_REG_POSITION(tsc, 0x557);
@@ -755,6 +802,7 @@ ASSERT_REG_POSITION(tic, 0x55D);
755ASSERT_REG_POSITION(code_address, 0x582); 802ASSERT_REG_POSITION(code_address, 0x582);
756ASSERT_REG_POSITION(draw, 0x585); 803ASSERT_REG_POSITION(draw, 0x585);
757ASSERT_REG_POSITION(index_array, 0x5F2); 804ASSERT_REG_POSITION(index_array, 0x5F2);
805ASSERT_REG_POSITION(cull, 0x646);
758ASSERT_REG_POSITION(query, 0x6C0); 806ASSERT_REG_POSITION(query, 0x6C0);
759ASSERT_REG_POSITION(vertex_array[0], 0x700); 807ASSERT_REG_POSITION(vertex_array[0], 0x700);
760ASSERT_REG_POSITION(independent_blend, 0x780); 808ASSERT_REG_POSITION(independent_blend, 0x780);
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index d0a4ac267..cc5ca656e 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -24,6 +24,15 @@ enum class RenderTargetFormat : u32 {
24 R11G11B10_FLOAT = 0xE0, 24 R11G11B10_FLOAT = 0xE0,
25}; 25};
26 26
27enum class DepthFormat : u32 {
28 Z32_FLOAT = 0xA,
29 Z16_UNORM = 0x13,
30 S8_Z24_UNORM = 0x14,
31 Z24_X8_UNORM = 0x15,
32 Z24_S8_UNORM = 0x16,
33 Z24_C8_UNORM = 0x18,
34};
35
27/// Returns the number of bytes per pixel of each rendertarget format. 36/// Returns the number of bytes per pixel of each rendertarget format.
28u32 RenderTargetBytesPerPixel(RenderTargetFormat format); 37u32 RenderTargetBytesPerPixel(RenderTargetFormat format);
29 38
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 324c28d1b..ca3814cfc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -304,10 +304,15 @@ void RasterizerOpenGL::DrawArrays() {
304 MICROPROFILE_SCOPE(OpenGL_Drawing); 304 MICROPROFILE_SCOPE(OpenGL_Drawing);
305 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 305 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
306 306
307 // TODO(bunnei): Implement these 307 // Sync the depth test state before configuring the framebuffer surfaces.
308 SyncDepthTestState();
309
310 // TODO(bunnei): Implement this
308 const bool has_stencil = false; 311 const bool has_stencil = false;
312
309 const bool using_color_fb = true; 313 const bool using_color_fb = true;
310 const bool using_depth_fb = false; 314 const bool using_depth_fb = regs.zeta.Address() != 0;
315
311 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; 316 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
312 317
313 const bool write_color_fb = 318 const bool write_color_fb =
@@ -338,11 +343,9 @@ void RasterizerOpenGL::DrawArrays() {
338 // Bind the framebuffer surfaces 343 // Bind the framebuffer surfaces
339 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); 344 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil);
340 345
341 // Sync the viewport
342 SyncViewport(surfaces_rect); 346 SyncViewport(surfaces_rect);
343
344 // Sync the blend state registers
345 SyncBlendState(); 347 SyncBlendState();
348 SyncCullMode();
346 349
347 // TODO(bunnei): Sync framebuffer_scale uniform here 350 // TODO(bunnei): Sync framebuffer_scale uniform here
348 // TODO(bunnei): Sync scissorbox uniform(s) here 351 // TODO(bunnei): Sync scissorbox uniform(s) here
@@ -712,7 +715,11 @@ void RasterizerOpenGL::SyncClipCoef() {
712} 715}
713 716
714void RasterizerOpenGL::SyncCullMode() { 717void RasterizerOpenGL::SyncCullMode() {
715 UNREACHABLE(); 718 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
719
720 state.cull.enabled = regs.cull.enabled != 0;
721 state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face);
722 state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face);
716} 723}
717 724
718void RasterizerOpenGL::SyncDepthScale() { 725void RasterizerOpenGL::SyncDepthScale() {
@@ -723,6 +730,14 @@ void RasterizerOpenGL::SyncDepthOffset() {
723 UNREACHABLE(); 730 UNREACHABLE();
724} 731}
725 732
733void RasterizerOpenGL::SyncDepthTestState() {
734 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
735
736 state.depth.test_enabled = regs.depth_test_enable != 0;
737 state.depth.write_mask = regs.depth_write_enabled ? GL_TRUE : GL_FALSE;
738 state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func);
739}
740
726void RasterizerOpenGL::SyncBlendState() { 741void RasterizerOpenGL::SyncBlendState() {
727 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 742 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
728 743
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 621200f03..493aa39e5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -126,6 +126,9 @@ private:
126 /// Syncs the depth offset to match the guest state 126 /// Syncs the depth offset to match the guest state
127 void SyncDepthOffset(); 127 void SyncDepthOffset();
128 128
129 /// Syncs the depth test state to match the guest state
130 void SyncDepthTestState();
131
129 /// Syncs the blend state to match the guest state 132 /// Syncs the blend state to match the guest state
130 void SyncBlendState(); 133 void SyncBlendState();
131 134
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 9410ddb4e..851ebc263 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -84,22 +84,18 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
84 true}, // DXT45 84 true}, // DXT45
85 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 85 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1
86 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 86 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4
87
88 // DepthStencil formats
89 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm,
90 false}, // Z24S8
87}}; 91}};
88 92
89static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { 93static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) {
90 const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); 94 ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size());
91 if (type == SurfaceType::ColorTexture) { 95 auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)];
92 ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); 96 ASSERT(component_type == format.component_type);
93 auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)];
94 ASSERT(component_type == format.component_type);
95 return format;
96 } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) {
97 // TODO(Subv): Implement depth formats
98 ASSERT_MSG(false, "Unimplemented");
99 }
100 97
101 UNREACHABLE(); 98 return format;
102 return {};
103} 99}
104 100
105VAddr SurfaceParams::GetCpuAddr() const { 101VAddr SurfaceParams::GetCpuAddr() const {
@@ -149,11 +145,17 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::
149 const auto& gpu = Core::System::GetInstance().GPU(); 145 const auto& gpu = Core::System::GetInstance().GPU();
150 146
151 if (morton_to_gl) { 147 if (morton_to_gl) {
152 auto data = Tegra::Texture::UnswizzleTexture( 148 if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) {
153 *gpu.memory_manager->GpuToCpuAddress(addr), 149 auto data = Tegra::Texture::UnswizzleTexture(
154 SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); 150 *gpu.memory_manager->GpuToCpuAddress(addr),
155 151 SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
156 std::memcpy(gl_buffer, data.data(), data.size()); 152 std::memcpy(gl_buffer, data.data(), data.size());
153 } else {
154 auto data = Tegra::Texture::UnswizzleDepthTexture(
155 *gpu.memory_manager->GpuToCpuAddress(addr),
156 SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height);
157 std::memcpy(gl_buffer, data.data(), data.size());
158 }
157 } else { 159 } else {
158 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should 160 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should
159 // check the configuration for this and perform more generic un/swizzle 161 // check the configuration for this and perform more generic un/swizzle
@@ -174,7 +176,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
174 MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>, 176 MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>,
175 MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, 177 MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>,
176 MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>, 178 MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>,
177 MortonCopy<true, PixelFormat::ASTC_2D_4X4>, 179 MortonCopy<true, PixelFormat::ASTC_2D_4X4>, MortonCopy<true, PixelFormat::Z24S8>,
178}; 180};
179 181
180static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), 182static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
@@ -194,6 +196,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
194 nullptr, 196 nullptr,
195 nullptr, 197 nullptr,
196 MortonCopy<false, PixelFormat::ABGR8>, 198 MortonCopy<false, PixelFormat::ABGR8>,
199 MortonCopy<false, PixelFormat::Z24S8>,
197}; 200};
198 201
199// Allocate an uninitialized texture of appropriate size and format for the surface 202// Allocate an uninitialized texture of appropriate size and format for the surface
@@ -397,9 +400,15 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
397 400
398 // get color and depth surfaces 401 // get color and depth surfaces
399 const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])}; 402 const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])};
400 const SurfaceParams depth_params{color_params}; 403 SurfaceParams depth_params{color_params};
401 404
402 ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented"); 405 if (using_depth_fb) {
406 depth_params.addr = regs.zeta.Address();
407 depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(regs.zeta.format);
408 depth_params.component_type = SurfaceParams::ComponentTypeFromDepthFormat(regs.zeta.format);
409 depth_params.type = SurfaceParams::GetFormatType(depth_params.pixel_format);
410 depth_params.size_in_bytes = depth_params.SizeInBytes();
411 }
403 412
404 MathUtil::Rectangle<u32> color_rect{}; 413 MathUtil::Rectangle<u32> color_rect{};
405 Surface color_surface; 414 Surface color_surface;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 99be250b4..eea432b0b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -37,7 +37,14 @@ struct SurfaceParams {
37 DXN1 = 11, // This is also known as BC4 37 DXN1 = 11, // This is also known as BC4
38 ASTC_2D_4X4 = 12, 38 ASTC_2D_4X4 = 12,
39 39
40 Max, 40 MaxColorFormat,
41
42 // DepthStencil formats
43 Z24S8 = 13,
44
45 MaxDepthStencilFormat,
46
47 Max = MaxDepthStencilFormat,
41 Invalid = 255, 48 Invalid = 255,
42 }; 49 };
43 50
@@ -84,6 +91,7 @@ struct SurfaceParams {
84 4, // DXT45 91 4, // DXT45
85 4, // DXN1 92 4, // DXN1
86 4, // ASTC_2D_4X4 93 4, // ASTC_2D_4X4
94 1, // Z24S8
87 }}; 95 }};
88 96
89 ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); 97 ASSERT(static_cast<size_t>(format) < compression_factor_table.size());
@@ -108,6 +116,7 @@ struct SurfaceParams {
108 128, // DXT45 116 128, // DXT45
109 64, // DXN1 117 64, // DXN1
110 32, // ASTC_2D_4X4 118 32, // ASTC_2D_4X4
119 32, // Z24S8
111 }}; 120 }};
112 121
113 ASSERT(static_cast<size_t>(format) < bpp_table.size()); 122 ASSERT(static_cast<size_t>(format) < bpp_table.size());
@@ -117,6 +126,16 @@ struct SurfaceParams {
117 return GetFormatBpp(pixel_format); 126 return GetFormatBpp(pixel_format);
118 } 127 }
119 128
129 static PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
130 switch (format) {
131 case Tegra::DepthFormat::Z24_S8_UNORM:
132 return PixelFormat::Z24S8;
133 default:
134 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
135 UNREACHABLE();
136 }
137 }
138
120 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { 139 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
121 switch (format) { 140 switch (format) {
122 case Tegra::RenderTargetFormat::RGBA8_UNORM: 141 case Tegra::RenderTargetFormat::RGBA8_UNORM:
@@ -205,6 +224,15 @@ struct SurfaceParams {
205 } 224 }
206 } 225 }
207 226
227 static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) {
228 switch (format) {
229 case PixelFormat::Z24S8:
230 return Tegra::DepthFormat::Z24_S8_UNORM;
231 default:
232 UNREACHABLE();
233 }
234 }
235
208 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { 236 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
209 // TODO(Subv): Implement more component types 237 // TODO(Subv): Implement more component types
210 switch (type) { 238 switch (type) {
@@ -244,11 +272,26 @@ struct SurfaceParams {
244 } 272 }
245 } 273 }
246 274
275 static ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) {
276 switch (format) {
277 case Tegra::DepthFormat::Z24_S8_UNORM:
278 return ComponentType::UNorm;
279 default:
280 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
281 UNREACHABLE();
282 }
283 }
284
247 static SurfaceType GetFormatType(PixelFormat pixel_format) { 285 static SurfaceType GetFormatType(PixelFormat pixel_format) {
248 if (static_cast<size_t>(pixel_format) < MaxPixelFormat) { 286 if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxColorFormat)) {
249 return SurfaceType::ColorTexture; 287 return SurfaceType::ColorTexture;
250 } 288 }
251 289
290 if (static_cast<size_t>(pixel_format) <
291 static_cast<size_t>(PixelFormat::MaxDepthStencilFormat)) {
292 return SurfaceType::DepthStencil;
293 }
294
252 // TODO(Subv): Implement the other formats 295 // TODO(Subv): Implement the other formats
253 ASSERT(false); 296 ASSERT(false);
254 297
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 2155fb019..392041a1c 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -201,4 +201,54 @@ inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
201 return {}; 201 return {};
202} 202}
203 203
204inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
205 switch (comparison) {
206 case Maxwell::ComparisonOp::Never:
207 return GL_NEVER;
208 case Maxwell::ComparisonOp::Less:
209 return GL_LESS;
210 case Maxwell::ComparisonOp::Equal:
211 return GL_EQUAL;
212 case Maxwell::ComparisonOp::LessEqual:
213 return GL_LEQUAL;
214 case Maxwell::ComparisonOp::Greater:
215 return GL_GREATER;
216 case Maxwell::ComparisonOp::NotEqual:
217 return GL_NOTEQUAL;
218 case Maxwell::ComparisonOp::GreaterEqual:
219 return GL_GEQUAL;
220 case Maxwell::ComparisonOp::Always:
221 return GL_ALWAYS;
222 }
223 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
224 UNREACHABLE();
225 return {};
226}
227
228inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
229 switch (front_face) {
230 case Maxwell::Cull::FrontFace::ClockWise:
231 return GL_CW;
232 case Maxwell::Cull::FrontFace::CounterClockWise:
233 return GL_CCW;
234 }
235 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
236 UNREACHABLE();
237 return {};
238}
239
240inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
241 switch (cull_face) {
242 case Maxwell::Cull::CullFace::Front:
243 return GL_FRONT;
244 case Maxwell::Cull::CullFace::Back:
245 return GL_BACK;
246 case Maxwell::Cull::CullFace::FrontAndBack:
247 return GL_FRONT_AND_BACK;
248 }
249 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
250 UNREACHABLE();
251 return {};
252}
253
204} // namespace MaxwellToGL 254} // namespace MaxwellToGL
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index eaf15da32..680f22ddb 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -5,6 +5,7 @@
5#include <cstring> 5#include <cstring>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/memory.h" 7#include "core/memory.h"
8#include "video_core/gpu.h"
8#include "video_core/textures/decoders.h" 9#include "video_core/textures/decoders.h"
9#include "video_core/textures/texture.h" 10#include "video_core/textures/texture.h"
10 11
@@ -73,6 +74,16 @@ u32 BytesPerPixel(TextureFormat format) {
73 } 74 }
74} 75}
75 76
77static u32 DepthBytesPerPixel(DepthFormat format) {
78 switch (format) {
79 case DepthFormat::Z24_S8_UNORM:
80 return 4;
81 default:
82 UNIMPLEMENTED_MSG("Format not implemented");
83 break;
84 }
85}
86
76std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, 87std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
77 u32 block_height) { 88 u32 block_height) {
78 u8* data = Memory::GetPointer(address); 89 u8* data = Memory::GetPointer(address);
@@ -110,6 +121,26 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
110 return unswizzled_data; 121 return unswizzled_data;
111} 122}
112 123
124std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
125 u32 block_height) {
126 u8* data = Memory::GetPointer(address);
127 u32 bytes_per_pixel = DepthBytesPerPixel(format);
128
129 std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
130
131 switch (format) {
132 case DepthFormat::Z24_S8_UNORM:
133 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
134 unswizzled_data.data(), true, block_height);
135 break;
136 default:
137 UNIMPLEMENTED_MSG("Format not implemented");
138 break;
139 }
140
141 return unswizzled_data;
142}
143
113std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, 144std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width,
114 u32 height) { 145 u32 height) {
115 std::vector<u8> rgba_data; 146 std::vector<u8> rgba_data;
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 2562c4b06..2b088c077 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -17,6 +17,12 @@ namespace Texture {
17std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, 17std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
18 u32 block_height = TICEntry::DefaultBlockHeight); 18 u32 block_height = TICEntry::DefaultBlockHeight);
19 19
20/**
21 * Unswizzles a swizzled depth texture without changing its format.
22 */
23std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
24 u32 block_height = TICEntry::DefaultBlockHeight);
25
20/// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. 26/// Copies texture data from a buffer and performs swizzling/unswizzling as necessary.
21void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, 27void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel,
22 u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); 28 u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height);