From 6d2b1840b4285a6eb88cba4969fd401d2ee12f07 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 13 Feb 2015 18:47:04 -0500 Subject: joujou: bofreplay was lost in translation somewhere --- bofreplay.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 bofreplay.c 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 + * + * 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 +#include +#include +#include +#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; +} -- cgit v1.2.3