~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/intel_tex_validate.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
 
4
 * All Rights Reserved.
 
5
 * 
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * copy of this software and associated documentation files (the
 
8
 * "Software"), to deal in the Software without restriction, including
 
9
 * without limitation the rights to use, copy, modify, merge, publish,
 
10
 * distribute, sub license, and/or sell copies of the Software, and to
 
11
 * permit persons to whom the Software is furnished to do so, subject to
 
12
 * the following conditions:
 
13
 * 
 
14
 * The above copyright notice and this permission notice (including the
 
15
 * next paragraph) shall be included in all copies or substantial portions
 
16
 * of the Software.
 
17
 * 
 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 
21
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 * 
 
26
 **************************************************************************/
 
27
 
 
28
#include "mtypes.h"
 
29
#include "macros.h"
 
30
 
 
31
#include "intel_context.h"
 
32
#include "intel_mipmap_tree.h"
 
33
#include "intel_tex.h"
 
34
#include "bufmgr.h"
 
35
 
 
36
/**
 
37
 * Compute which mipmap levels that really need to be sent to the hardware.
 
38
 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
 
39
 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
 
40
 */
 
41
static void intel_calculate_first_last_level( struct intel_texture_object *intelObj )
 
42
{
 
43
   struct gl_texture_object *tObj = &intelObj->base;
 
44
   const struct gl_texture_image * const baseImage =
 
45
       tObj->Image[0][tObj->BaseLevel];
 
46
 
 
47
   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
 
48
    * and having firstLevel and lastLevel as signed prevents the need for
 
49
    * extra sign checks.
 
50
    */
 
51
   int   firstLevel;
 
52
   int   lastLevel;
 
53
 
 
54
   /* Yes, this looks overly complicated, but it's all needed.
 
55
    */
 
56
   switch (tObj->Target) {
 
57
   case GL_TEXTURE_1D:
 
58
   case GL_TEXTURE_2D:
 
59
   case GL_TEXTURE_3D:
 
60
   case GL_TEXTURE_CUBE_MAP:
 
61
      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
 
62
         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
 
63
          */
 
64
         firstLevel = lastLevel = tObj->BaseLevel;
 
65
      }
 
66
      else {
 
67
         /* Currently not taking min/max lod into account here, those
 
68
          * values are programmed as sampler state elsewhere and we
 
69
          * upload the same mipmap levels regardless.  Not sure if
 
70
          * this makes sense as it means it isn't possible for the app
 
71
          * to use min/max lod to reduce texture memory pressure:
 
72
          */
 
73
         firstLevel = tObj->BaseLevel;
 
74
         lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2, 
 
75
                          tObj->MaxLevel);
 
76
         lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
 
77
      }
 
78
      break;
 
79
   case GL_TEXTURE_RECTANGLE_NV:
 
80
   case GL_TEXTURE_4D_SGIS:
 
81
      firstLevel = lastLevel = 0;
 
82
      break;
 
83
   default:
 
84
      return;
 
85
   }
 
86
 
 
87
   /* save these values */
 
88
   intelObj->firstLevel = firstLevel;
 
89
   intelObj->lastLevel = lastLevel;
 
90
}
 
91
 
 
92
static GLboolean copy_image_data_to_tree( struct intel_context *intel,
 
93
                                          struct intel_texture_object *intelObj,
 
94
                                          struct gl_texture_image *texImage,
 
95
                                          GLuint face,
 
96
                                          GLuint level)
 
97
{
 
98
   return intel_miptree_image_data(intel,
 
99
                                   intelObj->mt,
 
100
                                   face,
 
101
                                   level,
 
102
                                   texImage->Data,
 
103
                                   texImage->RowStride,
 
104
                                   (texImage->RowStride * 
 
105
                                    texImage->Height * 
 
106
                                    texImage->TexFormat->TexelBytes));
 
107
}
 
108
 
 
109
static void intel_texture_invalidate( struct intel_texture_object *intelObj )
 
110
{
 
111
   GLint nr_faces, face;
 
112
   intelObj->dirty = ~0;
 
113
 
 
114
   nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
 
115
   for (face = 0; face < nr_faces; face++) 
 
116
      intelObj->dirty_images[face] = ~0;
 
117
}
 
118
 
 
119
static void intel_texture_invalidate_cb( struct intel_context *intel,
 
120
                                         void *ptr )
 
121
{
 
122
   intel_texture_invalidate( (struct intel_texture_object *) ptr );
 
123
}
 
124
 
 
125
 
 
126
/*  
 
127
 */
 
128
GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
 
129
                                   struct gl_texture_object *tObj )
 
