r200/r300: add aperture space checks
[mesa.git] / src / mesa / drivers / dri / r300 / r300_swtcl.c
index c949f33bf33eb348432555c2aa15971258073408..ef65fbb127a683c86926ae068e0041d4fff0366b 100644 (file)
@@ -34,13 +34,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
-#include "glheader.h"
-#include "mtypes.h"
-#include "colormac.h"
-#include "enums.h"
-#include "image.h"
-#include "imports.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/colormac.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/imports.h"
+#include "main/light.h"
+#include "main/macros.h"
 
 #include "swrast/s_context.h"
 #include "swrast/s_fog.h"
@@ -55,12 +56,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_state.h"
 #include "r300_ioctl.h"
 #include "r300_emit.h"
-#include "r300_mem.h"
 
-static void flush_last_swtcl_prim( r300ContextPtr rmesa  );
+static void flush_last_swtcl_prim( GLcontext *ctx);
 
 
-void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset);
+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset);
 void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr);
 #define EMIT_ATTR( ATTR, STYLE )                                       \
 do {                                                                   \
@@ -77,31 +77,6 @@ do {                                                                 \
    rmesa->swtcl.vertex_attr_count++;                                   \
 } while (0)
 
-/* this differs from the VIR0 in emit.c - TODO merge them using another option */
-static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr,
-                                int *inputs, GLint * tab, GLuint nr)
-{
-       GLuint i, dw;
-
-       /* type, inputs, stop bit, size */
-       for (i = 0; i + 1 < nr; i += 2) {
-               dw = (inputs[tab[i]] << 8) | 0x3;
-               dw |= ((inputs[tab[i + 1]] << 8) | 0x3) << 16;
-               if (i + 2 == nr) {
-                       dw |= (R300_VAP_INPUT_ROUTE_END << 16);
-               }
-               dst[i >> 1] = dw;
-       }
-
-       if (nr & 1) {
-               dw = (inputs[tab[nr - 1]] << 8) | 0x3;
-               dw |= R300_VAP_INPUT_ROUTE_END;
-               dst[nr >> 1] = dw;
-       }
-
-       return (nr + 1) >> 1;
-}
-
 static void r300SetVertexFormat( GLcontext *ctx )
 {
        r300ContextPtr rmesa = R300_CONTEXT( ctx );
@@ -110,26 +85,30 @@ static void r300SetVertexFormat( GLcontext *ctx )
        DECLARE_RENDERINPUTS(index_bitset);
        GLuint InputsRead = 0, OutputsWritten = 0;
        int vap_fmt_0 = 0;
-       int vap_vte_cntl = 0;
        int offset = 0;
        int vte = 0;
        GLint inputs[VERT_ATTRIB_MAX];
        GLint tab[VERT_ATTRIB_MAX];
        int swizzle[VERT_ATTRIB_MAX][4];
        GLuint i, nr;
+       GLuint sz, vap_fmt_1 = 0;
 
        DECLARE_RENDERINPUTS(render_inputs_bitset);
        RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset);
        RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
        RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset);
 
+       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 );
@@ -139,14 +118,15 @@ static void r300SetVertexFormat( GLcontext *ctx )
         * build up a hardware vertex.
         */
        if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POS)) {
-               vap_vte_cntl |= R300_VTX_W0_FMT;
+               sz = VB->AttribPtr[VERT_ATTRIB_POS]->size;
                InputsRead |= 1 << VERT_ATTRIB_POS;
                OutputsWritten |= 1 << VERT_RESULT_HPOS;
-               EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
-       } else
+               EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_1F + sz - 1 );
+               offset = sz;
+       } else {
+               offset = 4;
                EMIT_PAD(4 * sizeof(float));
-
-       offset = 4;
+       }
 
        if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
                EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
@@ -155,18 +135,19 @@ static void r300SetVertexFormat( GLcontext *ctx )
        }
 
        if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR0)) {
+               sz = VB->AttribPtr[VERT_ATTRIB_COLOR0]->size;
                rmesa->swtcl.coloroffset = offset;
                InputsRead |= 1 << VERT_ATTRIB_COLOR0;
                OutputsWritten |= 1 << VERT_RESULT_COL0;
-               EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F );
+               EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_1F + sz - 1 );
+               offset += sz;
        }
 
