r300: move firevertices out into the main place its needed.
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texstate.c
index 12b828846f49d2fe611efaf1bbf316b0c3d8bf24..4937b0665d1cfc6cdfd63b50a0ace5a36cb69f2d 100644 (file)
@@ -37,10 +37,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/context.h"
 #include "main/macros.h"
 #include "main/texformat.h"
+#include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/enums.h"
 
-#include "common_context.h"
+#include "radeon_common.h"
 #include "radeon_mipmap_tree.h"
 #include "r200_context.h"
 #include "r200_state.h"
@@ -733,19 +734,18 @@ void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
        r200ContextPtr rmesa = pDRICtx->driverPrivate;
        struct gl_texture_object *tObj =
            _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
-       radeonTexObjPtr t;
+       radeonTexObjPtr t = radeon_tex_obj(tObj);
 
        if (!tObj)
                return;
 
-       t = (radeonTexObjPtr) tObj->DriverData;
-
        t->image_override = GL_TRUE;
 
        if (!offset)
                return;
 
-       t->pp_txoffset = offset;
+       t->bo = NULL;
+       t->override_offset = offset;
        t->pp_txpitch = pitch - 32;
 
        switch (depth) {
@@ -765,6 +765,109 @@ void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
        }
 }
 
+void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+       struct gl_texture_unit *texUnit;
+       struct gl_texture_object *texObj;
+       struct gl_texture_image *texImage;
+       struct radeon_renderbuffer *rb;
+       radeon_texture_image *rImage;
+       radeonContextPtr radeon;
+       r200ContextPtr rmesa;
+       struct radeon_framebuffer *rfb;
+       radeonTexObjPtr t;
+       uint32_t pitch_val;
+
+       target = GL_TEXTURE_RECTANGLE_ARB;
+
+       radeon = pDRICtx->driverPrivate;
+       rmesa = pDRICtx->driverPrivate;
+
+       rfb = dPriv->driverPrivate;
+        texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
+       texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
+        texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
+
+       rImage = get_radeon_texture_image(texImage);
+       t = radeon_tex_obj(texObj);
+        if (t == NULL) {
+           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;
+       }
+       rb = (void*)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+       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);
+               t->bo = NULL;
+       }
+       if (rImage->bo) {
+               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;
+       }
+       fprintf(stderr,"settexbuf %d %dx%d@%d\n", rb->pitch, rb->width, rb->height, rb->cpp);
+       _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
+                                  rb->width, rb->height, 1, 0, rb->cpp);
+       texImage->TexFormat = &_mesa_texformat_rgba8888_rev;
+       rImage->bo = rb->bo;
+       radeon_bo_ref(rImage->bo);
+       t->bo = rb->bo;
+       radeon_bo_ref(t->bo);
+       t->tile_bits = 0;
+       t->image_override = GL_TRUE;
+       t->override_offset = 0;
+       t->pp_txpitch &= (1 << 13) -1;
+       pitch_val = rb->pitch;
+       switch (rb->cpp) {
+       case 4:
+               t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
+               t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
+               break;
+       case 3:
+       default:
+               t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
+               t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
+               break;
+       case 2:
+               t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
+               t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
+               break;
+       }
+        t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT)
+                  | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT);
+        t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
+       t->pp_txpitch = pitch_val;
+        t->pp_txpitch -= 32;
+
+       t->validated = GL_TRUE;
+       _mesa_unlock_texture(radeon->glCtx, texObj);
+       return;
+}
+
 #define REF_COLOR 1
 #define REF_ALPHA 2
 
@@ -958,6 +1061,35 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
                                 R200_VOLUME_FILTER_MASK)
 
 
+static void disable_tex_obj_state( r200ContextPtr rmesa, 
+                                  int unit )
+{
+   
+   R200_STATECHANGE( rmesa, vtx );
+   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
+
+   if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
+      TCL_FALLBACK( rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
+   }
+
+   /* Actually want to keep all units less than max active texture
+    * enabled, right?  Fix this for >2 texunits.
+    */
+
+   {
+      GLuint tmp = rmesa->TexGenEnabled;
+
+      rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
+      rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
+      rmesa->TexGenNeedNormals[unit] = GL_FALSE;
+      rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
+
+      if (tmp != rmesa->TexGenEnabled) {
+        rmesa->recheck_texgen[unit] = GL_TRUE;
+        rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
+      }
+   }
+}
 static void import_tex_obj_state( r200ContextPtr rmesa,
                                  int unit,
                                  radeonTexObjPtr texobj )
@@ -976,18 +1108,9 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
    cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
    cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
-   if (rmesa->radeon.radeonScreen->drmSupportsFragShader) {
-      cmd[TEX_PP_TXOFFSET_NEWDRM] = texobj->pp_txoffset;
-   }
-   else {
-      cmd[TEX_PP_TXOFFSET_OLDDRM] = texobj->pp_txoffset;
-   }
 
    if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
       GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
-      //      GLuint bytesPerFace = texobj->base.totalSize / 6;
-      //      ASSERT(texobj->base.totalSize % 6 == 0);
-      GLuint bytesPerFace = 1; // TODO
 
       R200_STATECHANGE( rmesa, cube[unit] );
       cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
@@ -996,14 +1119,8 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
            to not include that command when new drm is used */
         cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
       }
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] = texobj->pp_txoffset + 2 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace;
    }
 
-   texobj->dirty_state &= ~(1<<unit);
 }
 
 static void set_texgen_matrix( r200ContextPtr rmesa, 
@@ -1291,6 +1408,10 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
       t->base.Image[0][t->mt->firstLevel];
    GLint log2Width, log2Height, log2Depth, texelBytes;
    
+   if ( t->bo ) {
+       return;
+   }
+
    log2Width  = firstImage->WidthLog2;
    log2Height = firstImage->HeightLog2;
    log2Depth  = firstImage->DepthLog2;
@@ -1371,7 +1492,7 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
    if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
       t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
    }
-   
+
 }
 
 static GLboolean r200_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit)
@@ -1401,23 +1522,32 @@ static GLboolean r200_validate_texture(GLcontext *ctx, struct gl_texture_object
    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
 
    rmesa->recheck_texgen[unit] = GL_TRUE;
-   if (t->dirty_state & (1<<unit)) {
-      import_tex_obj_state( rmesa, unit, t );
+   import_tex_obj_state( rmesa, unit, t );
+
+   if (rmesa->recheck_texgen[unit]) {
+      GLboolean fallback = !r200_validate_texgen( ctx, unit );
+      TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
+      rmesa->recheck_texgen[unit] = 0;
+      rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    }
 
-   t->dirty_state = R200_TEX_ALL;
-   
    t->validated = GL_TRUE;
-   return GL_TRUE;
+
+   FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
+
+   return !t->border_fallback;
 }
 
-GLboolean r200UpdateTextureUnit(GLcontext *ctx, int unit)
+static GLboolean r200UpdateTextureUnit(GLcontext *ctx, int unit)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
 
-   if (!unitneeded)
+   if (!unitneeded) {
+      /* disable the unit */
+     disable_tex_obj_state(rmesa, unit);
      return GL_TRUE;
+   }
 
    if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
     _mesa_warning(ctx,