summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2016-03-24 11:24:33 -0600
committerBrian Paul <brianp@vmware.com>2016-03-29 18:13:45 -0600
commit105fe527840ed5fc55e78c4561915fbe1fded76c (patch)
tree1ef565a326e9b11e3a19c86878168652d47812ed
parentd4a5a61d445e683c20de00c1febe847b4c2db910 (diff)
mesa: new _mesa_prepare_mipmap_levels() function for mipmap generation
Simplifies the loops in generate_mipmap_uncompressed() and generate_mipmap_compressed(). Will be used in the state tracker too. Could probably be used in the meta code. If so, some additional clean-ups can be done after that. v2: use unsigned types instead of GLuint, per Ian Reviewed-by: Roland Scheidegger <sroland@vmware.com> Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
-rw-r--r--src/mesa/main/mipmap.c88
-rw-r--r--src/mesa/main/mipmap.h5
2 files changed, 62 insertions, 31 deletions
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 5a02780b960..cb9afdef2af 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -1872,6 +1872,49 @@ _mesa_prepare_mipmap_level(struct gl_context *ctx,
}
+/**
+ * Prepare all mipmap levels beyond 'baseLevel' for mipmap generation.
+ * When finished, all the gl_texture_image structures for the smaller
+ * mipmap levels will be consistent with the base level (in terms of
+ * dimensions, format, etc).
+ */
+void
+_mesa_prepare_mipmap_levels(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ unsigned baseLevel, unsigned maxLevel)
+{
+ const struct gl_texture_image *baseImage =
+ _mesa_select_tex_image(texObj, texObj->Target, baseLevel);
+ const GLint border = 0;
+ GLint width = baseImage->Width;
+ GLint height = baseImage->Height;
+ GLint depth = baseImage->Depth;
+ const GLenum intFormat = baseImage->InternalFormat;
+ const mesa_format texFormat = baseImage->TexFormat;
+ GLint newWidth, newHeight, newDepth;
+
+ /* Prepare baseLevel + 1, baseLevel + 2, ... */
+ for (unsigned level = baseLevel + 1; level <= maxLevel; level++) {
+ if (!_mesa_next_mipmap_level_size(texObj->Target, border,
+ width, height, depth,
+ &newWidth, &newHeight, &newDepth)) {
+ /* all done */
+ break;
+ }
+
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, level,
+ newWidth, newHeight, newDepth,
+ border, intFormat, texFormat)) {
+ break;
+ }
+
+ width = newWidth;
+ height = newHeight;
+ depth = newDepth;
+ }
+}
+
+
static void
generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj,
@@ -1892,7 +1935,6 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
GLint dstWidth, dstHeight, dstDepth;
GLint border;
GLint slice;
- GLboolean nextLevel;
GLubyte **srcMaps, **dstMaps;
GLboolean success = GL_TRUE;
@@ -1904,22 +1946,14 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
srcDepth = srcImage->Depth;
border = srcImage->Border;
- nextLevel = _mesa_next_mipmap_level_size(target, border,
- srcWidth, srcHeight, srcDepth,
- &dstWidth, &dstHeight, &dstDepth);
- if (!nextLevel)
- return;
-
- if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
- dstWidth, dstHeight, dstDepth,
- border, srcImage->InternalFormat,
- srcImage->TexFormat)) {
- return;
- }
-
/* get dest gl_texture_image */
dstImage = _mesa_select_tex_image(texObj, target, level + 1);
- assert(dstImage);
+ if (!dstImage) {
+ break;
+ }
+ dstWidth = dstImage->Width;
+ dstHeight = dstImage->Height;
+ dstDepth = dstImage->Depth;
if (target == GL_TEXTURE_1D_ARRAY) {
srcDepth = srcHeight;
@@ -2087,7 +2121,6 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
GLint srcWidth, srcHeight, srcDepth;
GLint dstWidth, dstHeight, dstDepth;
GLint border;
- GLboolean nextLevel;
GLuint temp_dst_row_stride, temp_dst_img_stride; /* in bytes */
GLint i;
@@ -2099,23 +2132,14 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
srcDepth = srcImage->Depth;
border = srcImage->Border;
- nextLevel = _mesa_next_mipmap_level_size(target, border,
- srcWidth, srcHeight, srcDepth,
- &dstWidth, &dstHeight, &dstDepth);
- if (!nextLevel)
- goto end;
-
- if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
- dstWidth, dstHeight, dstDepth,
- border, srcImage->InternalFormat,
- srcImage->TexFormat)) {
- /* all done */
- goto end;
- }
-
/* get dest gl_texture_image */
dstImage = _mesa_select_tex_image(texObj, target, level + 1);
- assert(dstImage);
+ if (!dstImage) {
+ break;
+ }
+ dstWidth = dstImage->Width;
+ dstHeight = dstImage->Height;
+ dstDepth = dstImage->Depth;
/* Compute dst image strides and alloc memory on first iteration */
temp_dst_row_stride = _mesa_format_row_stride(temp_format, dstWidth);
@@ -2194,6 +2218,8 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
maxLevel = MIN2(maxLevel, texObj->MaxLevel);
+ _mesa_prepare_mipmap_levels(ctx, texObj, texObj->BaseLevel, maxLevel);
+
if (_mesa_is_format_compressed(srcImage->TexFormat)) {
generate_mipmap_compressed(ctx, target, texObj, srcImage, maxLevel);
} else {
diff --git a/src/mesa/main/mipmap.h b/src/mesa/main/mipmap.h
index c0366d329a2..33913e88417 100644
--- a/src/mesa/main/mipmap.h
+++ b/src/mesa/main/mipmap.h
@@ -47,6 +47,11 @@ _mesa_prepare_mipmap_level(struct gl_context *ctx,
GLsizei width, GLsizei height, GLsizei depth,
GLsizei border, GLenum intFormat, mesa_format format);
+void
+_mesa_prepare_mipmap_levels(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ unsigned baseLevel, unsigned maxLevel);
+
extern void
_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj);