summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-11-29 22:42:03 +0000
committerOwain G. Ainsworth <oga@openbsd.org>2010-03-01 16:55:39 +0000
commitf253bd6f9756b5de54e38d015481048c563a5515 (patch)
tree986e16bd60db87506fc7d29cb6b5cc32d0f98f68
parentad2e3e3e37e932a1a6bfa61a29d08af316346696 (diff)
batch: Track pixmap domains.
In order to detect when we require cache flushes we need to track which domains the pixmap currently belongs to. So to do so we create a device private structure to hold the extra information and hook it up. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (cherry-picked from commit 285f286597df5af13ac3f3d366f2fc9d0468dafa).
-rw-r--r--src/i830.h83
-rw-r--r--src/i830_accel.c21
-rw-r--r--src/i830_batchbuffer.c62
-rw-r--r--src/i830_batchbuffer.h28
-rw-r--r--src/i830_dri.c8
-rw-r--r--src/i830_driver.c13
-rw-r--r--src/i830_uxa.c250
-rw-r--r--src/i965_render.c23
8 files changed, 335 insertions, 153 deletions
diff --git a/src/i830.h b/src/i830.h
index ca5500dd..c79e4339 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -77,6 +77,87 @@ void i830_uxa_block_handler(ScreenPtr pScreen);
Bool i830_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
int num_bos);
+/* classic doubly-link circular list */
+struct list {
+ struct list *next, *prev;
+};
+
+static void
+list_init(struct list *list)
+{
+ list->next = list->prev = list;
+}
+
+static inline void
+__list_add(struct list *entry,
+ struct list *prev,
+ struct list *next)
+{
+ next->prev = entry;
+ entry->next = next;
+ entry->prev = prev;
+ prev->next = entry;
+}
+
+static inline void
+list_add(struct list *entry, struct list *head)
+{
+ __list_add(entry, head, head->next);
+}
+
+static inline void
+__list_del(struct list *prev, struct list *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void
+list_del(struct list *entry)
+{
+ __list_del(entry->prev, entry->next);
+ list_init(entry);
+}
+
+static inline Bool
+list_is_empty(struct list *head)
+{
+ return head->next == head;
+}
+
+#ifndef container_of
+#define container_of(ptr, type, member) \
+ (type *)((char *)(ptr) - (char *) &((type *)0)->member)
+#endif
+
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+struct intel_pixmap {
+ dri_bo *bo;
+ uint32_t tiling;
+ uint32_t flush_write_domain;
+ uint32_t flush_read_domains;
+ uint32_t batch_write_domain;
+ uint32_t batch_read_domains;
+ struct list flush, batch;
+};
+
+struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap);
+
+static inline Bool i830_uxa_pixmap_is_dirty(PixmapPtr pixmap)
+{
+ return i830_get_pixmap_intel(pixmap)->flush_write_domain != 0;
+}
+
+static inline Bool i830_pixmap_tiled(PixmapPtr pixmap)
+{
+ return i830_get_pixmap_intel(pixmap)->tiling != I915_TILING_NONE;
+}
+
dri_bo *i830_get_pixmap_bo(PixmapPtr pixmap);
void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo);
@@ -391,6 +472,8 @@ typedef struct intel_screen_private {
Bool in_batch_atomic;
/** Ending batch_used that was verified by i830_start_batch_atomic() */
int batch_atomic_limit;
+ struct list batch_pixmaps;
+ struct list flush_pixmaps;
/* For Xvideo */
i830_memory *overlay_regs;
diff --git a/src/i830_accel.c b/src/i830_accel.c
index 2734ccd7..626c751f 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -132,35 +132,16 @@ void I830Sync(ScrnInfoPtr scrn)
if (!scrn->vtSema || !intel->batch_bo)
return;
- I830EmitFlush(scrn);
-
intel_batch_flush(scrn, TRUE);
intel_batch_wait_last(scrn);
}
-void I830EmitFlush(ScrnInfoPtr scrn)
-{
- intel_screen_private *intel = intel_get_screen_private(scrn);
- int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
-
- if (IS_I965G(intel))
- flags = 0;
-
- {
- BEGIN_BATCH(1);
- OUT_BATCH(MI_FLUSH | flags);
- ADVANCE_BATCH();
- }
-}
-
void i830_debug_flush(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
- if (intel->debug_flush & DEBUG_FLUSH_BATCHES)
+ if (intel->debug_flush & (DEBUG_FLUSH_BATCHES | DEBUG_FLUSH_CACHES))
intel_batch_flush(scrn, FALSE);
- else if (intel->debug_flush & DEBUG_FLUSH_CACHES)
- I830EmitFlush(scrn);
}
/* The following function sets up the supported acceleration. Call it
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 22e1bb4f..1677f590 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -164,19 +164,45 @@ void intel_batch_teardown(ScrnInfoPtr scrn)
}
}
-void intel_batch_flush(ScrnInfoPtr scrn, Bool flushed)
+void intel_batch_pipelined_flush(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
- int ret;
+ int flags;
assert (!intel->in_batch_atomic);
if (intel->batch_used == 0)
return;
- /* If we're not using GEM, then emit a flush after each batch buffer */
- if (intel->debug_flush & DEBUG_FLUSH_CACHES ||
- (!intel->have_gem && !flushed)) {
+ /* Big hammer, look to the pipelined flushes in future. */
+ flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
+ if (IS_I965G(intel))
+ flags = 0;
+
+ BEGIN_BATCH(1);
+ OUT_BATCH(MI_FLUSH | flags);
+ ADVANCE_BATCH();
+
+ while (!list_is_empty(&intel->flush_pixmaps)) {
+ struct intel_pixmap *entry;
+
+ entry = list_first_entry(&intel->flush_pixmaps,
+ struct intel_pixmap,
+ flush);
+
+ entry->flush_read_domains = entry->flush_write_domain = 0;
+ list_del(&entry->flush);
+ }
+}
+
+void intel_batch_flush(ScrnInfoPtr scrn, Bool flush)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ int ret;
+
+ assert (!intel->in_batch_atomic);
+
+ if (flush || intel->debug_flush & DEBUG_FLUSH_CACHES) {
int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
if (IS_I965G(intel))
@@ -186,7 +212,10 @@ void intel_batch_flush(ScrnInfoPtr scrn, Bool flushed)
MI_FLUSH | flags;
intel->batch_used += 4;
}
-
+
+ if (intel->batch_used == 0)
+ return;
+
/* Emit a padding dword if we aren't going to be quad-word aligned. */
if ((intel->batch_used & 4) == 0) {
*(uint32_t *) (intel->batch_ptr + intel->batch_used) = MI_NOOP;
@@ -208,6 +237,27 @@ void intel_batch_flush(ScrnInfoPtr scrn, Bool flushed)
FatalError("Failed to submit batchbuffer: %s\n",
strerror(-ret));
+ while (!list_is_empty(&intel->batch_pixmaps)) {
+ struct intel_pixmap *entry;
+
+ entry = list_first_entry(&intel->batch_pixmaps,
+ struct intel_pixmap,
+ batch);
+
+ entry->batch_read_domains = entry->batch_write_domain = 0;
+ list_del(&entry->batch);
+ }
+ while (!list_is_empty(&intel->flush_pixmaps)) {
+ struct intel_pixmap *entry;
+
+ entry = list_first_entry(&intel->flush_pixmaps,
+ struct intel_pixmap,
+ flush);
+
+ entry->flush_read_domains = entry->flush_write_domain = 0;
+ list_del(&entry->flush);
+ }
+
/* Save a ref to the last batch emitted, which we use for syncing
* in debug code.
*/
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 51382286..5026a72c 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -32,9 +32,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define BATCH_RESERVED 16
+
void intel_batch_init(ScrnInfoPtr scrn);
void intel_batch_teardown(ScrnInfoPtr scrn);
-void intel_batch_flush(ScrnInfoPtr scrn, Bool flushed);
+void intel_batch_pipelined_flush(ScrnInfoPtr scrn);
+void intel_batch_flush(ScrnInfoPtr scrn, Bool flush);
void intel_batch_wait_last(ScrnInfoPtr scrn);
static inline int intel_batch_space(intel_screen_private *intel)
@@ -93,6 +95,27 @@ intel_batch_emit_reloc(intel_screen_private *intel,
}
static inline void
+intel_batch_mark_pixmap_domains(intel_screen_private *intel,
+ struct intel_pixmap *priv,
+ uint32_t read_domains, uint32_t write_domain)
+{
+ assert (read_domains);
+ assert (write_domain == 0 || write_domain == read_domains);
+ assert (write_domain == 0 ||
+ priv->flush_write_domain == 0 ||
+ priv->flush_write_domain == write_domain);
+
+ priv->flush_read_domains |= read_domains;
+ priv->batch_read_domains |= read_domains;
+ priv->flush_write_domain |= write_domain;
+ priv->batch_write_domain |= write_domain;
+ if (list_is_empty(&priv->batch))
+ list_add(&priv->batch, &intel->batch_pixmaps);
+ if (list_is_empty(&priv->flush))
+ list_add(&priv->flush, &intel->flush_pixmaps);
+}
+
+static inline void
intel_batch_emit_reloc_pixmap(intel_screen_private *intel, PixmapPtr pixmap,
uint32_t read_domains, uint32_t write_domain,
uint32_t delta)
@@ -102,6 +125,9 @@ intel_batch_emit_reloc_pixmap(intel_screen_private *intel, PixmapPtr pixmap,
assert(intel->batch_ptr != NULL);
assert(intel_batch_space(intel) >= 4);
if (bo) {
+ struct intel_pixmap *priv = i830_get_pixmap_intel(pixmap);
+ intel_batch_mark_pixmap_domains(intel, priv, read_domains,
+ write_domain);
intel_batch_emit_reloc(intel, bo, read_domains,
write_domain, delta);
return;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 1a5b56ad..3599d7bd 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -351,12 +351,10 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
/* Emit a flush of the rendering cache, or on the 965 and beyond
* rendering results may not hit the framebuffer until significantly
* later.
- */
- I830EmitFlush(scrn);
- intel->need_mi_flush = FALSE;
-
- /* We can't rely on getting into the block handler before the DRI
+ *
+ * We can't rely on getting into the block handler before the DRI
* client gets to run again so flush now. */
+ intel->need_mi_flush = FALSE;
intel_batch_flush(scrn, TRUE);
#if ALWAYS_SYNC
I830Sync(scrn);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index c5ab8b6d..99bd5308 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2160,20 +2160,19 @@ I830BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
screen->BlockHandler = I830BlockHandler;
if (scrn->vtSema) {
- Bool flushed = FALSE;
+ Bool flush = FALSE;
+
/* Emit a flush of the rendering cache, or on the 965 and beyond
* rendering results may not hit the framebuffer until significantly
* later.
*/
- if (intel->need_mi_flush || intel->batch_used) {
- flushed = TRUE;
- I830EmitFlush(scrn);
- }
+ if (intel->need_mi_flush || intel->batch_used)
+ flush = TRUE;
/* Flush the batch, so that any rendering is executed in a timely
* fashion.
*/
- intel_batch_flush(scrn, flushed);
+ intel_batch_flush(scrn, flush);
if (intel->have_gem)
drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE);
@@ -2331,6 +2330,8 @@ void i830_init_bufmgr(ScrnInfoPtr scrn)
intel->fake_bufmgr_mem->offset,
intel->fake_bufmgr_mem->size, NULL);
}
+ list_init(&intel->batch_pixmaps);
+ list_init(&intel->flush_pixmaps);
}
Bool i830_crtc_on(xf86CrtcPtr crtc)
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 75922cde..3d07185e 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -79,44 +79,6 @@ const int I830PatternROP[16] = {
static int uxa_pixmap_index;
-/**
- * Returns whether a given pixmap is tiled or not.
- *
- * Currently, we only have one pixmap that might be tiled, which is the front
- * buffer. At the point where we are tiling some pixmaps managed by the
- * general allocator, we should move this to using pixmap privates.
- */
-Bool i830_pixmap_tiled(PixmapPtr pixmap)
-{
- ScreenPtr pScreen = pixmap->drawable.pScreen;
- ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
- intel_screen_private *intel = intel_get_screen_private(scrn);
- unsigned long offset;
- dri_bo *bo;
- uint32_t tiling_mode, swizzle_mode;
- int ret;
-
- bo = i830_get_pixmap_bo(pixmap);
- if (bo != NULL) {
-
- ret = drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode);
- if (ret != 0) {
- FatalError("Couldn't get tiling on bo %p: %s\n",
- bo, strerror(-ret));
- }
-
- return tiling_mode != I915_TILING_NONE;
- }
-
- offset = intel_get_pixmap_offset(pixmap);
- if (offset == intel->front_buffer->offset &&
- intel->front_buffer->tiling != TILE_NONE) {
- return TRUE;
- }
-
- return FALSE;
-}
-
Bool
i830_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
int num_bos)
@@ -156,6 +118,62 @@ static int i830_pixmap_pitch_is_aligned(PixmapPtr pixmap)
intel->accel_pixmap_pitch_alignment == 0;
}
+static unsigned int
+i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
+ int w, int h,
+ uint32_t *tiling,
+ int *stride)
+{
+ ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ int pitch_align;
+ int size;
+
+ if (*tiling != I915_TILING_NONE) {
+ /* First check whether tiling is necessary. */
+ pitch_align = intel->accel_pixmap_pitch_alignment;
+ size = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
+ pitch_align) * ALIGN (h, 2);
+ if (size < 4096)
+ *tiling = I915_TILING_NONE;
+ }
+
+ if (*tiling == I915_TILING_NONE) {
+ pitch_align = intel->accel_pixmap_pitch_alignment;
+ } else {
+ pitch_align = 512;
+ }
+
+ *stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
+ pitch_align);
+
+ if (*tiling == I915_TILING_NONE) {
+ /* Round the height up so that the GPU's access to a 2x2 aligned
+ * subspan doesn't address an invalid page offset beyond the
+ * end of the GTT.
+ */
+ size = *stride * ALIGN(h, 2);
+ } else {
+ int aligned_h = h;
+ if (*tiling == I915_TILING_X)
+ aligned_h = ALIGN(h, 8);
+ else
+ aligned_h = ALIGN(h, 32);
+
+ *stride = i830_get_fence_pitch(intel, *stride, *tiling);
+ /* Round the object up to the size of the fence it will live in
+ * if necessary. We could potentially make the kernel allocate
+ * a larger aperture space and just bind the subset of pages in,
+ * but this is easier and also keeps us out of trouble (as much)
+ * with drm_intel_bufmgr_check_aperture().
+ */
+ size = i830_get_fence_size(intel, *stride * aligned_h);
+ assert(size >= *stride * aligned_h);
+ }
+
+ return size;
+}
+
/**
* Sets up hardware state for a series of solid fills.
*/
@@ -465,25 +483,71 @@ Bool i830_transform_is_affine(PictTransformPtr t)
return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
}
-dri_bo *i830_get_pixmap_bo(PixmapPtr pixmap)
+struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap)
{
return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
}
-void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
+static void i830_uxa_set_pixmap_intel(PixmapPtr pixmap, struct intel_pixmap *intel)
{
- dri_bo *old_bo = i830_get_pixmap_bo(pixmap);
+ dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel);
+}
- if (old_bo)
- dri_bo_unreference(old_bo);
- if (bo != NULL)
- dri_bo_reference(bo);
- dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+dri_bo *i830_get_pixmap_bo(PixmapPtr pixmap)
+{
+ struct intel_pixmap *intel;
+
+ intel = i830_get_pixmap_intel(pixmap);
+ if (intel == NULL)
+ return NULL;
+
+ return intel->bo;
}
-static void i830_uxa_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
+void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
{
- dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+ struct intel_pixmap *priv;
+
+ priv = i830_get_pixmap_intel(pixmap);
+
+ if (priv != NULL) {
+ dri_bo_unreference(priv->bo);
+
+ priv->flush_read_domains = priv->flush_write_domain = 0;
+ priv->batch_read_domains = priv->batch_write_domain = 0;
+ list_del(&priv->batch);
+ list_del(&priv->flush);
+ }
+
+ if (bo != NULL) {
+ uint32_t swizzle_mode;
+ int ret;
+
+ if (priv == NULL) {
+ priv = xcalloc(1, sizeof (struct intel_pixmap));
+ if (priv == NULL)
+ goto BAIL;
+ }
+
+ dri_bo_reference(bo);
+ priv->bo = bo;
+
+ ret = drm_intel_bo_get_tiling(bo,
+ &priv->tiling,
+ &swizzle_mode);
+ if (ret != 0) {
+ FatalError("Couldn't get tiling on bo %p: %s\n",
+ bo, strerror(-ret));
+ }
+ } else {
+ if (priv != NULL) {
+ xfree(priv);
+ priv = NULL;
+ }
+ }
+
+ BAIL:
+ i830_uxa_set_pixmap_intel(pixmap, priv);
}
static Bool i830_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
@@ -591,8 +655,6 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_screen_private *intel = intel_get_screen_private(scrn);
- dri_bo *bo;
- int stride;
PixmapPtr pixmap;
if (w > 32767 || h > 32767)
@@ -604,47 +666,26 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
if (w && h) {
+ struct intel_pixmap *priv;
unsigned int size;
- uint32_t tiling = I915_TILING_NONE;
- int pitch_align;
-
- if (usage == INTEL_CREATE_PIXMAP_TILING_X) {
- tiling = I915_TILING_X;
- pitch_align = 512;
- } else if (usage == INTEL_CREATE_PIXMAP_TILING_Y) {
- tiling = I915_TILING_Y;
- pitch_align = 512;
- } else {
- pitch_align = intel->accel_pixmap_pitch_alignment;
- }
+ int stride;
- stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
- pitch_align);
-
- if (tiling == I915_TILING_NONE) {
- /* Round the height up so that the GPU's access to a 2x2 aligned
- * subspan doesn't address an invalid page offset beyond the
- * end of the GTT.
- */
- size = stride * ALIGN(h, 2);
- } else {
- int aligned_h = h;
- if (tiling == I915_TILING_X)
- aligned_h = ALIGN(h, 8);
- else
- aligned_h = ALIGN(h, 32);
-
- stride = i830_get_fence_pitch(intel, stride, tiling);
- /* Round the object up to the size of the fence it will live in
- * if necessary. We could potentially make the kernel allocate
- * a larger aperture space and just bind the subset of pages in,
- * but this is easier and also keeps us out of trouble (as much)
- * with drm_intel_bufmgr_check_aperture().
- */
- size = i830_get_fence_size(intel, stride * aligned_h);
- assert(size >= stride * aligned_h);
+ priv = xcalloc(1, sizeof (struct intel_pixmap));
+ if (priv == NULL) {
+ fbDestroyPixmap(pixmap);
+ return NullPixmap;
}
+ if (usage == INTEL_CREATE_PIXMAP_TILING_X)
+ priv->tiling = I915_TILING_X;
+ else if (usage == INTEL_CREATE_PIXMAP_TILING_Y)
+ priv->tiling = I915_TILING_Y;
+ else
+ priv->tiling = I915_TILING_NONE;
+
+ size = i830_uxa_pixmap_compute_size(pixmap, w, h,
+ &priv->tiling, &stride);
+
/* Fail very large allocations on 32-bit systems. Large BOs will
* tend to hit SW fallbacks frequently, and also will tend to fail
* to successfully map when doing SW fallbacks because we overcommit
@@ -655,27 +696,34 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
*/
if (sizeof(unsigned long) == 4 &&
size > (unsigned int)(1024 * 1024 * 1024)) {
+ xfree(priv);
fbDestroyPixmap(pixmap);
return NullPixmap;
}
if (usage == UXA_CREATE_PIXMAP_FOR_MAP)
- bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size,
- 0);
+ priv->bo = drm_intel_bo_alloc(intel->bufmgr,
+ "pixmap", size, 0);
else
- bo = drm_intel_bo_alloc_for_render(intel->bufmgr,
- "pixmap", size, 0);
- if (!bo) {
+ priv->bo = drm_intel_bo_alloc_for_render(intel->bufmgr,
+ "pixmap",
+ size, 0);
+ if (!priv->bo) {
+ xfree(priv);
fbDestroyPixmap(pixmap);
return NullPixmap;
}
- if (tiling != I915_TILING_NONE)
- drm_intel_bo_set_tiling(bo, &tiling, stride);
+ if (priv->tiling != I915_TILING_NONE)
+ drm_intel_bo_set_tiling(priv->bo,
+ &priv->tiling,
+ stride);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
- i830_uxa_set_pixmap_bo(pixmap, bo);
+ list_init(&priv->batch);
+ list_init(&priv->flush);
+ i830_uxa_set_pixmap_intel(pixmap, priv);
}
return pixmap;
@@ -683,16 +731,13 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
static Bool i830_uxa_destroy_pixmap(PixmapPtr pixmap)
{
- if (pixmap->refcnt == 1) {
- dri_bo *bo = i830_get_pixmap_bo(pixmap);
-
- if (bo)
- dri_bo_unreference(bo);
- }
+ if (pixmap->refcnt == 1)
+ i830_set_pixmap_bo(pixmap, NULL);
fbDestroyPixmap(pixmap);
return TRUE;
}
+
void i830_uxa_create_screen_resources(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
@@ -701,8 +746,7 @@ void i830_uxa_create_screen_resources(ScreenPtr screen)
if (bo != NULL) {
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
- i830_uxa_set_pixmap_bo(pixmap, bo);
- dri_bo_reference(bo);
+ i830_set_pixmap_bo(pixmap, bo);
}
}
diff --git a/src/i965_render.c b/src/i965_render.c
index 8e907ebd..8746eb99 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1046,13 +1046,14 @@ static sampler_state_extend_t sampler_state_extend_from_picture(int repeat_type)
* picture in the given surface state buffer.
*/
static void
-i965_set_picture_surface_state(dri_bo * ss_bo, int ss_index,
+i965_set_picture_surface_state(intel_screen_private *intel,
+ dri_bo * ss_bo, int ss_index,
PicturePtr picture, PixmapPtr pixmap,
Bool is_dst)
{
struct brw_surface_state_padded *ss;
struct brw_surface_state local_ss;
- dri_bo *pixmap_bo = i830_get_pixmap_bo(pixmap);
+ struct intel_pixmap *priv = i830_get_pixmap_intel(pixmap);
ss = (struct brw_surface_state_padded *)ss_bo->virtual + ss_index;
@@ -1082,11 +1083,7 @@ i965_set_picture_surface_state(dri_bo * ss_bo, int ss_index,
local_ss.ss0.vert_line_stride_ofs = 0;
local_ss.ss0.mipmap_layout_mode = 0;
local_ss.ss0.render_cache_read_mode = 0;
- local_ss.ss1.base_addr = pixmap_bo->offset;
- if (pixmap_bo != NULL)
- local_ss.ss1.base_addr = pixmap_bo->offset;
- else
- local_ss.ss1.base_addr = intel_get_pixmap_offset(pixmap);
+ local_ss.ss1.base_addr = priv->bo->offset;
local_ss.ss2.mip_count = 0;
local_ss.ss2.render_target_rotation = 0;
@@ -1098,7 +1095,7 @@ i965_set_picture_surface_state(dri_bo * ss_bo, int ss_index,
memcpy(ss, &local_ss, sizeof(local_ss));
- if (pixmap_bo != NULL) {
+ if (priv->bo != NULL) {
uint32_t write_domain, read_domains;
if (is_dst) {
@@ -1108,11 +1105,13 @@ i965_set_picture_surface_state(dri_bo * ss_bo, int ss_index,
write_domain = 0;
read_domains = I915_GEM_DOMAIN_SAMPLER;
}
+
+ intel_batch_mark_pixmap_domains(intel, priv, read_domains, write_domain);
dri_bo_emit_reloc(ss_bo, read_domains, write_domain,
0,
ss_index * sizeof(*ss) +
offsetof(struct brw_surface_state, ss1),
- pixmap_bo);
+ priv->bo);
}
}
@@ -1512,14 +1511,14 @@ i965_prepare_composite(int op, PicturePtr source_picture,
return FALSE;
}
/* Set up the state buffer for the destination surface */
- i965_set_picture_surface_state(surface_state_bo, 0,
+ i965_set_picture_surface_state(intel, surface_state_bo, 0,
dest_picture, dest, TRUE);
/* Set up the source surface state buffer */
- i965_set_picture_surface_state(surface_state_bo, 1,
+ i965_set_picture_surface_state(intel, surface_state_bo, 1,
source_picture, source, FALSE);
if (mask) {
/* Set up the mask surface state buffer */
- i965_set_picture_surface_state(surface_state_bo, 2,
+ i965_set_picture_surface_state(intel, surface_state_bo, 2,
mask_picture, mask, FALSE);
}
dri_bo_unmap(surface_state_bo);