summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2015-02-13 18:47:04 -0500
committerJerome Glisse <jglisse@redhat.com>2015-02-13 18:47:04 -0500
commit6d2b1840b4285a6eb88cba4969fd401d2ee12f07 (patch)
tree4f3dcfc3c134f59b9a9d433f8203c98e2c482e95
parent8568c748f530bf0bb3cb03e8e456f206f4ae6f0a (diff)
joujou: bofreplay was lost in translation somewhereHEADmaster
-rw-r--r--bofreplay.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/bofreplay.c b/bofreplay.c
new file mode 100644
index 0000000..f3c504e
--- /dev/null
+++ b/bofreplay.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#define _FILE_OFFSET_BITS 64
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "xf86drm.h"
+#include "radeon.h"
+#include "radeon_bo.h"
+#include "radeon_drm.h"
+#include "bof.h"
+
+#pragma pack(1)
+struct radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+#pragma pack()
+
+struct ctx_bo {
+ struct radeon_bo *bo;
+ unsigned handle;
+};
+
+struct ctx {
+ struct radeon radeon;
+ const char **argv;
+ int argc;
+ uint32_t *cs;
+ uint32_t cs_ndw;
+ struct ctx_bo *bos;
+ unsigned nbos;
+ int fd;
+ struct radeon_cs_reloc *relocs;
+};
+
+#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
+#define PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
+
+void ctx_read_bof(struct ctx *ctx)
+{
+ bof_t *bof, *tmp;
+
+ bof = bof_load_file(ctx->argv[1]);
+ if (!bof) {
+ fprintf(stderr, "%s failed to load %s\n", ctx->argv[0], ctx->argv[1]);
+ exit(-1);
+ }
+
+ tmp = bof_object_get(bof, "pm4");
+ if (tmp == NULL) {
+ fprintf(stderr, "no pm4 in bof %s\n", ctx->argv[1]);
+ exit(-1);
+ }
+ ctx->cs_ndw = bof_blob_size(tmp) / 4;
+ ctx->cs = calloc(1, ctx->cs_ndw * 4);
+ memcpy(ctx->cs, bof_blob_value(tmp), ctx->cs_ndw * 4);
+
+ /* bo */
+ tmp = bof_object_get(bof, "bo");
+ if (tmp == NULL) {
+ fprintf(stderr, "no bo in bof %s\n", ctx->argv[1]);
+ exit(-1);
+ }
+ ctx->nbos = bof_array_size(tmp);
+ ctx->bos = calloc(ctx->nbos, sizeof(struct ctx_bo));
+ ctx->relocs = calloc(ctx->nbos, sizeof(struct radeon_cs_reloc));
+ for (unsigned i = 0; i < ctx->nbos; i++) {
+ bof_t *bo, *bo_size, *bo_handle;
+ unsigned size;
+
+ bo = bof_array_get(tmp, i);
+
+ bo_size = bof_object_get(bo, "size");
+ if (bo_size == NULL) {
+ fprintf(stderr, "invalid bo[%d] in bof %s\n", i, ctx->argv[1]);
+ exit(-1);
+ }
+ size = bof_int32_value(bo_size);
+
+ bo_handle = bof_object_get(bo, "handle");
+ if (bo_handle == NULL) {
+ fprintf(stderr, "invalid bo[%d] in bof %s\n", i, ctx->argv[1]);
+ exit(-1);
+ }
+ ctx->bos[i].handle = bof_int32_value(bo_handle);
+
+ bo = bof_object_get(bo, "data");
+ ctx->bos[i].bo = radeon_bo(ctx->radeon.fd, 0, size, 4096, bof_blob_value(bo));
+ if (ctx->bos[i].bo == NULL) {
+ fprintf(stderr, "failed to allocate bo[%d] from bof %s %d\n", i, ctx->argv[1], size);
+ exit(-1);
+ }
+ ctx->relocs[i].handle = ctx->bos[i].bo->handle;
+ ctx->relocs[i].read_domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+ ctx->relocs[i].write_domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+ ctx->relocs[i].flags = 0;
+ }
+
+ /* Update relocation packet. */
+ for (unsigned i = 0; i < ctx->cs_ndw;) {
+ switch (PKT_TYPE_G(ctx->cs[i])) {
+ case 3:
+ if ((ctx->cs[i] & 0xffff) == 0x10) {
+ for (unsigned j = 0; j < ctx->nbos; j++) {
+ if (ctx->bos[j].handle == ctx->cs[i + 1]) {
+ ctx->cs[i + 1] = ctx->bos[j].bo->handle;
+ break;
+ }
+ }
+ }
+ i += PKT_COUNT_G(ctx->cs[i]) + 1;
+ break;
+ case 2:
+ case 1:
+ i++;
+ break;
+ default:
+ i += PKT_COUNT_G(ctx->cs[i]) + 1;
+ break;
+ }
+ }
+}
+
+int ctx_cs_submit(struct ctx *ctx)
+{
+ struct drm_radeon_cs drmib;
+ struct drm_radeon_cs_chunk chunks[2];
+ uint64_t chunk_array[2];
+ int r = 0;
+
+ drmib.num_chunks = 2;
+ drmib.chunks = (uint64_t)(uintptr_t)chunk_array;
+ chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
+ chunks[0].length_dw = ctx->cs_ndw;
+ chunks[0].chunk_data = (uintptr_t)ctx->cs;
+ chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
+ chunks[1].length_dw = ctx->nbos * 4;
+ chunks[1].chunk_data = (uintptr_t)ctx->relocs;
+ chunk_array[0] = (uintptr_t)&chunks[0];
+ chunk_array[1] = (uintptr_t)&chunks[1];
+#if 1
+ r = drmCommandWriteRead(ctx->radeon.fd, DRM_RADEON_CS,
+ &drmib, sizeof(struct drm_radeon_cs));
+#endif
+ return r;
+}
+
+void ctx_dump_bo(struct ctx *ctx, struct radeon_bo *bo, FILE *file)
+{
+ uint32_t *ptr;
+
+ radeon_bo_map(bo);
+ ptr = bo->data;
+
+ for (unsigned i = 0; i < (bo->size >> 2); ++i) {
+ if (!(i % 7)) {
+ fprintf(file, "\n");
+ }
+ fprintf(file, " 0x%08x", ptr[i]);
+ }
+ fprintf(file, "\n");
+
+ radeon_bo_unmap(bo);
+}
+
+void ctx_dump_bos(struct ctx *ctx, FILE *file)
+{
+ for (unsigned i = 0; i < ctx->nbos; i++) {
+ fprintf(file, " bo[%4d](%8d)\n", i, ctx->bos[i].bo->size);
+ ctx_dump_bo(ctx, ctx->bos[i].bo, file);
+ }
+}
+
+int main(int argc, const char *argv[])
+{
+ FILE *file;
+ struct ctx ctx;
+ int r;
+
+ ctx.argc = argc;
+ ctx.argv = argv;
+ if (radeon_init(&ctx.radeon)) {
+ fprintf(stderr, "%s failed to init radeon\n", argv[0]);
+ return -1;
+ }
+
+ ctx_read_bof(&ctx);
+
+ file = fopen("B", "w");
+ fprintf(file, "BEFORE -----------------------------------------------------------------------\n");
+ ctx_dump_bos(&ctx, file);
+ fclose(file);
+
+ r = ctx_cs_submit(&ctx);
+ for (unsigned i = 0; i < ctx.nbos; i++) {
+ radeon_bo_wait(ctx.bos[i].bo);
+ }
+ printf("%s cs submit %s !\n", argv[0], r ? "failure" : "success");
+
+ file = fopen("A", "w");
+ fprintf(file, "AFTER ------------------------------------------------------------------------\n");
+ ctx_dump_bos(&ctx, file);
+ fclose(file);
+
+ return 0;
+}