From c0ebc4931a003b7b14e92c3b537b6ba76259507c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 31 Oct 2004 16:18:07 +0000 Subject: [PATCH] Map/Unmap PBO as needed so that the texstore routines can work with hardware-based PBOs in the future. --- src/mesa/main/texstore.c | 143 ++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 48 deletions(-) diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 8c33a0fd18c..2ca9b5941ad 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.3 * * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * @@ -1789,57 +1789,91 @@ _mesa_texstore_rgba_float16(STORE_PARAMS) /** - * Validate acces to a PBO for texture data. - * - * \todo If the PBO is really resident in VRAM, this won't work; the - * device driver should check for that and do the right thing. + * 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 unmap_teximage_pbo() too! */ static const GLvoid * -validate_pbo_teximage( GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *unpack ) +validate_pbo_teximage(GLcontext *ctx, + 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 (unpack->BufferObj->Name == 0) { /* no PBO */ return pixels; } - else if (_mesa_validate_pbo_access(unpack, width, height, depth, format, - type, pixels)) { - return ADD_POINTERS(unpack->BufferObj->Data, pixels); + if (!_mesa_validate_pbo_access(unpack, width, height, depth, format, + type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access"); + return NULL; + } + + buf = 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; } - /* bad access! */ - return NULL; + + return ADD_POINTERS(buf, pixels); } /** - * Validate that unpacking compressed texture image data from a PBO - * won't go out of bounds. - * - * \todo If the PBO is really resident in VRAM, this won't work; the - * device driver should check for that and do the right thing. + * 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 unmap_teximage_pbo() too! */ static const GLvoid * -validate_pbo_compressed_teximage(GLsizei imageSize, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing) +validate_pbo_compressed_teximage(GLcontext *ctx, + GLsizei imageSize, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + const char *funcName) { + GLubyte *buf; + if (packing->BufferObj->Name == 0) { /* not using a PBO - return pointer unchanged */ return pixels; } - else { - /* using a PBO */ - if ((const GLubyte *) pixels + imageSize > - (const GLubyte *) packing->BufferObj->Size) { - /* out of bounds read! */ - return NULL; - } - /* OK! */ - return ADD_POINTERS(packing->BufferObj->Data, pixels); + if ((const GLubyte *) pixels + imageSize > + (const GLubyte *) packing->BufferObj->Size) { + /* out of bounds read! */ + _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access"); + return NULL; + } + + buf = 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. + */ +static void +unmap_teximage_pbo(GLcontext *ctx, const struct gl_pixelstore_attrib *unpack) +{ + if (unpack->BufferObj->Name) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } +} + /* * This is the software fallback for Driver.TexImage1D() @@ -1881,7 +1915,8 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, return; } - pixels = validate_pbo_teximage(width, 1, 1, format, type, pixels, packing); + pixels = validate_pbo_teximage(ctx, width, 1, 1, format, type, pixels, + packing, "glTexImage1D"); if (!pixels) return; @@ -1898,7 +1933,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); if (!success) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - return; } } @@ -1908,6 +1942,8 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, packing); } @@ -1958,8 +1994,8 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, return; } - pixels = validate_pbo_teximage(width, height, 1, - format, type, pixels, packing); + pixels = validate_pbo_teximage(ctx, width, height, 1, format, type, pixels, + packing, "glTexImage2D"); if (!pixels) return; @@ -1982,7 +2018,6 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); if (!success) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; } } @@ -1992,6 +2027,8 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, packing); } @@ -2033,8 +2070,8 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, return; } - pixels = validate_pbo_teximage(width, height, depth, - format, type, pixels, packing); + pixels = validate_pbo_teximage(ctx, width, height, depth, format, type, + pixels, packing, "glTexImage3D"); if (!pixels) return; @@ -2060,7 +2097,6 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); if (!success) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - return; } } @@ -2070,6 +2106,8 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, packing); } @@ -2087,8 +2125,8 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - pixels = validate_pbo_teximage(width, 1, 1, - format, type, pixels, packing); + pixels = validate_pbo_teximage(ctx, width, 1, 1, format, type, pixels, + packing, "glTexSubImage1D"); if (!pixels) return; @@ -2105,7 +2143,6 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); if (!success) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); - return; } } @@ -2115,6 +2152,8 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, packing); } @@ -2132,8 +2171,8 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - pixels = validate_pbo_teximage(width, height, 1, - format, type, pixels, packing); + pixels = validate_pbo_teximage(ctx, width, height, 1, format, type, pixels, + packing, "glTexSubImage2D"); if (!pixels) return; @@ -2157,7 +2196,6 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); if (!success) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); - return; } } @@ -2167,6 +2205,8 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, packing); } @@ -2183,8 +2223,8 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - pixels = validate_pbo_teximage(width, height, depth, - format, type, pixels, packing); + pixels = validate_pbo_teximage(ctx, width, height, depth, format, type, + pixels, packing, "glTexSubImage3D"); if (!pixels) return; @@ -2210,7 +2250,6 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); if (!success) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); - return; } } @@ -2220,6 +2259,8 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, packing); } @@ -2284,7 +2325,8 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, return; } - data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack); + data = validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack, + "glCompressedTexImage2D"); if (!data) return; @@ -2298,6 +2340,8 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, &ctx->Unpack); } @@ -2375,7 +2419,8 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, ASSERT((xoffset & 3) == 0); ASSERT((yoffset & 3) == 0); - data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack); + data = validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack, + "glCompressedTexSubImage2D"); if (!data) return; @@ -2404,6 +2449,8 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } + + unmap_teximage_pbo(ctx, &ctx->Unpack); } -- 2.30.2