*
**************************************************************************/
+#include "intel_context.h"
#include "intel_batchbuffer.h"
-#include "intel_ioctl.h"
#include "intel_decode.h"
#include "intel_reg.h"
+#include "intel_bufmgr.h"
+#include "intel_buffers.h"
/* Relocations in kernel space:
* - pass dma buffer seperately
batch->buffer = malloc (intel->maxBatchSize);
batch->buf = dri_bo_alloc(intel->bufmgr, "batchbuffer",
- intel->maxBatchSize, 4096,
- DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
+ intel->maxBatchSize, 4096);
if (batch->buffer)
batch->map = batch->buffer;
else {
batch->ptr = batch->map;
batch->dirty_state = ~0;
batch->cliprect_mode = IGNORE_CLIPRECTS;
-
- /* account batchbuffer in aperture */
- dri_bufmgr_check_aperture_space(batch->buf);
-
}
struct intel_batchbuffer *
{
struct intel_context *intel = batch->intel;
int ret = 0;
+ unsigned int num_cliprects = 0;
+ struct drm_clip_rect *cliprects = NULL;
+ int x_off = 0, y_off = 0;
if (batch->buffer)
dri_bo_subdata (batch->buf, 0, used, batch->buffer);
batch->map = NULL;
batch->ptr = NULL;
- /* Throw away non-effective packets. Won't work once we have
- * hardware contexts which would preserve statechanges beyond a
- * single buffer.
- */
- if (!(intel->numClipRects == 0 &&
- batch->cliprect_mode == LOOP_CLIPRECTS)) {
- if (intel->ttm == GL_TRUE) {
- struct drm_i915_gem_execbuffer *execbuf;
-
- execbuf = dri_process_relocs(batch->buf);
- ret = intel_exec_ioctl(batch->intel,
- used,
- batch->cliprect_mode != LOOP_CLIPRECTS,
- allow_unlock,
- execbuf);
- } else {
- dri_process_relocs(batch->buf);
- ret = intel_batch_ioctl(batch->intel,
- batch->buf->offset,
- used,
- batch->cliprect_mode != LOOP_CLIPRECTS,
- allow_unlock);
- }
+ if (batch->cliprect_mode == LOOP_CLIPRECTS) {
+ intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
+ }
+ /* Dispatch the batchbuffer, if it has some effect (nonzero cliprects).
+ * Can't short-circuit like this once we have hardware contexts, but we
+ * should always be in DRI2 mode by then anyway.
+ */
+ if ((batch->cliprect_mode != LOOP_CLIPRECTS ||
+ num_cliprects != 0) && !intel->no_hw) {
+ dri_bo_exec(batch->buf, used, cliprects, num_cliprects,
+ (x_off & 0xffff) | (y_off << 16));
}
- dri_post_submit(batch->buf);
-
- if (intel->numClipRects == 0 &&
- batch->cliprect_mode == LOOP_CLIPRECTS) {
+ if (batch->cliprect_mode == LOOP_CLIPRECTS && num_cliprects == 0) {
if (allow_unlock) {
/* If we are not doing any actual user-visible rendering,
* do a sched_yield to keep the app from pegging the cpu while
{
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
- GLboolean was_locked = intel->locked;
- if (used == 0)
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
+ if (used == 0) {
+ batch->cliprect_mode = IGNORE_CLIPRECTS;
return;
+ }
if (INTEL_DEBUG & DEBUG_BATCH)
fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
used);
/* Emit a flush if the bufmgr doesn't do it for us. */
- if (!intel->ttm) {
+ if (intel->always_flush_cache || !intel->ttm) {
*(GLuint *) (batch->ptr) = intel->vtbl.flush_cmd();
batch->ptr += 4;
used = batch->ptr - batch->map;
* avoid that in the first place. */
batch->ptr = batch->map;
+ if (intel->vtbl.finish_batch)
+ intel->vtbl.finish_batch(intel);
+
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
*/
- if (!was_locked)
- LOCK_HARDWARE(intel);
-
+ LOCK_HARDWARE(intel);
do_flush_locked(batch, used, GL_FALSE);
-
- if (!was_locked)
- UNLOCK_HARDWARE(intel);
+ UNLOCK_HARDWARE(intel);
if (INTEL_DEBUG & DEBUG_SYNC) {
- int irq;
-
fprintf(stderr, "waiting for idle\n");
- LOCK_HARDWARE(intel);
- irq = intelEmitIrqLocked(intel);
- UNLOCK_HARDWARE(intel);
- intelWaitIrq(intel, irq);
+ dri_bo_map(batch->buf, GL_TRUE);
+ dri_bo_unmap(batch->buf);
}
/* Reset the buffer:
if (batch->ptr - batch->map > batch->buf->size)
_mesa_printf ("bad relocation ptr %p map %p offset %d size %d\n",
batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
- ret = dri_emit_reloc(batch->buf, read_domains, write_domain,
- delta, batch->ptr - batch->map, buffer);
+ ret = dri_bo_emit_reloc(batch->buf, read_domains, write_domain,
+ delta, batch->ptr - batch->map, buffer);
/*
* Using the old buffer offset, write in what the right data would be, in case