162abcb9aacc33218d0143a743c738435794b32a9Brian/**************************************************************************
262abcb9aacc33218d0143a743c738435794b32a9Brian *
362abcb9aacc33218d0143a743c738435794b32a9Brian * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
462abcb9aacc33218d0143a743c738435794b32a9Brian * All Rights Reserved.
562abcb9aacc33218d0143a743c738435794b32a9Brian *
662abcb9aacc33218d0143a743c738435794b32a9Brian * Permission is hereby granted, free of charge, to any person obtaining a
762abcb9aacc33218d0143a743c738435794b32a9Brian * copy of this software and associated documentation files (the
862abcb9aacc33218d0143a743c738435794b32a9Brian * "Software"), to deal in the Software without restriction, including
962abcb9aacc33218d0143a743c738435794b32a9Brian * without limitation the rights to use, copy, modify, merge, publish,
1062abcb9aacc33218d0143a743c738435794b32a9Brian * distribute, sub license, and/or sell copies of the Software, and to
1162abcb9aacc33218d0143a743c738435794b32a9Brian * permit persons to whom the Software is furnished to do so, subject to
1262abcb9aacc33218d0143a743c738435794b32a9Brian * the following conditions:
1362abcb9aacc33218d0143a743c738435794b32a9Brian *
1462abcb9aacc33218d0143a743c738435794b32a9Brian * The above copyright notice and this permission notice (including the
1562abcb9aacc33218d0143a743c738435794b32a9Brian * next paragraph) shall be included in all copies or substantial portions
1662abcb9aacc33218d0143a743c738435794b32a9Brian * of the Software.
1762abcb9aacc33218d0143a743c738435794b32a9Brian *
1862abcb9aacc33218d0143a743c738435794b32a9Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1962abcb9aacc33218d0143a743c738435794b32a9Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2062abcb9aacc33218d0143a743c738435794b32a9Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2162abcb9aacc33218d0143a743c738435794b32a9Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2262abcb9aacc33218d0143a743c738435794b32a9Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2362abcb9aacc33218d0143a743c738435794b32a9Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2462abcb9aacc33218d0143a743c738435794b32a9Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2562abcb9aacc33218d0143a743c738435794b32a9Brian *
2662abcb9aacc33218d0143a743c738435794b32a9Brian **************************************************************************/
2762abcb9aacc33218d0143a743c738435794b32a9Brian
2862abcb9aacc33218d0143a743c738435794b32a9Brian
2962abcb9aacc33218d0143a743c738435794b32a9Brian#include "main/imports.h"
3062abcb9aacc33218d0143a743c738435794b32a9Brian#include "main/mipmap.h"
3162abcb9aacc33218d0143a743c738435794b32a9Brian#include "main/teximage.h"
3262abcb9aacc33218d0143a743c738435794b32a9Brian
3362abcb9aacc33218d0143a743c738435794b32a9Brian#include "pipe/p_context.h"
3462abcb9aacc33218d0143a743c738435794b32a9Brian#include "pipe/p_defines.h"
3528486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
36b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol#include "util/u_format.h"
37088c6404fcae07dec6dcf16d2cb0777aa7b446adBrian#include "util/u_gen_mipmap.h"
3862abcb9aacc33218d0143a743c738435794b32a9Brian
39b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell#include "st_debug.h"
4062abcb9aacc33218d0143a743c738435794b32a9Brian#include "st_context.h"
41b0427bedde80e3189524651a327235bdfddbc613José Fonseca#include "st_texture.h"
4262abcb9aacc33218d0143a743c738435794b32a9Brian#include "st_gen_mipmap.h"
4362abcb9aacc33218d0143a743c738435794b32a9Brian#include "st_cb_texture.h"
4462abcb9aacc33218d0143a743c738435794b32a9Brian
4562abcb9aacc33218d0143a743c738435794b32a9Brian
4662abcb9aacc33218d0143a743c738435794b32a9Brian/**
4762abcb9aacc33218d0143a743c738435794b32a9Brian * one-time init for generate mipmap
4862abcb9aacc33218d0143a743c738435794b32a9Brian * XXX Note: there may be other times we need no-op/simple state like this.
4962abcb9aacc33218d0143a743c738435794b32a9Brian * In that case, some code refactoring would be good.
5062abcb9aacc33218d0143a743c738435794b32a9Brian */
5162abcb9aacc33218d0143a743c738435794b32a9Brianvoid
5262abcb9aacc33218d0143a743c738435794b32a9Brianst_init_generate_mipmap(struct st_context *st)
5362abcb9aacc33218d0143a743c738435794b32a9Brian{
547d95efde0a0e13e13c59444703bc47eb13926385Brian   st->gen_mipmap = util_create_gen_mipmap(st->pipe, st->cso_context);
5562abcb9aacc33218d0143a743c738435794b32a9Brian}
5662abcb9aacc33218d0143a743c738435794b32a9Brian
5762abcb9aacc33218d0143a743c738435794b32a9Brian
5862abcb9aacc33218d0143a743c738435794b32a9Brianvoid
59320da13c87c683cbe6e8145a9258ea2b7ef674cdBrianst_destroy_generate_mipmap(struct st_context *st)
6062abcb9aacc33218d0143a743c738435794b32a9Brian{
61088c6404fcae07dec6dcf16d2cb0777aa7b446adBrian   util_destroy_gen_mipmap(st->gen_mipmap);
62088c6404fcae07dec6dcf16d2cb0777aa7b446adBrian   st->gen_mipmap = NULL;
6362abcb9aacc33218d0143a743c738435794b32a9Brian}
6462abcb9aacc33218d0143a743c738435794b32a9Brian
6562abcb9aacc33218d0143a743c738435794b32a9Brian
6662abcb9aacc33218d0143a743c738435794b32a9Brian/**
6762abcb9aacc33218d0143a743c738435794b32a9Brian * Generate mipmap levels using hardware rendering.
6862abcb9aacc33218d0143a743c738435794b32a9Brian * \return TRUE if successful, FALSE if not possible
6962abcb9aacc33218d0143a743c738435794b32a9Brian */
7062abcb9aacc33218d0143a743c738435794b32a9Brianstatic boolean
7162abcb9aacc33218d0143a743c738435794b32a9Brianst_render_mipmap(struct st_context *st,
72e4026167d70f0aa0bc0cd2546ef9b41f7b167735Brian                 GLenum target,
738f55a95178069d5e8b18647e6b675fc403d68073Roland Scheidegger                 struct st_texture_object *stObj,
7462abcb9aacc33218d0143a743c738435794b32a9Brian                 uint baseLevel, uint lastLevel)
7562abcb9aacc33218d0143a743c738435794b32a9Brian{
7662abcb9aacc33218d0143a743c738435794b32a9Brian   struct pipe_context *pipe = st->pipe;
77364f8cad0f8f02fd39d9c51ea0774d349121b58dBrian   struct pipe_screen *screen = pipe->screen;
78c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul   struct pipe_sampler_view *psv;
79088c6404fcae07dec6dcf16d2cb0777aa7b446adBrian   const uint face = _mesa_tex_target_to_face(target);
8062abcb9aacc33218d0143a743c738435794b32a9Brian
814c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger#if 0
824c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   assert(target != GL_TEXTURE_3D); /* implemented but untested */
834c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger#endif
84e4026167d70f0aa0bc0cd2546ef9b41f7b167735Brian
8562abcb9aacc33218d0143a743c738435794b32a9Brian   /* check if we can render in the texture's format */
864c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   /* XXX should probably kill this and always use util_gen_mipmap
874c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      since this implements a sw fallback as well */
88c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul   if (!screen->is_format_supported(screen, stObj->pt->format,
89c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul                                    stObj->pt->target,
90e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                    0, PIPE_BIND_RENDER_TARGET)) {
9162abcb9aacc33218d0143a743c738435794b32a9Brian      return FALSE;
9262abcb9aacc33218d0143a743c738435794b32a9Brian   }
9362abcb9aacc33218d0143a743c738435794b32a9Brian
94c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul   psv = st_create_texture_sampler_view(pipe, stObj->pt);
95c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul
961c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák   /* Disable conditional rendering. */
971c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák   if (st->render_condition) {
981c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák      pipe->render_condition(pipe, NULL, 0);
991c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák   }
1001c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák
1018f55a95178069d5e8b18647e6b675fc403d68073Roland Scheidegger   util_gen_mipmap(st->gen_mipmap, psv, face, baseLevel, lastLevel,
102110b63d00fa0a555a00f5b1560452323517eafe1Brian                   PIPE_TEX_FILTER_LINEAR);
10362abcb9aacc33218d0143a743c738435794b32a9Brian
1041c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák   if (st->render_condition) {
1051c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák      pipe->render_condition(pipe, st->render_condition, st->condition_mode);
1061c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák   }
1071c95c3ef9c51c0eb218f80959bbbf29d213a6af0Marek Olšák
108c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul   pipe_sampler_view_reference(&psv, NULL);
109c5ba6a780769c61ffc7c5b1de94b583671bc5418Brian Paul
11062abcb9aacc33218d0143a743c738435794b32a9Brian   return TRUE;
11162abcb9aacc33218d0143a743c738435794b32a9Brian}
11262abcb9aacc33218d0143a743c738435794b32a9Brian
113c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul/**
114c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul * Compute the expected number of mipmap levels in the texture given
115c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul * the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/
116c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul * GL_TEXTURE_MAX_LEVEL settings.  This will tell us how many mipmap
11751523f1144ea5475a5cb08ddf95c80e1b737cafbBrian Paul * levels should be generated.
118c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul */
119c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paulstatic GLuint
120f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcompute_num_levels(struct gl_context *ctx,
121c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul                   struct gl_texture_object *texObj,
122c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul                   GLenum target)
123c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul{
1247bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   const struct gl_texture_image *baseImage;
1257bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   GLuint numLevels;
126c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
1277bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   baseImage = _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel);
128c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
1297bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   numLevels = texObj->BaseLevel + baseImage->MaxNumLevels;
1307bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   numLevels = MIN2(numLevels, texObj->MaxLevel + 1);
1317bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   assert(numLevels >= 1);
1324b59d2ba22fe73a912e4a8764ff6d4d440efc7d3Brian Paul
1337bcc228beb754a8f1586590d2c5b1786be281531Marek Olšák   return numLevels;
134c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul}
135c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
136c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
13751523f1144ea5475a5cb08ddf95c80e1b737cafbBrian Paul/**
13851523f1144ea5475a5cb08ddf95c80e1b737cafbBrian Paul * Called via ctx->Driver.GenerateMipmap().
13951523f1144ea5475a5cb08ddf95c80e1b737cafbBrian Paul */
14062abcb9aacc33218d0143a743c738435794b32a9Brianvoid
141f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_generate_mipmap(struct gl_context *ctx, GLenum target,
14262abcb9aacc33218d0143a743c738435794b32a9Brian                   struct gl_texture_object *texObj)
14362abcb9aacc33218d0143a743c738435794b32a9Brian{
14476c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
1458f55a95178069d5e8b18647e6b675fc403d68073Roland Scheidegger   struct st_texture_object *stObj = st_texture_object(texObj);
146c3016dcee562953dc187b484a27203c735f9662bBrian Paul   struct pipe_resource *pt = st_get_texobj_resource(texObj);
14762abcb9aacc33218d0143a743c738435794b32a9Brian   const uint baseLevel = texObj->BaseLevel;
14885dfed93fe2a6aace7dd2e08f97760e7062e6eb3Alan Hourihane   uint lastLevel;
14962abcb9aacc33218d0143a743c738435794b32a9Brian   uint dstLevel;
15062abcb9aacc33218d0143a743c738435794b32a9Brian
15185dfed93fe2a6aace7dd2e08f97760e7062e6eb3Alan Hourihane   if (!pt)
15285dfed93fe2a6aace7dd2e08f97760e7062e6eb3Alan Hourihane      return;
15385dfed93fe2a6aace7dd2e08f97760e7062e6eb3Alan Hourihane
154127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger   /* not sure if this ultimately actually should work,
155127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger      but we're not supporting multisampled textures yet. */
156127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger   assert(pt->nr_samples < 2);
157127328bfadaa5f080730fd41f404f1bc74f490d3Roland Scheidegger
1583293bcdc80cdfa20a2381aae2b94505bdf95d857Roland Scheidegger   /* find expected last mipmap level to generate*/
159c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul   lastLevel = compute_num_levels(ctx, texObj, target) - 1;
160c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
161ace937f1651c64d7fb22917489e29761130aaa0dYounes Manton   if (lastLevel == 0)
162ace937f1651c64d7fb22917489e29761130aaa0dYounes Manton      return;
163ace937f1651c64d7fb22917489e29761130aaa0dYounes Manton
16451f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul   /* The texture isn't in a "complete" state yet so set the expected
16551f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul    * lastLevel here, since it won't get done in st_finalize_texture().
16651f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul    */
16751f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul   stObj->lastLevel = lastLevel;
16851f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul
169c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul   if (pt->last_level < lastLevel) {
170c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul      /* The current gallium texture doesn't have space for all the
171c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul       * mipmap levels we need to generate.  So allocate a new texture.
172c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul       */
173287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      struct pipe_resource *oldTex = stObj->pt;
174c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
175c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul      /* create new texture with space for more levels */
176c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul      stObj->pt = st_texture_create(st,
177c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul                                    oldTex->target,
178c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul                                    oldTex->format,
179c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul                                    lastLevel,
180683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell                                    oldTex->width0,
181683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell                                    oldTex->height0,
182683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell                                    oldTex->depth0,
183db3a8af7f900e4970ea18659e86a824b4ebdefc7Brian Paul                                    oldTex->array_size,
184287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                    oldTex->bind);
185c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
186c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul      /* This will copy the old texture's base image into the new texture
187c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul       * which we just allocated.
188c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul       */
189295a87f6c211322faefc4ef7f88f02722973f5b6Brian Paul      st_finalize_texture(ctx, st->pipe, texObj);
190c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
191c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul      /* release the old tex (will likely be freed too) */
192287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&oldTex, NULL);
19340c3861e1e98116c573027b054a6a05208c53b6aMichal Krol      pipe_sampler_view_reference(&stObj->sampler_view, NULL);
194c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul   }
195cae2bb76c1147d48f75ddd7a058a48d11e72ba03Brian Paul   else {
196cae2bb76c1147d48f75ddd7a058a48d11e72ba03Brian Paul      /* Make sure that the base texture image data is present in the
197cae2bb76c1147d48f75ddd7a058a48d11e72ba03Brian Paul       * texture buffer.
198cae2bb76c1147d48f75ddd7a058a48d11e72ba03Brian Paul       */
199cae2bb76c1147d48f75ddd7a058a48d11e72ba03Brian Paul      st_finalize_texture(ctx, st->pipe, texObj);
200cae2bb76c1147d48f75ddd7a058a48d11e72ba03Brian Paul   }
201c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul
20251f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul   pt = stObj->pt;
20351f9713e39a4bd6dddff40328ca17632b80c5c81Brian Paul
2044b59d2ba22fe73a912e4a8764ff6d4d440efc7d3Brian Paul   assert(pt->last_level >= lastLevel);
20585dfed93fe2a6aace7dd2e08f97760e7062e6eb3Alan Hourihane
206e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul   /* Try to generate the mipmap by rendering/texturing.  If that fails,
207e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul    * use the software fallback.
208c7fddaf6122da489f4430f6bc2211bcb4740f416Brian Paul    */
209e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul   if (!st_render_mipmap(st, target, stObj, baseLevel, lastLevel)) {
2104c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      /* since the util code actually also has a fallback, should
2114c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         probably make it never fail and kill this */
212e0304180c32227342dbb67b707bfae446543bb48Brian Paul      _mesa_generate_mipmap(ctx, target, texObj);
21362abcb9aacc33218d0143a743c738435794b32a9Brian   }
21462abcb9aacc33218d0143a743c738435794b32a9Brian
215e4026167d70f0aa0bc0cd2546ef9b41f7b167735Brian   /* Fill in the Mesa gl_texture_image fields */
21662abcb9aacc33218d0143a743c738435794b32a9Brian   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
21762abcb9aacc33218d0143a743c738435794b32a9Brian      const uint srcLevel = dstLevel - 1;
21862abcb9aacc33218d0143a743c738435794b32a9Brian      const struct gl_texture_image *srcImage
21962abcb9aacc33218d0143a743c738435794b32a9Brian         = _mesa_get_tex_image(ctx, texObj, target, srcLevel);
22062abcb9aacc33218d0143a743c738435794b32a9Brian      struct gl_texture_image *dstImage;
22162abcb9aacc33218d0143a743c738435794b32a9Brian      struct st_texture_image *stImage;
22262abcb9aacc33218d0143a743c738435794b32a9Brian      uint border = srcImage->Border;
223318669f196ca922337da02af9d72773e76e70b45Brian Paul      uint dstWidth, dstHeight, dstDepth;
224318669f196ca922337da02af9d72773e76e70b45Brian Paul
225318669f196ca922337da02af9d72773e76e70b45Brian Paul      dstWidth = u_minify(pt->width0, dstLevel);
226318669f196ca922337da02af9d72773e76e70b45Brian Paul      if (texObj->Target == GL_TEXTURE_1D_ARRAY) {
227318669f196ca922337da02af9d72773e76e70b45Brian Paul         dstHeight = pt->array_size;
228318669f196ca922337da02af9d72773e76e70b45Brian Paul      }
229318669f196ca922337da02af9d72773e76e70b45Brian Paul      else {
230318669f196ca922337da02af9d72773e76e70b45Brian Paul         dstHeight = u_minify(pt->height0, dstLevel);
231318669f196ca922337da02af9d72773e76e70b45Brian Paul      }
232318669f196ca922337da02af9d72773e76e70b45Brian Paul      if (texObj->Target == GL_TEXTURE_2D_ARRAY) {
233318669f196ca922337da02af9d72773e76e70b45Brian Paul         dstDepth = pt->array_size;
234318669f196ca922337da02af9d72773e76e70b45Brian Paul      }
235318669f196ca922337da02af9d72773e76e70b45Brian Paul      else {
236318669f196ca922337da02af9d72773e76e70b45Brian Paul         dstDepth = u_minify(pt->depth0, dstLevel);
237318669f196ca922337da02af9d72773e76e70b45Brian Paul      }
23862abcb9aacc33218d0143a743c738435794b32a9Brian
23962abcb9aacc33218d0143a743c738435794b32a9Brian      dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel);
24062abcb9aacc33218d0143a743c738435794b32a9Brian      if (!dstImage) {
24162abcb9aacc33218d0143a743c738435794b32a9Brian         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
24262abcb9aacc33218d0143a743c738435794b32a9Brian         return;
24362abcb9aacc33218d0143a743c738435794b32a9Brian      }
24462abcb9aacc33218d0143a743c738435794b32a9Brian
24562abcb9aacc33218d0143a743c738435794b32a9Brian      /* Free old image data */
24668f8cf72638e974a5bf2ae3e88c2e3539d88e2b6Eric Anholt      ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
24762abcb9aacc33218d0143a743c738435794b32a9Brian
24862abcb9aacc33218d0143a743c738435794b32a9Brian      /* initialize new image */
249892a2542a3f0753a7064c710b96f077dd5490624Brian Paul      _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight,
25083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul                                 dstDepth, border, srcImage->InternalFormat,
25183e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul                                 srcImage->TexFormat);
25262abcb9aacc33218d0143a743c738435794b32a9Brian
25356f99ee640772f71c1eac0388ba2d70935010e3eBrian Paul      stImage = st_texture_image(dstImage);
25456f99ee640772f71c1eac0388ba2d70935010e3eBrian Paul
255287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&stImage->pt, pt);
25662abcb9aacc33218d0143a743c738435794b32a9Brian   }
25762abcb9aacc33218d0143a743c738435794b32a9Brian}
258