diff options
Diffstat (limited to 'src/mesa/drivers/dri/r300/r300_render.c')
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_render.c | 233 |
1 files changed, 96 insertions, 137 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index a118dab740..1aaf43bfaf 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -45,6 +45,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * obviously this does work... Further investigation is needed. * * \author Nicolai Haehnle <prefect_@gmx.net> + * + * \todo Add immediate implementation back? Perhaps this is useful if there are + * no bugs... */ #include "glheader.h" @@ -70,7 +73,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_reg.h" #include "r300_tex.h" -#include "r300_maos.h" #include "r300_emit.h" extern int future_hw_tcl_on; @@ -79,47 +81,42 @@ extern int future_hw_tcl_on; */ static int r300PrimitiveType(r300ContextPtr rmesa, GLcontext * ctx, int prim) { - int type = -1; - switch (prim & PRIM_MODE_MASK) { case GL_POINTS: - type = R300_VAP_VF_CNTL__PRIM_POINTS; + return R300_VAP_VF_CNTL__PRIM_POINTS; break; case GL_LINES: - type = R300_VAP_VF_CNTL__PRIM_LINES; + return R300_VAP_VF_CNTL__PRIM_LINES; break; case GL_LINE_STRIP: - type = R300_VAP_VF_CNTL__PRIM_LINE_STRIP; + return R300_VAP_VF_CNTL__PRIM_LINE_STRIP; break; case GL_LINE_LOOP: - type = R300_VAP_VF_CNTL__PRIM_LINE_LOOP; + return R300_VAP_VF_CNTL__PRIM_LINE_LOOP; break; case GL_TRIANGLES: - type = R300_VAP_VF_CNTL__PRIM_TRIANGLES; + return R300_VAP_VF_CNTL__PRIM_TRIANGLES; break; case GL_TRIANGLE_STRIP: - type = R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP; + return R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP; break; case GL_TRIANGLE_FAN: - type = R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN; + return R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN; break; case GL_QUADS: - type = R300_VAP_VF_CNTL__PRIM_QUADS; + return R300_VAP_VF_CNTL__PRIM_QUADS; break; case GL_QUAD_STRIP: - type = R300_VAP_VF_CNTL__PRIM_QUAD_STRIP; + return R300_VAP_VF_CNTL__PRIM_QUAD_STRIP; break; case GL_POLYGON: - type = R300_VAP_VF_CNTL__PRIM_POLYGON; + return R300_VAP_VF_CNTL__PRIM_POLYGON; break; default: - fprintf(stderr, - "%s:%s Do not know how to handle primitive 0x%04x - help me !\n", - __FILE__, __FUNCTION__, prim & PRIM_MODE_MASK); + assert(0); return -1; break; } - return type; } static int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) @@ -166,89 +163,103 @@ static int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) verts_off = num_verts; break; default: - fprintf(stderr, - "%s:%s Do not know how to handle primitive 0x%04x - help me !\n", - __FILE__, __FUNCTION__, prim & PRIM_MODE_MASK); + assert(0); return -1; break; } - if (num_verts - verts_off == 0) { - WARN_ONCE - ("user error: Need more than %d vertices to draw primitive 0x%04x !\n", - num_verts, prim & PRIM_MODE_MASK); - return -1; - } + return num_verts - verts_off; +} - if (verts_off > 0) { - WARN_ONCE - ("user error: %d is not a valid number of vertices for primitive 0x%04x !\n", - num_verts, prim & PRIM_MODE_MASK); - return -1; +static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + struct r300_dma_region *rvb = &rmesa->state.elt_dma; + void *out; + + if (r300IsGartMemory(rmesa, elts, n_elts * 4)) { + rvb->address = rmesa->radeon.radeonScreen->gartTextures.map; + rvb->start = ((char *)elts) - rvb->address; + rvb->aos_offset = + rmesa->radeon.radeonScreen->gart_texture_offset + + rvb->start; + return; + } else if (r300IsGartMemory(rmesa, elts, 1)) { + WARN_ONCE("Pointer not within GART memory!\n"); + _mesa_exit(-1); } - return num_verts - verts_off; + r300AllocDmaRegion(rmesa, rvb, n_elts * 4, 4); + rvb->aos_offset = GET_START(rvb); + + out = rvb->address + rvb->start; + memcpy(out, elts, n_elts * 4); } -static void inline r300FireEB(r300ContextPtr rmesa, unsigned long addr, - int vertex_count, int type, int elt_size) +static void r300FireEB(r300ContextPtr rmesa, unsigned long addr, + int vertex_count, int type) { int cmd_reserved = 0; int cmd_written = 0; drm_radeon_cmd_header_t *cmd = NULL; - unsigned long t_addr; - unsigned long magic_1, magic_2; - assert(elt_size == 2 || elt_size == 4); + start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0), 0); + e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); - if (addr & (elt_size - 1)) { - WARN_ONCE("Badly aligned buffer\n"); - return; - } + start_packet3(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2), 2); + e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); + e32(addr); + e32(vertex_count); +} + +static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) +{ + int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; + int i; + int cmd_reserved = 0; + int cmd_written = 0; + drm_radeon_cmd_header_t *cmd = NULL; - magic_1 = (addr % 32) / 4; - t_addr = addr & ~0x1d; - magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1; + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr, + offset); - start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0); - if (elt_size == 4) { - e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | - (vertex_count << 16) | type | - R300_VAP_VF_CNTL__INDEX_SIZE_32bit); - } else { - e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | - (vertex_count << 16) | type); - } + start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1), sz - 1); + e32(nr); - start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2); -#ifdef OPTIMIZE_ELTS - if (elt_size == 4) { - e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); - e32(addr); - } else { - e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2); - e32(t_addr); + for (i = 0; i + 1 < nr; i += 2) { + e32((rmesa->state.aos[i].aos_size << 0) | + (rmesa->state.aos[i].aos_stride << 8) | + (rmesa->state.aos[i + 1].aos_size << 16) | + (rmesa->state.aos[i + 1].aos_stride << 24)); + + e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride); + e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride); } -#else - e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); - e32(addr); -#endif - if (elt_size == 4) { - e32(vertex_count); - } else { -#ifdef OPTIMIZE_ELTS - e32(magic_2); -#else - e32((vertex_count + 1) / 2); -#endif + if (nr & 1) { + e32((rmesa->state.aos[nr - 1].aos_size << 0) | + (rmesa->state.aos[nr - 1].aos_stride << 8)); + e32(rmesa->state.aos[nr - 1].aos_offset + offset * 4 * rmesa->state.aos[nr - 1].aos_stride); } } +static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type) +{ + int cmd_reserved = 0; + int cmd_written = 0; + drm_radeon_cmd_header_t *cmd = NULL; + + start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0); + e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type); +} + static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, int start, int end, int prim) { int type, num_verts; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *vb = &tnl->vb; type = r300PrimitiveType(rmesa, ctx, prim); num_verts = r300NumVerts(rmesa, end - start, prim); @@ -256,88 +267,37 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, if (type < 0 || num_verts <= 0) return; - if (rmesa->state.VB.Elts) { + if (vb->Elts) { r300EmitAOS(rmesa, rmesa->state.aos_count, start); if (num_verts > 65535) { /* not implemented yet */ WARN_ONCE("Too many elts\n"); return; } - r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, - rmesa->state.VB.elt_size); - r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset, - num_verts, type, rmesa->state.VB.elt_size); + r300EmitElts(ctx, vb->Elts, num_verts); + r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type); } else { r300EmitAOS(rmesa, rmesa->state.aos_count, start); - fire_AOS(rmesa, num_verts, type); - } -} - -#define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \ - rvb->AttribPtr[(a)].type = GL_FLOAT, \ - rvb->AttribPtr[(a)].stride = vb->b->stride, \ - rvb->AttribPtr[(a)].data = vb->b->data - -static void radeon_vb_to_rvb(r300ContextPtr rmesa, - struct radeon_vertex_buffer *rvb, - struct vertex_buffer *vb) -{ - int i; - GLcontext *ctx; - ctx = rmesa->radeon.glCtx; - - memset(rvb, 0, sizeof(*rvb)); - - rvb->Elts = vb->Elts; - rvb->elt_size = 4; - rvb->elt_min = 0; - rvb->elt_max = vb->Count; - - rvb->Count = vb->Count; - - if (hw_tcl_on) { - CONV_VB(VERT_ATTRIB_POS, ObjPtr); - } else { - assert(vb->ClipPtr); - CONV_VB(VERT_ATTRIB_POS, ClipPtr); + r300FireAOS(rmesa, num_verts, type); } - - CONV_VB(VERT_ATTRIB_NORMAL, NormalPtr); - CONV_VB(VERT_ATTRIB_COLOR0, ColorPtr[0]); - CONV_VB(VERT_ATTRIB_COLOR1, SecondaryColorPtr[0]); - CONV_VB(VERT_ATTRIB_FOG, FogCoordPtr); - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) - CONV_VB(VERT_ATTRIB_TEX0 + i, TexCoordPtr[i]); - - for (i = 0; i < MAX_VERTEX_PROGRAM_ATTRIBS; i++) - CONV_VB(VERT_ATTRIB_GENERIC0 + i, - AttribPtr[VERT_ATTRIB_GENERIC0 + i]); - - rvb->Primitive = vb->Primitive; - rvb->PrimitiveCount = vb->PrimitiveCount; - rvb->LockFirst = rvb->LockCount = 0; - rvb->lock_uptodate = GL_FALSE; } static GLboolean r300RunRender(GLcontext * ctx, struct tnl_pipeline_stage *stage) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct radeon_vertex_buffer *VB = &rmesa->state.VB; int i; int cmd_reserved = 0; int cmd_written = 0; drm_radeon_cmd_header_t *cmd = NULL; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *vb = &tnl->vb; if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); - if (stage) { - TNLcontext *tnl = TNL_CONTEXT(ctx); - radeon_vb_to_rvb(rmesa, VB, &tnl->vb); - } - + if (hw_tcl_on == GL_FALSE) + vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr; r300UpdateShaders(rmesa); if (r300EmitArrays(ctx)) return GL_TRUE; @@ -352,11 +312,10 @@ static GLboolean r300RunRender(GLcontext * ctx, r300EmitState(rmesa); - for (i = 0; i < VB->PrimitiveCount; i++) { - GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); - GLuint start = VB->Primitive[i].start; - GLuint length = VB->Primitive[i].count; - GLuint end = VB->Primitive[i].start + VB->Primitive[i].count; + for (i = 0; i < vb->PrimitiveCount; i++) { + GLuint prim = _tnl_translate_prim(&vb->Primitive[i]); + GLuint start = vb->Primitive[i].start; + GLuint end = vb->Primitive[i].start + vb->Primitive[i].count; r300RunRenderPrimitive(rmesa, ctx, start, end, prim); } |