mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 16:08:04 +02:00
Map/Unmap PBO as needed so that the texstore routines can work with
hardware-based PBOs in the future.
This commit is contained in:
parent
ba164c4614
commit
c0ebc4931a
1 changed files with 95 additions and 48 deletions
|
|
@ -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;
|
||||
}
|
||||
/* bad 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue