winsys/radeon: cleanup CS offloading
[mesa.git] / src / gallium / winsys / radeon / drm / radeon_drm_winsys.c
index d1f76431b19d3faee864947ad298ba65722414dd..f8aeb968ca4773e32a6d190b4eb1f35073748b29 100644 (file)
@@ -41,6 +41,9 @@
 
 #include <xf86drm.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 /*
  * this are copy from radeon_drm, once an updated libdrm is released
 #define RADEON_INFO_TIMESTAMP 0x11
 #endif
 
+#ifndef RADEON_INFO_RING_WORKING
+#define RADEON_INFO_RING_WORKING 0x15
+#endif
+
+#ifndef RADEON_CS_RING_UVD
+#define RADEON_CS_RING_UVD     3
+#endif
+
 static struct util_hash_table *fd_tab = NULL;
 
 /* Enable/disable feature access for one command stream.
@@ -313,7 +324,13 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
     case CHIP_PITCAIRN:
     case CHIP_VERDE:
     case CHIP_OLAND:
-        ws->info.chip_class = TAHITI;
+    case CHIP_HAINAN:
+        ws->info.chip_class = SI;
+        break;
+    case CHIP_BONAIRE:
+    case CHIP_KAVERI:
+    case CHIP_KABINI:
+        ws->info.chip_class = CIK;
         break;
     }
 
@@ -323,6 +340,15 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
         ws->info.r600_has_dma = TRUE;
     }
 
+    /* Check for UVD */
+    ws->info.has_uvd = FALSE;
+    if (ws->info.drm_minor >= 32) {
+       uint32_t value = RADEON_CS_RING_UVD;
+        if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
+                                 "UVD Ring working", &value))
+            ws->info.has_uvd = value;
+    }
+
     /* Get GEM info. */
     retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
             &gem_info, sizeof(gem_info));
@@ -381,6 +407,8 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
                                       &ws->info.r600_ib_vm_max_size))
                 ws->info.r600_virtual_address = FALSE;
         }
+       if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", FALSE))
+               ws->info.r600_virtual_address = FALSE;
     }
 
     /* Get max pipes, this is only needed for compute shaders.  All evergreen+
@@ -402,11 +430,6 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
         pipe_thread_wait(ws->thread);
     }
     pipe_semaphore_destroy(&ws->cs_queued);
-    pipe_condvar_destroy(ws->cs_queue_empty);
-
-    if (!pipe_reference(&ws->base.reference, NULL)) {
-        return;
-    }
 
     pipe_mutex_destroy(ws->hyperz_owner_mutex);
     pipe_mutex_destroy(ws->cmask_owner_mutex);
@@ -467,57 +490,64 @@ static int radeon_drm_winsys_surface_best(struct radeon_winsys *rws,
     return radeon_surface_best(ws->surf_man, surf);
 }
 
-static uint64_t radeon_query_timestamp(struct radeon_winsys *rws)
-{
-    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
-    uint64_t ts = 0;
-
-    if (ws->info.drm_minor < 20 ||
-        ws->gen < DRV_R600) {
-        assert(0);
-        return 0;
-    }
-
-    radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp",
-                         (uint32_t*)&ts);
-    return ts;
-}
-
 static uint64_t radeon_query_value(struct radeon_winsys *rws,
                                    enum radeon_value_id value)
 {
     struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+    uint64_t ts = 0;
 
     switch (value) {
     case RADEON_REQUESTED_VRAM_MEMORY:
         return ws->allocated_vram;
     case RADEON_REQUESTED_GTT_MEMORY:
         return ws->allocated_gtt;
+    case RADEON_BUFFER_WAIT_TIME_NS:
+        return ws->buffer_wait_time;
+    case RADEON_TIMESTAMP:
+        if (ws->info.drm_minor < 20 || ws->gen < DRV_R600) {
+            assert(0);
+            return 0;
+        }
+
+        radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp",
+                             (uint32_t*)&ts);
+        return ts;
     }
     return 0;
 }
 
 static unsigned hash_fd(void *key)
 {
-    return pointer_to_intptr(key);
+    int fd = pointer_to_intptr(key);
+    struct stat stat;
+    fstat(fd, &stat);
+
+    return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
 }
 
 static int compare_fd(void *key1, void *key2)
 {
-    return pointer_to_intptr(key1) != pointer_to_intptr(key2);
+    int fd1 = pointer_to_intptr(key1);
+    int fd2 = pointer_to_intptr(key2);
+    struct stat stat1, stat2;
+    fstat(fd1, &stat1);
+    fstat(fd2, &stat2);
+
+    return stat1.st_dev != stat2.st_dev ||
+           stat1.st_ino != stat2.st_ino ||
+           stat1.st_rdev != stat2.st_rdev;
 }
 
 void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs)
 {
 retry:
     pipe_mutex_lock(ws->cs_stack_lock);
-    if (p_atomic_read(&ws->ncs) >= RING_LAST) {
+    if (ws->ncs >= RING_LAST) {
         /* no room left for a flush */
         pipe_mutex_unlock(ws->cs_stack_lock);
         goto retry;
     }
