diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 56 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 27 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 47 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 50 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.h | 6 |
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); | |||
| 747 | ASSERT_REG_POSITION(zeta, 0x3F8); | 791 | ASSERT_REG_POSITION(zeta, 0x3F8); |
| 748 | ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); | 792 | ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); |
| 749 | ASSERT_REG_POSITION(rt_control, 0x487); | 793 | ASSERT_REG_POSITION(rt_control, 0x487); |
| 794 | ASSERT_REG_POSITION(depth_test_enable, 0x4B3); | ||
| 750 | ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); | 795 | ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); |
| 796 | ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); | ||
| 797 | ASSERT_REG_POSITION(depth_test_func, 0x4C3); | ||
| 751 | ASSERT_REG_POSITION(blend, 0x4CF); | 798 | ASSERT_REG_POSITION(blend, 0x4CF); |
| 752 | ASSERT_REG_POSITION(vb_element_base, 0x50D); | 799 | ASSERT_REG_POSITION(vb_element_base, 0x50D); |
| 753 | ASSERT_REG_POSITION(tsc, 0x557); | 800 | ASSERT_REG_POSITION(tsc, 0x557); |
| @@ -755,6 +802,7 @@ ASSERT_REG_POSITION(tic, 0x55D); | |||
| 755 | ASSERT_REG_POSITION(code_address, 0x582); | 802 | ASSERT_REG_POSITION(code_address, 0x582); |
| 756 | ASSERT_REG_POSITION(draw, 0x585); | 803 | ASSERT_REG_POSITION(draw, 0x585); |
| 757 | ASSERT_REG_POSITION(index_array, 0x5F2); | 804 | ASSERT_REG_POSITION(index_array, 0x5F2); |
| 805 | ASSERT_REG_POSITION(cull, 0x646); | ||
| 758 | ASSERT_REG_POSITION(query, 0x6C0); | 806 | ASSERT_REG_POSITION(query, 0x6C0); |
| 759 | ASSERT_REG_POSITION(vertex_array[0], 0x700); | 807 | ASSERT_REG_POSITION(vertex_array[0], 0x700); |
| 760 | ASSERT_REG_POSITION(independent_blend, 0x780); | 808 | ASSERT_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 | ||
| 27 | enum 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. |
| 28 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format); | 37 | u32 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 | ||
| 714 | void RasterizerOpenGL::SyncCullMode() { | 717 | void 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 | ||
| 718 | void RasterizerOpenGL::SyncDepthScale() { | 725 | void RasterizerOpenGL::SyncDepthScale() { |
| @@ -723,6 +730,14 @@ void RasterizerOpenGL::SyncDepthOffset() { | |||
| 723 | UNREACHABLE(); | 730 | UNREACHABLE(); |
| 724 | } | 731 | } |
| 725 | 732 | ||
| 733 | void 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 | |||
| 726 | void RasterizerOpenGL::SyncBlendState() { | 741 | void 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 | ||
| 89 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | 93 | static 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 | ||
| 105 | VAddr SurfaceParams::GetCpuAddr() const { | 101 | VAddr 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 | ||
| 180 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | 182 | static 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 | ||
| 204 | inline 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 | |||
| 228 | inline 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 | |||
| 240 | inline 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 | ||
| 77 | static 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 | |||
| 76 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 87 | std::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 | ||
| 124 | std::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 | |||
| 113 | std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, | 144 | std::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 { | |||
| 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 17 | std::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 | */ | ||
| 23 | std::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. |
| 21 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, | 27 | void 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); |