mesa: Convert texstore.c to accessing textures using MapTextureImage.

This continues to allocate texImage->Data as before, so
drivers calling these functions need to use that when present.

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Brian Paul
2011-07-29 16:25:23 -07:00
committed by Eric Anholt
parent 5b257442a8
commit 81430ab54f

View File

@@ -4565,17 +4565,24 @@ texture_size(const struct gl_texture_image *texImage)
}
/** Return row stride in bytes */
static GLuint
texture_row_stride(const struct gl_texture_image *texImage)
/**
* Normally, we'll only _write_ texel data to a texture when we map it.
* But if the user is providing depth or stencil values and the texture
* image is a combined depth/stencil format, we'll actually read from
* the texture buffer too (in order to insert the depth or stencil values.
* \param userFormat the user-provided image format
* \param texFormat the destination texture format
*/
static GLbitfield
get_read_write_mode(GLenum userFormat, gl_format texFormat)
{
GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
texImage->Width);
return stride;
if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
&& _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
else
return GL_MAP_WRITE_BIT;
}
/**
* This is the software fallback for Driver.TexImage1D().
* \sa _mesa_store_teximage2d()
@@ -4590,6 +4597,12 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
GLuint sizeInBytes;
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
const GLuint zeroImageOffset = 0;
GLubyte *dstMap;
GLint dstRowStride;
GLboolean success;
(void) border;
/* allocate memory */
@@ -4608,20 +4621,26 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
*/
return;
}
else {
const GLint dstRowStride = 0;
GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
texImage->ImageOffsets,
width, 1, 1,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
}
}
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, 1,
rwMode,
&dstMap, &dstRowStride);
success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
texImage->TexFormat,
dstMap,
0, 0, 0, /* dstX/Y/Zoffset */
0, /* dstRowStride */
&zeroImageOffset,
width, 1, 1,
format, type, pixels, packing);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -4643,6 +4662,12 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
GLuint sizeInBytes;
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
const GLuint zeroImageOffset = 0;
GLubyte *dstMap;
GLint dstRowStride;
GLboolean success;
(void) border;
/* allocate memory */
@@ -4661,20 +4686,26 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
*/
return;
}
else {
GLint dstRowStride = texture_row_stride(texImage);
GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
texImage->ImageOffsets,
width, height, 1,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
}
}
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, height,
rwMode,
&dstMap, &dstRowStride);
assert(dstMap);
success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
dstMap,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&zeroImageOffset,
width, height, 1,
format, type, pixels, packing);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -4695,40 +4726,72 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
GLuint sizeInBytes;
const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
GLboolean success;
GLint slice;
GLubyte **sliceMaps;
GLuint *dstImageOffsets;
GLint dstRowStride;
GLuint texelSize = _mesa_get_format_bytes(texImage->TexFormat);
(void) border;
/* allocate memory */
sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
/* 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;
}
pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
type, pixels, packing, "glTexImage3D");
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;
}
else {
GLint dstRowStride = texture_row_stride(texImage);
GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
texImage->ImageOffsets,
width, height, depth,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
}
sliceMaps = (GLubyte **) malloc(depth * sizeof(GLubyte *));
dstImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
/* 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);
}
/* Compute image slice offsets */
for (slice = 0; slice < depth; slice++) {
dstImageOffsets[slice] = (sliceMaps[slice] - sliceMaps[0]) / texelSize;
}
success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
texImage->TexFormat,
sliceMaps[0],
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
dstImageOffsets,
width, height, depth,
format, type, pixels, packing);
/* Unmap dest texture buffer slices */
for (slice = 0; slice < depth; 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);
free(dstImageOffsets);
}
@@ -4746,26 +4809,37 @@ _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);
const GLuint zeroImageOffset = 0;
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;
{
const GLint dstRowStride = 0;
GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
xoffset, 0, 0, /* offsets */
dstRowStride,
texImage->ImageOffsets,
width, 1, 1,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
}
}
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
xoffset, 0, width, 1,
rwMode,
&dstMap, &dstRowStride);
success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
texImage->TexFormat,
dstMap,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&zeroImageOffset,
width, 1, 1,
format, type, pixels, packing);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -4785,26 +4859,37 @@ _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);
const GLuint zeroImageOffset = 0;
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, 2, width, height, 1, format, type,
pixels, packing, "glTexSubImage2D");
if (!pixels)
return;
{
GLint dstRowStride = texture_row_stride(texImage);
GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
xoffset, yoffset, 0,
dstRowStride,
texImage->ImageOffsets,
width, height, 1,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
}
}
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
xoffset, yoffset, width, height,
rwMode,
&dstMap, &dstRowStride);
success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
texImage->TexFormat,
dstMap,
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
&zeroImageOffset,
width, height, 1,
format, type, pixels, packing);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
if (!success)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -4823,6 +4908,14 @@ _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;
GLint slice;
GLubyte **sliceMaps;
GLuint *dstImageOffsets;
GLint dstRowStride;
GLuint texelSize = _mesa_get_format_bytes(texImage->TexFormat);
/* 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,
@@ -4830,22 +4923,44 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
if (!pixels)
return;
{
GLint dstRowStride = texture_row_stride(texImage);
GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data,
xoffset, yoffset, zoffset,
dstRowStride,
texImage->ImageOffsets,
width, height, depth,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
}
sliceMaps = (GLubyte **) malloc((zoffset + depth) * sizeof(GLubyte *));
dstImageOffsets = (GLuint *) malloc((zoffset + depth) * sizeof(GLuint));
/* Map dest texture buffer slices */
for (slice = 0; slice < depth; slice++) {
ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
xoffset, yoffset, width, height,
rwMode,
&sliceMaps[zoffset + slice], &dstRowStride);
}
/* Compute image slice offsets */
for (slice = 0; slice < depth; slice++) {
dstImageOffsets[slice] =
(sliceMaps[zoffset + slice] - sliceMaps[zoffset]) / texelSize;
}
success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
texImage->TexFormat,
sliceMaps[zoffset],
0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
dstImageOffsets,
width, height, depth,
format, type, pixels, packing);
/* Unmap dest texture buffer slices */
for (slice = 0; slice < depth; 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);
free(dstImageOffsets);
}
@@ -4885,7 +5000,8 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
(void) width; (void) height; (void) border;
GLubyte *dstMap;
GLint dstRowStride;
/* This is pretty simple, basically just do a memcpy without worrying
* about the usual image unpacking or image transfer operations.
@@ -4910,8 +5026,17 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
if (!data)
return;
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
0, 0, width, height,
GL_MAP_WRITE_BIT,
&dstMap, &dstRowStride);
/* copy the data */
memcpy(texImage->Data, data, imageSize);
memcpy(dstMap, data, imageSize);
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}
@@ -4980,19 +5105,15 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
GLint bytesPerRow, destRowStride, srcRowStride;
GLint bytesPerRow, dstRowStride, srcRowStride;
GLint i, rows;
GLubyte *dest;
GLubyte *dstMap;
const GLubyte *src;
const gl_format texFormat = texImage->TexFormat;
const GLint destWidth = texImage->Width;
GLuint bw, bh;
_mesa_get_format_block_size(texFormat, &bw, &bh);
(void) level;
(void) format;
/* these should have been caught sooner */
ASSERT((width % bw) == 0 || width == 2 || width == 1);
ASSERT((height % bh) == 0 || height == 2 || height == 1);
@@ -5009,21 +5130,24 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
srcRowStride = _mesa_format_row_stride(texFormat, width);
src = (const GLubyte *) data;
destRowStride = _mesa_format_row_stride(texFormat, destWidth);
dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
texFormat, destWidth,
(GLubyte *) texImage->Data);
/* Map dest texture buffer (write to whole region) */
ctx->Driver.MapTextureImage(ctx, texImage, 0,
xoffset, yoffset, width, height,
GL_MAP_WRITE_BIT,
&dstMap, &dstRowStride);
bytesPerRow = srcRowStride; /* bytes per row of blocks */
rows = height / bh; /* rows in blocks */
/* copy rows of blocks */
for (i = 0; i < rows; i++) {
memcpy(dest, src, bytesPerRow);
dest += destRowStride;
memcpy(dstMap, src, bytesPerRow);
dstMap += dstRowStride;
src += srcRowStride;
}
ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}