130
{
 
131
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
 
132
   GLuint face, i;
 
133
   GLuint nr_faces = 0;
 
134
   struct gl_texture_image *firstImage;
 
135
 
 
136
   if( tObj == intel->frame_buffer_texobj )
 
137
      return GL_FALSE;
 
138
   
 
139
   /* We know/require this is true by now: 
 
140
    */
 
141
   assert(intelObj->base.Complete);
 
142
 
 
143
   /* What levels must the tree include at a minimum?
 
144
    */
 
145
   if (intelObj->dirty) {
 
146
      intel_calculate_first_last_level( intelObj );
 
147
/*       intel_miptree_destroy(intel, intelObj->mt); */
 
148
/*       intelObj->mt = NULL; */
 
149
   }
 
150
 
 
151
   firstImage = intelObj->base.Image[0][intelObj->firstLevel];
 
152
 
 
153
   /* Fallback case:
 
154
    */
 
155
   if (firstImage->Border) {
 
156
      if (intelObj->mt) {
 
157
         intel_miptree_destroy(intel, intelObj->mt);
 
158
         intelObj->mt = NULL;
 
159
         /* Set all images dirty:
 
160
          */
 
161
         intel_texture_invalidate(intelObj);
 
162
      }
 
163
      return GL_FALSE;
 
164
   }
 
165
 
 
166
 
 
167
 
 
168
   /* Check tree can hold all active levels.  Check tree matches
 
169
    * target, imageFormat, etc.
 
170
    */
 
171
   if (intelObj->mt &&
 
172
       (intelObj->mt->target != intelObj->base.Target ||
 
173
        intelObj->mt->internal_format != firstImage->InternalFormat ||
 
174
        intelObj->mt->first_level != intelObj->firstLevel ||
 
175
        intelObj->mt->last_level != intelObj->lastLevel ||
 
176
        intelObj->mt->width0 != firstImage->Width ||
 
177
        intelObj->mt->height0 != firstImage->Height ||
 
178
        intelObj->mt->depth0 != firstImage->Depth ||
 
179
        intelObj->mt->cpp != firstImage->TexFormat->TexelBytes ||
 
180
        intelObj->mt->compressed != firstImage->IsCompressed)) 
 
181
   {
 
182
      intel_miptree_destroy(intel, intelObj->mt);
 
183
      intelObj->mt = NULL;
 
184
      
 
185
      /* Set all images dirty:
 
186
       */
 
187
      intel_texture_invalidate(intelObj);
 
188
   }
 
189
      
 
190
 
 
191
   /* May need to create a new tree:
 
192
    */
 
193
   if (!intelObj->mt) {
 
194
      intelObj->mt = intel_miptree_create(intel,
 
195
                                          intelObj->base.Target,
 
196
                                          firstImage->InternalFormat,
 
197
                                          intelObj->firstLevel,
 
198
                                          intelObj->lastLevel,
 
199
                                          firstImage->Width,
 
200
                                          firstImage->Height,
 
201
                                          firstImage->Depth,
 
202
                                          firstImage->TexFormat->TexelBytes,
 
203
                                          firstImage->IsCompressed);
 
204
 
 
205
      /* Tell the buffer manager that we will manage the backing
 
206
       * store, but we still want it to do fencing for us.
 
207
       */
 
208
      bmBufferSetInvalidateCB(intel, 
 
209
                              intelObj->mt->region->buffer,
 
210
                              intel_texture_invalidate_cb,
 
211
                              intelObj,
 
212
                              GL_FALSE);
 
213
   }
 
214
 
 
215
   /* Pull in any images not in the object's tree:
 
216
    */
 
217
   if (intelObj->dirty) {
 
218
      nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
 
219
      for (face = 0; face < nr_faces; face++) {
 
220
         if (intelObj->dirty_images[face]) {
 
221
            for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) {
 
222
               struct gl_texture_image *texImage = intelObj->base.Image[face][i];
 
223
 
 
224
               /* Need to import images in main memory or held in other trees.
 
225
                */
 
226
               if (intelObj->dirty_images[face] & (1<<i) &&
 
227
                   texImage) {
 
228
 
 
229
                  if (INTEL_DEBUG & DEBUG_TEXTURE)
 
230
                     _mesa_printf("copy data from image %d (%p) into object miptree\n",
 
231
                                  i,
 
232
                                  texImage->Data);
 
233
 
 
234
                  if (!copy_image_data_to_tree(intel,
 
235
                                               intelObj,
 
236
                                               texImage,
 
237
                                               face,
 
238
                                               i))
 
239
                     return GL_FALSE;
 
240
 
 
241
               }
 
242
            }
 
243
         }
 
244
      }
 
245
 
 
246
      /* Only clear the dirty flags if everything went ok:
 
247
       */
 
248
      for (face = 0; face < nr_faces; face++) {
 
249
         intelObj->dirty_images[face] = 0;
 
250
      }
 
251
 
 
252
      intelObj->dirty = 0;
 
253
   }
 
254
 
 
255
   return GL_TRUE;
 
256
}