summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i915/intel_tris.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i915/intel_tris.c')
-rw-r--r--src/mesa/drivers/dri/i915/intel_tris.c237
1 files changed, 76 insertions, 161 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c
index 5f4b852212..bbb4e0f3cd 100644
--- a/src/mesa/drivers/dri/i915/intel_tris.c
+++ b/src/mesa/drivers/dri/i915/intel_tris.c
@@ -25,12 +25,6 @@
*
**************************************************************************/
-/** @file intel_tris.c
- *
- * This file contains functions for managing the vertex buffer and emitting
- * primitives into it.
- */
-
#include "glheader.h"
#include "context.h"
#include "macros.h"
@@ -53,185 +47,111 @@
#include "intel_reg.h"
#include "intel_span.h"
#include "intel_tex.h"
-#include "intel_chipset.h"
-#include "i830_context.h"
-#include "i830_reg.h"
static void intelRenderPrimitive(GLcontext * ctx, GLenum prim);
static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim,
GLuint hwprim);
-/** Sets the primitive type for a primitive sequence, flushing as needed. */
-void intel_set_prim(struct intel_context *intel, uint32_t prim)
+/*
+ */
+static void
+intel_flush_inline_primitive(struct intel_context *intel)
{
- if (prim != intel->prim.primitive) {
- INTEL_FIREVERTICES(intel);
- intel->prim.primitive = prim;
- }
-}
+ GLuint used = intel->batch->ptr - intel->prim.start_ptr;
-/** Returns mapped VB space for the given number of vertices */
-uint32_t *intel_get_prim_space(struct intel_context *intel, unsigned int count)
-{
- uint32_t *addr;
-
- /* Check for space in the existing VB */
- if (intel->prim.vb_bo == NULL ||
- (intel->prim.current_offset +
- count * intel->vertex_size * 4) > INTEL_VB_SIZE ||
- (intel->prim.count + count) >= (1 << 16)) {
- /* Flush existing prim if any */
- INTEL_FIREVERTICES(intel);
+ assert(intel->prim.primitive != ~0);
- intel_finish_vb(intel);
+/* _mesa_printf("/\n"); */
- /* Start a new VB */
- if (intel->prim.vb == NULL)
- intel->prim.vb = malloc(INTEL_VB_SIZE);
- intel->prim.vb_bo = dri_bo_alloc(intel->bufmgr, "vb",
- INTEL_VB_SIZE, 4);
- intel->prim.start_offset = 0;
- intel->prim.current_offset = 0;
- }
+ if (used < 8)
+ goto do_discard;
+
+ *(int *) intel->prim.start_ptr = (_3DPRIMITIVE |
+ intel->prim.primitive | (used / 4 - 2));
- intel->prim.flush = intel_flush_prim;
+ goto finished;
- addr = (uint32_t *)(intel->prim.vb + intel->prim.current_offset);
- intel->prim.current_offset += intel->vertex_size * 4 * count;
- intel->prim.count += count;
+ do_discard:
+ intel->batch->ptr -= used;
- return addr;
+ finished:
+ intel->prim.primitive = ~0;
+ intel->prim.start_ptr = 0;
+ intel->prim.flush = 0;
}
-/** Dispatches the accumulated primitive to the batchbuffer. */
-void intel_flush_prim(struct intel_context *intel)
+
+/* Emit a primitive referencing vertices in a vertex buffer.
+ */
+void
+intelStartInlinePrimitive(struct intel_context *intel,
+ GLuint prim, GLuint batch_flags)
{
BATCH_LOCALS;
- dri_bo *aper_array[2];
- dri_bo *vb_bo;
-
- /* Must be called after an intel_start_prim. */
- assert(intel->prim.primitive != ~0);
-
- if (intel->prim.count == 0)
- return;
-
- /* Keep a reference on the BO as it may get finished as we start the
- * batch emit.
- */
- vb_bo = intel->prim.vb_bo;
- dri_bo_reference(vb_bo);
intel_wait_flips(intel);
intel->vtbl.emit_state(intel);
- aper_array[0] = intel->batch->buf;
- aper_array[1] = vb_bo;
- if (dri_bufmgr_check_aperture_space(aper_array, 2)) {
- intel_batchbuffer_flush(intel->batch);
- intel->vtbl.emit_state(intel);
- }
-
- /* Ensure that we don't start a new batch for the following emit, which
- * depends on the state just emitted. emit_state should be making sure we
- * have the space for this.
- */
intel->no_batch_wrap = GL_TRUE;
- /* Check that we actually emitted the state into this batch, using the
- * UPLOAD_CTX bit as the signal.
+/* _mesa_printf("%s *", __progname); */
+
+ /* Emit a slot which will be filled with the inline primitive
+ * command later.
*/
+ BEGIN_BATCH(2, batch_flags);
+ OUT_BATCH(0);
+
assert((intel->batch->dirty_state & (1<<1)) == 0);
-#if 0
- printf("emitting %d..%d=%d vertices size %d\n", intel->prim.start_offset,
- intel->prim.current_offset, intel->prim.count,
- intel->vertex_size * 4);
-#endif
+ intel->prim.start_ptr = intel->batch->ptr;
+ intel->prim.primitive = prim;
+ intel->prim.flush = intel_flush_inline_primitive;
- if (IS_9XX(intel->intelScreen->deviceID)) {
- BEGIN_BATCH(5, LOOP_CLIPRECTS);
- OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
- I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
- assert((intel->prim.start_offset & !S0_VB_OFFSET_MASK) == 0);
- OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
- intel->prim.start_offset);
- OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) |
- (intel->vertex_size << S1_VERTEX_PITCH_SHIFT));
-
- OUT_BATCH(_3DPRIMITIVE |
- PRIM_INDIRECT |
- PRIM_INDIRECT_SEQUENTIAL |
- intel->prim.primitive |
- intel->prim.count);
- OUT_BATCH(0); /* Beginning vertex index */
- ADVANCE_BATCH();
- } else {
- struct i830_context *i830 = i830_context(&intel->ctx);
-
- BEGIN_BATCH(5, LOOP_CLIPRECTS);
- OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
- I1_LOAD_S(0) | I1_LOAD_S(2) | 1);
- /* S0 */
- assert((intel->prim.start_offset & !S0_VB_OFFSET_MASK_830) == 0);
- OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
- intel->prim.start_offset |
- (intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
- S0_VB_ENABLE_830);
- /* S1
- * This is somewhat unfortunate -- VB width is tied up with
- * vertex format data that we've already uploaded through
- * _3DSTATE_VFT[01]_CMD. We may want to replace emits of VFT state with
- * STATE_IMMEDIATE_1 like this to avoid duplication.
- */
- OUT_BATCH((i830->state.Ctx[I830_CTXREG_VF] & VFT0_TEX_COUNT_MASK) >>
- VFT0_TEX_COUNT_SHIFT << S2_TEX_COUNT_SHIFT_830 |
- (i830->state.Ctx[I830_CTXREG_VF2] << 16) |
- intel->vertex_size << S2_VERTEX_0_WIDTH_SHIFT_830);
-
- OUT_BATCH(_3DPRIMITIVE |
- PRIM_INDIRECT |
- PRIM_INDIRECT_SEQUENTIAL |
- intel->prim.primitive |
- intel->prim.count);
- OUT_BATCH(0); /* Beginning vertex index */
- ADVANCE_BATCH();
- }
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
intel->no_batch_wrap = GL_FALSE;
- intel->prim.flush = NULL;
- intel->prim.start_offset = intel->prim.current_offset;
- if (!IS_9XX(intel->intelScreen->deviceID))
- intel->prim.start_offset = ALIGN(intel->prim.start_offset, 128);
- intel->prim.count = 0;
+/* _mesa_printf(">"); */
+}
+
+
+void
+intelWrapInlinePrimitive(struct intel_context *intel)
+{
+ GLuint prim = intel->prim.primitive;
+ enum cliprect_mode cliprect_mode = intel->batch->cliprect_mode;
- dri_bo_unreference(vb_bo);
+ intel_flush_inline_primitive(intel);
+ intel_batchbuffer_flush(intel->batch);
+ intelStartInlinePrimitive(intel, prim, cliprect_mode); /* ??? */
}
-/**
- * Uploads the locally-accumulated VB into the buffer object.
- *
- * This avoids us thrashing the cachelines in and out as the buffer gets
- * filled, dispatched, then reused as the hardware completes rendering from it,
- * and also lets us clflush less if we dispatch with a partially-filled VB.
- *
- * This is called normally from get_space when we're finishing a BO, but also
- * at batch flush time so that we don't try accessing the contents of a
- * just-dispatched buffer.
- */
-void intel_finish_vb(struct intel_context *intel)
+GLuint *
+intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords)
{
- if (intel->prim.vb_bo == NULL)
- return;
+ GLuint sz = dwords * sizeof(GLuint);
+ GLuint *ptr;
+
+ assert(intel->prim.flush == intel_flush_inline_primitive);
+
+ if (intel_batchbuffer_space(intel->batch) < sz)
+ intelWrapInlinePrimitive(intel);
+
+/* _mesa_printf("."); */
+
+ intel->vtbl.assert_not_dirty(intel);
- dri_bo_subdata(intel->prim.vb_bo, 0, intel->prim.start_offset,
- intel->prim.vb);
- dri_bo_unreference(intel->prim.vb_bo);
- intel->prim.vb_bo = NULL;
+ ptr = (GLuint *) intel->batch->ptr;
+ intel->batch->ptr += sz;
+
+ return ptr;
}
+
+
/***********************************************************************
* Emit primitives as inline vertices *
***********************************************************************/
@@ -262,7 +182,7 @@ intel_draw_quad(struct intel_context *intel,
intelVertexPtr v1, intelVertexPtr v2, intelVertexPtr v3)
{
GLuint vertsize = intel->vertex_size;
- GLuint *vb = intel_get_prim_space(intel, 6);
+ GLuint *vb = intelExtendInlinePrimitive(intel, 6 * vertsize);
int j;
COPY_DWORDS(j, vb, vertsize, v0);
@@ -290,7 +210,7 @@ intel_draw_triangle(struct intel_context *intel,
intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2)
{
GLuint vertsize = intel->vertex_size;
- GLuint *vb = intel_get_prim_space(intel, 3);
+ GLuint *vb = intelExtendInlinePrimitive(intel, 3 * vertsize);
int j;
COPY_DWORDS(j, vb, vertsize, v0);
@@ -304,7 +224,7 @@ intel_draw_line(struct intel_context *intel,
intelVertexPtr v0, intelVertexPtr v1)
{
GLuint vertsize = intel->vertex_size;
- GLuint *vb = intel_get_prim_space(intel, 2);
+ GLuint *vb = intelExtendInlinePrimitive(intel, 2 * vertsize);
int j;
COPY_DWORDS(j, vb, vertsize, v0);
@@ -316,7 +236,7 @@ static void
intel_draw_point(struct intel_context *intel, intelVertexPtr v0)
{
GLuint vertsize = intel->vertex_size;
- GLuint *vb = intel_get_prim_space(intel, 1);
+ GLuint *vb = intelExtendInlinePrimitive(intel, vertsize);
int j;
/* Adjust for sub pixel position -- still required for conform. */
@@ -825,7 +745,7 @@ intelFastRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n)
{
struct intel_context *intel = intel_context(ctx);
const GLuint vertsize = intel->vertex_size;
- GLuint *vb = intel_get_prim_space(intel, (n - 2) * 3);
+ GLuint *vb = intelExtendInlinePrimitive(intel, (n - 2) * 3 * vertsize);
GLubyte *vertptr = (GLubyte *) intel->verts;
const GLuint *start = (const GLuint *) V(elts[0]);
int i, j;
@@ -1030,7 +950,7 @@ intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim)
if (hwprim != intel->prim.primitive) {
INTEL_FIREVERTICES(intel);
- intel_set_prim(intel, hwprim);
+ intelStartInlinePrimitive(intel, hwprim, LOOP_CLIPRECTS);
}
}
@@ -1163,18 +1083,15 @@ intel_meta_draw_poly(struct intel_context *intel,
union fi *vb;
GLint i;
GLboolean was_locked = intel->locked;
- unsigned int saved_vertex_size = intel->vertex_size;
if (!was_locked)
LOCK_HARDWARE(intel);
- intel->vertex_size = 6;
-
/* All 3d primitives should be emitted with LOOP_CLIPRECTS,
* otherwise the drawing origin (DR4) might not be set correctly.
*/
- intel_set_prim(intel, PRIM3D_TRIFAN);
- vb = (union fi *) intel_get_prim_space(intel, n);
+ intelStartInlinePrimitive(intel, PRIM3D_TRIFAN, LOOP_CLIPRECTS);
+ vb = (union fi *) intelExtendInlinePrimitive(intel, n * 6);
for (i = 0; i < n; i++) {
vb[0].f = xy[i][0];
@@ -1188,8 +1105,6 @@ intel_meta_draw_poly(struct intel_context *intel,
INTEL_FIREVERTICES(intel);
- intel->vertex_size = saved_vertex_size;
-
if (!was_locked)
UNLOCK_HARDWARE(intel);
}