Mesa (master): r300g: reject resources from handles which are not large enough

Marek Olšák mareko at kemper.freedesktop.org
Sun Jul 25 09:07:30 UTC 2010


Module: Mesa
Branch: master
Commit: 065e3f7ff2a9b6170e51b0104036088e8d163ea0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=065e3f7ff2a9b6170e51b0104036088e8d163ea0

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sat Jul 24 03:34:18 2010 +0200

r300g: reject resources from handles which are not large enough

The driver gets a buffer and its size in resource_from_handle.
It computes the required minimum buffer size from given texture
properties, and compares the two sizes.

This is to early detect DDX bugs.

---

 src/gallium/drivers/r300/r300_context.h           |    7 ++++++-
 src/gallium/drivers/r300/r300_texture.c           |   18 +++++++++++++++---
 src/gallium/drivers/r300/r300_winsys.h            |    7 ++++---
 src/gallium/winsys/radeon/drm/radeon_drm_buffer.c |    2 +-
 src/gallium/winsys/radeon/drm/radeon_r300.c       |   11 ++++++++---
 5 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index b9c96d5..7b58587 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -352,9 +352,14 @@ struct r300_texture {
      */
     unsigned stride_override;
 
-    /* Total size of this texture, in bytes. */
+    /* Total size of this texture, in bytes,
+     * derived from the texture properties. */
     unsigned size;
 
+    /* Total size of the buffer backing this texture, in bytes.
+     * It must be >= size. */
+    unsigned buffer_size;
+
     /* Whether this texture has non-power-of-two dimensions
      * or a user-specified pitch.
      * It can be either a regular texture or a rectangle one.
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 176fa76..7110427 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -1022,6 +1022,7 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
 
     tex->buffer = rws->buffer_create(rws, tex->size, 2048, base->bind,
                                      base->usage, tex->domain);
+    tex->buffer_size = tex->size;
 
     if (!tex->buffer) {
 	FREE(tex);
@@ -1120,7 +1121,7 @@ r300_texture_from_handle(struct pipe_screen* screen,
     struct r300_screen* rscreen = r300_screen(screen);
     struct r300_winsys_buffer *buffer;
     struct r300_texture* tex;
-    unsigned stride;
+    unsigned stride, size;
     boolean override_zb_flags;
 
     /* Support only 2D textures without mipmaps */
@@ -1130,7 +1131,7 @@ r300_texture_from_handle(struct pipe_screen* screen,
         return NULL;
     }
 
-    buffer = rws->buffer_from_handle(rws, whandle, &stride);
+    buffer = rws->buffer_from_handle(rws, whandle, &stride, &size);
     if (!buffer) {
         return NULL;
     }
@@ -1150,6 +1151,7 @@ r300_texture_from_handle(struct pipe_screen* screen,
 
     /* one ref already taken */
     tex->buffer = buffer;
+    tex->buffer_size = size;
 
     rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile);
     r300_setup_flags(tex);
@@ -1186,8 +1188,18 @@ r300_texture_from_handle(struct pipe_screen* screen,
                 tex->pitch[0] * util_format_get_blocksize(tex->b.b.format));
     }
 
-    if (SCREEN_DBG_ON(rscreen, DBG_TEX))
+    /* Make sure the buffer we got is large enough. */
+    if (tex->size > tex->buffer_size) {
+        fprintf(stderr, "r300: texture_from_handle: The buffer is not "
+                        "large enough. Got: %i, Need: %i, Info:\n",
+                        tex->buffer_size, tex->size);
         r300_tex_print_info(rscreen, tex, "texture_from_handle");
+        pipe_resource_reference((struct pipe_resource**)&tex, NULL);
+        return NULL;
+    } else {
+        if (SCREEN_DBG_ON(rscreen, DBG_TEX))
+            r300_tex_print_info(rscreen, tex, "texture_from_handle");
+    }
 
     return (struct pipe_resource*)tex;
 }
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 7e115c2..ff11546 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -184,12 +184,13 @@ struct r300_winsys_screen {
      * \param ws        The winsys this function is called from.
      * \param whandle   A winsys handle pointer as was received from a state
      *                  tracker.
-     * \param stride    A pointer to the stride return variable.
-     *                  The stride is in bytes.
+     * \param stride    The returned buffer stride in bytes.
+     * \param size      The returned buffer size.
      */
     struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *ws,
                                                      struct winsys_handle *whandle,
-                                                     unsigned *stride);
+                                                     unsigned *stride,
+                                                     unsigned *size);
 
     /**
      * Get a winsys handle from a winsys buffer. The internal structure
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index 5ea5912..017eac8 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -189,7 +189,7 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
     pipe_reference_init(&buf->base.base.reference, 1);
     buf->base.base.alignment = 0;
     buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
-    buf->base.base.size = 0;
+    buf->base.base.size = bo->size;
     buf->base.vtbl = &radeon_drm_buffer_vtbl;
     buf->mgr = mgr;
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index effa27f..5544504 100644
--- a/src/gallium/winsys/radeon/drm/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -109,14 +109,19 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
 
 static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
                                                                         struct winsys_handle *whandle,
-                                                                        unsigned *stride)
+                                                                        unsigned *stride,
+                                                                        unsigned *size)
 {
     struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
     struct pb_buffer *_buf;
 
-    *stride = whandle->stride;
-
     _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle);
+
+    if (stride)
+        *stride = whandle->stride;
+    if (size)
+        *size = _buf->base.size;
+
     return radeon_libdrm_winsys_buffer(_buf);
 }
 




More information about the mesa-commit mailing list