R1xx/r2xx: Don't use an alpha texture format for GLX_TEXTURE_FORMAT_RGB_EXT
[mesa.git] / src / mesa / drivers / dri / r300 / r300_swtcl.c
index ca91cf750b54212bdc831a4264e3a095b62e4d13..a40d0378db1afcdecb4fac62f3bedad13118d6c2 100644 (file)
@@ -34,6 +34,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 
+#include "r300_state.h"
 #include "r300_swtcl.h"
 #include "r300_emit.h"
 #include "r300_tex.h"
@@ -63,13 +64,10 @@ do { \
        ++num_attrs; \
 } while (0)
 
-static void r300SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten)
+static void r300SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten, GLuint vap_out_fmt_1)
 {
        r300ContextPtr rmesa = R300_CONTEXT( ctx );
-       TNLcontext *tnl = TNL_CONTEXT(ctx);
-       struct vertex_buffer *VB = &tnl->vb;
        struct vertex_attribute *attrs = rmesa->swtcl.vert_attrs;
-       int vte = 0;
        int i, j, reg_count;
        uint32_t *vir0 = &rmesa->hw.vir[0].cmd[1];
        uint32_t *vir1 = &rmesa->hw.vir[1].cmd[1];
@@ -123,7 +121,6 @@ static void r300SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsW
        R300_STATECHANGE(rmesa, vir[0]);
        R300_STATECHANGE(rmesa, vir[1]);
        R300_STATECHANGE(rmesa, vof);
-       R300_STATECHANGE(rmesa, vte);
        R300_STATECHANGE(rmesa, vic);
 
        if (rmesa->radeon.radeonScreen->kernel_mm) {
@@ -139,25 +136,12 @@ static void r300SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsW
        rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
        rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
        rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
-       rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten);
-
-       vte = rmesa->hw.vte.cmd[1];
-       vte &= ~(R300_VTX_XY_FMT | R300_VTX_Z_FMT | R300_VTX_W0_FMT);
-       /* Important:
-        */
-       if ( VB->NdcPtr != NULL ) {
-               VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
-               vte |= R300_VTX_XY_FMT | R300_VTX_Z_FMT;
-       }
-       else {
-               VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
-               vte |= R300_VTX_W0_FMT;
-       }
-
-       assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
-
-       rmesa->hw.vte.cmd[1] = vte;
-       rmesa->hw.vte.cmd[2] = rmesa->radeon.swtcl.vertex_size;
+       /**
+         * Can't use r300VAPOutputCntl1 function because it assumes
+         * that all texture coords have 4 components and that's the case
+         * for HW TCL path, but not for SW TCL.
+         */
+       rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_out_fmt_1;
 }
 
 
@@ -166,7 +150,7 @@ static void r300SetVertexFormat( GLcontext *ctx )
        r300ContextPtr rmesa = R300_CONTEXT( ctx );
        TNLcontext *tnl = TNL_CONTEXT(ctx);
        struct vertex_buffer *VB = &tnl->vb;
-       int fog_id = -1;
+       int first_free_tex = 0, vap_out_fmt_1 = 0;
        GLuint InputsRead = 0;
        GLuint OutputsWritten = 0;
        int num_attrs = 0;
@@ -175,6 +159,9 @@ static void r300SetVertexFormat( GLcontext *ctx )
        rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
        rmesa->radeon.swtcl.vertex_attr_count = 0;
 
+       /* We always want non Ndc coords format */
+       VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
+
        if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS)) {
                InputsRead |= 1 << VERT_ATTRIB_POS;
                OutputsWritten |= 1 << VERT_RESULT_HPOS;
@@ -209,6 +196,29 @@ static void r300SetVertexFormat( GLcontext *ctx )
                rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1;
        }
 
