[virglrenderer-devel] [PATCH] vrend: make temporary buffer used by iovec read/write large enough

Gurchetan Singh gurchetansingh at chromium.org
Wed Feb 28 01:24:34 UTC 2018


"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).
---
 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;
-- 
2.16.2.395.g2e18187dfd-goog



More information about the virglrenderer-devel mailing list