summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2011-08-01 23:04:12 -0700
committerEric Anholt <[email protected]>2011-10-03 13:29:30 -0700
commite0304180c32227342dbb67b707bfae446543bb48 (patch)
tree05224697ca0948eded9adb328a215bc2c5a3a24f /src/mesa/state_tracker
parent1165b64f561a7bdd3f603d9e30a2340774ba31ee (diff)
mesa: Convert _mesa_generate_mipmap to MapTexImage()-based access.
Now that we can zero-copy generate the mipmaps into brand new glTexImage()-generated storage using MapTextureImage(), we no longer need to allocate image->Data in mipmap generate. This requires deleting the drivers' old overrides of the miptree tracking after calling _mesa_generate_mipmap at the same time, or the drivers promptly lose our newly-generated data. Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c205
1 files changed, 1 insertions, 204 deletions
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index e53da5fd4ae..36fea3d7ff8 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -106,209 +106,6 @@ st_render_mipmap(struct st_context *st,
return TRUE;
}
-
-/**
- * Helper function to decompress an image. The result is a 32-bpp RGBA
- * image with stride==width.
- */
-static void
-decompress_image(enum pipe_format format, int datatype,
- const uint8_t *src, void *dst,
- unsigned width, unsigned height, unsigned src_stride)
-{
- const struct util_format_description *desc = util_format_description(format);
- const uint bw = util_format_get_blockwidth(format);
- const uint bh = util_format_get_blockheight(format);
- uint dst_stride = 4 * MAX2(width, bw);
-
- if (datatype == GL_FLOAT) {
- desc->unpack_rgba_float((float *)dst, dst_stride * sizeof(GLfloat), src, src_stride, width, height);
- if (width < bw || height < bh) {
- float *dst_p = (float *)dst;
- /* We're decompressing an image smaller than the compression
- * block size. We don't want garbage pixel values in the region
- * outside (width x height) so replicate pixels from the (width
- * x height) region to fill out the (bw x bh) block size.
- */
- uint x, y;
- for (y = 0; y < bh; y++) {
- for (x = 0; x < bw; x++) {
- if (x >= width || y >= height) {
- uint p = (y * bw + x) * 4;
- dst_p[p + 0] = dst_p[0];
- dst_p[p + 1] = dst_p[1];
- dst_p[p + 2] = dst_p[2];
- dst_p[p + 3] = dst_p[3];
- }
- }
- }
- }
- } else {
- desc->unpack_rgba_8unorm((uint8_t *)dst, dst_stride, src, src_stride, width, height);
- if (width < bw || height < bh) {
- uint8_t *dst_p = (uint8_t *)dst;
- /* We're decompressing an image smaller than the compression
- * block size. We don't want garbage pixel values in the region
- * outside (width x height) so replicate pixels from the (width
- * x height) region to fill out the (bw x bh) block size.
- */
- uint x, y;
- for (y = 0; y < bh; y++) {
- for (x = 0; x < bw; x++) {
- if (x >= width || y >= height) {
- uint p = (y * bw + x) * 4;
- dst_p[p + 0] = dst_p[0];
- dst_p[p + 1] = dst_p[1];
- dst_p[p + 2] = dst_p[2];
- dst_p[p + 3] = dst_p[3];
- }
- }
- }
- }
- }
-}
-
-/**
- * Helper function to compress an image. The source is a 32-bpp RGBA image
- * with stride==width.
- */
-static void
-compress_image(enum pipe_format format, int datatype,
- const void *src, uint8_t *dst,
- unsigned width, unsigned height, unsigned dst_stride)
-{
- const struct util_format_description *desc = util_format_description(format);
- const uint src_stride = 4 * width;
-
- if (datatype == GL_FLOAT)
- desc->pack_rgba_float(dst, dst_stride, (GLfloat *)src, src_stride * sizeof(GLfloat), width, height);
- else
- desc->pack_rgba_8unorm(dst, dst_stride, (uint8_t *)src, src_stride, width, height);
-}
-
-
-/**
- * Software fallback for generate mipmap levels.
- */
-static void
-fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
- struct gl_texture_object *texObj)
-{
- struct pipe_context *pipe = st_context(ctx)->pipe;
- struct pipe_resource *pt = st_get_texobj_resource(texObj);
- const uint baseLevel = texObj->BaseLevel;
- const uint lastLevel = pt->last_level;
- const uint face = _mesa_tex_target_to_face(target);
- uint dstLevel;
- GLenum datatype;
- GLuint comps;
- GLboolean compressed;
-
- if (ST_DEBUG & DEBUG_FALLBACK)
- debug_printf("%s: fallback processing\n", __FUNCTION__);
-
- assert(target != GL_TEXTURE_3D); /* not done yet */
-
- compressed =
- _mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat);
-
- if (compressed) {
- GLenum type =
- _mesa_get_format_datatype(texObj->Image[face][baseLevel]->TexFormat);
-
- datatype = type == GL_UNSIGNED_NORMALIZED ? GL_UNSIGNED_BYTE : GL_FLOAT;
- comps = 4;
- }
- else {
- _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat,
- &datatype, &comps);
- assert(comps > 0 && "bad texture format in fallback_generate_mipmap()");
- }
-
- for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
- const uint srcLevel = dstLevel - 1;
- const uint srcWidth = u_minify(pt->width0, srcLevel);
- const uint srcHeight = u_minify(pt->height0, srcLevel);
- const uint srcDepth = u_minify(pt->depth0, srcLevel);
- const uint dstWidth = u_minify(pt->width0, dstLevel);
- const uint dstHeight = u_minify(pt->height0, dstLevel);
- const uint dstDepth = u_minify(pt->depth0, dstLevel);
- struct pipe_transfer *srcTrans, *dstTrans;
- const ubyte *srcData;
- ubyte *dstData;
- int srcStride, dstStride;
-
- srcTrans = pipe_get_transfer(pipe, pt, srcLevel,
- face,
- PIPE_TRANSFER_READ, 0, 0,
- srcWidth, srcHeight);
-
- dstTrans = pipe_get_transfer(pipe, pt, dstLevel,
- face,
- PIPE_TRANSFER_WRITE, 0, 0,
- dstWidth, dstHeight);
-
- srcData = (ubyte *) pipe_transfer_map(pipe, srcTrans);
- dstData = (ubyte *) pipe_transfer_map(pipe, dstTrans);
-
- srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->resource->format);
- dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->resource->format);
-
- /* this cannot work correctly for 3d since it does
- not respect layerStride. */
- if (compressed) {
- const enum pipe_format format = pt->format;
- const uint bw = util_format_get_blockwidth(format);
- const uint bh = util_format_get_blockheight(format);
- const uint srcWidth2 = align(srcWidth, bw);
- const uint srcHeight2 = align(srcHeight, bh);
- const uint dstWidth2 = align(dstWidth, bw);
- const uint dstHeight2 = align(dstHeight, bh);
- uint8_t *srcTemp, *dstTemp;
-
- assert(comps == 4);
-
- srcTemp = malloc(srcWidth2 * srcHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
- dstTemp = malloc(dstWidth2 * dstHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
-
- /* decompress the src image: srcData -> srcTemp */
- decompress_image(format, datatype, srcData, srcTemp, srcWidth2, srcHeight2, srcTrans->stride);
-
- _mesa_generate_mipmap_level(target, datatype, comps,
- 0 /*border*/,
- srcWidth2, srcHeight2, srcDepth,
- srcTemp,
- srcWidth2, /* stride in texels */
- dstWidth2, dstHeight2, dstDepth,
- dstTemp,
- dstWidth2); /* stride in texels */
-
- /* compress the new image: dstTemp -> dstData */
- compress_image(format, datatype, dstTemp, dstData, dstWidth2, dstHeight2, dstTrans->stride);
-
- free(srcTemp);
- free(dstTemp);
- }
- else {
- _mesa_generate_mipmap_level(target, datatype, comps,
- 0 /*border*/,
- srcWidth, srcHeight, srcDepth,
- srcData,
- srcStride, /* stride in texels */
- dstWidth, dstHeight, dstDepth,
- dstData,
- dstStride); /* stride in texels */
- }
-
- pipe_transfer_unmap(pipe, srcTrans);
- pipe_transfer_unmap(pipe, dstTrans);
-
- pipe->transfer_destroy(pipe, srcTrans);
- pipe->transfer_destroy(pipe, dstTrans);
- }
-}
-
-
/**
* Compute the expected number of mipmap levels in the texture given
* the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/
@@ -422,7 +219,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
if (!st_render_mipmap(st, target, stObj, baseLevel, lastLevel)) {
/* since the util code actually also has a fallback, should
probably make it never fail and kill this */
- fallback_generate_mipmap(ctx, target, texObj);
+ _mesa_generate_mipmap(ctx, target, texObj);
}
/* Fill in the Mesa gl_texture_image fields */