#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)
* 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;
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)
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");
}
}
- intel->batch->dirty_state &= ~dirty;
assert(get_dirty(state) == 0);
- assert((intel->batch->dirty_state & (1<<1)) == 0);
}
static void
#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)
* 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;
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)
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");
}
}
- intel->batch->dirty_state &= ~dirty;
assert(get_dirty(state) == 0);
- assert((intel->batch->dirty_state & (1<<1)) == 0);
}
static void
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);
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;
*/
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;
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;
}
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);
}
*/
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,
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,
* 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);
}
}
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)
* 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: */
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
}
if (intel->always_flush_batch)
- intel_batchbuffer_flush(intel->batch);
+ intel_batchbuffer_flush(intel);
out:
brw_state_cache_check_size(brw);
*
**************************************************************************/
+#undef NDEBUG
#include "main/glheader.h"
#include "main/bufferobj.h"
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
}
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++) {
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();
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 */
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 */
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 */
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
*/
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;
/***********************************************************************
* 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)) )
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;
}
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;
}
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
* 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);
}
GLubyte *base;
int i;
- bo = brw->intel.batch->buf;
+ bo = brw->intel.batch.bo;
drm_intel_bo_map(bo, GL_FALSE);
base = bo->virtual;
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;
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);
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;
}
/* 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,
* 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,
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,
#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);
}
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);
/* 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)
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
* 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);
#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)
{
* 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
}
*/
#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
/* 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;
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,
src_offset);
ADVANCE_BATCH();
- intel_batchbuffer_emit_mi_flush(intel->batch);
+ intel_batchbuffer_emit_mi_flush(intel);
return GL_TRUE;
}
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);
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);
__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)
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;
}
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;
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);
OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
ADVANCE_BATCH();
- intel_batchbuffer_emit_mi_flush(intel->batch);
+ intel_batchbuffer_emit_mi_flush(intel);
}
} 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) {
}
} 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);
}
}
/* 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)
* 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) {
* 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) {
* 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;
* 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
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
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;
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);
_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;
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;
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 */
* 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);
}
/**
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 */
GLuint dst_offset;
GLuint rowLength;
drm_intel_bo *dst_buffer;
- GLuint offset;
GLboolean all;
GLint dst_x, dst_y;
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,
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:
*/
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 = {
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);
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);
{
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);
}