From af653906d0cf38556acae1f8e5d3f8968ff7074a Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Mon, 8 Oct 2018 14:34:55 -0400 Subject: [PATCH] Fixed block height settings for RenderTargets and Depth Buffers, and added block width and block depth --- src/video_core/engines/fermi_2d.h | 14 ++++++++-- src/video_core/engines/maxwell_3d.h | 12 +++++++-- .../renderer_opengl/gl_rasterizer_cache.cpp | 27 +++++++++++++++---- .../renderer_opengl/gl_rasterizer_cache.h | 5 +++- src/video_core/textures/texture.h | 17 ++++++++++-- 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 81d15c62a8..2a6e8bbbb3 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -36,9 +36,9 @@ public: RenderTargetFormat format; BitField<0, 1, u32> linear; union { - BitField<0, 4, u32> block_depth; + BitField<0, 4, u32> block_width; BitField<4, 4, u32> block_height; - BitField<8, 4, u32> block_width; + BitField<8, 4, u32> block_depth; }; u32 depth; u32 layer; @@ -53,10 +53,20 @@ public: address_low); } + u32 BlockWidth() const { + // The block width is stored in log2 format. + return 1 << block_width; + } + u32 BlockHeight() const { // The block height is stored in log2 format. return 1 << block_height; } + + u32 BlockDepth() const { + // The block depth is stored in log2 format. + return 1 << block_depth; + } }; static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 4290da33f1..896498b899 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -432,7 +432,11 @@ public: u32 width; u32 height; Tegra::RenderTargetFormat format; - u32 block_dimensions; + union { + BitField<0, 3, u32> block_width; + BitField<4, 3, u32> block_height; + BitField<8, 3, u32> block_depth; + } block_dimensions; u32 array_mode; u32 layer_stride; u32 base_layer; @@ -548,7 +552,11 @@ public: u32 address_high; u32 address_low; Tegra::DepthFormat format; - u32 block_dimensions; + union { + BitField<0, 4, u32> block_width; + BitField<4, 4, u32> block_height; + BitField<8, 4, u32> block_depth; + } block_dimensions; u32 layer_stride; GPUVAddr Address() const { diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 56ff83eff0..433b34b272 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -45,7 +45,9 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { SurfaceParams params{}; params.addr = TryGetCpuAddr(config.tic.Address()); params.is_tiled = config.tic.IsTiled(); + params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, + params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0, params.pixel_format = PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value()); params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); @@ -98,7 +100,9 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { SurfaceParams params{}; params.addr = TryGetCpuAddr(config.Address()); params.is_tiled = true; - params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; + params.block_width = 1 << config.block_dimensions.block_width; + params.block_height = 1 << config.block_dimensions.block_height; + params.block_depth = 1 << config.block_dimensions.block_depth; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); params.component_type = ComponentTypeFromRenderTarget(config.format); params.type = GetFormatType(params.pixel_format); @@ -122,11 +126,15 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { /*static*/ SurfaceParams SurfaceParams::CreateForDepthBuffer(u32 zeta_width, u32 zeta_height, Tegra::GPUVAddr zeta_address, - Tegra::DepthFormat format) { + Tegra::DepthFormat format, + u32 block_width, u32 block_height, + u32 block_depth) { SurfaceParams params{}; params.addr = TryGetCpuAddr(zeta_address); params.is_tiled = true; - params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; + params.block_width = 1 << std::min(block_width, 5U); + params.block_height = 1 << std::min(block_height, 5U); + params.block_depth = 1 << std::min(block_depth, 5U); params.pixel_format = PixelFormatFromDepthFormat(format); params.component_type = ComponentTypeFromDepthFormat(format); params.type = GetFormatType(params.pixel_format); @@ -148,7 +156,9 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { SurfaceParams params{}; params.addr = TryGetCpuAddr(config.Address()); params.is_tiled = !config.linear; - params.block_height = params.is_tiled ? config.BlockHeight() : 0, + params.block_width = params.is_tiled ? std::min(config.BlockWidth(),32U) : 0, + params.block_height = params.is_tiled ? std::min(config.BlockHeight(),32U) : 0, + params.block_depth = params.is_tiled ? std::min(config.BlockDepth(),32U) : 0, params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); params.component_type = ComponentTypeFromRenderTarget(config.format); params.type = GetFormatType(params.pixel_format); @@ -818,6 +828,11 @@ void CachedSurface::LoadGLBuffer() { if (params.is_tiled) { gl_buffer.resize(total_size); + ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", + params.block_width, static_cast(params.target)); + ASSERT_MSG(params.block_depth == 1, "Block depth is defined as {} on texture type {}", + params.block_depth, static_cast(params.target)); + // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do // this for 3D textures, etc. switch (params.target) { @@ -989,7 +1004,9 @@ Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) { } SurfaceParams depth_params{SurfaceParams::CreateForDepthBuffer( - regs.zeta_width, regs.zeta_height, regs.zeta.Address(), regs.zeta.format)}; + regs.zeta_width, regs.zeta_height, regs.zeta.Address(), regs.zeta.format, + regs.zeta.block_dimensions.block_width, regs.zeta.block_dimensions.block_height, + regs.zeta.block_dimensions.block_depth)}; return GetSurface(depth_params, preserve_contents); } diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 0b4940b3c3..542886a6fc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -718,7 +718,8 @@ struct SurfaceParams { /// Creates SurfaceParams for a depth buffer configuration static SurfaceParams CreateForDepthBuffer(u32 zeta_width, u32 zeta_height, Tegra::GPUVAddr zeta_address, - Tegra::DepthFormat format); + Tegra::DepthFormat format, u32 block_width, + u32 block_height, u32 block_depth); /// Creates SurfaceParams for a Fermi2D surface copy static SurfaceParams CreateForFermiCopySurface( @@ -733,7 +734,9 @@ struct SurfaceParams { VAddr addr; bool is_tiled; + u32 block_width; u32 block_height; + u32 block_depth; PixelFormat pixel_format; ComponentType component_type; SurfaceType type; diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 8f31d825a3..58d17abcbf 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -161,7 +161,9 @@ struct TICEntry { BitField<21, 3, TICHeaderVersion> header_version; }; union { + BitField<0, 3, u32> block_width; BitField<3, 3, u32> block_height; + BitField<6, 3, u32> block_depth; // High 16 bits of the pitch value BitField<0, 16, u32> pitch_high; @@ -202,13 +204,24 @@ struct TICEntry { return depth_minus_1 + 1; } + u32 BlockWidth() const { + ASSERT(IsTiled()); + // The block height is stored in log2 format. + return 1 << block_width; + } + u32 BlockHeight() const { - ASSERT(header_version == TICHeaderVersion::BlockLinear || - header_version == TICHeaderVersion::BlockLinearColorKey); + ASSERT(IsTiled()); // The block height is stored in log2 format. return 1 << block_height; } + u32 BlockDepth() const { + ASSERT(IsTiled()); + // The block height is stored in log2 format. + return 1 << block_depth; + } + bool IsTiled() const { return header_version == TICHeaderVersion::BlockLinear || header_version == TICHeaderVersion::BlockLinearColorKey;