+       if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
+               VB->AttribPtr[VERT_ATTRIB_GENERIC0] = VB->ColorPtr[1];
+               OutputsWritten |= 1 << VERT_RESULT_BFC0;
+#if MESA_LITTLE_ENDIAN
+               EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_RGBA );
+               ADD_ATTR(VERT_ATTRIB_GENERIC0, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW);
+#else
+               EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_ABGR );
+               ADD_ATTR(VERT_ATTRIB_GENERIC0, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW);
+#endif
+               if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 )) {
+                       GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
+                       OutputsWritten |= 1 << VERT_RESULT_BFC1;
+#if MESA_LITTLE_ENDIAN
+                       EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_RGBA );
+                       ADD_ATTR(VERT_ATTRIB_GENERIC1, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR3, swiz, MASK_XYZW);
+#else
+                       EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_ABGR );
+                       ADD_ATTR(VERT_ATTRIB_GENERIC1, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR3, swiz, MASK_XYZW);
+#endif
+               }
+       }
+
        if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE )) {
                GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
                InputsRead |= 1 << VERT_ATTRIB_POINT_SIZE;
@@ -217,53 +227,31 @@ static void r300SetVertexFormat( GLcontext *ctx )
                ADD_ATTR(VERT_ATTRIB_POINT_SIZE, EMIT_1F, SWTCL_OVM_POINT_SIZE, swiz, MASK_X);
        }
 
-       if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_FOG)) {
-               /* find first free tex coord slot */
-               if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
-                       int i;
-                       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-                               if (!RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
-                                       fog_id = i;
-                                       break;
-                               }
-                       }
-               } else {
-                       fog_id = 0;
-               }
-
-               if (fog_id == -1) {
-                       fprintf(stderr, "\tout of free texcoords to do fog\n");
-                       _mesa_exit(-1);
-               }
-
-               InputsRead |= 1 << VERT_ATTRIB_FOG;
-               OutputsWritten |= 1 << VERT_RESULT_FOGC;
-               GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
-               EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F );
-               ADD_ATTR(VERT_ATTRIB_FOG, EMIT_1F, SWTCL_OVM_TEX(fog_id), swiz, MASK_X);
-       }
-
+       /**
+        *  Sending only one texcoord component may lead to lock up,
+        *  so for all textures always output 4 texcoord components to RS.
+        */
        if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
                int i;
-               GLuint swiz, mask, format;
+               GLuint swiz, format;
                for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
                        if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
                                switch (VB->TexCoordPtr[i]->size) {
                                        case 1:
+                                               format = EMIT_1F;
+                                               swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
+                                               break;
                                        case 2:
                                                format = EMIT_2F;
-                                               swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO);
-                                               mask = MASK_X | MASK_Y;
+                                               swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
                                                break;
                                        case 3:
                                                format = EMIT_3F;
-                                               swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
-                                               mask = MASK_X | MASK_Y | MASK_Z;
+                                               swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
                                                break;
                                        case 4:
                                                format = EMIT_4F;
                                                swiz = SWIZZLE_XYZW;
-                                               mask = MASK_XYZW;
                                                break;
                                        default:
                                                continue;
@@ -271,43 +259,44 @@ static void r300SetVertexFormat( GLcontext *ctx )
                                InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
                                OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
                                EMIT_ATTR(_TNL_ATTRIB_TEX(i), format);
-                               ADD_ATTR(VERT_ATTRIB_TEX0 + i, format, SWTCL_OVM_TEX(i), swiz, mask);
+                               ADD_ATTR(VERT_ATTRIB_TEX0 + i, format, SWTCL_OVM_TEX(i), swiz, MASK_XYZW);
+                               vap_out_fmt_1 |= 4 << (i * 3);
+                               ++first_free_tex;
                        }
                }
        }
 
        /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
        if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS) && (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) {
-               int first_free_tex = -1;
-               if (fog_id >= 0) {
-                       first_free_tex = fog_id+1;
-               } else {
-                       if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
-                               int i;
-                               for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-                                       if (!RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
-                                               first_free_tex = i;
-                                               break;
-                                       }
-                               }
-                       } else {
-                               first_free_tex = 0;
-                       }
-               }
-
-               if (first_free_tex == -1) {
+               if (first_free_tex >= ctx->Const.MaxTextureUnits) {
                        fprintf(stderr, "\tout of free texcoords to write w pos\n");
                        _mesa_exit(-1);
                }
 
                InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex);
                OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex);
