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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/mga/mgatexmem.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
 * Copyright 2000-2001 VA Linux Systems, Inc.
 
3
 * All Rights Reserved.
 
4
 *
 
5
 * Permission is hereby granted, free of charge, to any person obtaining a
 
6
 * copy of this software and associated documentation files (the "Software"),
 
7
 * to deal in the Software without restriction, including without limitation
 
8
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 
9
 * license, and/or sell copies of the Software, and to permit persons to whom
 
10
 * the Software is furnished to do so, subject to the following conditions:
 
11
 *
 
12
 * The above copyright notice and this permission notice (including the next
 
13
 * paragraph) shall be included in all copies or substantial portions of the
 
14
 * Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
 
19
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
22
 * OTHER DEALINGS IN THE SOFTWARE.
 
23
 *
 
24
 * Authors:
 
25
 *    Keith Whitwell <keith@tungstengraphics.com>
 
26
 */
 
27
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.7 2002/10/30 12:51:36 alanh Exp $ */
 
28
 
 
29
#include "glheader.h"
 
30
 
 
31
#include "mm.h"
 
32
#include "mgacontext.h"
 
33
#include "mgatex.h"
 
34
#include "mgaregs.h"
 
35
#include "mgaioctl.h"
 
36
#include "mga_xmesa.h"
 
37
 
 
38
#include "imports.h"
 
39
#include "simple_list.h"
 
40
 
 
41
/**
 
42
 * Destroy any device-dependent state associated with the texture.  This may
 
43
 * include NULLing out hardware state that points to the texture.
 
44
 */
 
45
void
 
46
mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t )
 
47
{
 
48
    unsigned   i;
 
49
 
 
50
 
 
51
    /* See if it was the driver's current object.
 
52
     */
 
53
 
 
54
    if ( mmesa != NULL )
 
55
    { 
 
56
        if ( t->age > mmesa->dirtyAge )
 
57
            mmesa->dirtyAge = t->age;
 
58
 
 
59
        for ( i = 0 ; i < mmesa->glCtx->Const.MaxTextureUnits ; i++ )
 
60
        {
 
61
            if ( t == mmesa->CurrentTexObj[ i ] ) {
 
62
                mmesa->CurrentTexObj[ i ] = NULL;
 
63
            }
 
64
        }
 
65
    }
 
66
}
 
67
 
 
68
 
 
69
/**
 
70
 * Upload a texture image from system memory to either on-card or AGP
 
71
 * memory.  Uploads to on-card memory are performed using an ILOAD operation.
 
72
 * This is used for both initial loading of the entire image, and texSubImage
 
73
 * updates.
 
74
 *
 
75
 * Performed with the hardware lock held.
 
76
 * 
 
77
 * Even though this function is named "upload subimage," the entire image
 
78
 * is uploaded.
 
79
 * 
 
80
 * \param mmesa  Driver context.
 
81
 * \param t      Texture to be uploaded.
 
82
 * \param hwlevel  Mipmap level of the texture to be uploaded.
 
83
 * 
 
84
 * \bug As mentioned above, this fuction actually copies the entier mipmap
 
85
 *      level.  There should be a version of this function that performs
 
86
 *      sub-rectangle uploads.  This will perform quite a bit better if only
 
87
 *      a small portion of a larger texture has been updated.  Care would
 
88
 *      need to be take with such an implementation once glCopyTexImage has
 
89
 *      been hardware accelerated.
 
90
 */
 
91
static void mgaUploadSubImage( mgaContextPtr mmesa,
 
92
                               mgaTextureObjectPtr t, GLint hwlevel )
 
