From e8c52d4c895cc4ab7a4d8962112323c9d15e922c Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 9 Aug 2018 00:30:02 -0400 Subject: [PATCH] gl_rasterizer_cache: Add bounds checking for gl_buffer copies. --- .../renderer_opengl/gl_rasterizer_cache.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index f6efce8182..114d35ce6a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -184,35 +184,37 @@ MathUtil::Rectangle SurfaceParams::GetRect() const { } template -void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr addr) { +void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector& gl_buffer, + Tegra::GPUVAddr addr) { constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT; constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); const auto& gpu = Core::System::GetInstance().GPU(); if (morton_to_gl) { + std::vector data; if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) { - auto data = Tegra::Texture::UnswizzleTexture( + 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( + data = Tegra::Texture::UnswizzleDepthTexture( *gpu.memory_manager->GpuToCpuAddress(addr), SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height); - std::memcpy(gl_buffer, data.data(), data.size()); } + const size_t size_to_copy{std::min(gl_buffer.size(), data.size())}; + gl_buffer.assign(data.begin(), data.begin() + size_to_copy); } 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 LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); VideoCore::MortonCopyPixels128( stride, height, bytes_per_pixel, gl_bytes_per_pixel, - Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(addr)), gl_buffer, + Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(addr)), gl_buffer.data(), morton_to_gl); } } -static constexpr std::array&, Tegra::GPUVAddr), SurfaceParams::MaxPixelFormat> morton_to_gl_fns = { MortonCopy, MortonCopy, @@ -235,7 +237,7 @@ static constexpr std::array, }; -static constexpr std::array&, Tegra::GPUVAddr), SurfaceParams::MaxPixelFormat> gl_to_morton_fns = { MortonCopy, @@ -467,7 +469,7 @@ void CachedSurface::LoadGLBuffer() { gl_buffer.resize(copy_size); morton_to_gl_fns[static_cast(params.pixel_format)]( - params.width, params.block_height, params.height, gl_buffer.data(), params.addr); + params.width, params.block_height, params.height, gl_buffer, params.addr); } else { const u8* const texture_src_data_end = texture_src_data + copy_size; @@ -494,7 +496,7 @@ void CachedSurface::FlushGLBuffer() { std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes); } else { gl_to_morton_fns[static_cast(params.pixel_format)]( - params.width, params.block_height, params.height, gl_buffer.data(), params.addr); + params.width, params.block_height, params.height, gl_buffer, params.addr); } }