-    ws->cs_stack[p_atomic_read(&ws->ncs)] = cs;
-    p_atomic_inc(&ws->ncs);
+    ws->cs_stack[ws->ncs++] = cs;
     pipe_mutex_unlock(ws->cs_stack_lock);
     pipe_semaphore_signal(&ws->cs_queued);
 }
@@ -526,45 +556,31 @@ static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param)
 {
     struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)param;
     struct radeon_drm_cs *cs;
-    unsigned i, empty_stack;
+    unsigned i;
 
     while (1) {
         pipe_semaphore_wait(&ws->cs_queued);
         if (ws->kill_thread)
             break;
-next:
+
         pipe_mutex_lock(ws->cs_stack_lock);
         cs = ws->cs_stack[0];
+        for (i = 1; i < ws->ncs; i++)
+            ws->cs_stack[i - 1] = ws->cs_stack[i];
+        ws->cs_stack[--ws->ncs] = NULL;
         pipe_mutex_unlock(ws->cs_stack_lock);
 
         if (cs) {
-            radeon_drm_cs_emit_ioctl_oneshot(cs->cst);
-
-            pipe_mutex_lock(ws->cs_stack_lock);
-            for (i = 1; i < p_atomic_read(&ws->ncs); i++) {
-                ws->cs_stack[i - 1] = ws->cs_stack[i];
-            }
-            ws->cs_stack[p_atomic_read(&ws->ncs) - 1] = NULL;
-            empty_stack = p_atomic_dec_zero(&ws->ncs);
-            if (empty_stack) {
-                pipe_condvar_signal(ws->cs_queue_empty);
-            }
-            pipe_mutex_unlock(ws->cs_stack_lock);
-
+            radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
             pipe_semaphore_signal(&cs->flush_completed);
-
-            if (!empty_stack) {
-                goto next;
-            }
         }
     }
     pipe_mutex_lock(ws->cs_stack_lock);
-    for (i = 0; i < p_atomic_read(&ws->ncs); i++) {
+    for (i = 0; i < ws->ncs; i++) {
         pipe_semaphore_signal(&ws->cs_stack[i]->flush_completed);
         ws->cs_stack[i] = NULL;
     }
-    p_atomic_set(&ws->ncs, 0);
-    pipe_condvar_signal(ws->cs_queue_empty);
+    ws->ncs = 0;
     pipe_mutex_unlock(ws->cs_stack_lock);
     return NULL;
 }
@@ -619,7 +635,6 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
     ws->base.cs_request_feature = radeon_cs_request_feature;
     ws->base.surface_init = radeon_drm_winsys_surface_init;
     ws->base.surface_best = radeon_drm_winsys_surface_best;
-    ws->base.query_timestamp = radeon_query_timestamp;
     ws->base.query_value = radeon_query_value;
 
     radeon_bomgr_init_functions(ws);
@@ -629,9 +644,8 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
     pipe_mutex_init(ws->cmask_owner_mutex);
     pipe_mutex_init(ws->cs_stack_lock);
 
-    p_atomic_set(&ws->ncs, 0);
+    ws->ncs = 0;
     pipe_semaphore_init(&ws->cs_queued, 0);
-    pipe_condvar_init(ws->cs_queue_empty);
     if (ws->num_cpus > 1 && debug_get_option_thread())
         ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);