93
{
 
94
   struct gl_texture_image * texImage;
 
95
   unsigned     offset;
 
96
   unsigned     texelBytes;
 
97
   unsigned     length;
 
98
   const int level = hwlevel + t->base.firstLevel;
 
99
 
 
100
 
 
101
   if ( (hwlevel < 0) 
 
102
        || (hwlevel >= (MGA_IS_G200(mmesa) 
 
103
                      ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS)) ) {
 
104
      fprintf( stderr, "[%s:%d] level = %d\n", __FILE__, __LINE__, level );
 
105
      return;
 
106
   }
 
107
 
 
108
   texImage = t->base.tObj->Image[0][level];
 
109
   if ( texImage == NULL ) {
 
110
      fprintf( stderr, "[%s:%d] Image[%d] = NULL\n", __FILE__, __LINE__,
 
111
               level );
 
112
      return;
 
113
   }
 
114
 
 
115
 
 
116
   if (texImage->Data == NULL) {
 
117
      fprintf(stderr, "null texture image data tObj %p level %d\n",
 
118
              (void *) t->base.tObj, level);
 
119
      return;
 
120
   }
 
121
 
 
122
 
 
123
   /* find the proper destination offset for this level */
 
124
   if ( MGA_IS_G200(mmesa) ) {
 
125
      offset = (t->base.memBlock->ofs + t->offsets[hwlevel]);
 
126
   }
 
127
   else {
 
128
      unsigned  i;
 
129
 
 
130
      offset = t->base.memBlock->ofs;
 
131
      for ( i = 0 ; i < hwlevel ; i++ ) {
 
132
         offset += (t->offsets[1] >> (i * 2));
 
133
      }
 
134
   }
 
135
 
 
136
 
 
137
   /* Copy the texture from system memory to a memory space that can be
 
138
    * directly used by the hardware for texturing.
 
139
    */
 
140
 
 
141
   texelBytes = texImage->TexFormat->TexelBytes;
 
142
   length = texImage->Width * texImage->Height * texelBytes;
 
143
   if ( t->base.heap->heapId == MGA_CARD_HEAP ) {
 
144
      unsigned  tex_offset = 0;
 
145
      unsigned  to_copy;
 
146
 
 
147
 
 
148
      /* We may not be able to upload the entire texture in one batch due to
 
149
       * register limits or dma buffer limits.  Split the copy up into maximum
 
150
       * sized chunks.
 
151
       */
 
152
 
 
153
      offset += mmesa->mgaScreen->textureOffset[ t->base.heap->heapId ];
 
154
      while ( length != 0 ) {
 
155
         mgaGetILoadBufferLocked( mmesa );
 
156
 
 
157
         /* The kernel ILOAD ioctl requires that the lenght be an even multiple
 
158
          * of MGA_ILOAD_ALIGN.
 
159
          */
 
160
         length = ((length) + MGA_ILOAD_MASK) & ~MGA_ILOAD_MASK;
 
161
 
 
162
         to_copy = MIN2( length, MGA_BUFFER_SIZE );
 
163
         (void) memcpy( mmesa->iload_buffer->address,
 
164
                        (GLubyte *) texImage->Data + tex_offset, to_copy );
 
165
 
 
166
         if ( MGA_DEBUG & DEBUG_VERBOSE_TEXTURE )
 
167
             fprintf(stderr, "[%s:%d] address/size = 0x%08lx/%d\n",
 
168
                     __FILE__, __LINE__,
 
169
                     (long) (offset + tex_offset),
 
170
                     to_copy );
 
171
 
 
172
         mgaFireILoadLocked( mmesa, offset + tex_offset, to_copy );
 
173
         tex_offset += to_copy;
 
174
         length -= to_copy;
 
175
      }
 
176
   } else {
 
177
      /* FIXME: the sync for direct copy reduces speed.. */
 
178
      /* This works, is slower for uploads to card space and needs
 
179
       * additional synchronization with the dma stream.
 
180
       */
 
181
       
 
182
      UPDATE_LOCK(mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT);
 
183
 
 
184
      memcpy( mmesa->mgaScreen->texVirtual[t->base.heap->heapId] + offset,
 
185
              texImage->Data, length );
 
186
 
 
187
      if ( MGA_DEBUG & DEBUG_VERBOSE_TEXTURE )
 
188
         fprintf(stderr, "[%s:%d] address/size = 0x%08lx/%d\n",
 
189
                 __FILE__, __LINE__,
 
190
                 (long) (mmesa->mgaScreen->texVirtual[t->base.heap->heapId] 
 
191
                         + offset),
 
192
                 length);
 
193
   }
 
194
}
 
