From 57ebdba06567bd59ce7246471c129fb36b5b1de3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 28 Nov 2008 19:38:47 +1000 Subject: [PATCH] intel: restore old vertex submit paths for i8xx hardware. For some reason the Intel 865 seem to claim VBO support in the docs, but doesn't seem to practice it in the hardware, or there is some missing errata. This restores the old pre-vbo code and uses it on all 8xx hw. --- src/mesa/drivers/dri/i915/intel_render.c | 25 ++++++- src/mesa/drivers/dri/i915/intel_tris.c | 98 +++++++++++++++++++++++++++- src/mesa/drivers/dri/intel/intel_context.h | 1 + src/mesa/drivers/dri/intel/intel_reg.h | 4 +- src/mesa/drivers/dri/intel/intel_screen.c | 1 + src/mesa/drivers/dri/intel/intel_screen.h | 1 + 6 files changed, 124 insertions(+), 6 deletions(-) diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index 467abe4..410052b 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -117,6 +117,26 @@ intelDmaPrimitive(struct intel_context *intel, GLenum prim) intel_set_prim(intel, hw_prim[prim]); } +static inline GLuint intel_get_vb_max(struct intel_context *intel) +{ + GLuint ret; + + if (intel->intelScreen->no_vbo) + ret = intel->batch->size - 1500; + else + ret = INTEL_VB_SIZE; + ret /= (intel->vertex_size * 4); + return ret; +} + +static inline GLuint intel_get_current_max(struct intel_context *intel) +{ + + if (intel->intelScreen->no_vbo) + return intel_get_vb_max(intel); + else + return (INTEL_VB_SIZE - intel->prim.current_offset) / (intel->vertex_size * 4); +} #define LOCAL_VARS struct intel_context *intel = intel_context(ctx) #define INIT( prim ) \ @@ -126,9 +146,8 @@ do { \ #define FLUSH() INTEL_FIREVERTICES(intel) -#define GET_SUBSEQUENT_VB_MAX_VERTS() (INTEL_VB_SIZE / (intel->vertex_size * 4)) -#define GET_CURRENT_VB_MAX_VERTS() \ - ((INTEL_VB_SIZE - intel->prim.current_offset) / (intel->vertex_size * 4)) +#define GET_SUBSEQUENT_VB_MAX_VERTS() intel_get_vb_max(intel) +#define GET_CURRENT_VB_MAX_VERTS() intel_get_current_max(intel) #define ALLOC_VERTS(nr) intel_get_prim_space(intel, nr) diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index 797d6c5..52f38e0 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -61,9 +61,101 @@ static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim); +static void +intel_flush_inline_primitive(struct intel_context *intel) +{ + GLuint used = intel->batch->ptr - intel->prim.start_ptr; + + assert(intel->prim.primitive != ~0); + +/* _mesa_printf("/\n"); */ + + if (used < 8) + goto do_discard; + + *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | + intel->prim.primitive | (used / 4 - 2)); + + goto finished; + + do_discard: + intel->batch->ptr -= used; + + finished: + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; +} + +static void intel_start_inline(struct intel_context *intel, uint32_t prim) +{ + BATCH_LOCALS; + uint32_t batch_flags = LOOP_CLIPRECTS; + + intel_wait_flips(intel); + intel->vtbl.emit_state(intel); + + intel->no_batch_wrap = GL_TRUE; + + /*_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); + + intel->prim.start_ptr = intel->batch->ptr; + intel->prim.primitive = prim; + intel->prim.flush = intel_flush_inline_primitive; + + OUT_BATCH(0); + ADVANCE_BATCH(); + + intel->no_batch_wrap = GL_FALSE; +/* _mesa_printf(">"); */ +} + +static void intel_wrap_inline(struct intel_context *intel) +{ + GLuint prim = intel->prim.primitive; + + intel_flush_inline_primitive(intel); + intel_batchbuffer_flush(intel->batch); + intel_start_inline(intel, prim); /* ??? */ +} + +static GLuint *intel_extend_inline(struct intel_context *intel, GLuint dwords) +{ + GLuint sz = dwords * sizeof(GLuint); + GLuint *ptr; + + assert(intel->prim.flush == intel_flush_inline_primitive); + + if (intel_batchbuffer_space(intel->batch) < sz) + intel_wrap_inline(intel); + +/* _mesa_printf("."); */ + + intel->vtbl.assert_not_dirty(intel); + + ptr = (GLuint *) intel->batch->ptr; + intel->batch->ptr += sz; + + return ptr; +} + /** Sets the primitive type for a primitive sequence, flushing as needed. */ void intel_set_prim(struct intel_context *intel, uint32_t prim) { + /* if we have no VBOs */ + + if (intel->intelScreen->no_vbo) { + intel_start_inline(intel, prim); + return; + } if (prim != intel->prim.primitive) { INTEL_FIREVERTICES(intel); intel->prim.primitive = prim; @@ -75,6 +167,10 @@ uint32_t *intel_get_prim_space(struct intel_context *intel, unsigned int count) { uint32_t *addr; + if (intel->intelScreen->no_vbo) { + return intel_extend_inline(intel, count * intel->vertex_size); + } + /* Check for space in the existing VB */ if (intel->prim.vb_bo == NULL || (intel->prim.current_offset + @@ -155,7 +251,7 @@ void intel_flush_prim(struct intel_context *intel) #if 0 printf("emitting %d..%d=%d vertices size %d\n", offset, - intel->prim.current_offset, intel->prim.count, + intel->prim.current_offset, count, intel->vertex_size * 4); #endif diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 3938af4..4d1f0d7 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -184,6 +184,7 @@ struct intel_context GLuint id; uint32_t primitive; /**< Current hardware primitive type */ void (*flush) (struct intel_context *); + GLubyte *start_ptr; /**< for i8xx */ dri_bo *vb_bo; uint8_t *vb; unsigned int start_offset; /**< Byte offset of primitive sequence */ diff --git a/src/mesa/drivers/dri/intel/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h index 68d8a05..57ac8f0 100644 --- a/src/mesa/drivers/dri/intel/intel_reg.h +++ b/src/mesa/drivers/dri/intel/intel_reg.h @@ -71,14 +71,14 @@ /** @{ * 915 definitions */ -#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_VB_OFFSET_MASK 0xffffffc0 #define S0_AUTO_CACHE_INV_DISABLE (1<<0) /** @} */ /** @{ * 830 definitions */ -#define S0_VB_OFFSET_MASK_830 0xffffff8 +#define S0_VB_OFFSET_MASK_830 0xffffff80 #define S0_VB_PITCH_SHIFT_830 1 #define S0_VB_ENABLE_830 (1<<0) /** @} */ diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index cf09fad..61b55b9 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -461,6 +461,7 @@ intelCreateContext(const __GLcontextModes * mesaVis, sharedContextPrivate); } } else { + intelScreen->no_vbo = GL_TRUE; return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); } #else diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h index fc913da..91f0d6d 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.h +++ b/src/mesa/drivers/dri/intel/intel_screen.h @@ -77,6 +77,7 @@ typedef struct GLboolean no_hw; + GLboolean no_vbo; int ttm; dri_bufmgr *bufmgr; -- 1.6.0.3