i965/bufmgr: Skip wait ioctl when not busy.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_program_cache.c
index 8939fb110fdf2833f276f14d1b2f0529ec1f394c..2fd989a41c9f15488815cae9bf499fc22c7a81d2 100644 (file)
 #include "main/imports.h"
 #include "intel_batchbuffer.h"
 #include "brw_state.h"
-#include "brw_vs.h"
 #include "brw_wm.h"
 #include "brw_gs.h"
 #include "brw_cs.h"
 #include "brw_program.h"
+#include "compiler/brw_eu.h"
 
 #define FILE_DEBUG_FLAG DEBUG_STATE
 
+struct brw_cache_item {
+   /**
+    * Effectively part of the key, cache_id identifies what kind of state
+    * buffer is involved, and also which dirty flag should set.
+    */
+   enum brw_cache_id cache_id;
+
+   /** 32-bit hash of the key data */
+   GLuint hash;
+
+   /** for variable-sized keys */
+   GLuint key_size;
+   GLuint aux_size;
+   const void *key;
+
+   uint32_t offset;
+   uint32_t size;
+
+   struct brw_cache_item *next;
+};
+
 static unsigned
 get_program_string_id(enum brw_cache_id cache_id, const void *key)
 {
@@ -192,28 +213,31 @@ static void
 brw_cache_new_bo(struct brw_cache *cache, uint32_t new_size)
 {
    struct brw_context *brw = cache->brw;
-   drm_intel_bo *new_bo;
+   struct brw_bo *new_bo;
+   void *llc_map;
 
-   new_bo = drm_intel_bo_alloc(brw->bufmgr, "program cache", new_size, 64);
+   new_bo = brw_bo_alloc(brw->bufmgr, "program cache", new_size, 64);
+   if (can_do_exec_capture(brw->screen))
+      new_bo->kflags = EXEC_OBJECT_CAPTURE;
    if (brw->has_llc)
-      drm_intel_gem_bo_map_unsynchronized(new_bo);
+      llc_map = brw_bo_map(brw, new_bo, MAP_READ | MAP_ASYNC);
 
    /* Copy any existing data that needs to be saved. */
    if (cache->next_offset != 0) {
       if (brw->has_llc) {
-         memcpy(new_bo->virtual, cache->bo->virtual, cache->next_offset);
+         memcpy(llc_map, cache->map, cache->next_offset);
       } else {
-         drm_intel_bo_map(cache->bo, false);
-         drm_intel_bo_subdata(new_bo, 0, cache->next_offset,
-                              cache->bo->virtual);
-         drm_intel_bo_unmap(cache->bo);
+         void *map = brw_bo_map(brw, cache->bo, MAP_READ);
+         brw_bo_subdata(new_bo, 0, cache->next_offset, map);
+         brw_bo_unmap(cache->bo);
       }
    }
 
    if (brw->has_llc)
-      drm_intel_bo_unmap(cache->bo);
-   drm_intel_bo_unreference(cache->bo);
+      brw_bo_unmap(cache->bo);
+   brw_bo_unreference(cache->bo);
    cache->bo = new_bo;
+   cache->map = brw->has_llc ? llc_map : NULL;
    cache->bo_used_by_gpu = false;
 
    /* Since we have a new BO in place, we need to signal the units
@@ -231,7 +255,7 @@ brw_lookup_prog(const struct brw_cache *cache,
                 enum brw_cache_id cache_id,
                 const void *data, unsigned data_size)
 {
-   const struct brw_context *brw = cache->brw;
+   struct brw_context *brw = cache->brw;
    unsigned i;
    const struct brw_cache_item *item;
 
@@ -242,11 +266,15 @@ brw_lookup_prog(const struct brw_cache *cache,
          if (item->cache_id != cache_id || item->size != data_size)
             continue;
 
+         void *map;
          if (!brw->has_llc)
-            drm_intel_bo_map(cache->bo, false);
-         ret = memcmp(cache->bo->virtual + item->offset, data, item->size);
+            map = brw_bo_map(brw, cache->bo, MAP_READ);
+         else
+            map = cache->map;
+
+         ret = memcmp(map + item->offset, data, item->size);
          if (!brw->has_llc)
-            drm_intel_bo_unmap(cache->bo);
+            brw_bo_unmap(cache->bo);
          if (ret)
             continue;
 
@@ -346,9 +374,9 @@ brw_upload_cache(struct brw_cache *cache,
 
       /* Copy data to the buffer */
       if (brw->has_llc) {
-         memcpy((char *)cache->bo->virtual + item->offset, data, data_size);
+         memcpy(cache->map + item->offset, data, data_size);
       } else {
-         drm_intel_bo_subdata(cache->bo, item->offset, data_size, data);
+         brw_bo_subdata(cache->bo, item->offset, data_size, data);
       }
    }
 
@@ -385,9 +413,11 @@ brw_init_caches(struct brw_context *brw)
    cache->items =
       calloc(cache->size, sizeof(struct brw_cache_item *));
 
-   cache->bo = drm_intel_bo_alloc(brw->bufmgr, "program cache",  4096, 64);
+   cache->bo = brw_bo_alloc(brw->bufmgr, "program cache",  4096, 64);
+   if (can_do_exec_capture(brw->screen))
+      cache->bo->kflags = EXEC_OBJECT_CAPTURE;
    if (brw->has_llc)
-      drm_intel_gem_bo_map_unsynchronized(cache->bo);
+      cache->map = brw_bo_map(brw, cache->bo, MAP_READ | MAP_WRITE | MAP_ASYNC);
 }
 
 static void
@@ -464,10 +494,14 @@ brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache)
 
    DBG("%s\n", __func__);
 
-   if (brw->has_llc)
-      drm_intel_bo_unmap(cache->bo);
-   drm_intel_bo_unreference(cache->bo);
-   cache->bo = NULL;
+   /* This can be NULL if context creation failed early on */
+   if (cache->bo) {
+      if (brw->has_llc)
+         brw_bo_unmap(cache->bo);
+      brw_bo_unreference(cache->bo);
+      cache->bo = NULL;
+      cache->map = NULL;
+   }
    brw_clear_cache(brw, cache);
    free(cache->items);
    cache->items = NULL;
@@ -513,16 +547,21 @@ brw_print_program_cache(struct brw_context *brw)
 {
    const struct brw_cache *cache = &brw->cache;
    struct brw_cache_item *item;
+   void *map;
 
-   drm_intel_bo_map(cache->bo, false);
+   if (!brw->has_llc)
+      map = brw_bo_map(brw, cache->bo, MAP_READ);
+   else
+      map = cache->map;
 
    for (unsigned i = 0; i < cache->size; i++) {
       for (item = cache->items[i]; item; item = item->next) {
          fprintf(stderr, "%s:\n", cache_name(i));
-         brw_disassemble(&brw->screen->devinfo, cache->bo->virtual,
+         brw_disassemble(&brw->screen->devinfo, map,
                          item->offset, item->size, stderr);
       }
    }
 
-   drm_intel_bo_unmap(cache->bo);
+   if (!brw->has_llc)
+      brw_bo_unmap(cache->bo);
 }