summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas@tungstengraphics.com>2006-03-02 11:46:02 +0000
committerThomas Hellstrom <thomas@tungstengraphics.com>2006-03-02 11:46:02 +0000
commit11fc8861d63f9bce4b8c544c989f13f7b65a5775 (patch)
tree9408c9185f5da57f9cfc13e89935213dd5ed7440
parent48e80f7308e543f4db75a61d6c5f08c12c706655 (diff)
ttm: Add lazy rx flush when pages are inserted. Typically this should flush
texture caches when a buffer is swapped in unknowingly to the client, as a result of a previous eviction. localize validation action flag structure.
-rw-r--r--linux-core/drmP.h3
-rw-r--r--linux-core/drm_ttm.c71
2 files changed, 45 insertions, 29 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index e8c02861..e95dd892 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -586,9 +586,6 @@ typedef struct drm_ttm_mm {
typedef struct drm_mm_driver {
int fence_types;
- int evicted_vram;
- int evicted_tt;
- int validated;
int cached_pages;
drm_ttm_mm_t ttm_mm;
drm_mm_t vr_mm;
diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c
index 7510c3a8..feace304 100644
--- a/linux-core/drm_ttm.c
+++ b/linux-core/drm_ttm.c
@@ -596,6 +596,7 @@ int drm_rebind_ttm_region(drm_ttm_backend_list_t * entry,
unsigned long aper_offset)
{
return drm_bind_ttm_region(entry, aper_offset);
+
}
/*
@@ -821,7 +822,6 @@ static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry)
* the locks to wait for fence.
*/
-
do {
list = entry->mm->lru_head.next;
@@ -837,8 +837,9 @@ static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry)
}
evict_fence = evict_priv->fence;
- if (dev->mm_driver->test_fence(dev, evict_priv->region->fence_type,
- evict_fence))
+ if (dev->mm_driver->
+ test_fence(dev, evict_priv->region->fence_type,
+ evict_fence))
break;
spin_unlock(mm_lock);
@@ -850,7 +851,6 @@ static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry)
} while (TRUE);
- dev->mm_driver->evicted_tt = TRUE;
evict_node = evict_priv->region->mm_node;
drm_evict_ttm_region(evict_priv->region);
list_del_init(list);
@@ -870,8 +870,16 @@ static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry)
* the lru list.
*/
+typedef struct drm_val_action {
+ int needs_rx_flush;
+ int evicted_tt;
+ int evicted_vram;
+ int validated;
+} drm_val_action_t;
+
static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry,
- uint32_t fence_type, unsigned *aper_offset)
+ uint32_t fence_type, unsigned *aper_offset,
+ drm_val_action_t * action)
{
drm_mm_node_t *mm_node = entry->mm_node;
drm_ttm_mm_t *mm = entry->mm;
@@ -900,6 +908,7 @@ static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry,
spin_unlock(mm_lock);
return ret;
}
+ action->evicted_tt = TRUE;
}
}
@@ -923,10 +932,12 @@ static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry,
break;
case ttm_evicted:
drm_rebind_ttm_region(entry, mm_node->start);
+ action->needs_rx_flush = TRUE;
break;
case ttm_unbound:
default:
drm_bind_ttm_region(entry, mm_node->start);
+ action->needs_rx_flush = TRUE;
break;
}
@@ -1073,7 +1084,8 @@ static int drm_ttm_create_user_buf(drm_ttm_buf_arg_t * buf_p,
return 0;
}
-static void drm_ttm_handle_buf(drm_file_t * priv, drm_ttm_buf_arg_t * buf_p)
+static void drm_ttm_handle_buf(drm_file_t * priv, drm_ttm_buf_arg_t * buf_p,
+ drm_val_action_t * action)
{
drm_device_t *dev = priv->head->dev;
drm_ttm_t *ttm;
@@ -1094,7 +1106,7 @@ static void drm_ttm_handle_buf(drm_file_t * priv, drm_ttm_buf_arg_t * buf_p)
}
buf_p->ret =
drm_validate_ttm_region(entry, buf_p->fence_type,
- &buf_p->aper_offset);
+ &buf_p->aper_offset, action);
break;
case ttm_validate:
buf_p->ret =
@@ -1121,7 +1133,7 @@ static void drm_ttm_handle_buf(drm_file_t * priv, drm_ttm_buf_arg_t * buf_p)
}
buf_p->ret =
drm_validate_ttm_region(entry, buf_p->fence_type,
- &buf_p->aper_offset);
+ &buf_p->aper_offset, action);
break;
case ttm_unbind:
buf_p->ret =
@@ -1170,18 +1182,17 @@ int drm_ttm_handle_bufs(drm_file_t * priv, drm_ttm_arg_t * ttm_arg)
drm_ttm_buf_arg_t *bufs = NULL, *next, *buf_p;
int i;
volatile drm_mm_sarea_t *sa;
+ drm_val_action_t action;
static void *old_priv;
+ memset(&action, 0, sizeof(action));
+
if (ttm_arg->num_bufs > DRM_TTM_MAX_BUF_BATCH) {
DRM_ERROR("Invalid number of TTM buffers.\n");
return -EINVAL;
}
- mm_driver->evicted_vram = FALSE;
- mm_driver->evicted_tt = FALSE;
- mm_driver->validated = FALSE;
-
if (ttm_arg->num_bufs) {
bufs =
@@ -1211,10 +1222,8 @@ int drm_ttm_handle_bufs(drm_file_t * priv, drm_ttm_arg_t * ttm_arg)
}
buf_p = bufs;
-
-
down(&dev->struct_sem);
-
+
#if 0
if (ttm_arg->do_fence) {
if (old_priv != priv)
@@ -1223,13 +1232,13 @@ int drm_ttm_handle_bufs(drm_file_t * priv, drm_ttm_arg_t * ttm_arg)
}
#endif
for (i = 0; i < ttm_arg->num_bufs; ++i) {
- if (! mm_driver->validated && (buf_p->op == ttm_validate ||
- buf_p->op == ttm_validate_user)) {
+ if (!action.validated && (buf_p->op == ttm_validate ||
+ buf_p->op == ttm_validate_user)) {
drm_ttm_fence_regions(dev, &mm_driver->ttm_mm);
- mm_driver->validated = TRUE;
+ action.validated = TRUE;
}
-
- drm_ttm_handle_buf(priv, buf_p);
+
+ drm_ttm_handle_buf(priv, buf_p, &action);
buf_p++;
}
up(&dev->struct_sem);
@@ -1250,12 +1259,22 @@ int drm_ttm_handle_bufs(drm_file_t * priv, drm_ttm_arg_t * ttm_arg)
}
sa = mm_driver->mm_sarea;
- if (mm_driver->validated)
+
+ if (action.needs_rx_flush) {
+/*
+ * We have inserted new pages and need to make sure that the GPU flushes
+ * read- and exe caches before they are used.
+ */
+ dev->mm_driver->flush_caches(dev,
+ DRM_FLUSH_READ | DRM_FLUSH_EXE);
+ }
+
+ if (action.validated)
sa->validation_seq++;
- if (mm_driver->evicted_vram)
- sa->evict_vram_seq++;
- if (mm_driver->evicted_tt)
+ if (action.evicted_vram)
sa->evict_vram_seq++;
+ if (action.evicted_tt)
+ sa->evict_tt_seq++;
return 0;
}
@@ -1492,7 +1511,7 @@ int drm_mm_fence_ioctl(DRM_IOCTL_ARGS)
ret = 0;
switch (arg.op) {
case emit_fence:
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, filp);
arg.fence_seq = mm_driver->emit_fence(dev, arg.fence_type);
break;
case wait_fence:
@@ -1510,7 +1529,7 @@ int drm_mm_fence_ioctl(DRM_IOCTL_ARGS)
ret = -EINVAL;
}
- arg.mm_sarea = dev->mm_driver->mm_sarea_map->user_token;
+ arg.mm_sarea = dev->mm_driver->mm_sarea_map->user_token;
if (ret)
return ret;