Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / dri / common / texmem.c
index acefce0f5971302e793e36881bc479e575fe751b..8eec07d5bcc611494f5e9be6dd46b95afa41d4b4 100644 (file)
@@ -28,7 +28,6 @@
  *    Kevin E. Martin <kem@users.sourceforge.net>
  *    Gareth Hughes <gareth@nvidia.com>
  */
-/* $XFree86:$ */
 
 /** \file texmem.c
  * Implements all of the device-independent texture memory management.
  * application.
  */
 
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/simple_list.h"
 #include "texmem.h"
-#include "simple_list.h"
-#include "imports.h"
-#include "macros.h"
-#include "texformat.h"
-
-#include <assert.h>
-
 
 
 static unsigned dummy_swap_counter;
@@ -94,7 +89,7 @@ driLog2( GLuint n )
  */
 
 GLboolean
-driIsTextureResident( GLcontext * ctx, 
+driIsTextureResident( struct gl_context * ctx, 
                      struct gl_texture_object * texObj )
 {
    driTextureObject * t;
@@ -410,11 +405,12 @@ static void driTexturesGone( driTexHeap * heap, int offset, int size,
         fprintf( stderr, "Couldn't alloc placeholder: heap %u sz %x ofs %x\n", heap->heapId,
                  (int)size, (int)offset );
         mmDumpMemInfo( heap->memory_heap );
+        FREE(t);
         return;
       }
       t->heap = heap;
       if (in_use) 
-        t->bound = 99;
+        t->reserved = 1; 
       insert_at_head( & heap->texture_objects, t );
    }
 }
@@ -572,7 +568,7 @@ driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps,
            /* The the LRU element.  If the texture is bound to one of
             * the texture units, then we cannot kick it out.
             */
