* Nicolai Haehnle <prefect_@gmx.net>
* Jérôme Glisse <glisse@freedesktop.org>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
+#include <string.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "radeon_cs_gem.h"
#include "radeon_bo_gem.h"
#include "drm.h"
+#include "libdrm.h"
#include "xf86drm.h"
#include "xf86atomic.h"
#include "radeon_drm.h"
+#include "bof.h"
+
+#define CS_BOF_DUMP 0
struct radeon_cs_manager_gem {
- struct radeon_cs_manager base;
- uint32_t device_id;
+ struct radeon_cs_manager base;
+ uint32_t device_id;
+ unsigned nbof;
};
#pragma pack(1)
#define RELOC_SIZE (sizeof(struct cs_reloc_gem) / sizeof(uint32_t))
struct cs_gem {
- struct radeon_cs_int base;
+ struct radeon_cs_int base;
struct drm_radeon_cs cs;
struct drm_radeon_cs_chunk chunks[2];
unsigned nrelocs;
if this bo is for sure not in this cs.*/
if ((atomic_read((atomic_t *)radeon_gem_get_reloc_in_cs(bo)) & cs->id)) {
/* check if bo is already referenced.
- * Scanning from end to begin reduces cycles with mesa because
- * it often relocates same shared dma bo again. */
+ * Scanning from end to begin reduces cycles with mesa because
+ * it often relocates same shared dma bo again. */
for(i = cs->crelocs; i != 0;) {
--i;
idx = i * RELOC_SIZE;
fprintf(stderr, "CS section end at (%s,%s,%d)\n",
file, func, line);
- /* We must reset the section even when there is error. */
- cs->section_ndw = 0;
- return -EPIPE;
+ /* We must reset the section even when there is error. */
+ cs->section_ndw = 0;
+ return -EPIPE;
}
cs->section_ndw = 0;
return 0;
}
+#if CS_BOF_DUMP
+static void cs_gem_dump_bof(struct radeon_cs_int *cs)
+{
+ struct cs_gem *csg = (struct cs_gem*)cs;
+ struct radeon_cs_manager_gem *csm;
+ bof_t *bcs, *blob, *array, *bo, *size, *handle, *device_id, *root;
+ char tmp[256];
+ unsigned i;
+
+ csm = (struct radeon_cs_manager_gem *)cs->csm;
+ root = device_id = bcs = blob = array = bo = size = handle = NULL;
+ root = bof_object();
+ if (root == NULL)
+ goto out_err;
+ device_id = bof_int32(csm->device_id);
+ if (device_id == NULL)
+ return;
+ if (bof_object_set(root, "device_id", device_id))
+ goto out_err;
+ bof_decref(device_id);
+ device_id = NULL;
+ /* dump relocs */
+ blob = bof_blob(csg->nrelocs * 16, csg->relocs);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "reloc", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump cs */
+ blob = bof_blob(cs->cdw * 4, cs->packets);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "pm4", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump bo */
+ array = bof_array();
+ if (array == NULL)
+ goto out_err;
+ for (i = 0; i < csg->base.crelocs; i++) {
+ bo = bof_object();
+ if (bo == NULL)
+ goto out_err;
+ size = bof_int32(csg->relocs_bo[i]->size);
+ if (size == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "size", size))
+ goto out_err;
+ bof_decref(size);
+ size = NULL;
+ handle = bof_int32(csg->relocs_bo[i]->handle);
+ if (handle == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "handle", handle))
+ goto out_err;
+ bof_decref(handle);
+ handle = NULL;
+ radeon_bo_map((struct radeon_bo*)csg->relocs_bo[i], 0);
+ blob = bof_blob(csg->relocs_bo[i]->size, csg->relocs_bo[i]->ptr);
+ radeon_bo_unmap((struct radeon_bo*)csg->relocs_bo[i]);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "data", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ if (bof_array_append(array, bo))
+ goto out_err;
+ bof_decref(bo);
+ bo = NULL;
+ }
+ if (bof_object_set(root, "bo", array))
+ goto out_err;
+ sprintf(tmp, "d-0x%04X-%08d.bof", csm->device_id, csm->nbof++);
+ bof_dump_file(root, tmp);
+out_err:
+ bof_decref(blob);
+ bof_decref(array);
+ bof_decref(bo);
+ bof_decref(size);
+ bof_decref(handle);
+ bof_decref(device_id);
+ bof_decref(root);
+}
+#endif
+
static int cs_gem_emit(struct radeon_cs_int *cs)
{
struct cs_gem *csg = (struct cs_gem*)cs;
unsigned i;
int r;
+ while (cs->cdw & 7)
+ radeon_cs_write_dword((struct radeon_cs *)cs, 0x80000000);
+
+#if CS_BOF_DUMP
+ cs_gem_dump_bof(cs);
+#endif
csg->chunks[0].length_dw = cs->cdw;
chunk_array[0] = (uint64_t)(uintptr_t)&csg->chunks[0];
static int radeon_get_device_id(int fd, uint32_t *device_id)
{
- struct drm_radeon_info info;
+ struct drm_radeon_info info = {};
int r;
*device_id = 0;
info.request = RADEON_INFO_DEVICE_ID;
- info.value = device_id;
+ info.value = (uintptr_t)device_id;
r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
sizeof(struct drm_radeon_info));
return r;
}
-struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
+drm_public struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
{
struct radeon_cs_manager_gem *csm;
return &csm->base;
}
-void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
+drm_public void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
{
free(csm);
}