195
 
 
196
 
 
197
/**
 
198
 * Upload the texture images associated with texture \a t.  This might
 
199
 * require the allocation of texture memory.
 
200
 * 
 
201
 * \param mmesa Context pointer
 
202
 * \param t Texture to be uploaded
 
203
 */
 
204
 
 
205
int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
 
206
{
 
207
   int i;
 
208
   int ofs;
 
209
 
 
210
 
 
211
   if ( (t == NULL) || (t->base.totalSize == 0) )
 
212
      return 0;
 
213
 
 
214
   LOCK_HARDWARE( mmesa );
 
215
 
 
216
   if (t->base.memBlock == NULL ) {
 
217
      int heap;
 
218
 
 
219
      heap = driAllocateTexture( mmesa->texture_heaps, mmesa->nr_heaps,
 
220
                                 (driTextureObject *) t );
 
221
      if ( heap == -1 ) {
 
222
         UNLOCK_HARDWARE( mmesa );
 
223
         return -1;
 
224
      }
 
225
 
 
226
      ofs = mmesa->mgaScreen->textureOffset[ heap ]
 
227
           + t->base.memBlock->ofs;
 
228
 
 
229
      if ( MGA_IS_G200(mmesa) ) {
 
230
         t->setup.texorg  = ofs;
 
231
         t->setup.texorg1 = ofs + t->offsets[1];
 
232
         t->setup.texorg2 = ofs + t->offsets[2];
 
233
         t->setup.texorg3 = ofs + t->offsets[3];
 
234
         t->setup.texorg4 = ofs + t->offsets[4];
 
235
      }
 
236
      else {
 
237
         t->setup.texorg  = ofs | TO_texorgoffsetsel;
 
238
         t->setup.texorg1 = t->offsets[1];
 
239
         t->setup.texorg2 = 0;
 
240
         t->setup.texorg3 = 0;
 
241
         t->setup.texorg4 = 0;
 
242
      }
 
243
 
 
244
      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 
245
   }
 
246
 
 
247
   /* Let the world know we've used this memory recently.
 
248
    */
 
249
   driUpdateTextureLRU( (driTextureObject *) t );
 
250
 
 
251
   if (MGA_DEBUG&DEBUG_VERBOSE_TEXTURE)
 
252
      fprintf(stderr, "[%s:%d] dispatch age: %d age freed memory: %d\n",
 
253
              __FILE__, __LINE__,
 
254
              GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge);
 
255
 
 
256
   if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa))
 
257
      mgaWaitAgeLocked( mmesa, mmesa->dirtyAge );
 
258
 
 
259
   if (t->base.dirty_images[0]) {
 
260
      const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
 
261
 
 
262
      if (MGA_DEBUG&DEBUG_VERBOSE_TEXTURE)
 
263
         fprintf(stderr, "[%s:%d] dirty_images[0] = 0x%04x\n",
 
264
                 __FILE__, __LINE__, t->base.dirty_images[0] );
 
265
 
 
266
      for (i = 0 ; i < numLevels ; i++) {
 
267
         if ( (t->base.dirty_images[0] & (1U << i)) != 0 ) {
 
268
            mgaUploadSubImage( mmesa, t, i );
 
269
         }
 
270
      }
 
271
      t->base.dirty_images[0] = 0;
 
272
   }
 
273
 
 
274
 
 
275
   UNLOCK_HARDWARE( mmesa );
 
276
 
 
277
   return 0;
 
278
}