Merge commit 'origin/master' into gallium-map-range
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_context.c
index c6a9af9a6282a36fa2e1e808f946bc58e82b34d1..ea81a3250b785a68ef183146686da5d569a71202 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.9 2003/09/24 02:43:12 dawes Exp $ */
 /**************************************************************************
 
 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
@@ -35,18 +34,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "api_arrayelt.h"
-#include "context.h"
-#include "simple_list.h"
-#include "imports.h"
-#include "matrix.h"
-#include "extensions.h"
-#include "framebuffer.h"
+#include "main/glheader.h"
+#include "main/api_arrayelt.h"
+#include "main/context.h"
+#include "main/simple_list.h"
+#include "main/imports.h"
+#include "main/matrix.h"
+#include "main/extensions.h"
+#include "main/framebuffer.h"
+#include "main/state.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
@@ -60,16 +60,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_tex.h"
 #include "radeon_swtcl.h"
 #include "radeon_tcl.h"
-#include "radeon_vtxfmt.h"
 #include "radeon_maos.h"
 
-#define need_GL_ARB_multisample
-#define need_GL_ARB_texture_compression
 #define need_GL_EXT_blend_minmax
+#define need_GL_EXT_fog_coord
 #define need_GL_EXT_secondary_color
 #include "extension_helper.h"
 
-#define DRIVER_DATE    "20050831"
+#define DRIVER_DATE    "20061018"
 
 #include "vblank.h"
 #include "utils.h"
@@ -79,20 +77,6 @@ int RADEON_DEBUG = (0);
 #endif
 
 
-/* Return the width and height of the given buffer.
- */
-static void radeonGetBufferSize( GLframebuffer *buffer,
-                                GLuint *width, GLuint *height )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
-   LOCK_HARDWARE( rmesa );
-   *width  = rmesa->dri.drawable->w;
-   *height = rmesa->dri.drawable->h;
-   UNLOCK_HARDWARE( rmesa );
-}
-
 /* Return various strings for glGetString().
  */
 static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
@@ -100,7 +84,7 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
    radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
    static char buffer[128];
    unsigned   offset;
