Quoting Kenneth Graunke (2018-05-04 02:12:37)
> @@ -933,6 +945,14 @@ emit_reloc(struct intel_batchbuffer *batch,
>  {
>     assert(target != NULL);
>  
> +   if (target->kflags & EXEC_OBJECT_PINNED) {
> +      brw_use_pinned_bo(batch, target, reloc_flags & RELOC_WRITE);
> +      return target->gtt_offset + target_offset;
> +   }
> +
> +   unsigned int index = add_exec_bo(batch, target);
> +   struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index];
> +
>     if (rlist->reloc_count == rlist->reloc_array_size) {
>        rlist->reloc_array_size *= 2;
>        rlist->relocs = realloc(rlist->relocs,
> @@ -940,9 +960,6 @@ emit_reloc(struct intel_batchbuffer *batch,
>                                sizeof(struct drm_i915_gem_relocation_entry));
>     }
>  
> -   unsigned int index = add_exec_bo(batch, target);
> -   struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index];
> -
>     if (reloc_flags & RELOC_32BIT) {
>        /* Restrict this buffer to the low 32 bits of the address space.
>         *
> @@ -976,6 +993,21 @@ emit_reloc(struct intel_batchbuffer *batch,
>     return entry->offset + target_offset;
>  }
>  
> +void
> +brw_use_pinned_bo(struct intel_batchbuffer *batch, struct brw_bo *bo,
> +                  unsigned writable_flag)
> +{
> +   assert(bo->kflags & EXEC_OBJECT_PINNED);
> +   assert((writable_flag & ~EXEC_OBJECT_WRITE) == 0);
> +
> +   unsigned int index = add_exec_bo(batch, bo);
> +   struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index];
> +   assert(entry->offset == bo->gtt_offset);
> +
> +   if (writable_flag)
> +      entry->flags |= EXEC_OBJECT_WRITE;
> +}

I'm not fond of this (at least the emit_reloc() perspective). In
emit_reloc() we were very careful to order the writes to ensure the
validation object was always consistent with the batchbuffer entry,
and this throws it all away (granted it's not a concern, my worry is
just that the code looks dangerous).

My preference would be something like:

static uint64_t
emit_reloc(struct intel_batchbuffer *batch,
           struct brw_reloc_list *rlist, uint32_t offset,
           struct brw_bo *target, int32_t target_offset,
           unsigned int reloc_flags)
{
   assert(target != NULL);

   unsigned int index = add_exec_bo(batch, target);
   struct drm_i915_gem_exec_object2 *entry = &batch->validation_list[index];

   if (target->kflags & EXEC_OBJECT_PINNED) {
      assert(!(reloc_flags & ~EXEC_OBJECT_WRITE));
      goto skip_relocs;
   }

   if (rlist->reloc_count == rlist->reloc_array_size) {
      rlist->reloc_array_size *= 2;
      rlist->relocs = realloc(rlist->relocs,
                              rlist->reloc_array_size *
                              sizeof(struct drm_i915_gem_relocation_entry));
   }

   if (reloc_flags & RELOC_32BIT) {
      /* Restrict this buffer to the low 32 bits of the address space.
       *
       * Altering the validation list flags restricts it for this batch,
       * but we also alter the BO's kflags to restrict it permanently
       * (until the BO is destroyed and put back in the cache).  Buffers
       * may stay bound across batches, and we want keep it constrained.
       */
      target->kflags &= ~EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
      entry->flags &= ~EXEC_OBJECT_SUPPORTS_48B_ADDRESS;

      /* RELOC_32BIT is not an EXEC_OBJECT_* flag, so get rid of it. */
      reloc_flags &= ~RELOC_32BIT;
   }

   rlist->relocs[rlist->reloc_count++] =
      (struct drm_i915_gem_relocation_entry) {
         .offset = offset,
         .delta = target_offset,
         .target_handle = batch->use_batch_first ? index : target->gem_handle,
         .presumed_offset = entry->offset,
      };

skip_relocs:
   if (reloc_flags)
      entry->flags |= reloc_flags & batch->valid_reloc_flags;

   /* Using the old buffer offset, write in what the right data would be, in
    * case the buffer doesn't move and we can short-circuit the relocation
    * processing in the kernel
    */
   return entry->offset + target_offset;
}

The relationship between validation object entry and the batch buffer
contents is much easier to verify.
-Chris
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to