-       offset += 4;
-
        rmesa->swtcl.specoffset = 0;
        if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+               sz = VB->AttribPtr[VERT_ATTRIB_COLOR1]->size;
                rmesa->swtcl.specoffset = offset;
-               EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F );
+               EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_1F + sz - 1 );
                InputsRead |= 1 << VERT_ATTRIB_COLOR1;
                OutputsWritten |= 1 << VERT_RESULT_COL1;
        }
@@ -176,9 +157,11 @@ static void r300SetVertexFormat( GLcontext *ctx )
 
                for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
                        if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
+                               sz = VB->TexCoordPtr[i]->size;
                                InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
                                OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
-                               EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_4F );
+                               EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1 );
+                               vap_fmt_1 |= sz << (3 * i);
                        }
                }
        }
@@ -190,7 +173,7 @@ static void r300SetVertexFormat( GLcontext *ctx )
                        inputs[i] = -1;
                }
        }
-       
+
        /* Fixed, apply to vir0 only */
        if (InputsRead & (1 << VERT_ATTRIB_POS))
                inputs[VERT_ATTRIB_POS] = 0;
@@ -201,16 +184,16 @@ static void r300SetVertexFormat( GLcontext *ctx )
        for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
                if (InputsRead & (1 << i))
                        inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
-       
+
        for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
                if (InputsRead & (1 << i)) {
                        tab[nr++] = i;
                }
        }
-       
+
        for (i = 0; i < nr; i++) {
                int ci;
-               
+
                swizzle[i][0] = SWIZZLE_ZERO;
                swizzle[i][1] = SWIZZLE_ZERO;
                swizzle[i][2] = SWIZZLE_ZERO;
@@ -230,26 +213,26 @@ static void r300SetVertexFormat( GLcontext *ctx )
        ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count =
                r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
                                   nr);
-   
+
        R300_STATECHANGE(rmesa, vic);
        rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
        rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
-   
+
        R300_STATECHANGE(rmesa, vof);
        rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
-       rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten);
-   
+       rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_fmt_1;
+
        rmesa->swtcl.vertex_size =
                _tnl_install_attrs( ctx,
-                                   rmesa->swtcl.vertex_attrs, 
+                                   rmesa->swtcl.vertex_attrs,
                                    rmesa->swtcl.vertex_attr_count,
                                    NULL, 0 );
-       
+
        rmesa->swtcl.vertex_size /= 4;
 
        RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset );
 
-       vte = rmesa->hw.vte.cmd[1];
+
        R300_STATECHANGE(rmesa, vte);
        rmesa->hw.vte.cmd[1] = vte;
        rmesa->hw.vte.cmd[2] = rmesa->swtcl.vertex_size;
@@ -258,40 +241,44 @@ static void r300SetVertexFormat( GLcontext *ctx )
 
 /* Flush vertices in the current dma region.
  */
