intel_tex_validate.c revision 8df81bca1704aef2f5cdc4052ef313d8f84f5d06
1#include "main/mtypes.h"
2#include "main/macros.h"
3
4#include "intel_context.h"
5#include "intel_batchbuffer.h"
6#include "intel_mipmap_tree.h"
7#include "intel_tex.h"
8#include "intel_chipset.h"
9
10#define FILE_DEBUG_FLAG DEBUG_TEXTURE
11
12/**
13 * Compute which mipmap levels that really need to be sent to the hardware.
14 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
15 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
16 */
17static void
18intel_calculate_first_last_level(struct intel_context *intel,
19				 struct intel_texture_object *intelObj)
20{
21   struct gl_texture_object *tObj = &intelObj->base;
22   const struct gl_texture_image *const baseImage =
23      tObj->Image[0][tObj->BaseLevel];
24
25   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
26    * and having firstLevel and lastLevel as signed prevents the need for
27    * extra sign checks.
28    */
29   int firstLevel;
30   int lastLevel;
31
32   /* Yes, this looks overly complicated, but it's all needed.
33    */
34   switch (tObj->Target) {
35   case GL_TEXTURE_1D:
36   case GL_TEXTURE_2D:
37   case GL_TEXTURE_3D:
38   case GL_TEXTURE_CUBE_MAP:
39      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
40         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
41          */
42         firstLevel = lastLevel = tObj->BaseLevel;
43      }
44      else {
45	 if (intel->gen == 2) {
46	    firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
47	    firstLevel = MAX2(firstLevel, tObj->BaseLevel);
48	    firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
49	    lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
50	    lastLevel = MAX2(lastLevel, tObj->BaseLevel);
51	    lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
52	    lastLevel = MIN2(lastLevel, tObj->MaxLevel);
53	    lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
54	 } else {
55	    /* Min/max LOD are taken into account in sampler state.  We don't
56	     * want to re-layout textures just because clamping has been applied
57	     * since it means a bunch of blitting around and probably no memory
58	     * savings (since we have to keep the other levels around anyway).
59	     */
60	    firstLevel = tObj->BaseLevel;
61	    lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
62			     tObj->MaxLevel);
63	    /* need at least one level */
64	    lastLevel = MAX2(firstLevel, lastLevel);
65	 }
66      }
67      break;
68   case GL_TEXTURE_RECTANGLE_NV:
69   case GL_TEXTURE_4D_SGIS:
70      firstLevel = lastLevel = 0;
71      break;
72   default:
73      return;
74   }
75
76   /* save these values */
77   intelObj->firstLevel = firstLevel;
78   intelObj->lastLevel = lastLevel;
79}
80
81/**
82 * Copies the image's contents at its level into the object's miptree,
83 * and updates the image to point at the object's miptree.
84 */
85static void
86copy_image_data_to_tree(struct intel_context *intel,
87                        struct intel_texture_object *intelObj,
88                        struct intel_texture_image *intelImage)
89{
90   if (intelImage->mt) {
91      /* Copy potentially with the blitter:
92       */
93      intel_miptree_image_copy(intel,
94                               intelObj->mt,
95                               intelImage->face,
96                               intelImage->level, intelImage->mt);
97
98      intel_miptree_release(intel, &intelImage->mt);
99   }
100   else {
101      assert(intelImage->base.Data != NULL);
102
103      /* More straightforward upload.
104       */
105      intel_miptree_image_data(intel,
106                               intelObj->mt,
107                               intelImage->face,
108                               intelImage->level,
109                               intelImage->base.Data,
110                               intelImage->base.RowStride,
111                               intelImage->base.RowStride *
112                               intelImage->base.Height);
113      _mesa_align_free(intelImage->base.Data);
114      intelImage->base.Data = NULL;
115   }
116
117   intel_miptree_reference(&intelImage->mt, intelObj->mt);
118}
119
120
121/*
122 */
123GLuint
124intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
125{
126   struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
127   struct intel_texture_object *intelObj = intel_texture_object(tObj);
128   int comp_byte = 0;
129   int cpp;
130   GLuint face, i;
131   GLuint nr_faces = 0;
132   struct intel_texture_image *firstImage;
133
134   /* We know/require this is true by now:
135    */
136   assert(intelObj->base._Complete);
137
138   /* What levels must the tree include at a minimum?
139    */
140   intel_calculate_first_last_level(intel, intelObj);
141   firstImage = intel_texture_image(tObj->Image[0][intelObj->firstLevel]);
142
143   /* Fallback case:
144    */
145   if (firstImage->base.Border) {
146      if (intelObj->mt) {
147         intel_miptree_release(intel, &intelObj->mt);
148      }
149      return GL_FALSE;
150   }
151
152
153   /* If both firstImage and intelObj have a tree which can contain
154    * all active images, favour firstImage.  Note that because of the
155    * completeness requirement, we know that the image dimensions
156    * will match.
157    */
158   if (firstImage->mt &&
159       firstImage->mt != intelObj->mt &&
160       firstImage->mt->first_level <= intelObj->firstLevel &&
161       firstImage->mt->last_level >= intelObj->lastLevel) {
162
163      if (intelObj->mt)
164         intel_miptree_release(intel, &intelObj->mt);
165
166      intel_miptree_reference(&intelObj->mt, firstImage->mt);
167   }
168
169   if (_mesa_is_format_compressed(firstImage->base.TexFormat)) {
170      comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat);
171      cpp = comp_byte;
172   }
173   else
174      cpp = _mesa_get_format_bytes(firstImage->base.TexFormat);
175
176   /* Check tree can hold all active levels.  Check tree matches
177    * target, imageFormat, etc.
178    *
179    * XXX: For some layouts (eg i945?), the test might have to be
180    * first_level == firstLevel, as the tree isn't valid except at the
181    * original start level.  Hope to get around this by
182    * programming minLod, maxLod, baseLevel into the hardware and
183    * leaving the tree alone.
184    */
185   if (intelObj->mt &&
186       (intelObj->mt->target != intelObj->base.Target ||
187	intelObj->mt->internal_format != firstImage->base.InternalFormat ||
188	intelObj->mt->first_level != intelObj->firstLevel ||
189	intelObj->mt->last_level != intelObj->lastLevel ||
190	intelObj->mt->width0 != firstImage->base.Width ||
191	intelObj->mt->height0 != firstImage->base.Height ||
192	intelObj->mt->depth0 != firstImage->base.Depth ||
193	intelObj->mt->cpp != cpp ||
194	intelObj->mt->compressed != _mesa_is_format_compressed(firstImage->base.TexFormat))) {
195      intel_miptree_release(intel, &intelObj->mt);
196   }
197
198
199   /* May need to create a new tree:
200    */
201   if (!intelObj->mt) {
202      intelObj->mt = intel_miptree_create(intel,
203                                          intelObj->base.Target,
204                                          firstImage->base._BaseFormat,
205                                          firstImage->base.InternalFormat,
206                                          intelObj->firstLevel,
207                                          intelObj->lastLevel,
208                                          firstImage->base.Width,
209                                          firstImage->base.Height,
210                                          firstImage->base.Depth,
211                                          cpp,
212                                          comp_byte,
213					  GL_TRUE);
214   }
215
216   /* Pull in any images not in the object's tree:
217    */
218   nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
219   for (face = 0; face < nr_faces; face++) {
220      for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) {
221         struct intel_texture_image *intelImage =
222            intel_texture_image(intelObj->base.Image[face][i]);
223
224         /* Need to import images in main memory or held in other trees.
225          */
226         if (intelObj->mt != intelImage->mt) {
227            copy_image_data_to_tree(intel, intelObj, intelImage);
228         }
229      }
230   }
231
232   return GL_TRUE;
233}
234
235void
236intel_tex_map_level_images(struct intel_context *intel,
237			   struct intel_texture_object *intelObj,
238			   int level)
239{
240   GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
241   GLuint face;
242
243   for (face = 0; face < nr_faces; face++) {
244      struct intel_texture_image *intelImage =
245	 intel_texture_image(intelObj->base.Image[face][level]);
246
247      if (intelImage && intelImage->mt) {
248	 intelImage->base.Data =
249	    intel_miptree_image_map(intel,
250				    intelImage->mt,
251				    intelImage->face,
252				    intelImage->level,
253				    &intelImage->base.RowStride,
254				    intelImage->base.ImageOffsets);
255	 /* convert stride to texels, not bytes */
256	 intelImage->base.RowStride /= intelImage->mt->cpp;
257	 /* intelImage->base.ImageStride /= intelImage->mt->cpp; */
258      }
259   }
260}
261
262void
263intel_tex_unmap_level_images(struct intel_context *intel,
264			     struct intel_texture_object *intelObj,
265			     int level)
266{
267   GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
268   GLuint face;
269
270   for (face = 0; face < nr_faces; face++) {
271      struct intel_texture_image *intelImage =
272	 intel_texture_image(intelObj->base.Image[face][level]);
273
274      if (intelImage && intelImage->mt) {
275	 intel_miptree_image_unmap(intel, intelImage->mt);
276	 intelImage->base.Data = NULL;
277      }
278   }
279}
280
281void
282intel_tex_map_images(struct intel_context *intel,
283                     struct intel_texture_object *intelObj)
284{
285   int i;
286
287   DBG("%s\n", __FUNCTION__);
288
289   for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++)
290      intel_tex_map_level_images(intel, intelObj, i);
291}
292
293void
294intel_tex_unmap_images(struct intel_context *intel,
295                       struct intel_texture_object *intelObj)
296{
297   int i;
298
299   for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++)
300      intel_tex_unmap_level_images(intel, intelObj, i);
301}
302