diff options
Diffstat (limited to 'src/mesa/drivers/dri/nouveau/nv10_swtcl.c')
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 261 |
1 files changed, 168 insertions, 93 deletions
diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 4576c1ede4..42b3d666fb 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -54,11 +54,55 @@ static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); static void nv10ResetLineStipple( GLcontext *ctx ); +static const int default_attr_size[8]={3,3,3,4,3,1,4,4}; +/* Mesa requires us to put pos attribute as the first attribute of the + * vertex, but on NV10 it is the last attribute. + * To fix that we put the pos attribute first, and we swap the pos + * attribute before sending it to the card. + * Speed cost of the swap seems negligeable + */ +#if 0 +/* old stuff where pos attribute isn't put first for mesa. + * Usefull for speed comparaison + */ +#define INV_VERT(i) i +#define OUT_RING_VERTp(nmesa, ptr,sz, vertex_size) OUT_RINGp(ptr,sz) +#define OUT_RING_VERT(nmesa, ptr, vertex_size) OUT_RINGp(ptr,vertex_size) +#else + +#define INV_VERT(i) (i==0?7:i-1) + +#define OUT_RING_VERT_RAW(ptr,vertex_size) do{ \ + /* if the vertex size is not null, we have at least pos attribute */ \ + OUT_RINGp((GLfloat *)(ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \ + OUT_RINGp((GLfloat *)(ptr), default_attr_size[_TNL_ATTRIB_POS]); \ +}while(0) + +#define OUT_RING_VERT(nmesa,ptr,vertex_size) do{ \ + if (nmesa->screen->card->type>=NV_20) \ + OUT_RINGp(ptr, vertex_size); \ + else \ + OUT_RING_VERT_RAW(ptr, vertex_size); \ +}while(0) -static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) + +#define OUT_RING_VERTp(nmesa, ptr,sz, vertex_size) do{ \ + int nb_vert; \ + if (nmesa->screen->card->type>=NV_20) \ + OUT_RINGp(ptr, sz); \ + else \ + for (nb_vert = 0; nb_vert < (sz)/(vertex_size); nb_vert++) { \ + OUT_RING_VERT_RAW((GLfloat*)(ptr)+nb_vert*(vertex_size), vertex_size); \ + } \ +}while(0) + +#endif + + +static inline void nv10StartPrimitive(struct nouveau_context* nmesa,GLuint primitive,GLuint size) { - if (nmesa->screen->card->type==NV_10) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -66,7 +110,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); OUT_RING(primitive); - if (nmesa->screen->card->type==NV_10) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size); else if (nmesa->screen->card->type==NV_20) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); @@ -74,9 +118,9 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); } -inline void nv10FinishPrimitive(struct nouveau_context *nmesa) +void nv10FinishPrimitive(struct nouveau_context *nmesa) { - if (nmesa->screen->card->type==NV_10) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -103,13 +147,13 @@ static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start)/4; + GLuint size_dword = vertsize*(count-start); nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); - OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword); + OUT_RING_VERTp(nmesa, (nouveauVertex*)(vertptr+(start*vertsize)),size_dword, vertsize); nv10FinishPrimitive(nmesa); } @@ -189,16 +233,16 @@ static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *, static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start)/4; + GLuint size_dword = vertsize*(count-start); const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; GLuint j; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); for (j=start; j<count; j++ ) { - OUT_RINGp((nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize/4); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize); } nv10FinishPrimitive(nmesa); } @@ -288,77 +332,80 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) -static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +static inline void nv10_render_point(GLcontext *ctx, GLfloat *vertptr) { + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize; -} - -static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint *tmp = VB->Elts; - VB->Elts = (GLuint *)elts; - nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON ); - VB->Elts = tmp; + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_POINTS+1,size_dword); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr),vertsize); + nv10FinishPrimitive(nmesa); } static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) { - WARN_ONCE("Unimplemented\n"); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLfloat *vertptr = (GLfloat *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint i; + + if (VB->Elts) { + for (i = first; i < last; i++) + if (VB->ClipMask[VB->Elts[i]] == 0) + nv10_render_point(ctx, vertptr + (VB->Elts[i]*vertsize)); + } + else { + for (i = first; i < last; i++) + if (VB->ClipMask[i] == 0) + nv10_render_point(ctx, vertptr + (i*vertsize)); + } } static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(2)/4; - - /* OUT_RINGp wants size in DWORDS */ - vertsize >>= 2; + GLuint size_dword = vertsize*2; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,GL_LINES+1,size_dword); - OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); - OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); nv10FinishPrimitive(nmesa); } static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(3)/4; - - /* OUT_RINGp wants size in DWORDS */ - vertsize >>= 2; + GLuint size_dword = vertsize*3; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword); - OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); - OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); - OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); nv10FinishPrimitive(nmesa); } static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(4)/4; - - /* OUT_RINGp wants size in DWORDS */ - vertsize >>= 2; + GLuint size_dword = vertsize*4; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword); - OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); - OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); - OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); - OUT_RINGp((nouveauVertex*)(vertptr+(v4*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v4*vertsize)),vertsize); nv10FinishPrimitive(nmesa); } @@ -371,8 +418,8 @@ static void nv10ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; - tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; - tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; tnl->Driver.Render.Points = nv10_render_points; tnl->Driver.Render.Line = nv10_render_line; tnl->Driver.Render.Triangle = nv10_render_triangle; @@ -388,7 +435,12 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) DECLARE_RENDERINPUTS(index); struct vertex_buffer *VB = &tnl->vb; int attr_size[16]; - int default_attr_size[8]={3,3,3,4,3,1,4,4}; + const int nv10_vtx_attribs[8]={ + _TNL_ATTRIB_FOG, _TNL_ATTRIB_WEIGHT, + _TNL_ATTRIB_NORMAL, _TNL_ATTRIB_TEX1, + _TNL_ATTRIB_TEX0, _TNL_ATTRIB_COLOR1, + _TNL_ATTRIB_COLOR0, _TNL_ATTRIB_POS + }; int i; int slots=0; int total_size=0; @@ -417,31 +469,55 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) /* * Tell t_vertex about the vertex format */ - for(i=0;i<16;i++) - { - if (RENDERINPUTS_TEST(index, i)) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { + for(i=0;i<8;i++) { + int j = nv10_vtx_attribs[INV_VERT(i)]; + if (RENDERINPUTS_TEST(index, j)) { + switch(attr_size[j]) + { + case 1: + EMIT_ATTR(j,EMIT_1F); + break; + case 2: + EMIT_ATTR(j,EMIT_2F); + break; + case 3: + EMIT_ATTR(j,EMIT_3F); + break; + case 4: + EMIT_ATTR(j,EMIT_4F); + break; + } + total_size+=attr_size[j]; + } + } + } else { + for(i=0;i<16;i++) { - slots=i+1; - switch(attr_size[i]) + if (RENDERINPUTS_TEST(index, i)) { - case 1: - EMIT_ATTR(i,EMIT_1F); - break; - case 2: - EMIT_ATTR(i,EMIT_2F); - break; - case 3: - EMIT_ATTR(i,EMIT_3F); - break; - case 4: - EMIT_ATTR(i,EMIT_4F); - break; + slots=i+1; + switch(attr_size[i]) + { + case 1: + EMIT_ATTR(i,EMIT_1F); + break; + case 2: + EMIT_ATTR(i,EMIT_2F); + break; + case 3: + EMIT_ATTR(i,EMIT_3F); + break; + case 4: + EMIT_ATTR(i,EMIT_4F); + break; + } + if (i==_TNL_ATTRIB_COLOR0) + nmesa->color_offset=total_size; + if (i==_TNL_ATTRIB_COLOR1) + nmesa->specular_offset=total_size; + total_size+=attr_size[i]; } - if (i==_TNL_ATTRIB_COLOR0) - nmesa->color_offset=total_size; - if (i==_TNL_ATTRIB_COLOR1) - nmesa->specular_offset=total_size; - total_size+=attr_size[i]; } } @@ -449,33 +525,32 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) nmesa->vertex_attrs, nmesa->vertex_attr_count, NULL, 0 ); - assert(nmesa->vertex_size==total_size*4); + /* OUT_RINGp wants size in DWORDS */ + nmesa->vertex_size = nmesa->vertex_size / 4; + assert(nmesa->vertex_size==total_size); /* * Tell the hardware about the vertex format */ - if (nmesa->screen->card->type==NV_10) { - int size; + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { + int total_stride = 0; #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2 -#define NV10_SET_VERTEX_ATTRIB(i,j) \ - do { \ - size = attr_size[j] << 4; \ - size |= (attr_size[j]*4) << 8; \ - size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \ - OUT_RING_CACHE(size); \ - } while (0) - - NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); - NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); - NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); - NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0); - NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1); - NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); - NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); - NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); + for(i=0;i<8;i++) { + int j = nv10_vtx_attribs[i]; + int size; + int stride = attr_size[j] << 2; + if (j==_TNL_ATTRIB_POS) { + stride += total_stride; + } + size = attr_size[j] << 4; + size |= stride << 8; + size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR((7-i)),1); + OUT_RING_CACHE(size); + total_stride += stride; + } BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1); OUT_RING_CACHE(0); @@ -489,7 +564,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) } else { BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1); OUT_RING(0); - BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); + BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR8_TX0,slots); for(i=0;i<slots;i++) { int size=attr_size[i]; |