From bfbecc5c42d9669fceaab683d1464dd353be9492 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 14 Nov 2008 12:08:27 +0100 Subject: libdrm-radeon: new tracker tools To keep record of bo activities and print them when necessary, should help in tracking unbalanced ref/unref calls. --- libdrm/radeon/Makefile.am | 6 +- libdrm/radeon/radeon_bo.h | 29 +++++---- libdrm/radeon/radeon_track.c | 139 +++++++++++++++++++++++++++++++++++++++++++ libdrm/radeon/radeon_track.h | 64 ++++++++++++++++++++ 4 files changed, 224 insertions(+), 14 deletions(-) create mode 100644 libdrm/radeon/radeon_track.c create mode 100644 libdrm/radeon/radeon_track.h (limited to 'libdrm/radeon') diff --git a/libdrm/radeon/Makefile.am b/libdrm/radeon/Makefile.am index d15a266b..39ee021f 100644 --- a/libdrm/radeon/Makefile.am +++ b/libdrm/radeon/Makefile.am @@ -36,11 +36,13 @@ libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ libdrm_radeon_la_SOURCES = \ radeon_bo_gem.c \ - radeon_cs_gem.c + radeon_cs_gem.c \ + radeon_track.c libdrm_radeonincludedir = ${includedir}/drm libdrm_radeoninclude_HEADERS = \ radeon_bo.h \ radeon_cs.h \ radeon_bo_gem.h \ - radeon_cs_gem.h + radeon_cs_gem.h \ + radeon_track.h diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h index f884e0fa..ed785034 100644 --- a/libdrm/radeon/radeon_bo.h +++ b/libdrm/radeon/radeon_bo.h @@ -32,6 +32,7 @@ #include #include +#include "radeon_track.h" /* bo object */ #define RADEON_BO_FLAGS_MACRO_TILE 1 @@ -46,6 +47,9 @@ struct radeon_bo { uint32_t domains; uint32_t flags; unsigned cref; +#ifdef RADEON_BO_TRACK + struct radeon_track *track; +#endif void *ptr; struct radeon_bo_manager *bom; }; @@ -67,6 +71,7 @@ struct radeon_bo_funcs { struct radeon_bo_manager { struct radeon_bo_funcs *funcs; int fd; + struct radeon_tracker tracker; }; static inline void _radeon_bo_debug(struct radeon_bo *bo, @@ -90,10 +95,12 @@ static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, int line) { struct radeon_bo *bo; + bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags); -#ifdef RADEON_BO_TRACK_OPEN +#ifdef RADEON_BO_TRACK if (bo) { - _radeon_bo_debug(bo, 1, file, func, line); + bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle); + radeon_track_add_event(bo->track, file, func, "open", line); } #endif return bo; @@ -105,8 +112,8 @@ static inline void _radeon_bo_ref(struct radeon_bo *bo, int line) { bo->cref++; -#ifdef RADEON_BO_TRACK_REF - _radeon_bo_debug(bo, 2, file, func, line); +#ifdef RADEON_BO_TRACK + radeon_track_add_event(bo->track, file, func, "ref", line); #endif bo->bom->funcs->bo_ref(bo); } @@ -117,8 +124,12 @@ static inline void _radeon_bo_unref(struct radeon_bo *bo, int line) { bo->cref--; -#ifdef RADEON_BO_TRACK_REF - _radeon_bo_debug(bo, 3, file, func, line); +#ifdef RADEON_BO_TRACK + radeon_track_add_event(bo->track, file, func, "unref", line); + if (bo->cref <= 0) { + radeon_tracker_remove_track(&bo->bom->tracker, bo->track); + bo->track = NULL; + } #endif bo->bom->funcs->bo_unref(bo); } @@ -129,9 +140,6 @@ static inline int _radeon_bo_map(struct radeon_bo *bo, const char *func, int line) { -#ifdef RADEON_BO_TRACK_MAP - _radeon_bo_debug(bo, 4, file, func, line); -#endif return bo->bom->funcs->bo_map(bo, write); } @@ -140,9 +148,6 @@ static inline int _radeon_bo_unmap(struct radeon_bo *bo, const char *func, int line) { -#ifdef RADEON_BO_TRACK_MAP - _radeon_bo_debug(bo, 5, file, func, line); -#endif return bo->bom->funcs->bo_unmap(bo); } diff --git a/libdrm/radeon/radeon_track.c b/libdrm/radeon/radeon_track.c new file mode 100644 index 00000000..c0c6f850 --- /dev/null +++ b/libdrm/radeon/radeon_track.c @@ -0,0 +1,139 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse + */ +#include +#include +#include +#include "radeon_track.h" + +void radeon_track_add_event(struct radeon_track *track, + const char *file, + const char *func, + const char *op, + unsigned line) +{ + struct radeon_track_event *event; + + if (track == NULL) { + return; + } + event = (void*)calloc(1,sizeof(struct radeon_track_event)); + if (event == NULL) { + return; + } + event->line = line; + event->file = strdup(file); + event->func = strdup(func); + event->op = strdup(op); + if (event->file == NULL || event->func == NULL || event->op == NULL) { + free(event->file); + free(event->func); + free(event->op); + free(event); + return; + } + event->next = track->events; + track->events = event; +} + +struct radeon_track *radeon_tracker_add_track(struct radeon_tracker *tracker, + unsigned key) +{ + struct radeon_track *track; + + track = (struct radeon_track*)calloc(1, sizeof(struct radeon_track)); + if (track) { + track->next = tracker->tracks.next; + track->prev = &tracker->tracks; + tracker->tracks.next = track; + if (track->next) { + track->next->prev = track; + } + track->key = key; + track->events = NULL; + } + return track; +} + +void radeon_tracker_remove_track(struct radeon_tracker *tracker, + struct radeon_track *track) +{ + struct radeon_track_event *event; + void *tmp; + + if (track == NULL) { + return; + } + track->prev->next = track->next; + if (track->next) { + track->next->prev = track->prev; + } + event = track->events; + while (event) { + tmp = event; + free(event->file); + free(event->func); + free(event->op); + event = event->next; + free(tmp); + } + track->events = NULL; + free(track); +} + +void radeon_tracker_print(struct radeon_tracker *tracker, FILE *file) +{ + struct radeon_track *track; + struct radeon_track_event *event; + void *tmp; + + track = tracker->tracks.next; + while (track) { + event = track->events; + fprintf(file, "[0x%08X] :\n", track->key); + while (event) { + tmp = event; + fprintf(file, " [0x%08X:%s](%s:%s:%d)\n", + track->key, event->op, event->file, + event->func, event->line); + free(event->file); + free(event->func); + free(event->op); + event->file = NULL; + event->func = NULL; + event->op = NULL; + event = event->next; + free(tmp); + } + track->events = NULL; + tmp = track; + track = track->next; + free(tmp); + } +} diff --git a/libdrm/radeon/radeon_track.h b/libdrm/radeon/radeon_track.h new file mode 100644 index 00000000..838d1f38 --- /dev/null +++ b/libdrm/radeon/radeon_track.h @@ -0,0 +1,64 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse + */ +#ifndef RADEON_TRACK_H +#define RADEON_TRACK_H + +struct radeon_track_event { + struct radeon_track_event *next; + char *file; + char *func; + char *op; + unsigned line; +}; + +struct radeon_track { + struct radeon_track *next; + struct radeon_track *prev; + unsigned key; + struct radeon_track_event *events; +}; + +struct radeon_tracker { + struct radeon_track tracks; +}; + +void radeon_track_add_event(struct radeon_track *track, + const char *file, + const char *func, + const char *op, + unsigned line); +struct radeon_track *radeon_tracker_add_track(struct radeon_tracker *tracker, + unsigned key); +void radeon_tracker_remove_track(struct radeon_tracker *tracker, + struct radeon_track *track); +void radeon_tracker_print(struct radeon_tracker *tracker, + FILE *file); + +#endif -- cgit v1.2.3 From 080a45624b2b0ac9e0173f5b93760ae018394dd1 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 14 Nov 2008 12:13:53 +0100 Subject: libdrm-radeon: unreference buffer once cs stream is submited or on cs clean BO are referenced once by reloc to make sure that they not destroyed before we get a chance to flush the cmd stream, so we need to unreference them once in cs submit or cs erase if cs i never submitted so bo can be destructed. --- libdrm/radeon/radeon_cs_gem.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'libdrm/radeon') diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c index f9c9fabb..9488f81c 100644 --- a/libdrm/radeon/radeon_cs_gem.c +++ b/libdrm/radeon/radeon_cs_gem.c @@ -251,7 +251,7 @@ static int cs_gem_emit(struct radeon_cs *cs) { struct cs_gem *csg = (struct cs_gem*)cs; uint64_t chunk_array[2]; - int r; + int r, i; chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0]; chunk_array[1] = (uint64_t)(intptr_t)&csg->chunks[1]; @@ -261,10 +261,11 @@ static int cs_gem_emit(struct radeon_cs *cs) r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS2, &csg->cs, sizeof(struct drm_radeon_cs2)); - if (r) { - return r; + for (i = 0; i < csg->base.crelocs; i++) { + radeon_bo_unref(csg->relocs_bo[i]); + csg->relocs_bo[i] = NULL; } - return 0; + return r; } static int cs_gem_destroy(struct radeon_cs *cs) @@ -281,7 +282,16 @@ static int cs_gem_destroy(struct radeon_cs *cs) static int cs_gem_erase(struct radeon_cs *cs) { struct cs_gem *csg = (struct cs_gem*)cs; + int i; + if (csg->relocs_bo) { + for (i = 0; i < csg->base.crelocs; i++) { + if (csg->relocs_bo[i]) { + radeon_bo_unref(csg->relocs_bo[i]); + csg->relocs_bo[i] = NULL; + } + } + } cs->relocs_total_size = 0; cs->cdw = 0; cs->section = 0; -- cgit v1.2.3 From 5ae79e7edd819b84d9e447a2ab9b995a862ac3a7 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 15 Nov 2008 10:38:44 +0100 Subject: libdrm-radeon: unref return current BO ptr to reflect BO destruction --- libdrm/radeon/radeon_bo.h | 12 ++++++------ libdrm/radeon/radeon_bo_gem.c | 11 ++++++----- libdrm/radeon/radeon_bo_gem.h | 4 ++-- libdrm/radeon/radeon_cs_gem.c | 9 +++++---- libdrm/radeon/radeon_cs_gem.h | 4 ++-- 5 files changed, 21 insertions(+), 19 deletions(-) (limited to 'libdrm/radeon') diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h index ed785034..523cf38e 100644 --- a/libdrm/radeon/radeon_bo.h +++ b/libdrm/radeon/radeon_bo.h @@ -63,7 +63,7 @@ struct radeon_bo_funcs { uint32_t domains, uint32_t flags); void (*bo_ref)(struct radeon_bo *bo); - void (*bo_unref)(struct radeon_bo *bo); + struct radeon_bo *(*bo_unref)(struct radeon_bo *bo); int (*bo_map)(struct radeon_bo *bo, int write); int (*bo_unmap)(struct radeon_bo *bo); }; @@ -118,10 +118,10 @@ static inline void _radeon_bo_ref(struct radeon_bo *bo, bo->bom->funcs->bo_ref(bo); } -static inline void _radeon_bo_unref(struct radeon_bo *bo, - const char *file, - const char *func, - int line) +static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo, + const char *file, + const char *func, + int line) { bo->cref--; #ifdef RADEON_BO_TRACK @@ -131,7 +131,7 @@ static inline void _radeon_bo_unref(struct radeon_bo *bo, bo->track = NULL; } #endif - bo->bom->funcs->bo_unref(bo); + return bo->bom->funcs->bo_unref(bo); } static inline int _radeon_bo_map(struct radeon_bo *bo, diff --git a/libdrm/radeon/radeon_bo_gem.c b/libdrm/radeon/radeon_bo_gem.c index 8ce82919..b6d5b294 100644 --- a/libdrm/radeon/radeon_bo_gem.c +++ b/libdrm/radeon/radeon_bo_gem.c @@ -115,16 +115,16 @@ static void bo_ref(struct radeon_bo *bo) { } -static void bo_unref(struct radeon_bo *bo) +static struct radeon_bo *bo_unref(struct radeon_bo *bo) { struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; struct drm_gem_close args; if (bo == NULL) { - return; + return NULL; } if (bo->cref) { - return; + return bo; } if (bo_gem->map_count) { munmap(bo->ptr, bo->size); @@ -134,6 +134,7 @@ static void bo_unref(struct radeon_bo *bo) args.handle = bo->handle; ioctl(bo->bom->fd, DRM_IOCTL_GEM_CLOSE, &args); free(bo_gem); + return NULL; } static int bo_map(struct radeon_bo *bo, int write) @@ -182,7 +183,7 @@ static struct radeon_bo_funcs bo_gem_funcs = { bo_unmap }; -struct radeon_bo_manager *radeon_bo_manager_gem(int fd) +struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd) { struct bo_manager_gem *bomg; @@ -195,7 +196,7 @@ struct radeon_bo_manager *radeon_bo_manager_gem(int fd) return (struct radeon_bo_manager*)bomg; } -void radeon_bo_manager_gem_shutdown(struct radeon_bo_manager *bom) +void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom) { struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom; diff --git a/libdrm/radeon/radeon_bo_gem.h b/libdrm/radeon/radeon_bo_gem.h index aaefd8c3..c0f68e6d 100644 --- a/libdrm/radeon/radeon_bo_gem.h +++ b/libdrm/radeon/radeon_bo_gem.h @@ -34,7 +34,7 @@ #include "radeon_bo.h" -struct radeon_bo_manager *radeon_bo_manager_gem(int fd); -void radeon_bo_manager_gem_shutdown(struct radeon_bo_manager *bom); +struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd); +void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom); #endif diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c index 9488f81c..91489dff 100644 --- a/libdrm/radeon/radeon_cs_gem.c +++ b/libdrm/radeon/radeon_cs_gem.c @@ -251,7 +251,8 @@ static int cs_gem_emit(struct radeon_cs *cs) { struct cs_gem *csg = (struct cs_gem*)cs; uint64_t chunk_array[2]; - int r, i; + unsigned i; + int r; chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0]; chunk_array[1] = (uint64_t)(intptr_t)&csg->chunks[1]; @@ -282,7 +283,7 @@ static int cs_gem_destroy(struct radeon_cs *cs) static int cs_gem_erase(struct radeon_cs *cs) { struct cs_gem *csg = (struct cs_gem*)cs; - int i; + unsigned i; if (csg->relocs_bo) { for (i = 0; i < csg->base.crelocs; i++) { @@ -318,7 +319,7 @@ static struct radeon_cs_funcs radeon_cs_gem_funcs = { cs_gem_need_flush }; -struct radeon_cs_manager *radeon_cs_manager_gem(int fd) +struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd) { struct radeon_cs_manager *csm; @@ -332,7 +333,7 @@ struct radeon_cs_manager *radeon_cs_manager_gem(int fd) return csm; } -void radeon_cs_manager_gem_shutdown(struct radeon_cs_manager *csm) +void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm) { free(csm); } diff --git a/libdrm/radeon/radeon_cs_gem.h b/libdrm/radeon/radeon_cs_gem.h index f50c5e84..5efd146f 100644 --- a/libdrm/radeon/radeon_cs_gem.h +++ b/libdrm/radeon/radeon_cs_gem.h @@ -35,7 +35,7 @@ #include "radeon_cs.h" -struct radeon_cs_manager *radeon_cs_manager_gem(int fd); -void radeon_cs_manager_gem_shutdown(struct radeon_cs_manager *csm); +struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd); +void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm); #endif -- cgit v1.2.3 From c0ba14fd90e7495d5634c1ce0a9fb5be26230010 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 16 Nov 2008 18:04:43 +0100 Subject: libdrm-radeon: add print callback to cs & small fixes --- libdrm/radeon/radeon_bo.h | 6 +-- libdrm/radeon/radeon_bo_gem.c | 3 +- libdrm/radeon/radeon_cs.h | 6 +++ libdrm/radeon/radeon_cs_gem.c | 103 +++++++++++++++++++++++++++++++++++++++++- libdrm/radeon/radeon_track.c | 1 + 5 files changed, 113 insertions(+), 6 deletions(-) (limited to 'libdrm/radeon') diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h index 523cf38e..44dc0901 100644 --- a/libdrm/radeon/radeon_bo.h +++ b/libdrm/radeon/radeon_bo.h @@ -75,13 +75,13 @@ struct radeon_bo_manager { }; static inline void _radeon_bo_debug(struct radeon_bo *bo, - int opcode, + const char *op, const char *file, const char *func, int line) { - fprintf(stderr, "%02d %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n", - opcode, bo, bo->handle, bo->size, bo->cref, file, func, line); + fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n", + op, bo, bo->handle, bo->size, bo->cref, file, func, line); } static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, diff --git a/libdrm/radeon/radeon_bo_gem.c b/libdrm/radeon/radeon_bo_gem.c index b6d5b294..fdf852a2 100644 --- a/libdrm/radeon/radeon_bo_gem.c +++ b/libdrm/radeon/radeon_bo_gem.c @@ -81,7 +81,6 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, open_arg.name = handle; r = ioctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg); if (r != 0) { - fprintf(stderr, "GEM open failed: %d (%s)\n",r,strerror(r)); free(bo); return NULL; } @@ -95,6 +94,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, args.alignment = alignment; args.initial_domain = bo->base.domains; args.no_backing_store = 0; + args.handle = 0; r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE, &args, sizeof(args)); bo->base.handle = args.handle; @@ -133,6 +133,7 @@ static struct radeon_bo *bo_unref(struct radeon_bo *bo) /* close object */ args.handle = bo->handle; ioctl(bo->bom->fd, DRM_IOCTL_GEM_CLOSE, &args); + memset(bo_gem, 0, sizeof(struct radeon_bo_gem)); free(bo_gem); return NULL; } diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h index 63f104b6..e76121ea 100644 --- a/libdrm/radeon/radeon_cs.h +++ b/libdrm/radeon/radeon_cs.h @@ -87,6 +87,7 @@ struct radeon_cs_funcs { int (*cs_destroy)(struct radeon_cs *cs); int (*cs_erase)(struct radeon_cs *cs); int (*cs_need_flush)(struct radeon_cs *cs); + void (*cs_print)(struct radeon_cs *cs, FILE *file); }; struct radeon_cs_manager { @@ -159,4 +160,9 @@ static inline int radeon_cs_need_flush(struct radeon_cs *cs) return cs->csm->funcs->cs_need_flush(cs); } +static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file) +{ + cs->csm->funcs->cs_print(cs, file); +} + #endif diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c index 91489dff..319d1b9e 100644 --- a/libdrm/radeon/radeon_cs_gem.c +++ b/libdrm/radeon/radeon_cs_gem.c @@ -254,6 +254,8 @@ static int cs_gem_emit(struct radeon_cs *cs) unsigned i; int r; + csg->chunks[0].length_dw = cs->cdw; + chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0]; chunk_array[1] = (uint64_t)(intptr_t)&csg->chunks[1]; @@ -304,7 +306,103 @@ static int cs_gem_erase(struct radeon_cs *cs) static int cs_gem_need_flush(struct radeon_cs *cs) { - return (cs->relocs_total_size > (16*1024*1024)); + return (cs->relocs_total_size > (32*1024*1024)); +} + +#define PACKET_TYPE0 0 +#define PACKET_TYPE1 1 +#define PACKET_TYPE2 2 +#define PACKET_TYPE3 3 + +#define PACKET3_NOP 0x10 +#define PACKET3_SET_SCISSORS 0x1E +#define PACKET3_3D_DRAW_VBUF 0x28 +#define PACKET3_3D_DRAW_IMMD 0x29 +#define PACKET3_3D_DRAW_INDX 0x2A +#define PACKET3_3D_LOAD_VBPNTR 0x2F +#define PACKET3_INDX_BUFFER 0x33 +#define PACKET3_3D_DRAW_VBUF_2 0x34 +#define PACKET3_3D_DRAW_IMMD_2 0x35 +#define PACKET3_3D_DRAW_INDX_2 0x36 + +#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) +#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) +#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) +#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) +#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) + +static void cs_gem_print(struct radeon_cs *cs, FILE *file) +{ + unsigned opcode; + unsigned reg; + unsigned cnt; + int i, j; + + for (i = 0; i < cs->cdw;) { + cnt = CP_PACKET_GET_COUNT(cs->packets[i]); + switch (CP_PACKET_GET_TYPE(cs->packets[i])) { + case PACKET_TYPE0: + fprintf(file, "Pkt0 at %d (%d dwords):\n", i, cnt + 1); + reg = CP_PACKET0_GET_REG(cs->packets[i]); + if (CP_PACKET0_GET_ONE_REG_WR(cs->packets[i++])) { + for (j = 0; j <= cnt; j++) { + fprintf(file, " 0x%08X -> 0x%04X\n", + cs->packets[i++], reg); + } + } else { + for (j = 0; j <= cnt; j++) { + fprintf(file, " 0x%08X -> 0x%04X\n", + cs->packets[i++], reg); + reg += 4; + } + } + break; + case PACKET_TYPE3: + fprintf(file, "Pkt3 at %d :\n", i); + opcode = CP_PACKET3_GET_OPCODE(cs->packets[i++]); + switch (opcode) { + case PACKET3_NOP: + fprintf(file, " PACKET3_NOP:\n"); + break; + case PACKET3_3D_DRAW_VBUF: + fprintf(file, " PACKET3_3D_DRAW_VBUF:\n"); + break; + case PACKET3_3D_DRAW_IMMD: + fprintf(file, " PACKET3_3D_DRAW_IMMD:\n"); + break; + case PACKET3_3D_DRAW_INDX: + fprintf(file, " PACKET3_3D_DRAW_INDX:\n"); + break; + case PACKET3_3D_LOAD_VBPNTR: + fprintf(file, " PACKET3_3D_LOAD_VBPNTR:\n"); + break; + case PACKET3_INDX_BUFFER: + fprintf(file, " PACKET3_INDX_BUFFER:\n"); + break; + case PACKET3_3D_DRAW_VBUF_2: + fprintf(file, " PACKET3_3D_DRAW_VBUF_2:\n"); + break; + case PACKET3_3D_DRAW_IMMD_2: + fprintf(file, " PACKET3_3D_DRAW_IMMD_2:\n"); + break; + case PACKET3_3D_DRAW_INDX_2: + fprintf(file, " PACKET3_3D_DRAW_INDX_2:\n"); + break; + default: + fprintf(file, "Unknow opcode 0x%02X at %d\n", opcode, i); + return; + } + for (j = 0; j <= cnt; j++) { + fprintf(file, " 0x%08X\n", cs->packets[i++]); + } + break; + case PACKET_TYPE1: + case PACKET_TYPE2: + default: + fprintf(file, "Unknow packet 0x%08X at %d\n", cs->packets[i], i); + return; + } + } } static struct radeon_cs_funcs radeon_cs_gem_funcs = { @@ -316,7 +414,8 @@ static struct radeon_cs_funcs radeon_cs_gem_funcs = { cs_gem_emit, cs_gem_destroy, cs_gem_erase, - cs_gem_need_flush + cs_gem_need_flush, + cs_gem_print }; struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd) diff --git a/libdrm/radeon/radeon_track.c b/libdrm/radeon/radeon_track.c index c0c6f850..1623906f 100644 --- a/libdrm/radeon/radeon_track.c +++ b/libdrm/radeon/radeon_track.c @@ -94,6 +94,7 @@ void radeon_tracker_remove_track(struct radeon_tracker *tracker, if (track->next) { track->next->prev = track->prev; } + track->next = track->prev = NULL; event = track->events; while (event) { tmp = event; -- cgit v1.2.3