From e3c79887c8f46716351ea159b351f0502560ae69 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 27 Feb 2018 17:24:34 -0800 Subject: [PATCH] vrend: make temporary buffer used by iovec read/write large enough "vrend: Fix iovec read/write for depth" started making of use of the bounding box's depth in the fallback path. It turns out in some instances, the temporary buffer used by iovec read/write is not large enough, leading to memory corruption. Let's separate send_size from alloc_size in some cases, since glReadnPixels requires it. With this fix, dEQP-GLES3.functional.texture.specification.basic_texsubimage3d.rgba32f_3d doesn't crash the virtual machine (though the test fails). Signed-off-by: Dave Airlie --- src/vrend_renderer.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index eb00157..57ce218 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -4669,8 +4669,7 @@ static void read_transfer_data(struct pipe_resource *res, { int blsize = util_format_get_blocksize(res->format); uint32_t size = vrend_get_iovec_size(iov, num_iovs); - uint32_t send_size = util_format_get_nblocks(res->format, box->width, - box->height) * blsize * box->depth; + uint32_t send_size = util_format_get_2d_size(res->format, src_stride, box->height) * box->depth; uint32_t bwx = util_format_get_nblocksx(res->format, box->width) * blsize; uint32_t bh = util_format_get_nblocksy(res->format, box->height); int d, h; @@ -4711,13 +4710,12 @@ static void write_transfer_data(struct pipe_resource *res, { int blsize = util_format_get_blocksize(res->format); uint32_t size = vrend_get_iovec_size(iov, num_iovs); - uint32_t send_size = util_format_get_nblocks(res->format, box->width, - box->height) * blsize * box->depth; uint32_t bwx = util_format_get_nblocksx(res->format, box->width) * blsize; uint32_t bh = util_format_get_nblocksy(res->format, box->height); int d, h; uint32_t myoffset = offset; uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * blsize; + uint32_t send_size = util_format_get_2d_size(res->format, stride, box->height) * box->depth; if ((send_size == size || bh == 1) && !invert) { vrend_write_to_iovec(iov, num_iovs, offset, data, send_size); @@ -4899,8 +4897,7 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, } if (need_temp) { - send_size = util_format_get_nblocks(res->base.format, info->box->width, - info->box->height) * elsize * info->box->depth; + send_size = util_format_get_2d_size(res->base.format, stride, info->box->height) * info->box->depth; data = malloc(send_size); if (!data) return ENOMEM; @@ -5156,8 +5153,12 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx, need_temp = 1; if (need_temp) { + uint32_t alloc_size, stride; + + stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, info->level)) * elsize; send_size = util_format_get_nblocks(res->base.format, info->box->width, info->box->height) * info->box->depth * util_format_get_blocksize(res->base.format); - data = malloc(send_size); + alloc_size = util_format_get_2d_size(res->base.format, stride, info->box->height) * info->box->depth; + data = malloc(alloc_size); if (!data) { fprintf(stderr,"malloc failed %d\n", send_size); return ENOMEM;