-           if ( cursor->bound /* || cursor->reserved */ ) {
+           if ( cursor->bound || cursor->reserved ) {
               continue;
            }
 
@@ -945,7 +941,7 @@ get_max_size( unsigned nr_heaps,
     do { if ( max_sizes[v] != 0 ) { limits-> f = max_sizes[v]; } } while( 0 )
 
 #define SET_MAX_RECT(f,v) \
-    do { if ( max_sizes[v] != 0 ) { limits-> f = 1 << max_sizes[v]; } } while( 0 )
+    do { if ( max_sizes[v] != 0 ) { limits-> f = 1 << (max_sizes[v] - 1); } } while( 0 )
 
 
 /**
@@ -971,19 +967,22 @@ get_max_size( unsigned nr_heaps,
  *     For hardware that does not support mipmapping, this will be 1.
  * \param all_textures_one_heap True if the hardware requires that all
  *     textures be in a single texture heap for multitexturing.
+ * \param allow_larger_textures 0 conservative, 1 calculate limits
+ *     so at least one worst-case texture can fit, 2 just use hw limits.
  */
 
 void
 driCalculateMaxTextureLevels( driTexHeap * const * heaps,
                              unsigned nr_heaps,
                              struct gl_constants * limits,
-                             unsigned max_bytes_per_texel, 
+                             unsigned max_bytes_per_texel,
                              unsigned max_2D_size,
                              unsigned max_3D_size,
                              unsigned max_cube_size,
                              unsigned max_rect_size,
                              unsigned mipmaps_at_once,
-                             int all_textures_one_heap )
+                             int all_textures_one_heap,
+                             int allow_larger_textures )
 {
    struct maps_per_heap  max_textures[8];
    unsigned         i;
@@ -1000,8 +999,8 @@ driCalculateMaxTextureLevels( driTexHeap * const * heaps,
 
    mipmaps[0] = mipmaps_at_once;
    mipmaps[1] = mipmaps_at_once;
-   mipmaps[2] = 1;
-   mipmaps[3] = mipmaps_at_once;
+   mipmaps[2] = mipmaps_at_once;
+   mipmaps[3] = 1;
 
 
    /* Calculate the maximum number of texture levels in two passes.  The
@@ -1012,18 +1011,22 @@ driCalculateMaxTextureLevels( driTexHeap * const * heaps,
     */
 
    for ( i = 0 ; i < 4 ; i++ ) {
-      if ( max_sizes[ i ] != 0 ) {
-        fill_in_maximums( heaps, nr_heaps, max_bytes_per_texel, 
+      if ( (allow_larger_textures != 2) && (max_sizes[ i ] != 0) ) {
+        fill_in_maximums( heaps, nr_heaps, max_bytes_per_texel,
                           max_sizes[ i ], mipmaps[ i ],
                           dimensions[ i ], faces[ i ],
                           max_textures );
 
-        max_sizes[ i ] = get_max_size( nr_heaps, 
-                                       limits->MaxTextureUnits,
+        max_sizes[ i ] = get_max_size( nr_heaps,
+                                       allow_larger_textures == 1 ?
+                                       1 : limits->MaxTextureUnits,
                                        max_sizes[ i ],
                                        all_textures_one_heap,
                                        max_textures );
       }
+      else if (max_sizes[ i ] != 0) {
+        max_sizes[ i ] += 1;
+      }
    }
 
    SET_MAX( MaxTextureLevels,        0 );
@@ -1044,7 +1047,7 @@ driCalculateMaxTextureLevels( driTexHeap * const * heaps,
  * \param targets Bit-mask of value texture targets
  */
 
-void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped,
+void driInitTextureObjects( struct gl_context *ctx, driTextureObject * swapped,
                            GLuint targets )
 {
    struct gl_texture_object *texObj;
@@ -1056,31 +1059,31 @@ void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped,
       ctx->Texture.CurrentUnit = i;
 
       if ( (targets & DRI_TEXMGR_DO_TEXTURE_1D) != 0 ) {
-        texObj = ctx->Texture.Unit[i].Current1D;
+        texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_1D_INDEX];
         ctx->Driver.BindTexture( ctx, GL_TEXTURE_1D, texObj );
         move_to_tail( swapped, (driTextureObject *) texObj->DriverData );
       }
 
       if ( (targets & DRI_TEXMGR_DO_TEXTURE_2D) != 0 ) {
-        texObj = ctx->Texture.Unit[i].Current2D;
+        texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_2D_INDEX];
         ctx->Driver.BindTexture( ctx, GL_TEXTURE_2D, texObj );
         move_to_tail( swapped, (driTextureObject *) texObj->DriverData );
       }
 
       if ( (targets & DRI_TEXMGR_DO_TEXTURE_3D) != 0 ) {
-        texObj = ctx->Texture.Unit[i].Current3D;
+        texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_3D_INDEX];
         ctx->Driver.BindTexture( ctx, GL_TEXTURE_3D, texObj );
         move_to_tail( swapped, (driTextureObject *) texObj->DriverData );
       }
 
       if ( (targets & DRI_TEXMGR_DO_TEXTURE_CUBE) != 0 ) {
-        texObj = ctx->Texture.Unit[i].CurrentCubeMap;
+        texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_CUBE_INDEX];
         ctx->Driver.BindTexture( ctx, GL_TEXTURE_CUBE_MAP_ARB, texObj );
         move_to_tail( swapped, (driTextureObject *) texObj->DriverData );
       }
 
       if ( (targets & DRI_TEXMGR_DO_TEXTURE_RECT) != 0 ) {
-        texObj = ctx->Texture.Unit[i].CurrentRect;
+        texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_RECT_INDEX];
         ctx->Driver.BindTexture( ctx, GL_TEXTURE_RECTANGLE_NV, texObj );
         move_to_tail( swapped, (driTextureObject *) texObj->DriverData );
       }
@@ -1138,7 +1141,7 @@ driValidateTextureHeaps( driTexHeap * const * texture_heaps,
       unsigned textures_in_heap = 0;
       unsigned blocks_in_mempool = 0;
       const driTexHeap * heap = texture_heaps[i];
-      const memHeap_t * p = heap->memory_heap;
+      const struct mem_block *p = heap->memory_heap;
 
       /* Check each texture object has a MemBlock, and is linked into
        * the correct heap.  
@@ -1270,6 +1273,7 @@ driCalculateTextureFirstLastLevel( driTextureObject * t )
       else {
         firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
         firstLevel = MAX2(firstLevel, tObj->BaseLevel);
+        firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
         lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
         lastLevel = MAX2(lastLevel, t->tObj->BaseLevel);
         lastLevel = MIN2(lastLevel, t->tObj->BaseLevel + baseImage->MaxLog2);
@@ -1294,46 +1298,44 @@ driCalculateTextureFirstLastLevel( driTextureObject * t )
 
 
 /**
- * \name DRI texture formats.  Pointers initialized to either the big- or
- * little-endian Mesa formats.
+ * \name DRI texture formats.  These vars are initialized to either the
+ * big- or little-endian Mesa formats.
  */
 /*@{*/
-const struct gl_texture_format *_dri_texformat_rgba8888 = NULL;
-const struct gl_texture_format *_dri_texformat_argb8888 = NULL;
-const struct gl_texture_format *_dri_texformat_rgb565 = NULL;
-const struct gl_texture_format *_dri_texformat_argb4444 = NULL;
-const struct gl_texture_format *_dri_texformat_argb1555 = NULL;
-const struct gl_texture_format *_dri_texformat_al88 = NULL;
-const struct gl_texture_format *_dri_texformat_a8 = &_mesa_texformat_a8;
-const struct gl_texture_format *_dri_texformat_ci8 = &_mesa_texformat_ci8;
-const struct gl_texture_format *_dri_texformat_i8 = &_mesa_texformat_i8;
-const struct gl_texture_format *_dri_texformat_l8 = &_mesa_texformat_l8;
+gl_format _dri_texformat_rgba8888 = MESA_FORMAT_NONE;
+gl_format _dri_texformat_argb8888 = MESA_FORMAT_NONE;
+gl_format _dri_texformat_rgb565 = MESA_FORMAT_NONE;
+gl_format _dri_texformat_argb4444 = MESA_FORMAT_NONE;
+gl_format _dri_texformat_argb1555 = MESA_FORMAT_NONE;
+gl_format _dri_texformat_al88 = MESA_FORMAT_NONE;
+gl_format _dri_texformat_a8 = MESA_FORMAT_A8;
+gl_format _dri_texformat_ci8 = MESA_FORMAT_CI8;
+gl_format _dri_texformat_i8 = MESA_FORMAT_I8;
+gl_format _dri_texformat_l8 = MESA_FORMAT_L8;
 /*@}*/
 
 
 /**
- * Initialize little endian target, host byte order independent texture formats
+ * Initialize _dri_texformat_* vars according to whether we're on
+ * a big or little endian system.
  */
 void
 driInitTextureFormats(void)
 {
-   const GLuint ui = 1;
-   const GLubyte littleEndian = *((const GLubyte *) &ui);
-
-   if (littleEndian) {
-      _dri_texformat_rgba8888  = &_mesa_texformat_rgba8888;
-      _dri_texformat_argb8888  = &_mesa_texformat_argb8888;
-      _dri_texformat_rgb565    = &_mesa_texformat_rgb565;
-      _dri_texformat_argb4444  = &_mesa_texformat_argb4444;
-      _dri_texformat_argb1555  = &_mesa_texformat_argb1555;
-      _dri_texformat_al88      = &_mesa_texformat_al88;
+   if (_mesa_little_endian()) {
+      _dri_texformat_rgba8888  = MESA_FORMAT_RGBA8888;
+      _dri_texformat_argb8888  = MESA_FORMAT_ARGB8888;
+      _dri_texformat_rgb565    = MESA_FORMAT_RGB565;
+      _dri_texformat_argb4444  = MESA_FORMAT_ARGB4444;
+      _dri_texformat_argb1555  = MESA_FORMAT_ARGB1555;
+      _dri_texformat_al88      = MESA_FORMAT_AL88;
    }
    else {
-      _dri_texformat_rgba8888  = &_mesa_texformat_rgba8888_rev;
-      _dri_texformat_argb8888  = &_mesa_texformat_argb8888_rev;
-      _dri_texformat_rgb565    = &_mesa_texformat_rgb565_rev;
-      _dri_texformat_argb4444  = &_mesa_texformat_argb4444_rev;
-      _dri_texformat_argb1555  = &_mesa_texformat_argb1555_rev;
-      _dri_texformat_al88      = &_mesa_texformat_al88_rev;
+      _dri_texformat_rgba8888  = MESA_FORMAT_RGBA8888_REV;
+      _dri_texformat_argb8888  = MESA_FORMAT_ARGB8888_REV;
+      _dri_texformat_rgb565    = MESA_FORMAT_RGB565_REV;
+      _dri_texformat_argb4444  = MESA_FORMAT_ARGB4444_REV;
+      _dri_texformat_argb1555  = MESA_FORMAT_ARGB1555_REV;
+      _dri_texformat_al88      = MESA_FORMAT_AL88_REV;
    }
 }