From: "Zbigniew Kempczyński" <zbigniew.kempczynski@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Subject: [igt-dev] [PATCH i-g-t 2/6] lib/intel_batchbuffer: Introduce intel_bb
Date: Tue, 12 May 2020 10:23:58 +0200 [thread overview]
Message-ID: <20200512082402.26792-3-zbigniew.kempczynski@intel.com> (raw)
In-Reply-To: <20200512082402.26792-1-zbigniew.kempczynski@intel.com>
Simple batchbuffer facility which gathers and outputs relocations.
Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
lib/intel_batchbuffer.c | 202 ++++++++++++++++++++++++++++++++++++++++
lib/intel_batchbuffer.h | 78 ++++++++++++++++
2 files changed, 280 insertions(+)
diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index f1a45b47..c7f52f01 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -41,6 +41,7 @@
#include "rendercopy.h"
#include "media_fill.h"
#include "ioctl_wrappers.h"
+#include "i915/gem_mman.h"
#include "media_spin.h"
#include "gpgpu_fill.h"
#include "igt_aux.h"
@@ -1171,3 +1172,204 @@ igt_media_spinfunc_t igt_get_media_spinfunc(int devid)
return spin;
}
+
+/* Intel batchbuffer v2 */
+struct intel_bb *intel_bb_create(int i915, uint32_t size)
+{
+ struct intel_bb *ibb = calloc(1, sizeof(*ibb));
+
+ igt_assert(ibb);
+
+ ibb->i915 = i915;
+ ibb->devid = intel_get_drm_devid(i915);
+ ibb->gen = intel_gen(ibb->devid);
+ ibb->handle = gem_create(i915, size);
+ ibb->size = size;
+ ibb->batch = gem_mmap__cpu_coherent(i915, ibb->handle, 0, size,
+ PROT_READ | PROT_WRITE);
+ memset(ibb->batch, 0, size);
+ ibb->ptr = ibb->batch;
+ ibb->objects = NULL;
+
+ return ibb;
+}
+
+void intel_bb_destroy(struct intel_bb *ibb)
+{
+ uint32_t i;
+
+ igt_assert(ibb);
+
+ /* Free relocations */
+ for (i = 0; i < ibb->num_objects; i++) {
+ if ((void *) ibb->objects->relocs_ptr)
+ free((void *) ibb->objects->relocs_ptr);
+ }
+
+ free(ibb->objects);
+
+ munmap(ibb->batch, ibb->size);
+ gem_close(ibb->i915, ibb->handle);
+
+ free(ibb);
+}
+
+void intel_bb_set_debug(struct intel_bb *ibb, bool debug)
+{
+ ibb->debug = debug;
+}
+
+static void intel_bb_add_handle(struct intel_bb *ibb, uint32_t handle)
+{
+ uint32_t i;
+
+ igt_assert(ibb);
+
+ /* Skip bb as object, it will be added before exec */
+ if (ibb->handle == handle)
+ return;
+
+ for (i = 0; i < ibb->num_objects; i++)
+ if (ibb->objects[i].handle == handle)
+ return;
+
+ i = ibb->num_objects;
+ ibb->objects = realloc(ibb->objects,
+ sizeof(*ibb->objects) * (i + 1));
+ igt_assert(ibb->objects);
+
+ memset(&ibb->objects[i], 0, sizeof(*ibb->objects));
+ ibb->objects[i].handle = handle;
+
+ ibb->num_objects++;
+}
+
+static void intel_bb_emit_reloc(struct intel_bb *ibb,
+ uint32_t handle,
+ uint32_t read_domains,
+ uint32_t write_domain,
+ uint64_t delta,
+ uint64_t offset,
+ bool use_offset,
+ bool out)
+
+{
+ struct drm_i915_gem_relocation_entry *relocs;
+ uint32_t i;
+
+ intel_bb_add_handle(ibb, handle);
+
+ relocs = ibb->relocs;
+ if (ibb->num_relocs == ibb->allocated_relocs) {
+ ibb->allocated_relocs += 4096 / sizeof(*relocs);
+ relocs = realloc(relocs, sizeof(*relocs) * ibb->allocated_relocs);
+ igt_assert(relocs);
+ ibb->relocs = relocs;
+ }
+
+ i = ibb->num_relocs++;
+ memset(&relocs[i], 0, sizeof(*relocs));
+ relocs[i].target_handle = handle;
+ relocs[i].read_domains = read_domains;
+ relocs[i].write_domain = write_domain;
+ relocs[i].delta = delta;
+ if (use_offset)
+ relocs[i].offset = offset;
+ else
+ relocs[i].offset = intel_bb_offset(ibb);
+
+ if (out) {
+ intel_bb_out(ibb, delta);
+ if (ibb->gen >= 8)
+ intel_bb_out(ibb, delta >> 32);
+ }
+}
+
+void intel_bb_out_reloc(struct intel_bb *ibb,
+ uint32_t read_domains,
+ uint32_t write_domain,
+ uint64_t delta)
+
+{
+ igt_assert(ibb);
+
+ intel_bb_emit_reloc(ibb, ibb->handle, read_domains, write_domain,
+ delta, intel_bb_offset(ibb),
+ false, true);
+}
+
+void intel_bb_offset_reloc(struct intel_bb *ibb, uint32_t handle,
+ uint32_t offset,
+ uint32_t read_domains,
+ uint32_t write_domain)
+{
+ igt_assert(ibb);
+
+ intel_bb_emit_reloc(ibb, handle, read_domains, write_domain,
+ 0, offset, true, false);
+}
+
+static void intel_bb_dump_execbuf(struct drm_i915_gem_execbuffer2 *execbuf)
+{
+ struct drm_i915_gem_exec_object2 *objects;
+ struct drm_i915_gem_relocation_entry *relocs, *reloc;
+ int i, j;
+
+ igt_info("execbuf batch len: %u, start offset: 0x%x, "
+ "DR1: 0x%x, DR4: 0x%x, "
+ "num clip: %u, clipptr: 0x%llx, "
+ "flags: 0x%llx, rsvd1: 0x%llx, rsvd2: 0x%llx\n",
+ execbuf->batch_len, execbuf->batch_start_offset,
+ execbuf->DR1, execbuf->DR4,
+ execbuf->num_cliprects, execbuf->cliprects_ptr,
+ execbuf->flags, execbuf->rsvd1, execbuf->rsvd2);
+
+ igt_info("execbuf buffer_count: %d\n", execbuf->buffer_count);
+ for (i = 0; i < execbuf->buffer_count; i++) {
+ objects = &((struct drm_i915_gem_exec_object2 *) execbuf->buffers_ptr)[i];
+ relocs = (struct drm_i915_gem_relocation_entry *) objects->relocs_ptr;
+ igt_info(" [%d] <handle: %u, reloc_count: %d, reloc_ptr: %p, "
+ "align: %llx, offset: %llx, flags: %llx, rsvd1: %llx, rsvd2: %llx\n",
+ i, objects->handle, objects->relocation_count,
+ (void *) objects->relocs_ptr, objects->alignment, objects->offset,
+ objects->flags, objects->rsvd1, objects->rsvd2);
+ if (objects->relocation_count) {
+ igt_info("execbuf relocs:\n");
+ for (j = 0; j < objects->relocation_count; j++) {
+ reloc = &relocs[j];
+ igt_info(" [%d] <target handle: %u, delta: %x, offset: %llx, "
+ "presumed_offset: %llx, read_domains: %x, write_domain: %x\n",
+ j, reloc->target_handle, reloc->delta, reloc->offset,
+ reloc->presumed_offset, reloc->read_domains, reloc->write_domain);
+ }
+ }
+ }
+}
+
+void intel_bb_exec(struct intel_bb *ibb, uint32_t end_offset)
+{
+ struct drm_i915_gem_execbuffer2 execbuf;
+ uint32_t i;
+ int64_t timeout = NSEC_PER_SEC / 2;
+
+ i = ibb->num_objects++;
+ ibb->objects = realloc(ibb->objects, sizeof(*ibb->objects) * (i + 1));
+ igt_assert(ibb->objects);
+
+ memset(&ibb->objects[i], 0, sizeof(*ibb->objects));
+ ibb->objects[i].relocs_ptr = to_user_pointer(ibb->relocs);
+ ibb->objects[i].relocation_count = ibb->num_relocs;
+ ibb->objects[i].handle = ibb->handle;
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = (uintptr_t) ibb->objects;
+ execbuf.buffer_count = ibb->num_objects;
+ execbuf.batch_len = end_offset;
+ execbuf.flags = I915_EXEC_DEFAULT;
+
+ gem_execbuf(ibb->i915, &execbuf);
+ gem_wait(ibb->i915, ibb->handle, &timeout);
+
+ if (ibb->debug)
+ intel_bb_dump_execbuf(&execbuf);
+}
diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
index 442f3a18..82e3fd91 100644
--- a/lib/intel_batchbuffer.h
+++ b/lib/intel_batchbuffer.h
@@ -7,6 +7,7 @@
#include "igt_core.h"
#include "intel_reg.h"
+#include "drmtest.h"
#define BATCH_SZ 4096
#define BATCH_RESERVED 16
@@ -422,4 +423,81 @@ typedef void (*igt_media_spinfunc_t)(struct intel_batchbuffer *batch,
igt_media_spinfunc_t igt_get_media_spinfunc(int devid);
+
+/*
+ * Batchbuffer without libdrm dependency
+ */
+struct intel_bb {
+ int i915;
+ int gen;
+ bool debug;
+ uint32_t devid;
+ uint32_t handle;
+ uint32_t size;
+ uint32_t *batch;
+ uint32_t *ptr;
+
+ struct drm_i915_gem_exec_object2 *objects;
+ uint32_t num_objects;
+
+ struct drm_i915_gem_relocation_entry *relocs;
+ uint32_t num_relocs;
+ uint32_t allocated_relocs;
+};
+
+struct intel_bb *intel_bb_create(int i915, uint32_t size);
+void intel_bb_destroy(struct intel_bb *ibb);
+void intel_bb_set_debug(struct intel_bb *ibb, bool debug);
+
+inline uint32_t intel_bb_offset(struct intel_bb *ibb)
+{
+ return (uint32_t) ((uint8_t *) ibb->ptr - (uint8_t *) ibb->batch);
+}
+
+inline void intel_bb_ptr_set(struct intel_bb *ibb, uint32_t offset)
+{
+ ibb->ptr = (void *) ((uint8_t *) ibb->batch + offset);
+
+ igt_assert(intel_bb_offset(ibb) < ibb->size);
+}
+
+inline void intel_bb_ptr_add(struct intel_bb *ibb, uint32_t offset)
+{
+ ibb->ptr = (void *) ((uint8_t *) ibb->ptr + offset);
+
+ igt_assert(intel_bb_offset(ibb) < ibb->size);
+}
+
+inline void intel_bb_ptr_align(struct intel_bb *ibb, uint32_t alignment)
+{
+ ibb->ptr = (void *) ALIGN((uintptr_t) ibb->ptr, (uintptr_t) alignment);
+
+ igt_assert(intel_bb_offset(ibb) < ibb->size);
+}
+
+inline void *intel_bb_ptr(struct intel_bb *ibb)
+{
+ return (void *) ibb->ptr;
+}
+
+inline void intel_bb_out(struct intel_bb *ibb, uint32_t dword)
+{
+ *ibb->ptr = dword;
+ ibb->ptr++;
+
+ igt_assert(intel_bb_offset(ibb) < ibb->size);
+}
+
+void intel_bb_out_reloc(struct intel_bb *ibb,
+ uint32_t read_domains,
+ uint32_t write_domain,
+ uint64_t delta);
+
+void intel_bb_offset_reloc(struct intel_bb *ibb, uint32_t handle,
+ uint32_t offset,
+ uint32_t read_domains,
+ uint32_t write_domain);
+
+void intel_bb_exec(struct intel_bb *ibb, uint32_t end_offset);
+
#endif
--
2.26.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
next prev parent reply other threads:[~2020-05-12 8:24 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-12 8:23 [igt-dev] [PATCH i-g-t 0/6] Make gpgpu fill tests libdrm independent Zbigniew Kempczyński
2020-05-12 8:23 ` [igt-dev] [PATCH i-g-t 1/6] lib/intel_bufops: Add bufops reference and relaxate stride requirement Zbigniew Kempczyński
2020-05-12 9:29 ` Chris Wilson
2020-05-12 8:23 ` Zbigniew Kempczyński [this message]
2020-05-12 9:39 ` [igt-dev] [PATCH i-g-t 2/6] lib/intel_batchbuffer: Introduce intel_bb Chris Wilson
2020-05-12 8:23 ` [igt-dev] [PATCH i-g-t 3/6] lib/intel_batchbuffer: Introduce temporary igt_fillfunc_v2_t Zbigniew Kempczyński
2020-05-12 8:24 ` [igt-dev] [PATCH i-g-t 4/6] lib/gpu_cmds: Add gpgpu pipeline functions based on intel_bb Zbigniew Kempczyński
2020-05-12 8:24 ` [igt-dev] [PATCH i-g-t 5/6] lib/gpgpu_fill: libdrm-free gpgpu pipeline creation for gen7 Zbigniew Kempczyński
2020-05-12 8:24 ` [igt-dev] [PATCH i-g-t 6/6] tests/gem_gpgpu_fill: Add gen7 version without libdrm dependency Zbigniew Kempczyński
2020-05-12 8:59 ` [igt-dev] ✓ Fi.CI.BAT: success for Make gpgpu fill tests libdrm independent Patchwork
2020-05-12 10:43 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200512082402.26792-3-zbigniew.kempczynski@intel.com \
--to=zbigniew.kempczynski@intel.com \
--cc=chris@chris-wilson.co.uk \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox