Explorar el Código

mesa: consolidate texstore functions

The code for storing 1D, 2D and 3D tex images (whole or sub-images) was
all pretty similar.  This consolidates those six paths.

v2: rework switch statement to catch unexpected targets

Reviewed-by: José Fonseca <jfonseca@vmware.com>
tags/mesa-8.0-rc1
Brian Paul hace 13 años
padre
commit
5c818c6277
Se han modificado 1 ficheros con 153 adiciones y 331 borrados
  1. 153
    331
      src/mesa/main/texstore.c

+ 153
- 331
src/mesa/main/texstore.c Ver fichero

@@ -4565,9 +4565,137 @@ get_read_write_mode(GLenum userFormat, gl_format texFormat)
return GL_MAP_WRITE_BIT;
}


/**
* Helper function for storing 1D, 2D, 3D whole and subimages into texture
* memory.
* The source of the image data may be user memory or a PBO. In the later
* case, we'll map the PBO, copy from it, then unmap it.
*/
static void
store_texsubimage(struct gl_context *ctx,
struct gl_texture_image *texImage,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
GLenum format, GLenum type, const GLvoid *pixels,
const struct gl_pixelstore_attrib *packing,
const char *caller)

{
const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
const GLenum target = texImage->TexObject->Target;
GLboolean success = GL_FALSE;
GLuint dims, slice, numSlices = 1, sliceOffset = 0;
GLint srcImageStride = 0;
const GLubyte *src;

assert(xoffset + width <= texImage->Width);
assert(yoffset + height <= texImage->Height);
assert(zoffset + depth <= texImage->Depth);

switch (target) {
case GL_TEXTURE_1D:
dims = 1;
break;
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_3D:
dims = 3;
break;
default:
dims = 2;
}

/* get pointer to src pixels (may be in a pbo which we'll map here) */
src = (const GLubyte *)
_mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
format, type, pixels, packing, caller);
if (!src)
return;

/* compute slice info (and do some sanity checks) */
switch (target) {
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_CUBE_MAP:
/* one image slice, nothing special needs to be done */
break;
case GL_TEXTURE_1D:
assert(height == 1);
assert(depth == 1);
assert(yoffset == 0);
assert(zoffset == 0);
break;
case GL_TEXTURE_1D_ARRAY:
assert(depth == 1);
assert(zoffset == 0);
numSlices = height;
sliceOffset = yoffset;
height = 1;
yoffset = 0;
srcImageStride = _mesa_image_row_stride(packing, width, format, type);
break;
case GL_TEXTURE_2D_ARRAY:
numSlices = depth;
sliceOffset = zoffset;
depth = 1;
zoffset = 0;
srcImageStride = _mesa_image_image_stride(packing, width, height,
format, type);
break;
case GL_TEXTURE_3D:
/* we'll store 3D images as a series of slices */
numSlices = depth;
sliceOffset = zoffset;
srcImageStride = _mesa_image_image_stride(packing, width, height,
format, type);
break;
default:
_mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
return;
}

assert(numSlices == 1 || srcImageStride != 0);

for (slice = 0; slice < numSlices; slice++) {
GLubyte *dstMap;
GLint dstRowStride;

ctx->Driver.MapTextureImage(ctx, texImage,
slice + sliceOffset,
xoffset, yoffset, width, height,
mapMode, &dstMap, &dstRowStride);
if (dstMap) {
/* Note: we're only storing a 2D (or 1D) slice at a time but we need
* to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
* used for 3D images.
*/
success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&dstMap,
width, height, 1, /* w, h, d */
format, type, src, packing);

ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
}

src += srcImageStride;

if (!success)
break;
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);

_mesa_unmap_teximage_pbo(ctx, packing);
}



/**
* This is the software fallback for Driver.TexImage1D().
* \sa _mesa_store_teximage2d()
* This is the fallback for Driver.TexImage1D().
*/
void
_mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4578,13 +4706,6 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLubyte *dstMap;
GLint dstRowStride;
GLboolean success;

(void) border;

if (width == 0)
return;

@@ -4595,47 +4716,14 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
return;
}

pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
pixels, packing, "glTexImage1D");
if (!pixels) {
/* Note: we check for a NULL image pointer here, _after_ we allocated
* memory for the texture. That's what the GL spec calls for.
*/
return;
}

/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, 1,
rwMode,
&dstMap, &dstRowStride);
if (dstMap) {
success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
0, /* dstRowStride */
&dstMap,
width, 1, 1,
format, type, pixels, packing);

ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
}
else {
success = GL_FALSE;
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");

_mesa_unmap_teximage_pbo(ctx, packing);
store_texsubimage(ctx, texImage,
0, 0, 0, width, 1, 1,
format, type, pixels, packing, "glTexImage1D");
}


/**
* This is the software fallback for Driver.TexImage2D().
*
* This function is oriented toward storing images in main memory, rather
* than VRAM. Device driver's can easily plug in their own replacement.
* This is the fallback for Driver.TexImage2D().
*/
void
_mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4646,13 +4734,6 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLubyte *dstMap;
GLint dstRowStride;
GLboolean success;

(void) border;

if (width == 0 || height == 0)
return;

@@ -4663,80 +4744,15 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
return;
}

pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
pixels, packing, "glTexImage2D");
if (!pixels) {
/* Note: we check for a NULL image pointer here, _after_ we allocated
* memory for the texture. That's what the GL spec calls for.
*/
return;
}

if (target == GL_TEXTURE_1D_ARRAY) {
const GLint srcStride =
_mesa_image_row_stride(packing, width, format, type);
int y;

success = GL_TRUE;

for (y = 0; y < height; y++) {
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, y,
0, 0, width, 1,
rwMode,
&dstMap, &dstRowStride);
if (dstMap) {
success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&dstMap,
width, 1, 1,
format, type, pixels, packing);
ctx->Driver.UnmapTextureImage(ctx, texImage, y);
}
else {
success = GL_FALSE;
}

if (!success)
break;

pixels = (const GLubyte *) pixels + srcStride;
}
} else {
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, height,
rwMode,
&dstMap, &dstRowStride);
if (dstMap) {
success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&dstMap,
width, height, 1,
format, type, pixels, packing);

ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
}
else {
success = GL_FALSE;
}
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");

_mesa_unmap_teximage_pbo(ctx, packing);
store_texsubimage(ctx, texImage,
0, 0, 0, width, height, 1,
format, type, pixels, packing, "glTexImage2D");
}



/**
* This is the software fallback for Driver.TexImage3D().
* \sa _mesa_store_teximage2d()
* This is the fallback for Driver.TexImage3D().
*/
void
_mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4747,14 +4763,6 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLboolean success = GL_TRUE;
GLint slice;
GLubyte **sliceMaps;
GLint dstRowStride;

(void) border;

if (width == 0 || height == 0 || depth == 0)
return;

@@ -4765,66 +4773,16 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
return;
}

pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth,
format, type,
pixels, packing, "glTexImage3D");
if (!pixels) {
/* Note: we check for a NULL image pointer here, _after_ we allocated
* memory for the texture. That's what the GL spec calls for.
*/
return;
}

if (target == GL_TEXTURE_1D_ARRAY) {
depth = height;
height = 1;
}

sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));

/* Map dest texture buffer slices */
for (slice = 0; slice < depth; slice++) {
ctx->Driver.MapTextureImage(ctx, texImage, slice,
0, 0, width, height,
rwMode,
&sliceMaps[slice], &dstRowStride);
if (!sliceMaps[slice]) {
success = GL_FALSE;
break;
}
}

if (success) {
success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
sliceMaps,
width, height, depth,
format, type, pixels, packing);
}

/* Unmap dest texture buffer slices */
for (slice = 0; slice < depth; slice++) {
if (sliceMaps[slice]) {
ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
}
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");

_mesa_unmap_teximage_pbo(ctx, packing);

free(sliceMaps);
store_texsubimage(ctx, texImage,
0, 0, 0, width, height, depth,
format, type, pixels, packing, "glTexImage3D");
}