-   GLuint agp_mode = rmesa->radeonScreen->IsPCI ? 0 :
+   GLuint agp_mode = (rmesa->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
       rmesa->radeonScreen->AGPMode;
 
    switch ( name ) {
@@ -127,10 +111,8 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
  */
 const struct dri_extension card_extensions[] =
 {
-    { "GL_ARB_multisample",                GL_ARB_multisample_functions },
     { "GL_ARB_multitexture",               NULL },
     { "GL_ARB_texture_border_clamp",       NULL },
-    { "GL_ARB_texture_compression",        GL_ARB_texture_compression_functions },
     { "GL_ARB_texture_env_add",            NULL },
     { "GL_ARB_texture_env_combine",        NULL },
     { "GL_ARB_texture_env_crossbar",       NULL },
@@ -138,6 +120,7 @@ const struct dri_extension card_extensions[] =
     { "GL_ARB_texture_mirrored_repeat",    NULL },
     { "GL_EXT_blend_logic_op",             NULL },
     { "GL_EXT_blend_subtract",             GL_EXT_blend_minmax_functions },
+    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
     { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
     { "GL_EXT_stencil_wrap",               NULL },
     { "GL_EXT_texture_edge_clamp",         NULL },
@@ -154,7 +137,6 @@ const struct dri_extension card_extensions[] =
     { NULL,                                NULL }
 };
 
-extern const struct tnl_pipeline_stage _radeon_texrect_stage;
 extern const struct tnl_pipeline_stage _radeon_render_stage;
 extern const struct tnl_pipeline_stage _radeon_tcl_stage;
 
@@ -173,10 +155,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = {
    &_tnl_texgen_stage,
    &_tnl_texture_transform_stage,
 
-   /* Scale texture rectangle to 0..1.
-    */
-   &_radeon_texrect_stage,
-
    &_radeon_render_stage,
    &_tnl_render_stage,         /* FALLBACK:  */
    NULL,
@@ -188,8 +166,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = {
  */
 static void radeonInitDriverFuncs( struct dd_function_table *functions )
 {
-    functions->GetBufferSize   = radeonGetBufferSize;
-    functions->ResizeBuffers   = _mesa_resize_framebuffer;
     functions->GetString       = radeonGetString;
 }
 
@@ -237,6 +213,9 @@ radeonCreateContext( const __GLcontextModes *glVisual,
    if ( !rmesa )
       return GL_FALSE;
 
+   /* init exp fog table data */
+   radeonInitStaticFogData();
+   
    /* Parse configuration files.
     * Do this here so that initialMaxAnisotropy is set before we create
     * the default textures.
@@ -247,14 +226,14 @@ radeonCreateContext( const __GLcontextModes *glVisual,
                                                  "def_max_anisotropy");
 
    if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
-      if ( sPriv->drmMinor < 13 )
+      if ( sPriv->drm_version.minor < 13 )
         fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
-                         "disabling.\n",sPriv->drmMinor );
+                         "disabling.\n", sPriv->drm_version.minor );
       else
         rmesa->using_hyperz = GL_TRUE;
    }
 
-   if ( sPriv->drmMinor >= 15 )
+   if ( sPriv->drm_version.minor >= 15 )
       rmesa->texmicrotile = GL_TRUE;
 
    /* Init default driver functions then plug in our Radeon-specific functions
@@ -280,11 +259,12 @@ radeonCreateContext( const __GLcontextModes *glVisual,
    /* Init radeon context data */
    rmesa->dri.context = driContextPriv;
    rmesa->dri.screen = sPriv;
-   rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
+   rmesa->dri.drawable = NULL;
+   rmesa->dri.readable = NULL;
    rmesa->dri.hwContext = driContextPriv->hHWContext;
    rmesa->dri.hwLock = &sPriv->pSAREA->lock;
    rmesa->dri.fd = sPriv->fd;
-   rmesa->dri.drmMinor = sPriv->drmMinor;
+   rmesa->dri.drmMinor = sPriv->drm_version.minor;
 
    rmesa->radeonScreen = screen;
    rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
@@ -321,32 +301,31 @@ radeonCreateContext( const __GLcontextModes *glVisual,
    rmesa->hw.all_dirty = GL_TRUE;
 
    /* Set the maximum texture size small enough that we can guarentee that
-    * all texture units can bind a maximal texture and have them both in
-    * texturable memory at once.
+    * all texture units can bind a maximal texture and have all of them in
+    * texturable memory at once. Depending on the allow_large_textures driconf
+    * setting allow larger textures.
     */
 
    ctx = rmesa->glCtx;
-   ctx->Const.MaxTextureUnits = 2;
-   ctx->Const.MaxTextureImageUnits = 2;
-   ctx->Const.MaxTextureCoordUnits = 2;
+   ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache,
+                                                "texture_units");
+   ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+   ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
+
+   i = driQueryOptioni( &rmesa->optionCache, "allow_large_textures");
 
    driCalculateMaxTextureLevels( rmesa->texture_heaps,
                                 rmesa->nr_heaps,
                                 & ctx->Const,
                                 4,
                                 11, /* max 2D texture size is 2048x2048 */
-                                0,  /* 3D textures unsupported. */
-                                0,  /* cube textures unsupported. */
+                                8,  /* 256^3 */
+                                9,  /* \todo: max cube texture size seems to be 512x512(x6) */
                                 11, /* max rect texture size is 2048x2048. */
                                 12,
-                                GL_FALSE );
+                                GL_FALSE,
+                                i );
 
-   /* adjust max texture size a bit. Hack, but I really want to use larger textures
-      which will work just fine in 99.999999% of all cases, especially with texture compression... */
-   if (driQueryOptionb( &rmesa->optionCache, "texture_level_hack" ))
-   {
-     if (ctx->Const.MaxTextureLevels < 12) ctx->Const.MaxTextureLevels += 1;
-   }
 
    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
 
@@ -374,10 +353,12 @@ radeonCreateContext( const __GLcontextModes *glVisual,
 
    rmesa->boxes = 0;
 
+   ctx->Const.MaxDrawBuffers = 1;
+
    /* Initialize the software rasterizer and helper modules.
     */
    _swrast_CreateContext( ctx );
-   _ac_CreateContext( ctx );
+   _vbo_CreateContext( ctx );
    _tnl_CreateContext( ctx );
    _swsetup_CreateContext( ctx );
    _ae_create_context( ctx );
@@ -386,13 +367,10 @@ radeonCreateContext( const __GLcontextModes *glVisual,
     */
    _tnl_destroy_pipeline( ctx );
    _tnl_install_pipeline( ctx, radeon_pipeline );
-   ctx->Driver.FlushVertices = radeonFlushVertices;
 
    /* Try and keep materials and vertices separate:
     */
-   _tnl_isolate_materials( ctx, GL_TRUE );
-
-/*     _mesa_allow_light_in_model( ctx, GL_FALSE ); */
+/*    _tnl_isolate_materials( ctx, GL_TRUE ); */
 
    /* Configure swrast and T&L to match hardware characteristics:
     */
@@ -402,14 +380,16 @@ radeonCreateContext( const __GLcontextModes *glVisual,
    _tnl_allow_vertex_fog( ctx, GL_TRUE );
 
 
-   _math_matrix_ctr( &rmesa->TexGenMatrix[0] );
-   _math_matrix_ctr( &rmesa->TexGenMatrix[1] );
-   _math_matrix_ctr( &rmesa->tmpmat );
-   _math_matrix_set_identity( &rmesa->TexGenMatrix[0] );
-   _math_matrix_set_identity( &rmesa->TexGenMatrix[1] );
-   _math_matrix_set_identity( &rmesa->tmpmat );
+   for ( i = 0 ; i < RADEON_MAX_TEXTURE_UNITS ; i++ ) {
+      _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
+      _math_matrix_ctr( &rmesa->tmpmat[i] );
+      _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
+      _math_matrix_set_identity( &rmesa->tmpmat[i] );
+   }
 
    driInitExtensions( ctx, card_extensions, GL_TRUE );
+   if (rmesa->radeonScreen->drmSupportsCubeMapsR100)
+      _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
    if (rmesa->glCtx->Mesa_DXTn) {
       _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
       _mesa_enable_extension( ctx, "GL_S3_s3tc" );
@@ -439,10 +419,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
 
    rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
 
-   rmesa->vblank_flags = (rmesa->radeonScreen->irq != 0)
-       ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
-   (*dri_interface->getUST)( & rmesa->swap_ust );
+   (*sPriv->systemTime->getUST)( & rmesa->swap_ust );
 
 
 #if DO_DEBUG
@@ -455,19 +432,16 @@ radeonCreateContext( const __GLcontextModes *glVisual,
       fprintf(stderr, "disabling 3D acceleration\n");
       FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
    } else if (tcl_mode == DRI_CONF_TCL_SW ||
-             !(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
-      if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) {
-        rmesa->radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
+             !(rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
+      if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
+        rmesa->radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
         fprintf(stderr, "Disabling HW TCL support\n");
       }
       TCL_FALLBACK(rmesa->glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
    }
 
-   if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) {
-      if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
-        radeonVtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
-
-      _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
+   if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
+/*       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
    }
    return GL_TRUE;
 }
@@ -498,7 +472,7 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
       release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
       _swsetup_DestroyContext( rmesa->glCtx );
       _tnl_DestroyContext( rmesa->glCtx );
-      _ac_DestroyContext( rmesa->glCtx );
+      _vbo_DestroyContext( rmesa->glCtx );
       _swrast_DestroyContext( rmesa->glCtx );
 
       radeonDestroySwtcl( rmesa->glCtx );
@@ -508,16 +482,6 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
         radeonFlushCmdBuf( rmesa, __FUNCTION__ );
       }
 
-      if (!(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)) {
-        int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
-        if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
-           radeonVtxfmtDestroy( rmesa->glCtx );
-      }
-
-      /* free the Mesa context */
-      rmesa->glCtx->DriverCtx = NULL;
-      _mesa_destroy_context( rmesa->glCtx );
-
       _mesa_vector4f_free( &rmesa->tcl.ObjClean );
 
       if (rmesa->state.scissor.pClipRects) {
@@ -539,6 +503,10 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
         assert( is_empty_list( & rmesa->swapped ) );
       }
 
+      /* free the Mesa context */
+      rmesa->glCtx->DriverCtx = NULL;
+      _mesa_destroy_context( rmesa->glCtx );
+
       /* free the option cache */
       driDestroyOptionCache (&rmesa->optionCache);
 
@@ -565,7 +533,7 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
             radeonPageFlip( dPriv );
          }
          else {
-            radeonCopyBuffer( dPriv );
+            radeonCopyBuffer( dPriv, NULL );
          }
       }
    }
@@ -575,9 +543,34 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
    }
 }
 
+void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
+                        int x, int y, int w, int h )
+{
+    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+       radeonContextPtr radeon;
+       GLcontext *ctx;
+
+       radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+       ctx = radeon->glCtx;
+
+       if (ctx->Visual.doubleBufferMode) {
+           drm_clip_rect_t rect;
+           rect.x1 = x + dPriv->x;
+           rect.y1 = (dPriv->h - y - h) + dPriv->y;
+           rect.x2 = rect.x1 + w;
+           rect.y2 = rect.y1 + h;
+           _mesa_notifySwapBuffers(ctx);       /* flush pending rendering comands */
+           radeonCopyBuffer(dPriv, &rect);
+       }
+    } else {
+       /* XXX this shouldn't be an error but we can't handle it for now */
+       _mesa_problem(NULL, "%s: drawable has no context!",
+                     __FUNCTION__);
+    }
+}
 
-/* Force the context `c' to be the current context and associate with it
- * buffer `b'.
+/* Make context `c' the current context and bind it to the given
+ * drawing and reading surfaces.
  */
 GLboolean
 radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
@@ -591,20 +584,29 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
       if (RADEON_DEBUG & DEBUG_DRI)
         fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) newCtx->glCtx);
 
-      if ( newCtx->dri.drawable != driDrawPriv ) {
-        driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
+      newCtx->dri.readable = driReadPriv;
+
+      if ( (newCtx->dri.drawable != driDrawPriv) ||
+           newCtx->lastStamp != driDrawPriv->lastStamp ) {
+        if (driDrawPriv->swap_interval == (unsigned)-1) {
+           driDrawPriv->vblFlags = (newCtx->radeonScreen->irq != 0)
+              ? driGetDefaultVBlankFlags(&newCtx->optionCache)
+              : VBLANK_FLAG_NO_IRQ;
+
+           driDrawableInitVBlank( driDrawPriv );
+        }
+
         newCtx->dri.drawable = driDrawPriv;
-        radeonUpdateWindow( newCtx->glCtx );
+
+        radeonSetCliprects(newCtx);
         radeonUpdateViewportOffset( newCtx->glCtx );
       }
-  
+
       _mesa_make_current( newCtx->glCtx,
                          (GLframebuffer *) driDrawPriv->driverPrivate,
                          (GLframebuffer *) driReadPriv->driverPrivate );
 
-      if (newCtx->vb.enabled)
-        radeonVtxfmtMakeCurrent( newCtx->glCtx );
-
+      _mesa_update_state( newCtx->glCtx );
    } else {
       if (RADEON_DEBUG & DEBUG_DRI)
         fprintf(stderr, "%s ctx is null\n", __FUNCTION__);