i965: Use I915_EXEC_BATCH_FIRST when available.
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 3 Aug 2017 06:40:50 +0000 (23:40 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 4 Aug 2017 17:26:37 +0000 (10:26 -0700)
This will make it easier to use I915_EXEC_HANDLE_LUT.

Based on a patch by Chris Wilson.

src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/i965/intel_screen.h

index a4a04daaa99aa0052ecf21d5f7097eedbd5b435e..33e8947bb8f7ce06a84c662c92830a3c5d720324 100644 (file)
@@ -451,6 +451,7 @@ struct intel_batchbuffer {
 
    uint32_t state_batch_offset;
    enum brw_gpu_ring ring;
+   bool use_batch_first;
    bool needs_sol_reset;
    bool state_base_address_emitted;
 
index 19a6c0edb7c073555fe677774bf5764dccc8e7c8..e9a30ef34ab7474b4180d821e6529d82daade912 100644 (file)
@@ -62,7 +62,7 @@ intel_batchbuffer_init(struct intel_batchbuffer *batch,
                        struct brw_bufmgr *bufmgr,
                        bool has_llc)
 {
-   intel_batchbuffer_reset(batch, bufmgr, has_llc);
+   struct brw_context *brw = container_of(batch, brw, batch);
 
    if (!has_llc) {
       batch->cpu_map = malloc(BATCH_SZ);
@@ -85,6 +85,11 @@ intel_batchbuffer_init(struct intel_batchbuffer *batch,
       batch->state_batch_sizes =
          _mesa_hash_table_create(NULL, uint_key_hash, uint_key_compare);
    }
+
+   batch->use_batch_first =
+      brw->screen->kernel_features & KERNEL_ALLOWS_EXEC_BATCH_FIRST;
+
+   intel_batchbuffer_reset(batch, bufmgr, has_llc);
 }
 
 #define READ_ONCE(x) (*(volatile __typeof__(x) *)&(x))
@@ -120,13 +125,8 @@ add_exec_bo(struct intel_batchbuffer *batch, struct brw_bo *bo)
    struct drm_i915_gem_exec_object2 *validation_entry =
       &batch->validation_list[batch->exec_count];
    validation_entry->handle = bo->gem_handle;
-   if (bo == batch->bo) {
-      validation_entry->relocation_count = batch->reloc_count;
-      validation_entry->relocs_ptr = (uintptr_t) batch->relocs;
-   } else {
-      validation_entry->relocation_count = 0;
-      validation_entry->relocs_ptr = 0;
-   }
+   validation_entry->relocation_count = 0;
+   validation_entry->relocs_ptr = 0;
    validation_entry->alignment = bo->align;
    validation_entry->offset = bo->offset64;
    validation_entry->flags = bo->kflags;
@@ -157,6 +157,9 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch,
    }
    batch->map_next = batch->map;
 
+   add_exec_bo(batch, batch->bo);
+   assert(batch->bo->index == 0);
+
    batch->reserved_space = BATCH_RESERVED;
    batch->state_batch_offset = batch->bo->size;
    batch->needs_sol_reset = false;
@@ -662,8 +665,22 @@ do_flush_locked(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
       if (ret == 0) {
          uint32_t hw_ctx = batch->ring == RENDER_RING ? brw->hw_ctx : 0;
 
-         /* Add the batch itself to the end of the validation list */
-         add_exec_bo(batch, batch->bo);
+         struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[0];
+         assert(entry->handle == batch->bo->gem_handle);
+         entry->relocation_count = batch->reloc_count;
+         entry->relocs_ptr = (uintptr_t) batch->relocs;
+
+         if (batch->use_batch_first) {
+            flags |= I915_EXEC_BATCH_FIRST;
+         } else {
+            /* Move the batch to the end of the validation list */
+            struct drm_i915_gem_exec_object2 tmp;
+            const unsigned index = batch->exec_count - 1;
+
+            tmp = *entry;
+            *entry = batch->validation_list[index];
+            batch->validation_list[index] = tmp;
+         }
 
          ret = execbuffer(dri_screen->fd, batch, hw_ctx,
                           4 * USED_BATCH(*batch),
index dd6bc68ded61261b393f6da9ee5968ea9570f030..ec07cf0acc72a0908162541fd448f2f257e5731e 100644 (file)
@@ -2267,6 +2267,10 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
       screen->kernel_features |= KERNEL_ALLOWS_EXEC_CAPTURE;
    }
 
+   if (intel_get_boolean(screen, I915_PARAM_HAS_EXEC_BATCH_FIRST)) {
+      screen->kernel_features |= KERNEL_ALLOWS_EXEC_BATCH_FIRST;
+   }
+
    if (!intel_detect_pipelined_so(screen)) {
       /* We can't do anything, so the effective version is 0. */
       screen->cmd_parser_version = 0;
index 0c750befd101dd230945ff77284258a6f1965a9a..41e1dbdd4e93cb2b680cfd01a4f0cc8615cfaca1 100644 (file)
@@ -80,6 +80,7 @@ struct intel_screen
 #define KERNEL_ALLOWS_HSW_SCRATCH1_AND_ROW_CHICKEN3 (1<<3)
 #define KERNEL_ALLOWS_COMPUTE_DISPATCH              (1<<4)
 #define KERNEL_ALLOWS_EXEC_CAPTURE                  (1<<5)
+#define KERNEL_ALLOWS_EXEC_BATCH_FIRST              (1<<6)
 
    struct brw_bufmgr *bufmgr;