From 0f929762b3ba722bab1290a9fe23fc8ad6e909f4 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 2 Jul 2018 12:42:04 -0500 Subject: GPU: Implemented the Z24S8 depth format and load the depth framebuffer. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 +- .../renderer_opengl/gl_rasterizer_cache.cpp | 49 +++++++++++++--------- .../renderer_opengl/gl_rasterizer_cache.h | 47 ++++++++++++++++++++- 3 files changed, 77 insertions(+), 23 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 62ee45a36..b80f4336d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -307,7 +307,9 @@ void RasterizerOpenGL::DrawArrays() { // TODO(bunnei): Implement these const bool has_stencil = false; const bool using_color_fb = true; - const bool using_depth_fb = false; + + const bool using_depth_fb = regs.zeta.Address() != 0; + const MathUtil::Rectangle viewport_rect{regs.viewport_transform[0].GetRect()}; const bool write_color_fb = diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index ae48378f3..35ad4f161 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 tex_form true}, // DXT45 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 + + // DepthStencil formats + {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, + false}, // Z24S8 }}; static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { - const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); - if (type == SurfaceType::ColorTexture) { - ASSERT(static_cast(pixel_format) < tex_format_tuples.size()); - auto& format = tex_format_tuples[static_cast(pixel_format)]; - ASSERT(component_type == format.component_type); - return format; - } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { - // TODO(Subv): Implement depth formats - ASSERT_MSG(false, "Unimplemented"); - } + ASSERT(static_cast(pixel_format) < tex_format_tuples.size()); + auto& format = tex_format_tuples[static_cast(pixel_format)]; + ASSERT(component_type == format.component_type); - UNREACHABLE(); - return {}; + return format; } VAddr SurfaceParams::GetCpuAddr() const { @@ -149,11 +145,17 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra:: const auto& gpu = Core::System::GetInstance().GPU(); if (morton_to_gl) { - auto data = Tegra::Texture::UnswizzleTexture( - *gpu.memory_manager->GpuToCpuAddress(addr), - SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); - - std::memcpy(gl_buffer, data.data(), data.size()); + if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) { + auto data = Tegra::Texture::UnswizzleTexture( + *gpu.memory_manager->GpuToCpuAddress(addr), + SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); + std::memcpy(gl_buffer, data.data(), data.size()); + } else { + auto data = Tegra::Texture::UnswizzleDepthTexture( + *gpu.memory_manager->GpuToCpuAddress(addr), + SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height); + std::memcpy(gl_buffer, data.data(), data.size()); + } } else { // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should // check the configuration for this and perform more generic un/swizzle @@ -174,7 +176,7 @@ static constexpr std::array, MortonCopy, MortonCopy, MortonCopy, MortonCopy, MortonCopy, - MortonCopy, + MortonCopy, MortonCopy, }; static constexpr std::array, + MortonCopy, }; // Allocate an uninitialized texture of appropriate size and format for the surface @@ -397,9 +400,15 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( // get color and depth surfaces const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(regs.rt[0])}; - const SurfaceParams depth_params{color_params}; + SurfaceParams depth_params{color_params}; - ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented"); + if (using_depth_fb) { + depth_params.addr = regs.zeta.Address(); + depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(regs.zeta.format); + depth_params.component_type = SurfaceParams::ComponentTypeFromDepthFormat(regs.zeta.format); + depth_params.type = SurfaceParams::GetFormatType(depth_params.pixel_format); + depth_params.size_in_bytes = depth_params.SizeInBytes(); + } MathUtil::Rectangle color_rect{}; 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 { DXN1 = 11, // This is also known as BC4 ASTC_2D_4X4 = 12, - Max, + MaxColorFormat, + + // DepthStencil formats + Z24S8 = 13, + + MaxDepthStencilFormat, + + Max = MaxDepthStencilFormat, Invalid = 255, }; @@ -84,6 +91,7 @@ struct SurfaceParams { 4, // DXT45 4, // DXN1 4, // ASTC_2D_4X4 + 1, // Z24S8 }}; ASSERT(static_cast(format) < compression_factor_table.size()); @@ -108,6 +116,7 @@ struct SurfaceParams { 128, // DXT45 64, // DXN1 32, // ASTC_2D_4X4 + 32, // Z24S8 }}; ASSERT(static_cast(format) < bpp_table.size()); @@ -117,6 +126,16 @@ struct SurfaceParams { return GetFormatBpp(pixel_format); } + static PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { + switch (format) { + case Tegra::DepthFormat::Z24_S8_UNORM: + return PixelFormat::Z24S8; + default: + NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast(format)); + UNREACHABLE(); + } + } + static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { switch (format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: @@ -205,6 +224,15 @@ struct SurfaceParams { } } + static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) { + switch (format) { + case PixelFormat::Z24S8: + return Tegra::DepthFormat::Z24_S8_UNORM; + default: + UNREACHABLE(); + } + } + static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { // TODO(Subv): Implement more component types switch (type) { @@ -244,11 +272,26 @@ struct SurfaceParams { } } + static ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) { + switch (format) { + case Tegra::DepthFormat::Z24_S8_UNORM: + return ComponentType::UNorm; + default: + NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast(format)); + UNREACHABLE(); + } + } + static SurfaceType GetFormatType(PixelFormat pixel_format) { - if (static_cast(pixel_format) < MaxPixelFormat) { + if (static_cast(pixel_format) < static_cast(PixelFormat::MaxColorFormat)) { return SurfaceType::ColorTexture; } + if (static_cast(pixel_format) < + static_cast(PixelFormat::MaxDepthStencilFormat)) { + return SurfaceType::DepthStencil; + } + // TODO(Subv): Implement the other formats ASSERT(false); -- cgit v1.2.3 From d480b63e0da6c869157117fe2771da258c4e8ea0 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 2 Jul 2018 13:31:49 -0500 Subject: MaxwellToGL: Added conversion functions for depth test and cull mode. --- src/video_core/renderer_opengl/maxwell_to_gl.h | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/video_core/renderer_opengl') 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) { return {}; } +inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { + switch (comparison) { + case Maxwell::ComparisonOp::Never: + return GL_NEVER; + case Maxwell::ComparisonOp::Less: + return GL_LESS; + case Maxwell::ComparisonOp::Equal: + return GL_EQUAL; + case Maxwell::ComparisonOp::LessEqual: + return GL_LEQUAL; + case Maxwell::ComparisonOp::Greater: + return GL_GREATER; + case Maxwell::ComparisonOp::NotEqual: + return GL_NOTEQUAL; + case Maxwell::ComparisonOp::GreaterEqual: + return GL_GEQUAL; + case Maxwell::ComparisonOp::Always: + return GL_ALWAYS; + } + NGLOG_CRITICAL(Render_OpenGL, "Unimplemented comparison op={}", static_cast(comparison)); + UNREACHABLE(); + return {}; +} + +inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) { + switch (front_face) { + case Maxwell::Cull::FrontFace::ClockWise: + return GL_CW; + case Maxwell::Cull::FrontFace::CounterClockWise: + return GL_CCW; + } + NGLOG_CRITICAL(Render_OpenGL, "Unimplemented front face cull={}", static_cast(front_face)); + UNREACHABLE(); + return {}; +} + +inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) { + switch (cull_face) { + case Maxwell::Cull::CullFace::Front: + return GL_FRONT; + case Maxwell::Cull::CullFace::Back: + return GL_BACK; + case Maxwell::Cull::CullFace::FrontAndBack: + return GL_FRONT_AND_BACK; + } + NGLOG_CRITICAL(Render_OpenGL, "Unimplemented cull face={}", static_cast(cull_face)); + UNREACHABLE(); + return {}; +} + } // namespace MaxwellToGL -- cgit v1.2.3 From 18c8ae7750d0dac42c94ef41be041aeea6eb2e9e Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 2 Jul 2018 13:33:06 -0500 Subject: GPU: Set up the depth test state on every draw. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 +++++++++++ src/video_core/renderer_opengl/gl_rasterizer.h | 3 +++ 2 files changed, 14 insertions(+) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b80f4336d..0d0e0653d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -304,6 +304,9 @@ void RasterizerOpenGL::DrawArrays() { MICROPROFILE_SCOPE(OpenGL_Drawing); const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + // Sync the depth test state before configuring the framebuffer surfaces. + SyncDepthTestState(); + // TODO(bunnei): Implement these const bool has_stencil = false; const bool using_color_fb = true; @@ -719,6 +722,14 @@ void RasterizerOpenGL::SyncDepthOffset() { UNREACHABLE(); } +void RasterizerOpenGL::SyncDepthTestState() { + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + + state.depth.test_enabled = regs.depth_test_enable != 0; + state.depth.write_mask = regs.depth_write_enabled ? GL_TRUE : GL_FALSE; + state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func); +} + void RasterizerOpenGL::SyncBlendState() { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 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: /// Syncs the depth offset to match the guest state void SyncDepthOffset(); + /// Syncs the depth test state to match the guest state + void SyncDepthTestState(); + /// Syncs the blend state to match the guest state void SyncBlendState(); -- cgit v1.2.3 From a6d4903aaff4633bcd5a39ca79ea368f86bc3ce5 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 2 Jul 2018 13:33:41 -0500 Subject: GPU: Set up the culling configuration on each draw. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0d0e0653d..a3c5ad2a9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -307,10 +307,10 @@ void RasterizerOpenGL::DrawArrays() { // Sync the depth test state before configuring the framebuffer surfaces. SyncDepthTestState(); - // TODO(bunnei): Implement these + // TODO(bunnei): Implement this const bool has_stencil = false; - const bool using_color_fb = true; + const bool using_color_fb = true; const bool using_depth_fb = regs.zeta.Address() != 0; const MathUtil::Rectangle viewport_rect{regs.viewport_transform[0].GetRect()}; @@ -343,11 +343,9 @@ void RasterizerOpenGL::DrawArrays() { // Bind the framebuffer surfaces BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); - // Sync the viewport SyncViewport(surfaces_rect); - - // Sync the blend state registers SyncBlendState(); + SyncCullMode(); // TODO(bunnei): Sync framebuffer_scale uniform here // TODO(bunnei): Sync scissorbox uniform(s) here @@ -711,7 +709,11 @@ void RasterizerOpenGL::SyncClipCoef() { } void RasterizerOpenGL::SyncCullMode() { - UNREACHABLE(); + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + + state.cull.enabled = regs.cull.enabled != 0; + state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); + state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face); } void RasterizerOpenGL::SyncDepthScale() { -- cgit v1.2.3