r200: fix up some problems with TFP on r200
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texstate.c
index c94834752edca6bb5659c47bc1d30f0b6f5f9d97..7adf9ad73ed946feedbb73078ba811789c3071cb 100644 (file)
@@ -36,7 +36,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/imports.h"
 #include "main/context.h"
 #include "main/macros.h"
-#include "main/texformat.h"
 #include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/enums.h"
@@ -303,7 +302,7 @@ do {                                                        \
  * Texture unit state management
  */
 
-static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuint replaceargs )
+static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
@@ -765,7 +764,7 @@ void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
        }
 }
 
-void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format,
+void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
                       __DRIdrawable *dPriv)
 {
        struct gl_texture_unit *texUnit;
@@ -778,11 +777,11 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
        struct radeon_framebuffer *rfb;
        radeonTexObjPtr t;
        uint32_t pitch_val;
-       uint32_t internalFormat, type, format;
+       uint32_t internalFormat, format;
+       gl_format texFormat;
 
-       type = GL_BGRA;
        format = GL_UNSIGNED_BYTE;
-       internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4);
+       internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
 
        radeon = pDRICtx->driverPrivate;
        rmesa = pDRICtx->driverPrivate;
@@ -798,24 +797,13 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
            return;
        }
 
-       radeon_update_renderbuffers(pDRICtx, dPriv);
-       /* back & depth buffer are useless free them right away */
-       rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
-       if (rb && rb->bo) {
-               radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-       }
-       rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-       if (rb && rb->bo) {
-               radeon_bo_unref(rb->bo);
-               rb->bo = NULL;
-       }
+       radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
        rb = rfb->color_rb[0];
        if (rb->bo == NULL) {
                /* Failed to BO for the buffer */
                return;
        }
-       
+
        _mesa_lock_texture(radeon->glCtx, texObj);
        if (t->bo) {
                radeon_bo_unref(t->bo);
@@ -825,20 +813,10 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
                radeon_bo_unref(rImage->bo);
                rImage->bo = NULL;
        }
-       if (t->mt) {
-               radeon_miptree_unreference(t->mt);
-               t->mt = NULL;
-       }
-       if (rImage->mt) {
-               radeon_miptree_unreference(rImage->mt);
-               rImage->mt = NULL;
-       }
-       _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
-                                  rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
-       texImage->RowStride = rb->pitch / rb->cpp;
-       texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
-                                                       internalFormat,
-                                                       type, format, 0);
+
+       radeon_miptree_unreference(&t->mt);
+       radeon_miptree_unreference(&rImage->mt);
+
        rImage->bo = rb->bo;
        radeon_bo_ref(rImage->bo);
        t->bo = rb->bo;
@@ -850,27 +828,51 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
        pitch_val = rb->pitch;
        switch (rb->cpp) {
        case 4:
-               if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
+               if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
+                       texFormat = MESA_FORMAT_RGB888;
                        t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
-               else
+               }
+               else {
+                       texFormat = MESA_FORMAT_ARGB8888;
                        t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
+               }
                t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
                break;
        case 3:
        default:
+               texFormat = MESA_FORMAT_RGB888;
                t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
                t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
                break;
        case 2:
+               texFormat = MESA_FORMAT_RGB565;
                t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
                t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
                break;
        }
+
+       _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
+                                  rb->base.Width, rb->base.Height, 1, 0,
+                                  rb->cpp, texFormat);
+       texImage->RowStride = rb->pitch / rb->cpp;
+
+
         t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
                   | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
-        t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
-       t->pp_txpitch = pitch_val;
-        t->pp_txpitch -= 32;
+
+       if (target == GL_TEXTURE_RECTANGLE_NV) {
+               t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
+               t->pp_txpitch = pitch_val;
+               t->pp_txpitch -= 32;
+       } else {
+               t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
+                                   R200_TXFORMAT_HEIGHT_MASK |
+                                   R200_TXFORMAT_CUBIC_MAP_ENABLE |
+                                   R200_TXFORMAT_F5_WIDTH_MASK |
+                                   R200_TXFORMAT_F5_HEIGHT_MASK);
+               t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
+                                  (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
+       }
 
        t->validated = GL_TRUE;
        _mesa_unlock_texture(radeon->glCtx, texObj);
@@ -880,14 +882,14 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
 
 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
 {
-        r200SetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
+        r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
 }
 
 
 #define REF_COLOR 1
 #define REF_ALPHA 2
 