/*
* This is the software fallback for Driver.TexSubImage1D()
* and Driver.CopyTexSubImage1D().
* This is the fallback for Driver.TexSubImage1D().
*/
void
_mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4834,49 +4792,15 @@ _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLubyte *dstMap;
GLint dstRowStride;
GLboolean success;

/* get pointer to src pixels (may be in a pbo which we'll map here) */
pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
pixels, packing, "glTexSubImage1D");
if (!pixels)
return;

/* Map dest texture buffer */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
xoffset, 0, width, 1,
rwMode,
&dstMap, &dstRowStride);

if (dstMap) {
success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&dstMap,
width, 1, 1,
format, type, pixels, packing);

ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
}
else {
success = GL_FALSE;
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");

_mesa_unmap_teximage_pbo(ctx, packing);
store_texsubimage(ctx, texImage,
xoffset, 0, 0, width, 1, 1,
format, type, pixels, packing, "glTexSubImage1D");
}



/**
* This is the software fallback for Driver.TexSubImage2D()
* and Driver.CopyTexSubImage2D().
* This is the fallback for Driver.TexSubImage2D().
*/
void
_mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4887,69 +4811,14 @@ _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLboolean success = GL_FALSE;
GLuint slice, numSlices, sliceOffset, srcImageStride;
const GLubyte *src;

/* get pointer to src pixels (may be in a pbo which we'll map here) */
src = (const GLubyte *)
_mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
pixels, packing, "glTexSubImage2D");
if (!src)
return;

if (target == GL_TEXTURE_1D_ARRAY) {
/* map each slice of the 1D array separately */
numSlices = height;
sliceOffset = yoffset;
height = 1;
yoffset = 0;
srcImageStride = _mesa_image_row_stride(packing, width, format, type);
}
else {
/* regular 2D image */
numSlices = 1;
sliceOffset = 0;
srcImageStride = 0;
}

for (slice = 0; slice < numSlices; slice++) {
GLubyte *dstMap;
GLint dstRowStride;

ctx->Driver.MapTextureImage(ctx, texImage,
slice + sliceOffset,
xoffset, yoffset, width, height,
rwMode, &dstMap, &dstRowStride);
if (dstMap) {
success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&dstMap,
width, height, 1, /* w, h, d */
format, type, src, packing);

ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
}

src += srcImageStride;

if (!success)
break;
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");

_mesa_unmap_teximage_pbo(ctx, packing);
store_texsubimage(ctx, texImage,
xoffset, yoffset, 0, width, height, 1,
format, type, pixels, packing, "glTexSubImage2D");
}


/*
* This is the software fallback for Driver.TexSubImage3D().
* and Driver.CopyTexSubImage3D().
* This is the fallback for Driver.TexSubImage3D().
*/
void
_mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
@@ -4960,56 +4829,9 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLboolean success = GL_TRUE;
GLint slice;
GLubyte **sliceMaps;
GLint dstRowStride;

/* get pointer to src pixels (may be in a pbo which we'll map here) */
pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
type, pixels, packing,
"glTexSubImage3D");
if (!pixels)
return;

sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));

/* Map dest texture buffer slices */
for (slice = 0; slice < depth; slice++) {
ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
xoffset, yoffset, width, height,
rwMode,
&sliceMaps[slice], &dstRowStride);
if (!sliceMaps[slice]) {
success = GL_FALSE;
break;
}
}

if (success) {
success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
texImage->TexFormat,
0, 0, 0,
dstRowStride,
sliceMaps,
width, height, depth,
format, type, pixels, packing);
}

/* Unmap dest texture buffer slices */
for (slice = 0; slice < depth; slice++) {
if (sliceMaps[slice]) {
ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
}
}

if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");

_mesa_unmap_teximage_pbo(ctx, packing);

free(sliceMaps);
store_texsubimage(ctx, texImage,
xoffset, yoffset, zoffset, width, height, depth,
format, type, pixels, packing, "glTexSubImage3D");
}



Cargando…
Cancelar
Guardar