-static void flush_last_swtcl_prim( r300ContextPtr rmesa  )
+static void flush_last_swtcl_prim( GLcontext *ctx  )
 {
+       r300ContextPtr rmesa = R300_CONTEXT(ctx);
+       struct radeon_dma *dma = &rmesa->radeon.dma;
+               
+
        if (RADEON_DEBUG & DEBUG_IOCTL)
                fprintf(stderr, "%s\n", __FUNCTION__);
-       
-       rmesa->dma.flush = NULL;
-
-       if (rmesa->dma.current.buf) {
-               struct r300_dma_region *current = &rmesa->dma.current;
-               GLuint current_offset = GET_START(current);
-
-               assert (current->start + 
-                       rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
-                       current->ptr);
-
-               if (rmesa->dma.current.start != rmesa->dma.current.ptr) {
-
-                       r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__);
-                       
-                       r300EmitState(rmesa);
-                       
-                       r300EmitVertexAOS( rmesa,
-                                          rmesa->swtcl.vertex_size,
-                                          current_offset);
-                       
-                       r300EmitVbufPrim( rmesa,
-                                         rmesa->swtcl.hw_primitive,
-                                         rmesa->swtcl.numverts);
-                       
-                       r300EmitCacheFlush(rmesa);
-               }
-               
-               rmesa->swtcl.numverts = 0;
-               current->start = current->ptr;
+       dma->flush = NULL;
+
+       if (dma->current) {
+           GLuint current_offset = dma->current_used;
+
+           assert (dma->current_used +
+                   rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
+                   dma->current_vertexptr);
+
+           radeon_bo_unmap(dma->current);
+           if (dma->current_used != dma->current_vertexptr) {
+                   dma->current_used = dma->current_vertexptr;
+
+                   rcommonEnsureCmdBufSpace(rmesa,
+                                            rmesa->hw.max_state_size + (12*sizeof(int)),
+                                            __FUNCTION__);
+                   r300EmitState(rmesa);
+                   r300EmitVertexAOS(rmesa,
+                                     rmesa->swtcl.vertex_size,
+                                     dma->current,
+                                     current_offset);
+
+                   r300EmitVbufPrim(rmesa,
+                                    rmesa->swtcl.hw_primitive,
+                                    rmesa->swtcl.numverts);
+                   r300EmitCacheFlush(rmesa);
+                   COMMIT_BATCH();
+           }
+           radeonReleaseDmaRegion(&rmesa->radeon);
+           rmesa->swtcl.numverts = 0;
        }
 }
 
@@ -301,27 +288,29 @@ static void *
 r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize )
 {
        GLuint bytes = vsize * nverts;
+       void *head;
 
-       if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) 
-               r300RefillCurrentDmaRegion( rmesa, bytes);
-
-       if (!rmesa->dma.flush) {
-               rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
-               rmesa->dma.flush = flush_last_swtcl_prim;
+       if (!rmesa->radeon.dma.current || rmesa->radeon.dma.current_vertexptr + bytes > rmesa->radeon.dma.current->size) {
+                radeonRefillCurrentDmaRegion( &rmesa->radeon, bytes);
        }
 
+        if (!rmesa->radeon.dma.flush) {
+                rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
+                rmesa->radeon.dma.flush = flush_last_swtcl_prim;
+        }
+
        ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
-       ASSERT( rmesa->dma.flush == flush_last_swtcl_prim );
-       ASSERT( rmesa->dma.current.start + 
-               rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
-               rmesa->dma.current.ptr );
-
-       {
-               GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr);
-               rmesa->dma.current.ptr += bytes;
-               rmesa->swtcl.numverts += nverts;
-               return head;
-       }
+        ASSERT( rmesa->radeon.dma.flush == flush_last_swtcl_prim );
+        ASSERT( rmesa->radeon.dma.current_used +
+                rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
+                rmesa->radeon.dma.current_vertexptr );
+
+//     fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
+//             rmesa->radeon.dma.current_vertexptr);
+       head = (rmesa->radeon.dma.current->ptr + rmesa->radeon.dma.current_vertexptr);
+       rmesa->radeon.dma.current_vertexptr += bytes;
+       rmesa->swtcl.numverts += nverts;
+       return head;
 }
 
 static GLuint reduced_prim[] = {
@@ -367,7 +356,7 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim );
    r300ContextPtr rmesa = R300_CONTEXT(ctx);           \
    const char *r300verts = (char *)rmesa->swtcl.verts;
 #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
-#define VERTEX r300Vertex 
+#define VERTEX r300Vertex
 #define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS))
 #define PRINT_VERTEX(x)
 #undef TAG
@@ -587,17 +576,18 @@ static void r300RenderStart(GLcontext *ctx)
         r300ContextPtr rmesa = R300_CONTEXT( ctx );
        //      fprintf(stderr, "%s\n", __FUNCTION__);
 
-       r300ChooseRenderState(ctx);     
+       r300ChooseRenderState(ctx);
        r300SetVertexFormat(ctx);
 
+       r300ValidateTextures(ctx);
+
+       r300UpdateShaders(rmesa);
        r300UpdateShaderStates(rmesa);
 
        r300EmitCacheFlush(rmesa);