-static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
+static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLint i, j, currslot;
@@ -1073,6 +1075,7 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
 
 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK |         \
                                 R200_TEXCOORD_MASK |           \
+                                R200_MIN_MIP_LEVEL_MASK |      \
                                 R200_CLAMP_Q_MASK |            \
                                 R200_VOLUME_FILTER_MASK)
 
@@ -1220,7 +1223,7 @@ static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
 /*
  * Returns GL_FALSE if fallback required.  
  */
-static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
+static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
 {  
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
@@ -1402,7 +1405,7 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
    return GL_TRUE;
 }
 
-void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
+void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
@@ -1426,10 +1429,10 @@ void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
  */
 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
 {
-   int firstlevel = t->mt ? t->mt->firstLevel : 0;
-   const struct gl_texture_image *firstImage = t->base.Image[0][firstlevel];
+   const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
    GLint log2Width, log2Height, log2Depth, texelBytes;
-   
+   uint extra_size = 0;
+
    if ( t->bo ) {
        return;
    }
@@ -1437,11 +1440,15 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
    log2Width  = firstImage->WidthLog2;
    log2Height = firstImage->HeightLog2;
    log2Depth  = firstImage->DepthLog2;
-   texelBytes = firstImage->TexFormat->TexelBytes;
+   texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
 
+   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+       "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
+       __func__, rmesa, t, log2Width, log2Height,
+       log2Depth, texelBytes, firstImage->TexFormat);
 
    if (!t->image_override) {
-      if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
+      if (VALID_FORMAT(firstImage->TexFormat)) {
         const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
            tx_table_be;
         
@@ -1449,29 +1456,46 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
                             R200_TXFORMAT_ALPHA_IN_MAP);
         t->pp_txfilter &= ~R200_YUV_TO_RGB;
         
-        t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format;
-        t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter;
+        t->pp_txformat |= table[ firstImage->TexFormat ].format;
+        t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
+
+
       } else {
         _mesa_problem(NULL, "unexpected texture format in %s",
                       __FUNCTION__);
         return;
       }
    }
-   
+
    t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
-   t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << R200_MAX_MIP_LEVEL_SHIFT;
-       
+   t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
+          & R200_MAX_MIP_LEVEL_MASK;
+
+   if ( t->pp_txfilter &
+               (R200_MIN_FILTER_NEAREST_MIP_NEAREST
+                | R200_MIN_FILTER_NEAREST_MIP_LINEAR
+                | R200_MIN_FILTER_LINEAR_MIP_NEAREST
+                | R200_MIN_FILTER_LINEAR_MIP_LINEAR
+                | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
+                | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
+                extra_size = t->minLod;
+
    t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
                       R200_TXFORMAT_HEIGHT_MASK |
                       R200_TXFORMAT_CUBIC_MAP_ENABLE |
                       R200_TXFORMAT_F5_WIDTH_MASK |
                       R200_TXFORMAT_F5_HEIGHT_MASK);
-   t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
-                     (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
+   t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
+                     ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
    
    t->tile_bits = 0;
    
-   t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
+   t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
+                  | R200_MIN_MIP_LEVEL_MASK);
+
+   t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
+          & R200_MIN_MIP_LEVEL_MASK;
+
    if (t->base.Target == GL_TEXTURE_3D) {
       t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
       t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
@@ -1499,12 +1523,12 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
        */
       t->pp_txformat_x |= R200_TEXCOORD_PROJ;
    }
-
+   /* FIXME: NPOT sizes, Is it correct realy? */
    t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
                   | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
 
    if ( !t->image_override ) {
-      if (firstImage->IsCompressed)
+      if (_mesa_is_format_compressed(firstImage->TexFormat))
          t->pp_txpitch = (firstImage->Width + 63) & ~(63);
       else
          t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
@@ -1517,7 +1541,7 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
 
 }
 
-static GLboolean r200_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit)
+static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    radeonTexObj *t = radeon_tex_obj(texObj);
@@ -1560,7 +1584,7 @@ static GLboolean r200_validate_texture(GLcontext *ctx, struct gl_texture_object
    return !t->border_fallback;
 }
 
-static GLboolean r200UpdateTextureUnit(GLcontext *ctx, int unit)
+static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
@@ -1584,7 +1608,7 @@ static GLboolean r200UpdateTextureUnit(GLcontext *ctx, int unit)
 }
 
 
-void r200UpdateTextureState( GLcontext *ctx )
+void r200UpdateTextureState( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLboolean ok;