-               EMIT_ATTR( _TNL_ATTRIB_TEX(first_free_tex), EMIT_4F );
-               ADD_ATTR(VERT_ATTRIB_TEX0 + first_free_tex, EMIT_4F, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW);
+               EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
+               ADD_ATTR(VERT_ATTRIB_POS, EMIT_4F, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW);
+               vap_out_fmt_1 |= 4 << (first_free_tex * 3);
+               ++first_free_tex;
+       }
+
+       if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_FOG)) {
+               if (first_free_tex >= ctx->Const.MaxTextureUnits) {
+                       fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
+                       _mesa_exit(-1);
+               }
+
+               InputsRead |= 1 << VERT_ATTRIB_FOG;
+               OutputsWritten |= 1 << VERT_RESULT_FOGC;
+               GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
+               EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F );
+               ADD_ATTR(VERT_ATTRIB_FOG, EMIT_1F, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_X);
+               vap_out_fmt_1 |=  1 << (first_free_tex * 3);
        }
 
        R300_NEWPRIM(rmesa);
-       r300SwtclVAPSetup(ctx, InputsRead, OutputsWritten);
+       r300SwtclVAPSetup(ctx, InputsRead, OutputsWritten, vap_out_fmt_1);
 
        rmesa->radeon.swtcl.vertex_size =
                _tnl_install_attrs( ctx,
@@ -317,7 +306,7 @@ static void r300SetVertexFormat( GLcontext *ctx )
 
        rmesa->radeon.swtcl.vertex_size /= 4;
 
-       RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, tnl->render_inputs_bitset);
+       RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset);
 }
 
 
@@ -383,9 +372,8 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim );
  *              Build render functions from dd templates               *
  ***********************************************************************/
 
-#define R300_TWOSIDE_BIT       0x01
-#define R300_UNFILLED_BIT      0x02
-#define R300_MAX_TRIFUNC       0x04
+#define R300_UNFILLED_BIT      0x01
+#define R300_MAX_TRIFUNC       0x02
 
 static struct {
    tnl_points_func             points;
@@ -396,9 +384,9 @@ static struct {
 
 #define DO_FALLBACK  0
 #define DO_UNFILLED (IND & R300_UNFILLED_BIT)
-#define DO_TWOSIDE  (IND & R300_TWOSIDE_BIT)
+#define DO_TWOSIDE   0
 #define DO_FLAT      0
-#define DO_OFFSET     0
+#define DO_OFFSET    0
 #define DO_TRI       1
 #define DO_QUAD      1
 #define DO_LINE      1
@@ -486,26 +474,15 @@ do { \
 #define TAG(x) x
 #include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (R300_TWOSIDE_BIT)
-#define TAG(x) x##_twoside
-#include "tnl_dd/t_dd_tritmp.h"
-
 #define IND (R300_UNFILLED_BIT)
 #define TAG(x) x##_unfilled
 #include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
-#define TAG(x) x##_twoside_unfilled
-#include "tnl_dd/t_dd_tritmp.h"
-
-
 
 static void init_rast_tab( void )
 {
    init();
-   init_twoside();
    init_unfilled();
-   init_twoside_unfilled();
 }
 
 /**********************************************************************/
@@ -557,7 +534,6 @@ static void r300ChooseRenderState( GLcontext *ctx )
        GLuint index = 0;
        GLuint flags = ctx->_TriangleCaps;
 
-       if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT;
        if (flags & DD_TRI_UNFILLED)      index |= R300_UNFILLED_BIT;
 
        if (index != rmesa->radeon.swtcl.RenderIndex) {