gl_rasterizer_cache: Add bounds checking for gl_buffer copies.
This commit is contained in:
parent
37e1ed3744
commit
e8c52d4c89
|
@ -184,35 +184,37 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool morton_to_gl, PixelFormat format>
|
template <bool morton_to_gl, PixelFormat format>
|
||||||
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<u8>& gl_buffer,
|
||||||
|
Tegra::GPUVAddr addr) {
|
||||||
constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT;
|
constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT;
|
||||||
constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
|
constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
|
||||||
const auto& gpu = Core::System::GetInstance().GPU();
|
const auto& gpu = Core::System::GetInstance().GPU();
|
||||||
|
|
||||||
if (morton_to_gl) {
|
if (morton_to_gl) {
|
||||||
|
std::vector<u8> data;
|
||||||
if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) {
|
if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) {
|
||||||
auto data = Tegra::Texture::UnswizzleTexture(
|
data = Tegra::Texture::UnswizzleTexture(
|
||||||
*gpu.memory_manager->GpuToCpuAddress(addr),
|
*gpu.memory_manager->GpuToCpuAddress(addr),
|
||||||
SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
|
SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
|
||||||
std::memcpy(gl_buffer, data.data(), data.size());
|
|
||||||
} else {
|
} else {
|
||||||
auto data = Tegra::Texture::UnswizzleDepthTexture(
|
data = Tegra::Texture::UnswizzleDepthTexture(
|
||||||
*gpu.memory_manager->GpuToCpuAddress(addr),
|
*gpu.memory_manager->GpuToCpuAddress(addr),
|
||||||
SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height);
|
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 {
|
} else {
|
||||||
// TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should
|
// 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
|
// check the configuration for this and perform more generic un/swizzle
|
||||||
LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!");
|
LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!");
|
||||||
VideoCore::MortonCopyPixels128(
|
VideoCore::MortonCopyPixels128(
|
||||||
stride, height, bytes_per_pixel, gl_bytes_per_pixel,
|
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);
|
morton_to_gl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
|
static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
|
||||||
SurfaceParams::MaxPixelFormat>
|
SurfaceParams::MaxPixelFormat>
|
||||||
morton_to_gl_fns = {
|
morton_to_gl_fns = {
|
||||||
MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
|
MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
|
||||||
|
@ -235,7 +237,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
|
||||||
MortonCopy<true, PixelFormat::Z32FS8>,
|
MortonCopy<true, PixelFormat::Z32FS8>,
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
|
static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
|
||||||
SurfaceParams::MaxPixelFormat>
|
SurfaceParams::MaxPixelFormat>
|
||||||
gl_to_morton_fns = {
|
gl_to_morton_fns = {
|
||||||
MortonCopy<false, PixelFormat::ABGR8>,
|
MortonCopy<false, PixelFormat::ABGR8>,
|
||||||
|
@ -467,7 +469,7 @@ void CachedSurface::LoadGLBuffer() {
|
||||||
gl_buffer.resize(copy_size);
|
gl_buffer.resize(copy_size);
|
||||||
|
|
||||||
morton_to_gl_fns[static_cast<size_t>(params.pixel_format)](
|
morton_to_gl_fns[static_cast<size_t>(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 {
|
} else {
|
||||||
const u8* const texture_src_data_end = texture_src_data + copy_size;
|
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);
|
std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes);
|
||||||
} else {
|
} else {
|
||||||
gl_to_morton_fns[static_cast<size_t>(params.pixel_format)](
|
gl_to_morton_fns[static_cast<size_t>(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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue