summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-03-26 17:15:11 -0700
committerEric Anholt <eric@anholt.net>2009-03-26 17:15:11 -0700
commit8c64183a461a422b0443f84622af48858d5fe6ed (patch)
treefd501f110cf01d6986660b3a4d13271d5978078e /lib
Initial import of intel-graphics-tools with some microbenchmarks.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am10
-rw-r--r--lib/drmtest.c84
-rw-r--r--lib/drmtest.h37
-rw-r--r--lib/intel_batchbuffer.c139
-rw-r--r--lib/intel_batchbuffer.h117
5 files changed, 387 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 00000000..cfcc2bd0
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,10 @@
+libintel_tools_la_SOURCES = \
+ intel_batchbuffer.c \
+ intel_batchbuffer.h \
+ drmtest.c \
+ drmtest.h
+
+noinst_LTLIBRARIES = libintel_tools.la
+
+AM_CFLAGS = $(DRM_CFLAGS) $(WARN_CFLAGS) \
+ -I$(srcdir)/..
diff --git a/lib/drmtest.c b/lib/drmtest.c
new file mode 100644
index 00000000..5d09974b
--- /dev/null
+++ b/lib/drmtest.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include "drmtest.h"
+
+/** Open the first DRM device we can find, searching up to 16 device nodes */
+int drm_open_any(void)
+{
+ char name[20];
+ int i, fd;
+
+ for (i = 0; i < 16; i++) {
+ sprintf(name, "/dev/dri/card%d", i);
+ fd = open(name, O_RDWR);
+ if (fd != -1)
+ return fd;
+ }
+ abort();
+}
+
+
+/**
+ * Open the first DRM device we can find where we end up being the master.
+ */
+int drm_open_any_master(void)
+{
+ char name[20];
+ int i, fd;
+
+ for (i = 0; i < 16; i++) {
+ drm_client_t client;
+ int ret;
+
+ sprintf(name, "/dev/dri/card%d", i);
+ fd = open(name, O_RDWR);
+ if (fd == -1)
+ continue;
+
+ /* Check that we're the only opener and authed. */
+ client.idx = 0;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ assert (ret == 0);
+ if (!client.auth) {
+ close(fd);
+ continue;
+ }
+ client.idx = 1;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ if (ret != -1 || errno != EINVAL) {
+ close(fd);
+ continue;
+ }
+ return fd;
+ }
+ fprintf(stderr, "Couldn't find an un-controlled DRM device\n");
+ abort();
+}
diff --git a/lib/drmtest.h b/lib/drmtest.h
new file mode 100644
index 00000000..afa0df4a
--- /dev/null
+++ b/lib/drmtest.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "xf86drm.h"
+
+int drm_open_any(void);
+int drm_open_any_master(void);
diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
new file mode 100644
index 00000000..1e3148ab
--- /dev/null
+++ b/lib/intel_batchbuffer.c
@@ -0,0 +1,139 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "drm.h"
+#include "intel_batchbuffer.h"
+#include "intel_bufmgr.h"
+
+void
+intel_batchbuffer_reset(struct intel_batchbuffer *batch)
+{
+ if (batch->bo != NULL) {
+ drm_intel_bo_unreference(batch->bo);
+ batch->bo = NULL;
+ }
+
+ if (!batch->buffer)
+ batch->buffer = malloc(BATCH_SZ);
+
+ batch->bo = drm_intel_bo_alloc(batch->bufmgr, "batchbuffer",
+ BATCH_SZ, 4096);
+
+ batch->map = batch->buffer;
+ batch->size = BATCH_SZ;
+ batch->ptr = batch->map;
+}
+
+struct intel_batchbuffer *
+intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr)
+{
+ struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
+
+ batch->bufmgr = bufmgr;
+ intel_batchbuffer_reset(batch);
+
+ return batch;
+}
+
+void
+intel_batchbuffer_free(struct intel_batchbuffer *batch)
+{
+ free (batch->buffer);
+
+ drm_intel_bo_unreference(batch->bo);
+ batch->bo = NULL;
+ free(batch);
+}
+
+void
+intel_batchbuffer_flush(struct intel_batchbuffer *batch)
+{
+ unsigned int used = batch->ptr - batch->map;
+ int ret;
+
+ if (used == 0)
+ return;
+
+ /* Round batchbuffer usage to 2 DWORDs. */
+ if ((used & 4) == 0) {
+ *(uint32_t *) (batch->ptr) = 0; /* noop */
+ batch->ptr += 4;
+ used = batch->ptr - batch->map;
+ }
+
+ /* Mark the end of the buffer. */
+ *(uint32_t *) (batch->ptr) = MI_BATCH_BUFFER_END; /* noop */
+ batch->ptr += 4;
+ used = batch->ptr - batch->map;
+
+ drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer);
+
+ batch->map = NULL;
+ batch->ptr = NULL;
+
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+ assert(ret == 0);
+
+ intel_batchbuffer_reset(batch);
+}
+
+
+/* This is the only way buffers get added to the validate list.
+ */
+void
+intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
+ drm_intel_bo *buffer, uint32_t delta,
+ uint32_t read_domains, uint32_t write_domain)
+{
+ int ret;
+
+ if (batch->ptr - batch->map > batch->bo->size)
+ printf("bad relocation ptr %p map %p offset %d size %ld\n",
+ batch->ptr, batch->map, batch->ptr - batch->map,
+ batch->bo->size);
+
+ ret = drm_intel_bo_emit_reloc(batch->bo, batch->ptr - batch->map,
+ buffer, delta,
+ read_domains, write_domain);
+ intel_batchbuffer_emit_dword(batch, buffer->offset + delta);
+ assert(ret == 0);
+}
+
+void
+intel_batchbuffer_data(struct intel_batchbuffer *batch,
+ const void *data, unsigned int bytes)
+{
+ assert((bytes & 3) == 0);
+ intel_batchbuffer_require_space(batch, bytes);
+ memcpy(batch->ptr, data, bytes);
+ batch->ptr += bytes;
+}
diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
new file mode 100644
index 00000000..d2238309
--- /dev/null
+++ b/lib/intel_batchbuffer.h
@@ -0,0 +1,117 @@
+#ifndef INTEL_BATCHBUFFER_H
+#define INTEL_BATCHBUFFER_H
+
+#include "intel_bufmgr.h"
+#include "i810_reg.h"
+
+#define BATCH_SZ 4096
+#define BATCH_RESERVED 16
+
+struct intel_batchbuffer
+{
+ drm_intel_bufmgr *bufmgr;
+
+ drm_intel_bo *bo;
+
+ uint8_t *buffer;
+
+ uint8_t *map;
+ uint8_t *ptr;
+
+ /* debug stuff */
+ struct {
+ uint8_t *start_ptr;
+ unsigned int total;
+ } emit;
+
+ unsigned int size;
+};
+
+struct intel_batchbuffer *intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr);
+
+void intel_batchbuffer_free(struct intel_batchbuffer *batch);
+
+
+void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
+
+void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
+
+void intel_batchbuffer_data(struct intel_batchbuffer *batch,
+ const void *data, unsigned int bytes);
+
+void intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
+ drm_intel_bo *buffer,
+ uint32_t delta,
+ uint32_t read_domains,
+ uint32_t write_domain);
+
+/* Inline functions - might actually be better off with these
+ * non-inlined. Certainly better off switching all command packets to
+ * be passed as structs rather than dwords, but that's a little bit of
+ * work...
+ */
+static inline int
+intel_batchbuffer_space(struct intel_batchbuffer *batch)
+{
+ return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
+}
+
+
+static inline void
+intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint32_t dword)
+{
+ assert(batch->map);
+ assert(intel_batchbuffer_space(batch) >= 4);
+ *(uint32_t *) (batch->ptr) = dword;
+ batch->ptr += 4;
+}
+
+static inline void
+intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
+ unsigned int sz)
+{
+ assert(sz < batch->size - 8);
+ if (intel_batchbuffer_space(batch) < sz)
+ intel_batchbuffer_flush(batch);
+}
+
+/* Here are the crusty old macros, to be removed:
+ */
+#define BATCH_LOCALS
+
+#define BEGIN_BATCH(n) do { \
+ intel_batchbuffer_require_space(batch, (n)*4); \
+ assert(batch->emit.start_ptr == NULL); \
+ batch->emit.total = (n) * 4; \
+ batch->emit.start_ptr = batch->ptr; \
+} while (0)
+
+#define OUT_BATCH(d) intel_batchbuffer_emit_dword(batch, d)
+
+#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
+ assert((delta) >= 0); \
+ intel_batchbuffer_emit_reloc(batch, buf, delta, \
+ read_domains, write_domain); \
+} while (0)
+
+#define ADVANCE_BATCH() do { \
+ unsigned int _n = batch->ptr - batch->emit.start_ptr; \
+ assert(batch->emit.start_ptr != NULL); \
+ if (_n != batch->emit.total) { \
+ fprintf(stderr, \
+ "ADVANCE_BATCH: %d of %d dwords emitted\n", \
+ _n, batch->emit.total); \
+ abort(); \
+ } \
+ batch->emit.start_ptr = NULL; \
+} while(0)
+
+
+static inline void
+intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
+{
+ intel_batchbuffer_require_space(batch, 4);
+ intel_batchbuffer_emit_dword(batch, MI_FLUSH);
+}
+
+#endif