From bbf3b2da0cee61ee99cdc42d08543881640990e4 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Wed, 24 Oct 2018 18:30:27 -0400 Subject: Implement Mipmaps --- .../renderer_opengl/gl_rasterizer_cache.cpp | 240 +++++++++++++-------- 1 file changed, 146 insertions(+), 94 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index b057e2efa..70d1ebda5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -90,27 +90,33 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { } } -std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { +std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, bool layer_only, + bool uncompressed) const { const u32 compression_factor{GetCompressionFactor(pixel_format)}; const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; u32 m_depth = (layer_only ? 1U : depth); - u32 m_width = std::max(1U, width / compression_factor); - u32 m_height = std::max(1U, height / compression_factor); - std::size_t size = Tegra::Texture::CalculateSize(is_tiled, bytes_per_pixel, m_width, m_height, - m_depth, block_height, block_depth); - u32 m_block_height = block_height; - u32 m_block_depth = block_depth; + u32 m_width = uncompressed ? width : std::max(1U, width / compression_factor); + u32 m_height = uncompressed ? height : std::max(1U, height / compression_factor); + m_width = std::max(1U, m_width >> mip_level); + m_height = std::max(1U, m_height >> mip_level); + m_depth = std::max(1U, m_depth >> mip_level); + u32 m_block_height = MipBlockHeight(mip_level); + u32 m_block_depth = MipBlockDepth(mip_level); + return Tegra::Texture::CalculateSize(force_gl ? false : is_tiled, bytes_per_pixel, m_width, + m_height, m_depth, m_block_height, m_block_depth); +} + +std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, + bool uncompressed) const { std::size_t block_size_bytes = 512 * block_height * block_depth; // 512 is GOB size - for (u32 i = 1; i < max_mip_level; i++) { - m_width = std::max(1U, m_width / 2); - m_height = std::max(1U, m_height / 2); - m_depth = std::max(1U, m_depth / 2); - m_block_height = std::max(1U, m_block_height / 2); - m_block_depth = std::max(1U, m_block_depth / 2); - size += Tegra::Texture::CalculateSize(is_tiled, bytes_per_pixel, m_width, m_height, m_depth, - m_block_height, m_block_depth); + std::size_t size = 0; + for (u32 i = 0; i < max_mip_level; i++) { + size += InnerMipmapMemorySize(i, force_gl, layer_only, uncompressed); + } + if (!force_gl && is_tiled) { + size = Common::AlignUp(size, block_size_bytes); } - return is_tiled ? Common::AlignUp(size, block_size_bytes) : size; + return size; } /*static*/ SurfaceParams SurfaceParams::CreateForTexture( @@ -188,7 +194,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { params.unaligned_height = config.height; params.target = SurfaceTarget::Texture2D; params.depth = 1; - params.max_mip_level = 0; + params.max_mip_level = 1; params.is_layered = false; // Render target specific parameters, not used for caching @@ -222,7 +228,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { params.unaligned_height = zeta_height; params.target = SurfaceTarget::Texture2D; params.depth = 1; - params.max_mip_level = 0; + params.max_mip_level = 1; params.is_layered = false; params.rt = {}; @@ -249,7 +255,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { params.unaligned_height = config.height; params.target = SurfaceTarget::Texture2D; params.depth = 1; - params.max_mip_level = 0; + params.max_mip_level = 1; params.rt = {}; params.InitCacheParameters(config.Address()); @@ -373,13 +379,13 @@ static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType return format; } -MathUtil::Rectangle SurfaceParams::GetRect() const { - u32 actual_height{unaligned_height}; +MathUtil::Rectangle SurfaceParams::GetRect(u32 mip_level) const { + u32 actual_height{std::max(1U, unaligned_height >> mip_level)}; if (IsPixelFormatASTC(pixel_format)) { // ASTC formats must stop at the ATSC block size boundary actual_height = Common::AlignDown(actual_height, GetASTCBlockSize(pixel_format).second); } - return {0, actual_height, width, 0}; + return {0, actual_height, MipWidth(mip_level), 0}; } /// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN @@ -563,28 +569,31 @@ static constexpr GLConversionArray gl_to_morton_fns = { }; void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params, - std::vector& gl_buffer) { - u32 depth = params.depth; + std::vector& gl_buffer, u32 mip_level) { + u32 depth = params.MipDepth(mip_level); if (params.target == SurfaceParams::SurfaceTarget::Texture2D) { // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented. depth = 1U; } if (params.is_layered) { - u64 offset = 0; + u64 offset = params.GetMipmapLevelOffset(mip_level); u64 offset_gl = 0; u64 layer_size = params.LayerMemorySize(); - u64 gl_size = params.LayerSizeGL(); - for (u32 i = 0; i < depth; i++) { + u64 gl_size = params.LayerSizeGL(mip_level); + for (u32 i = 0; i < params.depth; i++) { functions[static_cast(params.pixel_format)]( - params.width, params.block_height, params.height, params.block_depth, 1, + params.MipWidth(mip_level), params.MipBlockHeight(mip_level), + params.MipHeight(mip_level), params.MipBlockDepth(mip_level), 1, gl_buffer.data() + offset_gl, gl_size, params.addr + offset); offset += layer_size; offset_gl += gl_size; } } else { + u64 offset = params.GetMipmapLevelOffset(mip_level); functions[static_cast(params.pixel_format)]( - params.width, params.block_height, params.height, params.block_depth, depth, - gl_buffer.data(), gl_buffer.size(), params.addr); + params.MipWidth(mip_level), params.MipBlockHeight(mip_level), + params.MipHeight(mip_level), params.MipBlockDepth(mip_level), depth, gl_buffer.data(), + gl_buffer.size(), params.addr + offset); } } @@ -839,29 +848,31 @@ CachedSurface::CachedSurface(const SurfaceParams& params) // Only pre-create the texture for non-compressed textures. switch (params.target) { case SurfaceParams::SurfaceTarget::Texture1D: - glTexStorage1D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, - rect.GetWidth()); + glTexStorage1D(SurfaceTargetToGL(params.target), params.max_mip_level, + format_tuple.internal_format, rect.GetWidth()); break; case SurfaceParams::SurfaceTarget::Texture2D: case SurfaceParams::SurfaceTarget::TextureCubemap: - glTexStorage2D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, - rect.GetWidth(), rect.GetHeight()); + glTexStorage2D(SurfaceTargetToGL(params.target), params.max_mip_level, + format_tuple.internal_format, rect.GetWidth(), rect.GetHeight()); break; case SurfaceParams::SurfaceTarget::Texture3D: case SurfaceParams::SurfaceTarget::Texture2DArray: - glTexStorage3D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, - rect.GetWidth(), rect.GetHeight(), params.depth); + glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level, + format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(), + params.depth); break; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(params.target)); UNREACHABLE(); - glTexStorage2D(GL_TEXTURE_2D, 1, format_tuple.internal_format, rect.GetWidth(), - rect.GetHeight()); + glTexStorage2D(GL_TEXTURE_2D, params.max_mip_level, format_tuple.internal_format, + rect.GetWidth(), rect.GetHeight()); } } glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -992,20 +1003,22 @@ static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector& data, PixelForm MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); void CachedSurface::LoadGLBuffer() { MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); - - gl_buffer.resize(params.size_in_bytes_gl); + gl_buffer.resize(params.max_mip_level); + for (u32 i = 0; i < params.max_mip_level; i++) + gl_buffer[i].resize(params.GetMipmapSizeGL(i)); if (params.is_tiled) { ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", params.block_width, static_cast(params.target)); - - SwizzleFunc(morton_to_gl_fns, params, gl_buffer); + for (u32 i = 0; i < params.max_mip_level; i++) + SwizzleFunc(morton_to_gl_fns, params, gl_buffer[i], i); } else { const auto texture_src_data{Memory::GetPointer(params.addr)}; const auto texture_src_data_end{texture_src_data + params.size_in_bytes_gl}; - gl_buffer.assign(texture_src_data, texture_src_data_end); + gl_buffer[0].assign(texture_src_data, texture_src_data_end); } - - ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer, params.pixel_format, params.width, params.height); + for (u32 i = 0; i < params.max_mip_level; i++) + ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer[i], params.pixel_format, params.MipWidth(i), + params.MipHeight(i)); } MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); @@ -1015,7 +1028,8 @@ void CachedSurface::FlushGLBuffer() { ASSERT_MSG(!IsPixelFormatASTC(params.pixel_format), "Unimplemented"); // OpenGL temporary buffer needs to be big enough to store raw texture size - gl_buffer.resize(GetSizeInBytes()); + gl_buffer.resize(1); + gl_buffer[0].resize(GetSizeInBytes()); const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); // Ensure no bad interactions with GL_UNPACK_ALIGNMENT @@ -1023,10 +1037,10 @@ void CachedSurface::FlushGLBuffer() { glPixelStorei(GL_PACK_ROW_LENGTH, static_cast(params.width)); ASSERT(!tuple.compressed); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, - static_cast(gl_buffer.size()), gl_buffer.data()); + glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, static_cast(gl_buffer[0].size()), + gl_buffer[0].data()); glPixelStorei(GL_PACK_ROW_LENGTH, 0); - ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer, params.pixel_format, params.width, + ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width, params.height); ASSERT(params.type != SurfaceType::Fill); const u8* const texture_src_data = Memory::GetPointer(params.addr); @@ -1035,26 +1049,21 @@ void CachedSurface::FlushGLBuffer() { ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", params.block_width, static_cast(params.target)); - SwizzleFunc(gl_to_morton_fns, params, gl_buffer); + SwizzleFunc(gl_to_morton_fns, params, gl_buffer[0], 0); } else { - std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes()); + std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer[0].data(), GetSizeInBytes()); } } -MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); -void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { - if (params.type == SurfaceType::Fill) - return; - - MICROPROFILE_SCOPE(OpenGL_TextureUL); - - const auto& rect{params.GetRect()}; +void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, + GLuint draw_fb_handle) { + const auto& rect{params.GetRect(mip_map)}; // Load data from memory to the surface const GLint x0 = static_cast(rect.left); const GLint y0 = static_cast(rect.bottom); std::size_t buffer_offset = - static_cast(static_cast(y0) * params.width + + static_cast(static_cast(y0) * params.MipWidth(mip_map) + static_cast(x0)) * SurfaceParams::GetBytesPerPixel(params.pixel_format); @@ -1072,88 +1081,131 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle cur_state.Apply(); // Ensure no bad interactions with GL_UNPACK_ALIGNMENT - ASSERT(params.width * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == 0); - glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast(params.width)); + ASSERT(params.MipWidth(mip_map) * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == + 0); + glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast(params.MipWidth(mip_map))); + GLsizei image_size = static_cast(params.GetMipmapSizeGL(mip_map, false)); glActiveTexture(GL_TEXTURE0); if (tuple.compressed) { switch (params.target) { case SurfaceParams::SurfaceTarget::Texture2D: - glCompressedTexImage2D( - SurfaceTargetToGL(params.target), 0, tuple.internal_format, - static_cast(params.width), static_cast(params.height), 0, - static_cast(params.size_in_bytes_gl), &gl_buffer[buffer_offset]); + glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, + static_cast(params.MipWidth(mip_map)), + static_cast(params.MipHeight(mip_map)), 0, image_size, + &gl_buffer[mip_map][buffer_offset]); break; case SurfaceParams::SurfaceTarget::Texture3D: + glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, + static_cast(params.MipWidth(mip_map)), + static_cast(params.MipHeight(mip_map)), + static_cast(params.MipDepth(mip_map)), 0, image_size, + &gl_buffer[mip_map][buffer_offset]); + break; case SurfaceParams::SurfaceTarget::Texture2DArray: - glCompressedTexImage3D( - SurfaceTargetToGL(params.target), 0, tuple.internal_format, - static_cast(params.width), static_cast(params.height), - static_cast(params.depth), 0, - static_cast(params.size_in_bytes_gl), &gl_buffer[buffer_offset]); + glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, + static_cast(params.MipWidth(mip_map)), + static_cast(params.MipHeight(mip_map)), + static_cast(params.depth), 0, image_size, + &gl_buffer[mip_map][buffer_offset]); break; - case SurfaceParams::SurfaceTarget::TextureCubemap: + case SurfaceParams::SurfaceTarget::TextureCubemap: { + GLsizei layer_size = static_cast(params.LayerSizeGL(mip_map)); for (std::size_t face = 0; face < params.depth; ++face) { glCompressedTexImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), - 0, tuple.internal_format, static_cast(params.width), - static_cast(params.height), 0, - static_cast(params.SizeInBytesCubeFaceGL()), - &gl_buffer[buffer_offset]); - buffer_offset += params.SizeInBytesCubeFace(); + mip_map, tuple.internal_format, + static_cast(params.MipWidth(mip_map)), + static_cast(params.MipHeight(mip_map)), 0, + layer_size, &gl_buffer[mip_map][buffer_offset]); + buffer_offset += layer_size; } break; + } default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(params.target)); UNREACHABLE(); - glCompressedTexImage2D( - GL_TEXTURE_2D, 0, tuple.internal_format, static_cast(params.width), - static_cast(params.height), 0, - static_cast(params.size_in_bytes_gl), &gl_buffer[buffer_offset]); + glCompressedTexImage2D(GL_TEXTURE_2D, mip_map, tuple.internal_format, + static_cast(params.MipWidth(mip_map)), + static_cast(params.MipHeight(mip_map)), 0, + static_cast(params.size_in_bytes_gl), + &gl_buffer[mip_map][buffer_offset]); } } else { switch (params.target) { case SurfaceParams::SurfaceTarget::Texture1D: - glTexSubImage1D(SurfaceTargetToGL(params.target), 0, x0, + glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0, static_cast(rect.GetWidth()), tuple.format, tuple.type, - &gl_buffer[buffer_offset]); + &gl_buffer[mip_map][buffer_offset]); break; case SurfaceParams::SurfaceTarget::Texture2D: - glTexSubImage2D(SurfaceTargetToGL(params.target), 0, x0, y0, + glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0, static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), tuple.format, tuple.type, - &gl_buffer[buffer_offset]); + &gl_buffer[mip_map][buffer_offset]); break; case SurfaceParams::SurfaceTarget::Texture3D: + glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, + static_cast(rect.GetWidth()), + static_cast(rect.GetHeight()), params.MipDepth(mip_map), + tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); + break; case SurfaceParams::SurfaceTarget::Texture2DArray: - glTexSubImage3D(SurfaceTargetToGL(params.target), 0, x0, y0, 0, + glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), params.depth, tuple.format, - tuple.type, &gl_buffer[buffer_offset]); + tuple.type, &gl_buffer[mip_map][buffer_offset]); break; - case SurfaceParams::SurfaceTarget::TextureCubemap: + case SurfaceParams::SurfaceTarget::TextureCubemap: { + std::size_t start = buffer_offset; for (std::size_t face = 0; face < params.depth; ++face) { - glTexSubImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, x0, - y0, static_cast(rect.GetWidth()), + glTexSubImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map, + x0, y0, static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), tuple.format, tuple.type, - &gl_buffer[buffer_offset]); - buffer_offset += params.SizeInBytesCubeFace(); + &gl_buffer[mip_map][buffer_offset]); + buffer_offset += params.LayerSizeGL(mip_map); } break; + } default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", static_cast(params.target)); UNREACHABLE(); - glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast(rect.GetWidth()), + glTexSubImage2D(GL_TEXTURE_2D, mip_map, x0, y0, static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), tuple.format, tuple.type, - &gl_buffer[buffer_offset]); + &gl_buffer[mip_map][buffer_offset]); } } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } +MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); +void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { + if (params.type == SurfaceType::Fill) + return; + + MICROPROFILE_SCOPE(OpenGL_TextureUL); + + for (u32 i = 0; i < params.max_mip_level; i++) + UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle); + + if (params.max_mip_level == 1) { + const GLuint target_tex = texture.handle; + OpenGLState cur_state = OpenGLState::GetCurState(); + const auto& old_tex = cur_state.texture_units[0]; + SCOPE_EXIT({ + cur_state.texture_units[0] = old_tex; + cur_state.Apply(); + }); + cur_state.texture_units[0].texture = target_tex; + cur_state.texture_units[0].target = SurfaceTargetToGL(params.target); + cur_state.Apply(); + glGenerateMipmap(SurfaceTargetToGL(params.target)); + } +} + RasterizerCacheOpenGL::RasterizerCacheOpenGL() { read_framebuffer.Create(); draw_framebuffer.Create(); -- cgit v1.2.3 From dc85e3bff16c375a909617908c9c7b82ec61cbdd Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Wed, 24 Oct 2018 18:44:37 -0400 Subject: Zero out memory region of recreated surface before flushing --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 70d1ebda5..28f17bc75 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1325,6 +1325,8 @@ void RasterizerCacheOpenGL::AccurateCopySurface(const Surface& src_surface, const Surface& dst_surface) { const auto& src_params{src_surface->GetSurfaceParams()}; const auto& dst_params{dst_surface->GetSurfaceParams()}; + auto* start = Memory::GetPointer(src_params.addr); + std::fill(start, start + dst_params.MemorySize(), 0); FlushRegion(src_params.addr, dst_params.MemorySize()); LoadSurface(dst_surface); } -- cgit v1.2.3 From f4432b5d0cb0cb89ff4af8172720f7457514d981 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Thu, 25 Oct 2018 12:24:10 -0400 Subject: Fixed Block Resizing algorithm and Clang Format --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 28f17bc75..cbe5bf664 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -100,7 +100,7 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b m_width = std::max(1U, m_width >> mip_level); m_height = std::max(1U, m_height >> mip_level); m_depth = std::max(1U, m_depth >> mip_level); - u32 m_block_height = MipBlockHeight(mip_level); + u32 m_block_height = MipBlockHeight(mip_level, m_height); u32 m_block_depth = MipBlockDepth(mip_level); return Tegra::Texture::CalculateSize(force_gl ? false : is_tiled, bytes_per_pixel, m_width, m_height, m_depth, m_block_height, m_block_depth); @@ -875,6 +875,9 @@ CachedSurface::CachedSurface(const SurfaceParams& params) glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (params.max_mip_level == 1) { + glTexParameterf(SurfaceTargetToGL(params.target), GL_TEXTURE_LOD_BIAS, 1000.0); + } VideoCore::LabelGLObject(GL_TEXTURE, texture.handle, params.addr, SurfaceParams::SurfaceTargetName(params.target)); @@ -1325,8 +1328,6 @@ void RasterizerCacheOpenGL::AccurateCopySurface(const Surface& src_surface, const Surface& dst_surface) { const auto& src_params{src_surface->GetSurfaceParams()}; const auto& dst_params{dst_surface->GetSurfaceParams()}; - auto* start = Memory::GetPointer(src_params.addr); - std::fill(start, start + dst_params.MemorySize(), 0); FlushRegion(src_params.addr, dst_params.MemorySize()); LoadSurface(dst_surface); } -- cgit v1.2.3 From 87f8181405cd09da15e7d1eb4a64024431fc0957 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Fri, 26 Oct 2018 16:17:29 -0400 Subject: Fixed Invalid Image size and Mipmap calculation --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index cbe5bf664..4d89d0f67 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -95,10 +95,13 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b const u32 compression_factor{GetCompressionFactor(pixel_format)}; const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; u32 m_depth = (layer_only ? 1U : depth); - u32 m_width = uncompressed ? width : std::max(1U, width / compression_factor); - u32 m_height = uncompressed ? height : std::max(1U, height / compression_factor); - m_width = std::max(1U, m_width >> mip_level); - m_height = std::max(1U, m_height >> mip_level); + u32 m_width = MipWidth(mip_level); + u32 m_height = MipHeight(mip_level); + m_width = uncompressed ? m_width + : std::max(1U, (m_width + compression_factor - 1) / compression_factor); + m_height = uncompressed + ? m_height + : std::max(1U, (m_height + compression_factor - 1) / compression_factor); m_depth = std::max(1U, m_depth >> mip_level); u32 m_block_height = MipBlockHeight(mip_level, m_height); u32 m_block_depth = MipBlockDepth(mip_level); -- cgit v1.2.3 From f0e902a7d6df72531fbd01d27756f9875dc3c65d Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Fri, 26 Oct 2018 19:18:03 -0400 Subject: Fixed mipmap block autosizing algorithm --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 4d89d0f67..b2250e6be 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -103,7 +103,7 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b ? m_height : std::max(1U, (m_height + compression_factor - 1) / compression_factor); m_depth = std::max(1U, m_depth >> mip_level); - u32 m_block_height = MipBlockHeight(mip_level, m_height); + u32 m_block_height = MipBlockHeight(mip_level); u32 m_block_depth = MipBlockDepth(mip_level); return Tegra::Texture::CalculateSize(force_gl ? false : is_tiled, bytes_per_pixel, m_width, m_height, m_depth, m_block_height, m_block_depth); @@ -111,7 +111,7 @@ std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, b std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, bool uncompressed) const { - std::size_t block_size_bytes = 512 * block_height * block_depth; // 512 is GOB size + std::size_t block_size_bytes = Tegra::Texture::GetGOBSize() * block_height * block_depth; std::size_t size = 0; for (u32 i = 0; i < max_mip_level; i++) { size += InnerMipmapMemorySize(i, force_gl, layer_only, uncompressed); @@ -1043,8 +1043,8 @@ void CachedSurface::FlushGLBuffer() { glPixelStorei(GL_PACK_ROW_LENGTH, static_cast(params.width)); ASSERT(!tuple.compressed); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, static_cast(gl_buffer[0].size()), - gl_buffer[0].data()); + glGetTextureImage(texture.handle, 0, tuple.format, tuple.type, + static_cast(gl_buffer[0].size()), gl_buffer[0].data()); glPixelStorei(GL_PACK_ROW_LENGTH, 0); ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer[0], params.pixel_format, params.width, params.height); -- cgit v1.2.3 From dde3094058358cfeaa436b4324adda305b4570bf Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Sun, 28 Oct 2018 18:58:07 -0400 Subject: Fixed black textures, pixelation and we no longer require to auto-generate mipmaps --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index b2250e6be..81b86b7a5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -878,6 +878,8 @@ CachedSurface::CachedSurface(const SurfaceParams& params) glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, + params.max_mip_level - 1); if (params.max_mip_level == 1) { glTexParameterf(SurfaceTargetToGL(params.target), GL_TEXTURE_LOD_BIAS, 1000.0); } @@ -1196,20 +1198,6 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle for (u32 i = 0; i < params.max_mip_level; i++) UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle); - - if (params.max_mip_level == 1) { - const GLuint target_tex = texture.handle; - OpenGLState cur_state = OpenGLState::GetCurState(); - const auto& old_tex = cur_state.texture_units[0]; - SCOPE_EXIT({ - cur_state.texture_units[0] = old_tex; - cur_state.Apply(); - }); - cur_state.texture_units[0].texture = target_tex; - cur_state.texture_units[0].target = SurfaceTargetToGL(params.target); - cur_state.Apply(); - glGenerateMipmap(SurfaceTargetToGL(params.target)); - } } RasterizerCacheOpenGL::RasterizerCacheOpenGL() { -- cgit v1.2.3