From: Chris Wilson Date: Thu, 10 Feb 2011 20:25:51 +0000 (+0000) Subject: intel: use pwrite for batch X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8d68a90e225d831a395ba788e425cb717eec1f9a;p=mesa.git intel: use pwrite for batch It's faster. Not only is the memcpy more efficiently performed in the kernel (making up for the system call overhead), but by not using mmap we remove the greater overhead of tracking the vma of every batch. And it means we can read back from the batch buffer without incurring the cost of a uncached read through the GTT. Signed-off-by: Chris Wilson --- diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index ebdefeac874..19f08077599 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -364,7 +364,7 @@ i830_emit_invarient_state(struct intel_context *intel) #define emit( intel, state, size ) \ - intel_batchbuffer_data(intel->batch, state, size, false) + intel_batchbuffer_data(intel, state, size, false) static GLuint get_dirty(struct i830_hw_state *state) @@ -428,7 +428,7 @@ i830_emit_state(struct intel_context *intel) * scheduling is allowed, rather than assume that it is whenever a * batchbuffer fills up. */ - intel_batchbuffer_require_space(intel->batch, + intel_batchbuffer_require_space(intel, get_state_size(state) + INTEL_PRIM_EMIT_SIZE, false); count = 0; @@ -436,7 +436,7 @@ i830_emit_state(struct intel_context *intel) aper_count = 0; dirty = get_dirty(state); - aper_array[aper_count++] = intel->batch->buf; + aper_array[aper_count++] = intel->batch.bo; if (dirty & I830_UPLOAD_BUFFERS) { aper_array[aper_count++] = state->draw_region->buffer; if (state->depth_region) @@ -453,7 +453,7 @@ i830_emit_state(struct intel_context *intel) if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) { if (count == 0) { count++; - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); goto again; } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "i830 emit state"); @@ -556,9 +556,7 @@ i830_emit_state(struct intel_context *intel) } } - intel->batch->dirty_state &= ~dirty; assert(get_dirty(state) == 0); - assert((intel->batch->dirty_state & (1<<1)) == 0); } static void diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index a94b9571275..394935c96cc 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -217,7 +217,7 @@ i915_emit_invarient_state(struct intel_context *intel) #define emit(intel, state, size ) \ - intel_batchbuffer_data(intel->batch, state, size, false) + intel_batchbuffer_data(intel, state, size, false) static GLuint get_dirty(struct i915_hw_state *state) @@ -299,7 +299,7 @@ i915_emit_state(struct intel_context *intel) * scheduling is allowed, rather than assume that it is whenever a * batchbuffer fills up. */ - intel_batchbuffer_require_space(intel->batch, + intel_batchbuffer_require_space(intel, get_state_size(state) + INTEL_PRIM_EMIT_SIZE, false); count = 0; @@ -307,7 +307,7 @@ i915_emit_state(struct intel_context *intel) aper_count = 0; dirty = get_dirty(state); - aper_array[aper_count++] = intel->batch->buf; + aper_array[aper_count++] = intel->batch.bo; if (dirty & I915_UPLOAD_BUFFERS) { aper_array[aper_count++] = state->draw_region->buffer; if (state->depth_region) @@ -327,7 +327,7 @@ i915_emit_state(struct intel_context *intel) if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) { if (count == 0) { count++; - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); goto again; } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "i915 emit state"); @@ -476,9 +476,7 @@ i915_emit_state(struct intel_context *intel) } } - intel->batch->dirty_state &= ~dirty; assert(get_dirty(state) == 0); - assert((intel->batch->dirty_state & (1<<1)) == 0); } static void diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index 0d8ab4b507e..2d361ca0a9a 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -124,7 +124,7 @@ static INLINE GLuint intel_get_vb_max(struct intel_context *intel) GLuint ret; if (intel->intelScreen->no_vbo) - ret = intel->batch->size - 1500; + ret = sizeof(intel->batch.map) - 1500; else ret = INTEL_VB_SIZE; ret /= (intel->vertex_size * 4); diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index b9a8aeb12f2..c6b5a01885f 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -62,22 +62,22 @@ static void intelRasterPrimitive(struct gl_context * ctx, GLenum rprim, static void intel_flush_inline_primitive(struct intel_context *intel) { - GLuint used = intel->batch->ptr - intel->prim.start_ptr; + GLuint used = intel->batch.used - intel->prim.start_ptr; assert(intel->prim.primitive != ~0); /* printf("/\n"); */ - if (used < 8) + if (used < 2) goto do_discard; - *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | - intel->prim.primitive | (used / 4 - 2)); + intel->batch.map[intel->prim.start_ptr] = + _3DPRIMITIVE | intel->prim.primitive | (used - 2); goto finished; do_discard: - intel->batch->ptr -= used; + intel->batch.used = intel->prim.start_ptr; finished: intel->prim.primitive = ~0; @@ -100,9 +100,7 @@ static void intel_start_inline(struct intel_context *intel, uint32_t prim) */ BEGIN_BATCH(1); - assert((intel->batch->dirty_state & (1<<1)) == 0); - - intel->prim.start_ptr = intel->batch->ptr; + intel->prim.start_ptr = intel->batch.used; intel->prim.primitive = prim; intel->prim.flush = intel_flush_inline_primitive; @@ -118,26 +116,25 @@ 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_batchbuffer_flush(intel); 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) + if (intel_batchbuffer_space(intel) < dwords * sizeof(GLuint)) intel_wrap_inline(intel); /* printf("."); */ intel->vtbl.assert_not_dirty(intel); - ptr = (GLuint *) intel->batch->ptr; - intel->batch->ptr += sz; + ptr = intel->batch.map + intel->batch.used; + intel->batch.used += dwords; return ptr; } @@ -223,10 +220,10 @@ void intel_flush_prim(struct intel_context *intel) intel->vtbl.emit_state(intel); - aper_array[0] = intel->batch->buf; + aper_array[0] = intel->batch.bo; aper_array[1] = vb_bo; if (dri_bufmgr_check_aperture_space(aper_array, 2)) { - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); intel->vtbl.emit_state(intel); } @@ -236,11 +233,6 @@ void intel_flush_prim(struct intel_context *intel) */ intel->no_batch_wrap = GL_TRUE; - /* Check that we actually emitted the state into this batch, using the - * UPLOAD_CTX bit as the signal. - */ - assert((intel->batch->dirty_state & (1<<1)) == 0); - #if 0 printf("emitting %d..%d=%d vertices size %d\n", offset, intel->prim.current_offset, count, diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c index 408783a3e6a..c37376ef0de 100644 --- a/src/mesa/drivers/dri/i965/brw_cc.c +++ b/src/mesa/drivers/dri/i965/brw_cc.c @@ -214,7 +214,7 @@ static void upload_cc_unit(struct brw_context *brw) brw->state.dirty.cache |= CACHE_NEW_CC_UNIT; /* Emit CC viewport relocation */ - drm_intel_bo_emit_reloc(brw->intel.batch->buf, + drm_intel_bo_emit_reloc(brw->intel.batch.bo, (brw->cc.state_offset + offsetof(struct brw_cc_unit_state, cc4)), brw->cc.vp_bo, 0, diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 57d1d7bbe07..99c1b2b359c 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -155,14 +155,14 @@ static void brw_emit_prim(struct brw_context *brw, * the besides the draw code. */ if (intel->always_flush_cache) { - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); } if (prim_packet.verts_per_instance) { - intel_batchbuffer_data( brw->intel.batch, &prim_packet, + intel_batchbuffer_data(&brw->intel, &prim_packet, sizeof(prim_packet), false); } if (intel->always_flush_cache) { - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); } } @@ -303,7 +303,6 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx, struct brw_context *brw = brw_context(ctx); GLboolean retval = GL_FALSE; GLboolean warn = GL_FALSE; - GLboolean first_time = GL_TRUE; GLuint i; if (ctx->NewState) @@ -351,14 +350,10 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx, * an upper bound of how much we might emit in a single * brw_try_draw_prims(). */ - intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4, - false); + intel_batchbuffer_require_space(intel, 1024, false); hw_prim = brw_set_prim(brw, &prim[i]); - - if (first_time || (brw->state.dirty.brw & BRW_NEW_PRIMITIVE)) { - first_time = GL_FALSE; - + if (brw->state.dirty.brw) { brw_validate_state(brw); /* Various fallback checks: */ @@ -371,7 +366,7 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx, if (dri_bufmgr_check_aperture_space(brw->state.validated_bos, brw->state.validated_bo_count)) { static GLboolean warned; - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); /* Validate the state after we flushed the batch (which would have * changed the set of dirty state). If we still fail to @@ -400,7 +395,7 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx, } if (intel->always_flush_batch) - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); out: brw_state_cache_check_size(brw); diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index fb31b2c2d4b..c257b9c517e 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#undef NDEBUG #include "main/glheader.h" #include "main/bufferobj.h" @@ -298,6 +299,9 @@ static void brw_prepare_vertices(struct brw_context *brw) brw->vb.enabled[brw->vb.nr_enabled++] = input; } + if (brw->vb.nr_enabled == 0) + return; + /* XXX: In the rare cases where this happens we fallback all * the way to software rasterization, although a tnl fallback * would be sufficient. I don't know of *any* real world @@ -481,6 +485,7 @@ static void brw_emit_vertices(struct brw_context *brw) } ADVANCE_BATCH(); + BEGIN_BATCH(1 + brw->vb.nr_enabled * 2); OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2)); for (i = 0; i < brw->vb.nr_enabled; i++) { diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index fc4e18d9b2b..c5c74098246 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -151,7 +151,7 @@ static void upload_pipelined_state_pointers(struct brw_context *brw ) OUT_RELOC(brw->clip.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); OUT_RELOC(brw->sf.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_RELOC(brw->wm.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); - OUT_RELOC(brw->intel.batch->buf, I915_GEM_DOMAIN_INSTRUCTION, 0, + OUT_RELOC(brw->intel.batch.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, brw->cc.state_offset); ADVANCE_BATCH(); @@ -565,7 +565,7 @@ static void upload_state_base_address( struct brw_context *brw ) BEGIN_BATCH(10); OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2)); OUT_BATCH(1); /* General state base address */ - OUT_RELOC(intel->batch->buf, I915_GEM_DOMAIN_SAMPLER, 0, + OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0, 1); /* Surface state base address */ OUT_BATCH(1); /* Dynamic state base address */ OUT_BATCH(1); /* Indirect object base address */ @@ -579,7 +579,7 @@ static void upload_state_base_address( struct brw_context *brw ) BEGIN_BATCH(8); OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2)); OUT_BATCH(1); /* General state base address */ - OUT_RELOC(intel->batch->buf, I915_GEM_DOMAIN_SAMPLER, 0, + OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0, 1); /* Surface state base address */ OUT_BATCH(1); /* Indirect object base address */ OUT_BATCH(1); /* Instruction base address */ @@ -591,7 +591,7 @@ static void upload_state_base_address( struct brw_context *brw ) BEGIN_BATCH(6); OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2)); OUT_BATCH(1); /* General state base address */ - OUT_RELOC(intel->batch->buf, I915_GEM_DOMAIN_SAMPLER, 0, + OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0, 1); /* Surface state base address */ OUT_BATCH(1); /* Indirect object base address */ OUT_BATCH(1); /* General state upper bound */ diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c index 656aad630a1..b41d05dd438 100644 --- a/src/mesa/drivers/dri/i965/brw_queryobj.c +++ b/src/mesa/drivers/dri/i965/brw_queryobj.c @@ -177,7 +177,7 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q) ADVANCE_BATCH(); } - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); } else { /* Flush the batchbuffer in case it has writes to our query BO. * Have later queries write to a new query BO so that further rendering @@ -185,7 +185,7 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q) */ if (query->bo) { brw_emit_query_end(brw); - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); drm_intel_bo_unreference(brw->query.bo); brw->query.bo = NULL; diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index ece05540a40..23d9e90c6e4 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -164,7 +164,7 @@ void brw_destroy_caches( struct brw_context *brw ); /*********************************************************************** * brw_state_batch.c */ -#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data(brw->intel.batch, (s), \ +#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data(&brw->intel, (s), \ sizeof(*(s)), false) #define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) ) diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c index 6d7b6a429dc..f363a922c1d 100644 --- a/src/mesa/drivers/dri/i965/brw_state_batch.c +++ b/src/mesa/drivers/dri/i965/brw_state_batch.c @@ -48,7 +48,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw, struct header *newheader = (struct header *)data; if (brw->emit_state_always) { - intel_batchbuffer_data(brw->intel.batch, data, sz, false); + intel_batchbuffer_data(&brw->intel, data, sz, false); return GL_TRUE; } @@ -75,7 +75,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw, emit: memcpy(item->header, newheader, sz); - intel_batchbuffer_data(brw->intel.batch, data, sz, false); + intel_batchbuffer_data(&brw->intel, data, sz, false); return GL_TRUE; } @@ -118,10 +118,10 @@ brw_state_batch(struct brw_context *brw, int alignment, uint32_t *out_offset) { - struct intel_batchbuffer *batch = brw->intel.batch; + struct intel_batchbuffer *batch = &brw->intel.batch; uint32_t offset; - assert(size < batch->buf->size); + assert(size < batch->bo->size); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); /* If allocating from the top would wrap below the batchbuffer, or @@ -129,13 +129,13 @@ brw_state_batch(struct brw_context *brw, * space, then flush and try again. */ if (batch->state_batch_offset < size || - offset < batch->ptr - batch->map + batch->reserved_space) { - intel_batchbuffer_flush(batch); + offset < 4*batch->used + batch->reserved_space) { + intel_batchbuffer_flush(&brw->intel); offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment); } batch->state_batch_offset = offset; *out_offset = offset; - return batch->map + offset; + return batch->map + (offset>>2); } diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c index 6c153319b82..fdce79da2f4 100644 --- a/src/mesa/drivers/dri/i965/brw_state_dump.c +++ b/src/mesa/drivers/dri/i965/brw_state_dump.c @@ -104,7 +104,7 @@ static void dump_wm_surface_state(struct brw_context *brw) GLubyte *base; int i; - bo = brw->intel.batch->buf; + bo = brw->intel.batch.bo; drm_intel_bo_map(bo, GL_FALSE); base = bo->virtual; @@ -285,7 +285,7 @@ static void dump_cc_state(struct brw_context *brw) const char *name = "CC"; struct gen6_color_calc_state *cc; uint32_t cc_off; - dri_bo *bo = brw->intel.batch->buf; + dri_bo *bo = brw->intel.batch.bo; if (brw->cc.state_offset == 0) return; @@ -376,7 +376,7 @@ void brw_debug_batch(struct intel_context *intel) struct brw_context *brw = brw_context(&intel->ctx); state_struct_out("WM bind", - brw->intel.batch->buf, + brw->intel.batch.bo, brw->wm.bind_bo_offset, 4 * brw->wm.nr_surfaces); dump_wm_surface_state(brw); diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 9d120cf8425..08b7ac90796 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -352,7 +352,7 @@ void brw_validate_state( struct brw_context *brw ) state->mesa |= brw->intel.NewGLState; brw->intel.NewGLState = 0; - brw_add_validated_bo(brw, intel->batch->buf); + brw_add_validated_bo(brw, intel->batch.bo); if (intel->gen >= 6) { atoms = gen6_atoms; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 82da6c4777e..1010d9f6f9c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -224,7 +224,7 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit ) } /* Emit relocation to surface contents */ - drm_intel_bo_emit_reloc(brw->intel.batch->buf, + drm_intel_bo_emit_reloc(brw->intel.batch.bo, brw->wm.surf_offset[surf_index] + offsetof(struct brw_surface_state, ss1), intelObj->mt->region->buffer, 0, @@ -268,7 +268,7 @@ brw_create_constant_surface(struct brw_context *brw, * bspec ("Data Cache") says that the data cache does not exist as * a separate cache and is just the sampler cache. */ - drm_intel_bo_emit_reloc(brw->intel.batch->buf, + drm_intel_bo_emit_reloc(brw->intel.batch.bo, (*out_offset + offsetof(struct brw_surface_state, ss1)), bo, 0, @@ -491,7 +491,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, surf->ss0.writedisable_alpha = !ctx->Color.ColorMask[unit][3]; } - drm_intel_bo_emit_reloc(brw->intel.batch->buf, + drm_intel_bo_emit_reloc(brw->intel.batch.bo, brw->wm.surf_offset[unit] + offsetof(struct brw_surface_state, ss1), region->buffer, diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 5564e3ea2c7..7d224ae535c 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -34,83 +34,61 @@ #include "intel_buffers.h" void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) +intel_batchbuffer_reset(struct intel_context *intel) { - struct intel_context *intel = batch->intel; - - if (batch->buf != NULL) { - drm_intel_bo_unreference(batch->buf); - batch->buf = NULL; + if (intel->batch.bo != NULL) { + drm_intel_bo_unreference(intel->batch.bo); + intel->batch.bo = NULL; } - batch->buf = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer", - intel->maxBatchSize, 4096); - drm_intel_gem_bo_map_gtt(batch->buf); - batch->map = batch->buf->virtual; - - batch->size = intel->maxBatchSize; - batch->ptr = batch->map; - batch->reserved_space = BATCH_RESERVED; - batch->dirty_state = ~0; - batch->state_batch_offset = batch->size; -} - -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - intel_batchbuffer_reset(batch); + intel->batch.bo = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer", + intel->maxBatchSize, 4096); - return batch; + intel->batch.reserved_space = BATCH_RESERVED; + intel->batch.state_batch_offset = intel->batch.bo->size; + intel->batch.used = 0; } void -intel_batchbuffer_free(struct intel_batchbuffer *batch) +intel_batchbuffer_free(struct intel_context *intel) { - if (batch->map) { - drm_intel_gem_bo_unmap_gtt(batch->buf); - batch->map = NULL; - } - dri_bo_unreference(batch->buf); - batch->buf = NULL; - free(batch); + drm_intel_bo_unreference(intel->batch.bo); } - /* TODO: Push this whole function into bufmgr. */ static void -do_flush_locked(struct intel_batchbuffer *batch, GLuint used) +do_flush_locked(struct intel_context *intel) { - struct intel_context *intel = batch->intel; + struct intel_batchbuffer *batch = &intel->batch; int ret = 0; - int x_off = 0, y_off = 0; - - drm_intel_gem_bo_unmap_gtt(batch->buf); - - batch->ptr = NULL; if (!intel->intelScreen->no_hw) { int ring; - if (intel->gen < 6 || !intel->batch->is_blit) { + if (intel->gen < 6 || !batch->is_blit) { ring = I915_EXEC_RENDER; } else { ring = I915_EXEC_BLT; } - drm_intel_bo_mrb_exec(batch->buf, used, NULL, 0, - (x_off & 0xffff) | (y_off << 16), ring); + ret = drm_intel_bo_subdata(batch->bo, 0, 4*batch->used, batch->map); + if (ret == 0 && batch->state_batch_offset != batch->bo->size) { + ret = drm_intel_bo_subdata(batch->bo, + batch->state_batch_offset, + batch->bo->size - batch->state_batch_offset, + (char *)batch->map + batch->state_batch_offset); + } + + if (ret == 0) + ret = drm_intel_bo_mrb_exec(batch->bo, 4*batch->used, NULL, 0, 0, ring); } if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) { - drm_intel_bo_map(batch->buf, GL_FALSE); - intel_decode(batch->buf->virtual, used / 4, batch->buf->offset, + intel_decode(batch->map, batch->used, + batch->bo->offset, intel->intelScreen->deviceID, GL_TRUE); - drm_intel_bo_unmap(batch->buf); if (intel->vtbl.debug_batch != NULL) intel->vtbl.debug_batch(intel); @@ -123,55 +101,33 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint used) } void -_intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, - int line) +_intel_batchbuffer_flush(struct intel_context *intel, + const char *file, int line) { - struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; + if (intel->batch.used == 0) + return; if (intel->first_post_swapbuffers_batch == NULL) { - intel->first_post_swapbuffers_batch = intel->batch->buf; + intel->first_post_swapbuffers_batch = intel->batch.bo; drm_intel_bo_reference(intel->first_post_swapbuffers_batch); } - if (used == 0) - return; - if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line, - used); + 4*intel->batch.used); - batch->reserved_space = 0; + intel->batch.reserved_space = 0; if (intel->always_flush_cache) { - intel_batchbuffer_emit_mi_flush(batch); - used = batch->ptr - batch->map; - } - - /* Round batchbuffer usage to 2 DWORDs. */ - - if ((used & 4) == 0) { - *(GLuint *) (batch->ptr) = 0; /* noop */ - batch->ptr += 4; - used = batch->ptr - batch->map; + intel_batchbuffer_emit_mi_flush(intel); } /* Mark the end of the buffer. */ - *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END; - batch->ptr += 4; - used = batch->ptr - batch->map; - assert (used <= batch->buf->size); - - /* Workaround for recursive batchbuffer flushing: If the window is - * moved, we can get into a case where we try to flush during a - * flush. What happens is that when we try to grab the lock for - * the first flush, we detect that the window moved which then - * causes another flush (from the intel_draw_buffer() call in - * intelUpdatePageFlipping()). To work around this we reset the - * batchbuffer tail pointer before trying to get the lock. This - * prevent the nested buffer flush, but a better fix would be to - * avoid that in the first place. */ - batch->ptr = batch->map; + intel_batchbuffer_emit_dword(intel, MI_BATCH_BUFFER_END); + if (intel->batch.used & 1) { + /* Round batchbuffer usage to 2 DWORDs. */ + intel_batchbuffer_emit_dword(intel, MI_NOOP); + } if (intel->vtbl.finish_batch) intel->vtbl.finish_batch(intel); @@ -181,24 +137,23 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, /* Check that we didn't just wrap our batchbuffer at a bad time. */ assert(!intel->no_batch_wrap); - do_flush_locked(batch, used); + do_flush_locked(intel); if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) { fprintf(stderr, "waiting for idle\n"); - drm_intel_bo_map(batch->buf, GL_TRUE); - drm_intel_bo_unmap(batch->buf); + drm_intel_bo_wait_rendering(intel->batch.bo); } /* Reset the buffer: */ - intel_batchbuffer_reset(batch); + intel_batchbuffer_reset(intel); } /* This is the only way buffers get added to the validate list. */ GLboolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, +intel_batchbuffer_emit_reloc(struct intel_context *intel, drm_intel_bo *buffer, uint32_t read_domains, uint32_t write_domain, uint32_t delta) @@ -207,58 +162,55 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, assert(delta < buffer->size); - if (batch->ptr - batch->map > batch->buf->size) - printf ("bad relocation ptr %p map %p offset %d size %lu\n", - batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size); - ret = drm_intel_bo_emit_reloc(batch->buf, batch->ptr - batch->map, + ret = drm_intel_bo_emit_reloc(intel->batch.bo, 4*intel->batch.used, buffer, delta, read_domains, write_domain); + assert (ret == 0); /* * Using the old buffer offset, write in what the right data would be, in case * the buffer doesn't move and we can short-circuit the relocation processing * in the kernel */ - intel_batchbuffer_emit_dword (batch, buffer->offset + delta); + intel_batchbuffer_emit_dword(intel, buffer->offset + delta); return GL_TRUE; } GLboolean -intel_batchbuffer_emit_reloc_fenced(struct intel_batchbuffer *batch, +intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel, drm_intel_bo *buffer, - uint32_t read_domains, uint32_t write_domain, + uint32_t read_domains, + uint32_t write_domain, uint32_t delta) { int ret; assert(delta < buffer->size); - if (batch->ptr - batch->map > batch->buf->size) - printf ("bad relocation ptr %p map %p offset %d size %lu\n", - batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size); - ret = drm_intel_bo_emit_reloc_fence(batch->buf, batch->ptr - batch->map, + ret = drm_intel_bo_emit_reloc_fence(intel->batch.bo, 4*intel->batch.used, buffer, delta, read_domains, write_domain); + assert (ret == 0); /* * Using the old buffer offset, write in what the right data would * be, in case the buffer doesn't move and we can short-circuit the * relocation processing in the kernel */ - intel_batchbuffer_emit_dword (batch, buffer->offset + delta); + intel_batchbuffer_emit_dword(intel, buffer->offset + delta); return GL_TRUE; } void -intel_batchbuffer_data(struct intel_batchbuffer *batch, +intel_batchbuffer_data(struct intel_context *intel, const void *data, GLuint bytes, bool is_blit) { assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, is_blit); - __memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; + intel_batchbuffer_require_space(intel, bytes, is_blit); + __memcpy(intel->batch.map + intel->batch.used, data, bytes); + intel->batch.used += bytes >> 2; } /* Emit a pipelined flush to either flush render and texture cache for @@ -268,12 +220,10 @@ intel_batchbuffer_data(struct intel_batchbuffer *batch, * This is also used for the always_flush_cache driconf debug option. */ void -intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch) +intel_batchbuffer_emit_mi_flush(struct intel_context *intel) { - struct intel_context *intel = batch->intel; - if (intel->gen >= 6) { - if (intel->batch->is_blit) { + if (intel->batch.is_blit) { BEGIN_BATCH_BLT(4); OUT_BATCH(MI_FLUSH_DW); OUT_BATCH(0); diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h index 635708587a6..7699715c0ea 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h @@ -7,71 +7,37 @@ #include "intel_bufmgr.h" #include "intel_reg.h" -#define BATCH_SZ 16384 #define BATCH_RESERVED 16 +void intel_batchbuffer_reset(struct intel_context *intel); +void intel_batchbuffer_free(struct intel_context *intel); -struct intel_batchbuffer -{ - struct intel_context *intel; - - drm_intel_bo *buf; - - GLubyte *map; - GLubyte *ptr; - - GLuint size; - uint32_t state_batch_offset; - -#ifdef DEBUG - /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */ - struct { - GLuint total; - GLubyte *start_ptr; - } emit; -#endif - - bool is_blit; - GLuint dirty_state; - GLuint reserved_space; -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void _intel_batchbuffer_flush(struct intel_batchbuffer *batch, +void _intel_batchbuffer_flush(struct intel_context *intel, const char *file, int line); -#define intel_batchbuffer_flush(batch) \ - _intel_batchbuffer_flush(batch, __FILE__, __LINE__) +#define intel_batchbuffer_flush(intel) \ + _intel_batchbuffer_flush(intel, __FILE__, __LINE__) -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); /* Unlike bmBufferData, this currently requires the buffer be mapped. * Consider it a convenience function wrapping multple * intel_buffer_dword() calls. */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, +void intel_batchbuffer_data(struct intel_context *intel, const void *data, GLuint bytes, bool is_blit); -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, +GLboolean intel_batchbuffer_emit_reloc(struct intel_context *intel, drm_intel_bo *buffer, uint32_t read_domains, uint32_t write_domain, uint32_t offset); -GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_batchbuffer *batch, +GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel, drm_intel_bo *buffer, uint32_t read_domains, uint32_t write_domain, uint32_t offset); -void intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch); +void intel_batchbuffer_emit_mi_flush(struct intel_context *intel); static INLINE uint32_t float_as_int(float f) { @@ -90,73 +56,70 @@ static INLINE uint32_t float_as_int(float f) * work... */ static INLINE GLint -intel_batchbuffer_space(struct intel_batchbuffer *batch) +intel_batchbuffer_space(struct intel_context *intel) { - return (batch->state_batch_offset - batch->reserved_space) - - (batch->ptr - batch->map); + return (intel->batch.state_batch_offset - intel->batch.reserved_space) - intel->batch.used*4; } static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +intel_batchbuffer_emit_dword(struct intel_context *intel, GLuint dword) { #ifdef DEBUG - assert(intel_batchbuffer_space(batch) >= 4); + assert(intel_batchbuffer_space(intel) >= 4); #endif - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; + intel->batch.map[intel->batch.used++] = dword; } static INLINE void -intel_batchbuffer_emit_float(struct intel_batchbuffer *batch, float f) +intel_batchbuffer_emit_float(struct intel_context *intel, float f) { - intel_batchbuffer_emit_dword(batch, float_as_int(f)); + intel_batchbuffer_emit_dword(intel, float_as_int(f)); } static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, +intel_batchbuffer_require_space(struct intel_context *intel, GLuint sz, int is_blit) { - if (batch->intel->gen >= 6 && batch->is_blit != is_blit && - batch->ptr != batch->map) { - intel_batchbuffer_flush(batch); + if (intel->gen >= 6 && + intel->batch.is_blit != is_blit && intel->batch.used) { + intel_batchbuffer_flush(intel); } - batch->is_blit = is_blit; + intel->batch.is_blit = is_blit; #ifdef DEBUG - assert(sz < batch->size - 8); + assert(sz < sizeof(intel->batch.map) - BATCH_RESERVED); #endif - if (intel_batchbuffer_space(batch) < sz) - intel_batchbuffer_flush(batch); + if (intel_batchbuffer_space(intel) < sz) + intel_batchbuffer_flush(intel); } static INLINE void -intel_batchbuffer_begin(struct intel_batchbuffer *batch, int n, bool is_blit) +intel_batchbuffer_begin(struct intel_context *intel, int n, bool is_blit) { - intel_batchbuffer_require_space(batch, n * 4, is_blit); + intel_batchbuffer_require_space(intel, n * 4, is_blit); #ifdef DEBUG - assert(batch->map); - assert(batch->emit.start_ptr == NULL); - batch->emit.total = n * 4; - batch->emit.start_ptr = batch->ptr; + intel->batch.emit.total = n; + intel->batch.emit.start_ptr = intel->batch.used; #endif } static INLINE void -intel_batchbuffer_advance(struct intel_batchbuffer *batch) +intel_batchbuffer_advance(struct intel_context *intel) { #ifdef DEBUG - unsigned int _n = batch->ptr - batch->emit.start_ptr; - assert(batch->emit.start_ptr != NULL); - if (_n != batch->emit.total) { + struct intel_batchbuffer *batch = &intel->batch; + unsigned int _n = batch->used - batch->emit; + assert(batch->total != 0); + if (_n != batch->total) { fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n", - _n, batch->emit.total); + _n, batch->total); abort(); } - batch->emit.start_ptr = NULL; + batch->total = 0; #endif } @@ -164,19 +127,19 @@ intel_batchbuffer_advance(struct intel_batchbuffer *batch) */ #define BATCH_LOCALS -#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel->batch, n, false) -#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel->batch, n, true) -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) -#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel->batch,f) +#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel, n, false) +#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel, n, true) +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel, d) +#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel,f) #define OUT_RELOC(buf, read_domains, write_domain, delta) do { \ - intel_batchbuffer_emit_reloc(intel->batch, buf, \ + intel_batchbuffer_emit_reloc(intel, buf, \ read_domains, write_domain, delta); \ } while (0) #define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do { \ - intel_batchbuffer_emit_reloc_fenced(intel->batch, buf, \ + intel_batchbuffer_emit_reloc_fenced(intel, buf, \ read_domains, write_domain, delta); \ } while (0) -#define ADVANCE_BATCH() intel_batchbuffer_advance(intel->batch); +#define ADVANCE_BATCH() intel_batchbuffer_advance(intel); #endif diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 6232e479cb6..e1ab7f16371 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -123,12 +123,12 @@ intelEmitCopyBlit(struct intel_context *intel, /* do space check before going any further */ do { - aper_array[0] = intel->batch->buf; + aper_array[0] = intel->batch.bo; aper_array[1] = dst_buffer; aper_array[2] = src_buffer; if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) { - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); pass++; } else break; @@ -137,7 +137,7 @@ intelEmitCopyBlit(struct intel_context *intel, if (pass >= 2) return GL_FALSE; - intel_batchbuffer_require_space(intel->batch, 8 * 4, true); + intel_batchbuffer_require_space(intel, 8 * 4, true); DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __FUNCTION__, src_buffer, src_pitch, src_offset, src_x, src_y, @@ -193,7 +193,7 @@ intelEmitCopyBlit(struct intel_context *intel, src_offset); ADVANCE_BATCH(); - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); return GL_TRUE; } @@ -343,12 +343,12 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) assert(y1 < y2); /* do space check before going any further */ - aper_array[0] = intel->batch->buf; + aper_array[0] = intel->batch.bo; aper_array[1] = write_buffer; if (drm_intel_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array)) != 0) { - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); } BEGIN_BATCH_BLT(6); @@ -363,7 +363,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) ADVANCE_BATCH(); if (intel->always_flush_cache) - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); @@ -410,10 +410,10 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords); - intel_batchbuffer_require_space( intel->batch, - (8 * 4) + - (3 * 4) + - dwords * 4, true); + intel_batchbuffer_require_space(intel, + (8 * 4) + + (3 * 4) + + dwords * 4, true); opcode = XY_SETUP_BLT_CMD; if (cpp == 4) @@ -449,11 +449,9 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, OUT_BATCH(((y + h) << 16) | (x + w)); ADVANCE_BATCH(); - intel_batchbuffer_data(intel->batch, - src_bits, - dwords * 4, true); + intel_batchbuffer_data(intel, src_bits, dwords * 4, true); - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); return GL_TRUE; } @@ -543,10 +541,10 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx, DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", __FUNCTION__, - intel_image->mt->region->buffer, (pitch * region->cpp), + intel_image->mt->region->buffer, (pitch * cpp), x1, y1, x2 - x1, y2 - y1); - BR13 = br13_for_cpp(region->cpp) | 0xf0 << 16; + BR13 = br13_for_cpp(cpp) | 0xf0 << 16; CMD = XY_COLOR_BLT_CMD; CMD |= XY_BLT_WRITE_ALPHA; @@ -558,15 +556,15 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx, pitch /= 4; } #endif - BR13 |= (pitch * region->cpp); + BR13 |= (pitch * cpp); /* do space check before going any further */ - aper_array[0] = intel->batch->buf; + aper_array[0] = intel->batch.bo; aper_array[1] = region->buffer; if (drm_intel_bufmgr_check_aperture_space(aper_array, ARRAY_SIZE(aper_array)) != 0) { - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); } BEGIN_BATCH_BLT(6); @@ -580,5 +578,5 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx, OUT_BATCH(0xffffffff); /* white, but only alpha gets written */ ADVANCE_BATCH(); - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); } diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 19c73e6ab3a..4edf29ec759 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -225,7 +225,7 @@ intel_bufferobj_subdata(struct gl_context * ctx, } else { bool busy = drm_intel_bo_busy(intel_obj->buffer) || - drm_intel_bo_references(intel->batch->buf, intel_obj->buffer); + drm_intel_bo_references(intel->batch.bo, intel_obj->buffer); /* replace the current busy bo with fresh data */ if (busy && size == intel_obj->Base.Size) { @@ -251,8 +251,8 @@ intel_bufferobj_subdata(struct gl_context * ctx, } } else { /* Can't use the blit to modify the buffer in the middle of batch. */ - if (drm_intel_bo_references(intel->batch->buf, intel_obj->buffer)) { - intel_batchbuffer_flush(intel->batch); + if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) { + intel_batchbuffer_flush(intel); } drm_intel_bo_subdata(intel_obj->buffer, offset, size, data); } @@ -309,7 +309,7 @@ intel_bufferobj_map(struct gl_context * ctx, } /* Flush any existing batchbuffer that might reference this data. */ - if (drm_intel_bo_references(intel->batch->buf, intel_obj->buffer)) + if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) intel_flush(ctx); if (intel_obj->region) @@ -386,7 +386,7 @@ intel_bufferobj_map_range(struct gl_context * ctx, * syncing. */ if (!(access & GL_MAP_UNSYNCHRONIZED_BIT) && - drm_intel_bo_references(intel->batch->buf, intel_obj->buffer)) + drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) intel_flush(ctx); if (intel_obj->buffer == NULL) { @@ -499,7 +499,7 @@ intel_bufferobj_unmap(struct gl_context * ctx, * flush. Once again, we wish for a domain tracker in libdrm to cover * usage inside of a batchbuffer. */ - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); free(intel_obj->range_map_buffer); intel_obj->range_map_buffer = NULL; } else if (intel_obj->range_map_bo != NULL) { @@ -519,7 +519,7 @@ intel_bufferobj_unmap(struct gl_context * ctx, * flush. Once again, we wish for a domain tracker in libdrm to cover * usage inside of a batchbuffer. */ - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); drm_intel_bo_unreference(intel_obj->range_map_bo); intel_obj->range_map_bo = NULL; @@ -766,7 +766,7 @@ intel_bufferobj_copy_subdata(struct gl_context *ctx, * flush. Once again, we wish for a domain tracker in libdrm to cover * usage inside of a batchbuffer. */ - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); } #if FEATURE_APPLE_object_purgeable diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 65c4148e73e..c470febfb3a 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -554,8 +554,8 @@ intel_flush(struct gl_context *ctx) if (intel->gen < 4) INTEL_FIREVERTICES(intel); - if (intel->batch->map != intel->batch->ptr) - intel_batchbuffer_flush(intel->batch); + if (intel->batch.used) + intel_batchbuffer_flush(intel); } static void @@ -751,7 +751,7 @@ intelInitContext(struct intel_context *intel, if (intelScreen->deviceID == PCI_CHIP_I865_G) intel->maxBatchSize = 4096; else - intel->maxBatchSize = BATCH_SZ; + intel->maxBatchSize = sizeof(intel->batch.map); intel->bufmgr = intelScreen->bufmgr; @@ -863,7 +863,7 @@ intelInitContext(struct intel_context *intel, if (INTEL_DEBUG & DEBUG_BUFMGR) dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE); - intel->batch = intel_batchbuffer_alloc(intel); + intel_batchbuffer_reset(intel); intel_fbo_init(intel); @@ -920,8 +920,7 @@ intelDestroyContext(__DRIcontext * driContextPriv) _swrast_DestroyContext(&intel->ctx); intel->Fallback = 0x0; /* don't call _swrast_Flush later */ - intel_batchbuffer_free(intel->batch); - intel->batch = NULL; + intel_batchbuffer_free(intel); free(intel->prim.vb); intel->prim.vb = NULL; diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 0ea273837de..bf2a0b4ead8 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -169,7 +169,27 @@ struct intel_context int urb_size; - struct intel_batchbuffer *batch; + struct intel_batchbuffer { + drm_intel_bo *bo; + + uint16_t used; + uint16_t reserved_space; + uint32_t map[8192]; +#define BATCH_SZ (8192*sizeof(uint32_t)) + + uint32_t state_batch_offset; + +#ifdef DEBUG + /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */ + struct { + uint16_t total; + uint16_t start_ptr; + } emit; +#endif + + bool is_blit; + } batch; + drm_intel_bo *first_post_swapbuffers_batch; GLboolean need_throttle; GLboolean no_batch_wrap; @@ -177,9 +197,9 @@ struct intel_context struct { GLuint id; + uint32_t start_ptr; /**< for i8xx */ uint32_t primitive; /**< Current hardware primitive type */ void (*flush) (struct intel_context *); - GLubyte *start_ptr; /**< for i8xx */ drm_intel_bo *vb_bo; uint8_t *vb; unsigned int start_offset; /**< Byte offset of primitive sequence */ diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 0db5a491c8f..886b25c23b4 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -580,7 +580,7 @@ intel_finish_render_texture(struct gl_context * ctx, * batch. Once again, we wish for a domain tracker in libdrm to cover * usage inside of a batchbuffer like GEM does in the kernel. */ - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); } /** diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index e7356a6da0d..d7561ee689d 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -285,7 +285,7 @@ do_blit_bitmap( struct gl_context *ctx, out: if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); if (_mesa_is_bufferobj(unpack->BufferObj)) { /* done with PBO so unmap it now */ diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c index 716b9cea402..f90f8224c95 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_read.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -78,7 +78,6 @@ do_blit_readpixels(struct gl_context * ctx, GLuint dst_offset; GLuint rowLength; drm_intel_bo *dst_buffer; - GLuint offset; GLboolean all; GLint dst_x, dst_y; @@ -148,7 +147,7 @@ do_blit_readpixels(struct gl_context * ctx, if (!intelEmitCopyBlit(intel, src->cpp, src->pitch, src->buffer, 0, src->tiling, - rowLength, dst_buffer, dst_offset + offset, GL_FALSE, + rowLength, dst_buffer, dst_offset, GL_FALSE, x, y, dst_x, dst_y, width, height, diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index e87e29462c3..0857fa8ad70 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -491,7 +491,7 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region) assert(region->cpp * region->pitch * region->height == pbo->Base.Size); - _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size); + _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, (int)pbo->Base.Size); /* Now blit from the texture buffer to the new buffer: */ diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 2f35fe7f240..356d5f72d89 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -111,8 +111,8 @@ intelDRI2Flush(__DRIdrawable *drawable) intel->need_throttle = GL_TRUE; - if (intel->batch->map != intel->batch->ptr) - intel_batchbuffer_flush(intel->batch); + if (intel->batch.used) + intel_batchbuffer_flush(intel); } static const struct __DRI2flushExtensionRec intelFlushExtension = { diff --git a/src/mesa/drivers/dri/intel/intel_syncobj.c b/src/mesa/drivers/dri/intel/intel_syncobj.c index bbfac74b605..b303ea84dd8 100644 --- a/src/mesa/drivers/dri/intel/intel_syncobj.c +++ b/src/mesa/drivers/dri/intel/intel_syncobj.c @@ -72,9 +72,9 @@ intel_fence_sync(struct gl_context *ctx, struct gl_sync_object *s, struct intel_sync_object *sync = (struct intel_sync_object *)s; assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE); - intel_batchbuffer_emit_mi_flush(intel->batch); + intel_batchbuffer_emit_mi_flush(intel); - sync->bo = intel->batch->buf; + sync->bo = intel->batch.bo; drm_intel_bo_reference(sync->bo); intel_flush(ctx); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index ddcb748c828..9dba529c58d 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -231,7 +231,7 @@ try_pbo_upload(struct intel_context *intel, dst_stride = intelImage->mt->region->pitch; - if (drm_intel_bo_references(intel->batch->buf, dst_buffer)) + if (drm_intel_bo_references(intel->batch.bo, dst_buffer)) intel_flush(&intel->ctx); { @@ -431,7 +431,7 @@ intelTexImage(struct gl_context * ctx, if (intelImage->mt) { if (pixels != NULL) { /* Flush any queued rendering with the texture before mapping. */ - if (drm_intel_bo_references(intel->batch->buf, + if (drm_intel_bo_references(intel->batch.bo, intelImage->mt->region->buffer)) { intel_flush(ctx); }