summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/r300_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r300/r300_render.c')
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c233
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);
}