-       
-       if (rmesa->dma.flush != 0 && 
-           rmesa->dma.flush != flush_last_swtcl_prim)
-               rmesa->dma.flush( rmesa );
-
+       if (rmesa->radeon.dma.flush != NULL) {
+               rmesa->radeon.dma.flush(ctx);
+       }
 }
 
 static void r300RenderFinish(GLcontext *ctx)
@@ -607,7 +597,7 @@ static void r300RenderFinish(GLcontext *ctx)
 static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
-       
+
        if (rmesa->swtcl.hw_primitive != hwprim) {
                R300_NEWPRIM( rmesa );
                rmesa->swtcl.hw_primitive = hwprim;
@@ -625,7 +615,7 @@ static void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
 
        r300RasterPrimitive( ctx, reduced_prim[prim] );
        //      fprintf(stderr, "%s\n", __FUNCTION__);
-       
+
 }
 
 static void r300ResetLineStipple(GLcontext *ctx)
@@ -639,12 +629,12 @@ void r300InitSwtcl(GLcontext *ctx)
        TNLcontext *tnl = TNL_CONTEXT(ctx);
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
        static int firsttime = 1;
-       
+
        if (firsttime) {
                init_rast_tab();
                firsttime = 0;
        }
-       
+
        tnl->Driver.Render.Start = r300RenderStart;
        tnl->Driver.Render.Finish = r300RenderFinish;
        tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive;
@@ -652,15 +642,15 @@ void r300InitSwtcl(GLcontext *ctx)
        tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
        tnl->Driver.Render.CopyPV = _tnl_copy_pv;
        tnl->Driver.Render.Interp = _tnl_interp;
-       
+
        /* FIXME: what are these numbers? */
-       _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 
+       _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
                            48 * sizeof(GLfloat) );
-       
+
        rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
        rmesa->swtcl.RenderIndex = ~0;
        rmesa->swtcl.render_primitive = GL_TRIANGLES;
-       rmesa->swtcl.hw_primitive = 0;  
+       rmesa->swtcl.hw_primitive = 0;
 
        _tnl_invalidate_vertex_state( ctx, ~0 );
        _tnl_invalidate_vertices( ctx, ~0 );
@@ -669,9 +659,9 @@ void r300InitSwtcl(GLcontext *ctx)
        _tnl_need_projected_coords( ctx, GL_FALSE );
        r300ChooseRenderState(ctx);
 
-       _mesa_validate_all_lighting_tables( ctx ); 
+       _mesa_validate_all_lighting_tables( ctx );
 
-       tnl->Driver.NotifyMaterialChange = 
+       tnl->Driver.NotifyMaterialChange =
          _mesa_validate_all_lighting_tables;
 }
 
@@ -679,33 +669,32 @@ void r300DestroySwtcl(GLcontext *ctx)
 {
 }
 
-void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset)
+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
 {
-       int cmd_reserved = 0;
-       int cmd_written = 0;
+       BATCH_LOCALS(&rmesa->radeon);
 
-       drm_radeon_cmd_header_t *cmd = NULL;
        if (RADEON_DEBUG & DEBUG_VERTS)
-         fprintf(stderr, "%s:  vertex_size %d, offset 0x%x \n",
-                 __FUNCTION__, vertex_size, offset);
-
-       start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2), 2);
-       e32(1);
-       e32(vertex_size | (vertex_size << 8));
-       e32(offset);
+               fprintf(stderr, "%s:  vertex_size %d, offset 0x%x \n",
+                       __FUNCTION__, vertex_size, offset);
+
+       BEGIN_BATCH(5);
+       OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2);
+       OUT_BATCH(1);
+       OUT_BATCH(vertex_size | (vertex_size << 8));
+       OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
+       END_BATCH();
 }
 
 void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
 {
-
-       int cmd_reserved = 0;
-       int cmd_written = 0;
+       BATCH_LOCALS(&rmesa->radeon);
        int type, num_verts;
-       drm_radeon_cmd_header_t *cmd = NULL;
 
        type = r300PrimitiveType(rmesa, primitive);
        num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
-       
-       start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0);
-       e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
+
+       BEGIN_BATCH(3);
+       OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
+       OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
+       END_BATCH();
 }