From b70610b9823fc7dc3672735c11be1a75fbb1a2a4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Feb 2011 18:24:35 -0700 Subject: [PATCH] mesa: move PBO-related functions into a new file --- src/mesa/SConscript | 1 + src/mesa/drivers/common/meta.c | 1 + .../drivers/dri/intel/intel_pixel_bitmap.c | 1 + src/mesa/drivers/dri/intel/intel_tex_image.c | 1 + .../drivers/dri/intel/intel_tex_subimage.c | 1 + src/mesa/drivers/dri/radeon/radeon_texture.c | 1 + src/mesa/drivers/dri/unichrome/via_tex.c | 1 + src/mesa/drivers/x11/xm_dd.c | 1 + src/mesa/main/bufferobj.c | 242 ------------ src/mesa/main/bufferobj.h | 41 -- src/mesa/main/colortab.c | 1 + src/mesa/main/dlist.c | 1 + src/mesa/main/drawpix.c | 1 + src/mesa/main/pbo.c | 372 ++++++++++++++++++ src/mesa/main/pbo.h | 92 +++++ src/mesa/main/pixel.c | 1 + src/mesa/main/polygon.c | 2 +- src/mesa/main/readpix.c | 1 + src/mesa/main/texgetimage.c | 1 + src/mesa/main/texstore.c | 89 +---- src/mesa/main/texstore.h | 18 - src/mesa/sources.mak | 1 + src/mesa/state_tracker/st_cb_bitmap.c | 1 + src/mesa/state_tracker/st_cb_drawpixels.c | 1 + src/mesa/state_tracker/st_cb_readpixels.c | 1 + src/mesa/state_tracker/st_cb_texture.c | 1 + src/mesa/swrast/s_bitmap.c | 1 + src/mesa/swrast/s_drawpix.c | 1 + src/mesa/swrast/s_readpix.c | 2 +- 29 files changed, 488 insertions(+), 391 deletions(-) create mode 100644 src/mesa/main/pbo.c create mode 100644 src/mesa/main/pbo.h diff --git a/src/mesa/SConscript b/src/mesa/SConscript index 90fec124af9..d65750b93e2 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -87,6 +87,7 @@ main_sources = [ 'main/multisample.c', 'main/nvprogram.c', 'main/pack.c', + 'main/pbo.c', 'main/pixel.c', 'main/pixelstore.c', 'main/pixeltransfer.c', diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index fd12e4d0a66..2b00e8979d2 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -48,6 +48,7 @@ #include "main/macros.h" #include "main/matrix.h" #include "main/mipmap.h" +#include "main/pbo.h" #include "main/polygon.h" #include "main/readpix.h" #include "main/scissor.h" diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index d7561ee689d..d398775906e 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -31,6 +31,7 @@ #include "main/colormac.h" #include "main/mtypes.h" #include "main/macros.h" +#include "main/pbo.h" #include "main/bufferobj.h" #include "main/state.h" #include "main/texobj.h" diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 9dba529c58d..1ffc19756e6 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -7,6 +7,7 @@ #include "main/bufferobj.h" #include "main/context.h" #include "main/formats.h" +#include "main/pbo.h" #include "main/texcompress.h" #include "main/texstore.h" #include "main/texgetimage.h" diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index c9b992a21b9..6b7f13ff353 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -27,6 +27,7 @@ **************************************************************************/ #include "main/mtypes.h" +#include "main/pbo.h" #include "main/texobj.h" #include "main/texstore.h" #include "main/texcompress.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index cf85a5bb572..9ec53881bb2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -35,6 +35,7 @@ #include "main/enums.h" #include "main/mfeatures.h" #include "main/mipmap.h" +#include "main/pbo.h" #include "main/texcompress.h" #include "main/texstore.h" #include "main/teximage.h" diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c index 18fb8f33b9f..a2fb010e142 100644 --- a/src/mesa/drivers/dri/unichrome/via_tex.c +++ b/src/mesa/drivers/dri/unichrome/via_tex.c @@ -34,6 +34,7 @@ #include "main/context.h" #include "main/mipmap.h" #include "main/mm.h" +#include "main/pbo.h" #include "main/simple_list.h" #include "main/texobj.h" #include "main/texstore.h" diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index b8d9e20c426..3031b7b3273 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -41,6 +41,7 @@ #include "main/image.h" #include "main/imports.h" #include "main/mtypes.h" +#include "main/pbo.h" #include "main/state.h" #include "main/texobj.h" #include "main/teximage.h" diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 75afae0add1..35d92616f45 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -658,248 +658,6 @@ _mesa_update_default_objects_buffer_objects(struct gl_context *ctx) } -/** - * When we're about to read pixel data out of a PBO (via glDrawPixels, - * glTexImage, etc) or write data into a PBO (via glReadPixels, - * glGetTexImage, etc) we call this function to check that we're not - * going to read out of bounds. - * - * XXX This would also be a convenient time to check that the PBO isn't - * currently mapped. Whoever calls this function should check for that. - * Remember, we can't use a PBO when it's mapped! - * - * If we're not using a PBO, this is a no-op. - * - * \param width width of image to read/write - * \param height height of image to read/write - * \param depth depth of image to read/write - * \param format format of image to read/write - * \param type datatype of image to read/write - * \param ptr the user-provided pointer/offset - * \return GL_TRUE if the PBO access is OK, GL_FALSE if the access would - * go out of bounds. - */ -GLboolean -_mesa_validate_pbo_access(GLuint dimensions, - const struct gl_pixelstore_attrib *pack, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *ptr) -{ - GLvoid *start, *end; - const GLubyte *sizeAddr; /* buffer size, cast to a pointer */ - - if (!_mesa_is_bufferobj(pack->BufferObj)) - return GL_TRUE; /* no PBO, OK */ - - if (pack->BufferObj->Size == 0) - /* no buffer! */ - return GL_FALSE; - - /* get address of first pixel we'll read */ - start = _mesa_image_address(dimensions, pack, ptr, width, height, - format, type, 0, 0, 0); - - /* get address just past the last pixel we'll read */ - end = _mesa_image_address(dimensions, pack, ptr, width, height, - format, type, depth-1, height-1, width); - - - sizeAddr = ((const GLubyte *) 0) + pack->BufferObj->Size; - - if ((const GLubyte *) start > sizeAddr) { - /* This will catch negative values / wrap-around */ - return GL_FALSE; - } - if ((const GLubyte *) end > sizeAddr) { - /* Image read goes beyond end of buffer */ - return GL_FALSE; - } - - /* OK! */ - return GL_TRUE; -} - - -/** - * For commands that read from a PBO (glDrawPixels, glTexImage, - * glPolygonStipple, etc), if we're reading from a PBO, map it read-only - * and return the pointer into the PBO. If we're not reading from a - * PBO, return \p src as-is. - * If non-null return, must call _mesa_unmap_pbo_source() when done. - * - * \return NULL if error, else pointer to start of data - */ -const GLvoid * -_mesa_map_pbo_source(struct gl_context *ctx, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *src) -{ - const GLubyte *buf; - - if (_mesa_is_bufferobj(unpack->BufferObj)) { - /* unpack from PBO */ - buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - GL_READ_ONLY_ARB, - unpack->BufferObj); - if (!buf) - return NULL; - - buf = ADD_POINTERS(buf, src); - } - else { - /* unpack from normal memory */ - buf = src; - } - - return buf; -} - - -/** - * Combine PBO-read validation and mapping. - * If any GL errors are detected, they'll be recorded and NULL returned. - * \sa _mesa_validate_pbo_access - * \sa _mesa_map_pbo_source - * A call to this function should have a matching call to - * _mesa_unmap_pbo_source(). - */ -const GLvoid * -_mesa_map_validate_pbo_source(struct gl_context *ctx, - GLuint dimensions, - const struct gl_pixelstore_attrib *unpack, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *ptr, - const char *where) -{ - ASSERT(dimensions == 1 || dimensions == 2 || dimensions == 3); - - if (!_mesa_is_bufferobj(unpack->BufferObj)) { - /* non-PBO access: no validation to be done */ - return ptr; - } - - if (!_mesa_validate_pbo_access(dimensions, unpack, - width, height, depth, format, type, ptr)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(out of bounds PBO access)", where); - return NULL; - } - - if (_mesa_bufferobj_mapped(unpack->BufferObj)) { - /* buffer is already mapped - that's an error */ - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where); - return NULL; - } - - ptr = _mesa_map_pbo_source(ctx, unpack, ptr); - return ptr; -} - - -/** - * Counterpart to _mesa_map_pbo_source() - */ -void -_mesa_unmap_pbo_source(struct gl_context *ctx, - const struct gl_pixelstore_attrib *unpack) -{ - ASSERT(unpack != &ctx->Pack); /* catch pack/unpack mismatch */ - if (_mesa_is_bufferobj(unpack->BufferObj)) { - ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - unpack->BufferObj); - } -} - - -/** - * For commands that write to a PBO (glReadPixels, glGetColorTable, etc), - * if we're writing to a PBO, map it write-only and return the pointer - * into the PBO. If we're not writing to a PBO, return \p dst as-is. - * If non-null return, must call _mesa_unmap_pbo_dest() when done. - * - * \return NULL if error, else pointer to start of data - */ -void * -_mesa_map_pbo_dest(struct gl_context *ctx, - const struct gl_pixelstore_attrib *pack, - GLvoid *dest) -{ - void *buf; - - if (_mesa_is_bufferobj(pack->BufferObj)) { - /* pack into PBO */ - buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, - GL_WRITE_ONLY_ARB, - pack->BufferObj); - if (!buf) - return NULL; - - buf = ADD_POINTERS(buf, dest); - } - else { - /* pack to normal memory */ - buf = dest; - } - - return buf; -} - - -/** - * Combine PBO-write validation and mapping. - * If any GL errors are detected, they'll be recorded and NULL returned. - * \sa _mesa_validate_pbo_access - * \sa _mesa_map_pbo_dest - * A call to this function should have a matching call to - * _mesa_unmap_pbo_dest(). - */ -GLvoid * -_mesa_map_validate_pbo_dest(struct gl_context *ctx, - GLuint dimensions, - const struct gl_pixelstore_attrib *unpack, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, GLvoid *ptr, - const char *where) -{ - ASSERT(dimensions == 1 || dimensions == 2 || dimensions == 3); - - if (!_mesa_is_bufferobj(unpack->BufferObj)) { - /* non-PBO access: no validation to be done */ - return ptr; - } - - if (!_mesa_validate_pbo_access(dimensions, unpack, - width, height, depth, format, type, ptr)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(out of bounds PBO access)", where); - return NULL; - } - - if (_mesa_bufferobj_mapped(unpack->BufferObj)) { - /* buffer is already mapped - that's an error */ - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where); - return NULL; - } - - ptr = _mesa_map_pbo_dest(ctx, unpack, ptr); - return ptr; -} - - -/** - * Counterpart to _mesa_map_pbo_dest() - */ -void -_mesa_unmap_pbo_dest(struct gl_context *ctx, - const struct gl_pixelstore_attrib *pack) -{ - ASSERT(pack != &ctx->Unpack); /* catch pack/unpack mismatch */ - if (_mesa_is_bufferobj(pack->BufferObj)) { - ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj); - } -} - - /** * Return the gl_buffer_object for the given ID. diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 09ccab31742..91fa073b649 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -79,47 +79,6 @@ _mesa_reference_buffer_object(struct gl_context *ctx, struct gl_buffer_object **ptr, struct gl_buffer_object *bufObj); -extern GLboolean -_mesa_validate_pbo_access(GLuint dimensions, - const struct gl_pixelstore_attrib *pack, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *ptr); - -extern const GLvoid * -_mesa_map_pbo_source(struct gl_context *ctx, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *src); - -extern const GLvoid * -_mesa_map_validate_pbo_source(struct gl_context *ctx, - GLuint dimensions, - const struct gl_pixelstore_attrib *unpack, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *ptr, - const char *where); - -extern void -_mesa_unmap_pbo_source(struct gl_context *ctx, - const struct gl_pixelstore_attrib *unpack); - -extern void * -_mesa_map_pbo_dest(struct gl_context *ctx, - const struct gl_pixelstore_attrib *pack, - GLvoid *dest); - -extern GLvoid * -_mesa_map_validate_pbo_dest(struct gl_context *ctx, - GLuint dimensions, - const struct gl_pixelstore_attrib *unpack, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, GLvoid *ptr, - const char *where); - -extern void -_mesa_unmap_pbo_dest(struct gl_context *ctx, - const struct gl_pixelstore_attrib *pack); - - extern void _mesa_init_buffer_object_functions(struct dd_function_table *driver); diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c index cf34997a8d1..d0c865735ac 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.c @@ -32,6 +32,7 @@ #include "mfeatures.h" #include "mtypes.h" #include "pack.h" +#include "pbo.h" #include "state.h" #include "teximage.h" #include "texstate.h" diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 8e904c7787a..4e463dd06a1 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -54,6 +54,7 @@ #include "light.h" #include "macros.h" #include "pack.h" +#include "pbo.h" #include "queryobj.h" #include "teximage.h" #include "mtypes.h" diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index df4712de894..98e82ef852b 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -31,6 +31,7 @@ #include "feedback.h" #include "framebuffer.h" #include "mfeatures.h" +#include "pbo.h" #include "readpix.h" #include "state.h" #include "dispatch.h" diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c new file mode 100644 index 00000000000..dc00d423ba9 --- /dev/null +++ b/src/mesa/main/pbo.c @@ -0,0 +1,372 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009-2011 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \file pbo.c + * \brief Functions related to Pixel Buffer Objects. + */ + + + +#include "glheader.h" +#include "bufferobj.h" +#include "image.h" +#include "imports.h" +#include "mtypes.h" +#include "pbo.h" + + + +/** + * When we're about to read pixel data out of a PBO (via glDrawPixels, + * glTexImage, etc) or write data into a PBO (via glReadPixels, + * glGetTexImage, etc) we call this function to check that we're not + * going to read out of bounds. + * + * XXX This would also be a convenient time to check that the PBO isn't + * currently mapped. Whoever calls this function should check for that. + * Remember, we can't use a PBO when it's mapped! + * + * If we're not using a PBO, this is a no-op. + * + * \param width width of image to read/write + * \param height height of image to read/write + * \param depth depth of image to read/write + * \param format format of image to read/write + * \param type datatype of image to read/write + * \param ptr the user-provided pointer/offset + * \return GL_TRUE if the PBO access is OK, GL_FALSE if the access would + * go out of bounds. + */ +GLboolean +_mesa_validate_pbo_access(GLuint dimensions, + const struct gl_pixelstore_attrib *pack, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *ptr) +{ + GLvoid *start, *end; + const GLubyte *sizeAddr; /* buffer size, cast to a pointer */ + + if (!_mesa_is_bufferobj(pack->BufferObj)) + return GL_TRUE; /* no PBO, OK */ + + if (pack->BufferObj->Size == 0) + /* no buffer! */ + return GL_FALSE; + + /* get address of first pixel we'll read */ + start = _mesa_image_address(dimensions, pack, ptr, width, height, + format, type, 0, 0, 0); + + /* get address just past the last pixel we'll read */ + end = _mesa_image_address(dimensions, pack, ptr, width, height, + format, type, depth-1, height-1, width); + + + sizeAddr = ((const GLubyte *) 0) + pack->BufferObj->Size; + + if ((const GLubyte *) start > sizeAddr) { + /* This will catch negative values / wrap-around */ + return GL_FALSE; + } + if ((const GLubyte *) end > sizeAddr) { + /* Image read goes beyond end of buffer */ + return GL_FALSE; + } + + /* OK! */ + return GL_TRUE; +} + + +/** + * For commands that read from a PBO (glDrawPixels, glTexImage, + * glPolygonStipple, etc), if we're reading from a PBO, map it read-only + * and return the pointer into the PBO. If we're not reading from a + * PBO, return \p src as-is. + * If non-null return, must call _mesa_unmap_pbo_source() when done. + * + * \return NULL if error, else pointer to start of data + */ +const GLvoid * +_mesa_map_pbo_source(struct gl_context *ctx, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *src) +{ + const GLubyte *buf; + + if (_mesa_is_bufferobj(unpack->BufferObj)) { + /* unpack from PBO */ + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) + return NULL; + + buf = ADD_POINTERS(buf, src); + } + else { + /* unpack from normal memory */ + buf = src; + } + + return buf; +} + + +/** + * Combine PBO-read validation and mapping. + * If any GL errors are detected, they'll be recorded and NULL returned. + * \sa _mesa_validate_pbo_access + * \sa _mesa_map_pbo_source + * A call to this function should have a matching call to + * _mesa_unmap_pbo_source(). + */ +const GLvoid * +_mesa_map_validate_pbo_source(struct gl_context *ctx, + GLuint dimensions, + const struct gl_pixelstore_attrib *unpack, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *ptr, + const char *where) +{ + ASSERT(dimensions == 1 || dimensions == 2 || dimensions == 3); + + if (!_mesa_is_bufferobj(unpack->BufferObj)) { + /* non-PBO access: no validation to be done */ + return ptr; + } + + if (!_mesa_validate_pbo_access(dimensions, unpack, + width, height, depth, format, type, ptr)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(out of bounds PBO access)", where); + return NULL; + } + + if (_mesa_bufferobj_mapped(unpack->BufferObj)) { + /* buffer is already mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where); + return NULL; + } + + ptr = _mesa_map_pbo_source(ctx, unpack, ptr); + return ptr; +} + + +/** + * Counterpart to _mesa_map_pbo_source() + */ +void +_mesa_unmap_pbo_source(struct gl_context *ctx, + const struct gl_pixelstore_attrib *unpack) +{ + ASSERT(unpack != &ctx->Pack); /* catch pack/unpack mismatch */ + if (_mesa_is_bufferobj(unpack->BufferObj)) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } +} + + +/** + * For commands that write to a PBO (glReadPixels, glGetColorTable, etc), + * if we're writing to a PBO, map it write-only and return the pointer + * into the PBO. If we're not writing to a PBO, return \p dst as-is. + * If non-null return, must call _mesa_unmap_pbo_dest() when done. + * + * \return NULL if error, else pointer to start of data + */ +void * +_mesa_map_pbo_dest(struct gl_context *ctx, + const struct gl_pixelstore_attrib *pack, + GLvoid *dest) +{ + void *buf; + + if (_mesa_is_bufferobj(pack->BufferObj)) { + /* pack into PBO */ + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + GL_WRITE_ONLY_ARB, + pack->BufferObj); + if (!buf) + return NULL; + + buf = ADD_POINTERS(buf, dest); + } + else { + /* pack to normal memory */ + buf = dest; + } + + return buf; +} + + +/** + * Combine PBO-write validation and mapping. + * If any GL errors are detected, they'll be recorded and NULL returned. + * \sa _mesa_validate_pbo_access + * \sa _mesa_map_pbo_dest + * A call to this function should have a matching call to + * _mesa_unmap_pbo_dest(). + */ +GLvoid * +_mesa_map_validate_pbo_dest(struct gl_context *ctx, + GLuint dimensions, + const struct gl_pixelstore_attrib *unpack, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, GLvoid *ptr, + const char *where) +{ + ASSERT(dimensions == 1 || dimensions == 2 || dimensions == 3); + + if (!_mesa_is_bufferobj(unpack->BufferObj)) { + /* non-PBO access: no validation to be done */ + return ptr; + } + + if (!_mesa_validate_pbo_access(dimensions, unpack, + width, height, depth, format, type, ptr)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(out of bounds PBO access)", where); + return NULL; + } + + if (_mesa_bufferobj_mapped(unpack->BufferObj)) { + /* buffer is already mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where); + return NULL; + } + + ptr = _mesa_map_pbo_dest(ctx, unpack, ptr); + return ptr; +} + + +/** + * Counterpart to _mesa_map_pbo_dest() + */ +void +_mesa_unmap_pbo_dest(struct gl_context *ctx, + const struct gl_pixelstore_attrib *pack) +{ + ASSERT(pack != &ctx->Unpack); /* catch pack/unpack mismatch */ + if (_mesa_is_bufferobj(pack->BufferObj)) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj); + } +} + + + +/** + * Check if an unpack PBO is active prior to fetching a texture image. + * If so, do bounds checking and map the buffer into main memory. + * Any errors detected will be recorded. + * The caller _must_ call _mesa_unmap_teximage_pbo() too! + */ +const GLvoid * +_mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *unpack, + const char *funcName) +{ + GLubyte *buf; + + if (!_mesa_is_bufferobj(unpack->BufferObj)) { + /* no PBO */ + return pixels; + } + if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)"); + return NULL; + } + + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, unpack->BufferObj); + if (!buf) { + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped)"); + return NULL; + } + + return ADD_POINTERS(buf, pixels); +} + + +/** + * Check if an unpack PBO is active prior to fetching a compressed texture + * image. + * If so, do bounds checking and map the buffer into main memory. + * Any errors detected will be recorded. + * The caller _must_ call _mesa_unmap_teximage_pbo() too! + */ +const GLvoid * +_mesa_validate_pbo_compressed_teximage(struct gl_context *ctx, + GLsizei imageSize, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + const char *funcName) +{ + GLubyte *buf; + + if (!_mesa_is_bufferobj(packing->BufferObj)) { + /* not using a PBO - return pointer unchanged */ + return pixels; + } + if ((const GLubyte *) pixels + imageSize > + ((const GLubyte *) 0) + packing->BufferObj->Size) { + /* out of bounds read! */ + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)"); + return NULL; + } + + buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, packing->BufferObj); + if (!buf) { + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped"); + return NULL; + } + + return ADD_POINTERS(buf, pixels); +} + + +/** + * This function must be called after either of the validate_pbo_*_teximage() + * functions. It unmaps the PBO buffer if it was mapped earlier. + */ +void +_mesa_unmap_teximage_pbo(struct gl_context *ctx, + const struct gl_pixelstore_attrib *unpack) +{ + if (_mesa_is_bufferobj(unpack->BufferObj)) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } +} + + diff --git a/src/mesa/main/pbo.h b/src/mesa/main/pbo.h new file mode 100644 index 00000000000..0cddd72ba7f --- /dev/null +++ b/src/mesa/main/pbo.h @@ -0,0 +1,92 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009-2011 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef PBO_H +#define PBO_H + + +#include "mtypes.h" + + +extern GLboolean +_mesa_validate_pbo_access(GLuint dimensions, + const struct gl_pixelstore_attrib *pack, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *ptr); + +extern const GLvoid * +_mesa_map_pbo_source(struct gl_context *ctx, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *src); + +extern const GLvoid * +_mesa_map_validate_pbo_source(struct gl_context *ctx, + GLuint dimensions, + const struct gl_pixelstore_attrib *unpack, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *ptr, + const char *where); + +extern void +_mesa_unmap_pbo_source(struct gl_context *ctx, + const struct gl_pixelstore_attrib *unpack); + +extern void * +_mesa_map_pbo_dest(struct gl_context *ctx, + const struct gl_pixelstore_attrib *pack, + GLvoid *dest); + +extern GLvoid * +_mesa_map_validate_pbo_dest(struct gl_context *ctx, + GLuint dimensions, + const struct gl_pixelstore_attrib *unpack, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, GLvoid *ptr, + const char *where); + +extern void +_mesa_unmap_pbo_dest(struct gl_context *ctx, + const struct gl_pixelstore_attrib *pack); + + +extern const GLvoid * +_mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *unpack, + const char *funcName); + +extern const GLvoid * +_mesa_validate_pbo_compressed_teximage(struct gl_context *ctx, + GLsizei imageSize, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + const char *funcName); + +extern void +_mesa_unmap_teximage_pbo(struct gl_context *ctx, + const struct gl_pixelstore_attrib *unpack); + + +#endif diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 08ef8fc8441..195fa234be2 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -35,6 +35,7 @@ #include "macros.h" #include "mfeatures.h" #include "pixel.h" +#include "pbo.h" #include "mtypes.h" #include "main/dispatch.h" diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index 9c213b9b4c0..ff4232ecc39 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -30,11 +30,11 @@ #include "glheader.h" #include "imports.h" -#include "bufferobj.h" #include "context.h" #include "image.h" #include "enums.h" #include "pack.h" +#include "pbo.h" #include "polygon.h" #include "mtypes.h" diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index 9a4f15f7279..6e09a52c88a 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -32,6 +32,7 @@ #include "formats.h" #include "image.h" #include "mtypes.h" +#include "pbo.h" #include "state.h" diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 28829694153..21d9140c550 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -38,6 +38,7 @@ #include "mfeatures.h" #include "mtypes.h" #include "pack.h" +#include "pbo.h" #include "texgetimage.h" #include "teximage.h" diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 8a3e5f77979..cd30fa02149 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -61,6 +61,7 @@ #include "mfeatures.h" #include "mtypes.h" #include "pack.h" +#include "pbo.h" #include "imports.h" #include "pack.h" #include "texcompress.h" @@ -4200,94 +4201,6 @@ _mesa_texstore(TEXSTORE_PARAMS) } -/** - * Check if an unpack PBO is active prior to fetching a texture image. - * If so, do bounds checking and map the buffer into main memory. - * Any errors detected will be recorded. - * The caller _must_ call _mesa_unmap_teximage_pbo() too! - */ -const GLvoid * -_mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *unpack, - const char *funcName) -{ - GLubyte *buf; - - if (!_mesa_is_bufferobj(unpack->BufferObj)) { - /* no PBO */ - return pixels; - } - if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)"); - return NULL; - } - - buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - GL_READ_ONLY_ARB, unpack->BufferObj); - if (!buf) { - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped)"); - return NULL; - } - - return ADD_POINTERS(buf, pixels); -} - - -/** - * Check if an unpack PBO is active prior to fetching a compressed texture - * image. - * If so, do bounds checking and map the buffer into main memory. - * Any errors detected will be recorded. - * The caller _must_ call _mesa_unmap_teximage_pbo() too! - */ -const GLvoid * -_mesa_validate_pbo_compressed_teximage(struct gl_context *ctx, - GLsizei imageSize, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - const char *funcName) -{ - GLubyte *buf; - - if (!_mesa_is_bufferobj(packing->BufferObj)) { - /* not using a PBO - return pointer unchanged */ - return pixels; - } - if ((const GLubyte *) pixels + imageSize > - ((const GLubyte *) 0) + packing->BufferObj->Size) { - /* out of bounds read! */ - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)"); - return NULL; - } - - buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - GL_READ_ONLY_ARB, packing->BufferObj); - if (!buf) { - _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped"); - return NULL; - } - - return ADD_POINTERS(buf, pixels); -} - - -/** - * This function must be called after either of the validate_pbo_*_teximage() - * functions. It unmaps the PBO buffer if it was mapped earlier. - */ -void -_mesa_unmap_teximage_pbo(struct gl_context *ctx, - const struct gl_pixelstore_attrib *unpack) -{ - if (_mesa_is_bufferobj(unpack->BufferObj)) { - ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - unpack->BufferObj); - } -} - - /** Return texture size in bytes */ static GLuint texture_size(const struct gl_texture_image *texImage) diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index 2f3c4e821fc..d563187098c 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -206,22 +206,4 @@ _mesa_store_compressed_texsubimage3d(struct gl_context *ctx, GLenum target, struct gl_texture_image *texImage); -extern const GLvoid * -_mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *unpack, - const char *funcName); - -extern const GLvoid * -_mesa_validate_pbo_compressed_teximage(struct gl_context *ctx, - GLsizei imageSize, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - const char *funcName); - -extern void -_mesa_unmap_teximage_pbo(struct gl_context *ctx, - const struct gl_pixelstore_attrib *unpack); - - #endif diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index bdf4126cf58..a8c0bbd2b9a 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -59,6 +59,7 @@ MAIN_SOURCES = \ main/multisample.c \ main/nvprogram.c \ main/pack.c \ + main/pbo.c \ main/pixel.c \ main/pixelstore.c \ main/pixeltransfer.c \ diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 0ea5671557c..149f1ca4450 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -35,6 +35,7 @@ #include "main/bufferobj.h" #include "main/macros.h" #include "main/mfeatures.h" +#include "main/pbo.h" #include "program/program.h" #include "program/prog_print.h" diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c0da1696247..c2b4e1808f5 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -37,6 +37,7 @@ #include "main/mfeatures.h" #include "main/mtypes.h" #include "main/pack.h" +#include "main/pbo.h" #include "main/texformat.h" #include "main/texstore.h" #include "program/program.h" diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 4689a0032b7..f8da2a4d158 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -38,6 +38,7 @@ #include "main/context.h" #include "main/image.h" #include "main/pack.h" +#include "main/pbo.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 08c498b1491..c3c4246d139 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -35,6 +35,7 @@ #include "main/macros.h" #include "main/mipmap.h" #include "main/pack.h" +#include "main/pbo.h" #include "main/pixeltransfer.h" #include "main/texcompress.h" #include "main/texfetch.h" diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c index 21488d3ba3e..18f1c1866bf 100644 --- a/src/mesa/swrast/s_bitmap.c +++ b/src/mesa/swrast/s_bitmap.c @@ -33,6 +33,7 @@ #include "main/condrender.h" #include "main/image.h" #include "main/macros.h" +#include "main/pbo.h" #include "s_context.h" #include "s_span.h" diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 4d0666898b4..11c63457f52 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -31,6 +31,7 @@ #include "main/imports.h" #include "main/macros.h" #include "main/pack.h" +#include "main/pbo.h" #include "main/pixeltransfer.h" #include "main/state.h" diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 9fe0752a37f..5c8d7e9c5cf 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -24,7 +24,6 @@ #include "main/glheader.h" -#include "main/bufferobj.h" #include "main/colormac.h" #include "main/feedback.h" #include "main/formats.h" @@ -32,6 +31,7 @@ #include "main/imports.h" #include "main/macros.h" #include "main/pack.h" +#include "main/pbo.h" #include "main/state.h" #include "s_context.h" -- 2.30.2