summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-11 00:16:25 -0700
committerKeith Packard <keithp@keithp.com>2008-05-11 00:16:25 -0700
commit145523ba3acb95a9ff390430a9e0a3fa958cae1b (patch)
treeb783bdcfe39964f41f0fb85e05ec6a666937ab35
parent0cb006c1fdb75e1fe282120cc5455a4e8c59b1a7 (diff)
[intel] update GEM api. Add bo_subdata and bo_get_subdata driver hooks.
Track DRM GEM name changes. Add driver hooks for bo_subdata and bo_get_subdata so that GEM can use pread and pwrite.
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.c25
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.h26
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c26
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_bufmgr_gem.c155
5 files changed, 166 insertions, 68 deletions
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c
index 5967d7dafb3..19ea2a8f86d 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.c
@@ -90,28 +90,41 @@ dri_bo_unmap(dri_bo *buf)
return buf->bufmgr->bo_unmap(buf);
}
-void
+int
dri_bo_subdata(dri_bo *bo, unsigned long offset,
unsigned long size, const void *data)
{
+ int ret;
+ if (bo->bufmgr->bo_subdata)
+ return bo->bufmgr->bo_subdata(bo, offset, size, data);
if (size == 0 || data == NULL)
- return;
+ return 0;
- dri_bo_map(bo, GL_TRUE);
+ ret = dri_bo_map(bo, GL_TRUE);
+ if (ret)
+ return ret;
memcpy((unsigned char *)bo->virtual + offset, data, size);
dri_bo_unmap(bo);
+ return 0;
}
-void
+int
dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
unsigned long size, void *data)
{
+ int ret;
+ if (bo->bufmgr->bo_subdata)
+ return bo->bufmgr->bo_get_subdata(bo, offset, size, data);
+
if (size == 0 || data == NULL)
- return;
+ return 0;
- dri_bo_map(bo, GL_FALSE);
+ ret = dri_bo_map(bo, GL_FALSE);
+ if (ret)
+ return ret;
memcpy(data, (unsigned char *)bo->virtual + offset, size);
dri_bo_unmap(bo);
+ return 0;
}
void
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h
index 99cfb2cd058..29f9aea2b15 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.h
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.h
@@ -110,6 +110,24 @@ struct _dri_bufmgr {
int (*bo_unmap)(dri_bo *buf);
/**
+ * Write data into an object.
+ *
+ * This is an optional function, if missing,
+ * dri_bo will map/memcpy/unmap.
+ */
+ int (*bo_subdata) (dri_bo *buf, unsigned long offset,
+ unsigned long size, const void *data);
+
+ /**
+ * Read data from an object
+ *
+ * This is an optional function, if missing,
+ * dri_bo will map/memcpy/unmap.
+ */
+ int (*bo_get_subdata) (dri_bo *bo, unsigned long offset,
+ unsigned long size, void *data);
+
+ /**
* Tears down the buffer manager instance.
*/
void (*destroy)(dri_bufmgr *bufmgr);
@@ -170,10 +188,10 @@ void dri_bo_unreference(dri_bo *bo);
int dri_bo_map(dri_bo *buf, GLboolean write_enable);
int dri_bo_unmap(dri_bo *buf);
-void dri_bo_subdata(dri_bo *bo, unsigned long offset,
- unsigned long size, const void *data);
-void dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
- unsigned long size, void *data);
+int dri_bo_subdata(dri_bo *bo, unsigned long offset,
+ unsigned long size, const void *data);
+int dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
+ unsigned long size, void *data);
void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, GLboolean enable_debug);
void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index b626e90476f..803ff5e90ee 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -78,11 +78,18 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
batch->buf = NULL;
}
+ if (!batch->buffer && intel->ttm == GL_TRUE)
+ batch->buffer = malloc (intel->maxBatchSize);
+
batch->buf = dri_bo_alloc(intel->bufmgr, "batchbuffer",
intel->maxBatchSize, 4096,
DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
- dri_bo_map(batch->buf, GL_TRUE);
- batch->map = batch->buf->virtual;
+ if (batch->buffer)
+ batch->map = batch->buffer;
+ else {
+ dri_bo_map(batch->buf, GL_TRUE);
+ batch->map = batch->buf->virtual;
+ }
batch->size = intel->maxBatchSize;
batch->ptr = batch->map;
batch->dirty_state = ~0;
@@ -107,9 +114,13 @@ intel_batchbuffer_alloc(struct intel_context *intel)
void
intel_batchbuffer_free(struct intel_batchbuffer *batch)
{
- if (batch->map) {
- dri_bo_unmap(batch->buf);
- batch->map = NULL;
+ if (batch->buffer)
+ free (batch->buffer);
+ else {
+ if (batch->map) {
+ dri_bo_unmap(batch->buf);
+ batch->map = NULL;
+ }
}
dri_bo_unreference(batch->buf);
batch->buf = NULL;
@@ -127,7 +138,10 @@ do_flush_locked(struct intel_batchbuffer *batch,
struct intel_context *intel = batch->intel;
int ret = 0;
- dri_bo_unmap(batch->buf);
+ if (batch->buffer)
+ dri_bo_subdata (batch->buf, 0, used, batch->buffer);
+ else
+ dri_bo_unmap(batch->buf);
batch->map = NULL;
batch->ptr = NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index 5e8b14b4010..d3c656c8034 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -41,6 +41,8 @@ struct intel_batchbuffer
dri_bo *buf;
+ GLubyte *buffer;
+
GLubyte *map;
GLubyte *ptr;
diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c b/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c
index 399a6a12e31..2de08f6529e 100644
--- a/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c
+++ b/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c
@@ -92,10 +92,10 @@ typedef struct _dri_bufmgr_gem {
uint32_t max_relocs;
- struct drm_i915_gem_validate_entry *validate_array;
- dri_bo **validate_bo;
- int validate_array_size;
- int validate_count;
+ struct drm_i915_gem_exec_object *exec_objects;
+ dri_bo **exec_bos;
+ int exec_size;
+ int exec_count;
/** Array of lists of cached gem objects of power-of-two sizes */
struct dri_gem_bo_bucket cache_bucket[INTEL_GEM_BO_BUCKETS];
@@ -166,8 +166,8 @@ static void dri_gem_dump_validation_list(dri_bufmgr_gem *bufmgr_gem)
{
int i, j;
- for (i = 0; i < bufmgr_gem->validate_count; i++) {
- dri_bo *bo = bufmgr_gem->validate_bo[i];
+ for (i = 0; i < bufmgr_gem->exec_count; i++) {
+ dri_bo *bo = bufmgr_gem->exec_bos[i];
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
if (bo_gem->relocs == NULL) {
@@ -207,32 +207,32 @@ intel_add_validate_buffer(dri_bo *bo)
return;
/* Extend the array of validation entries as necessary. */
- if (bufmgr_gem->validate_count == bufmgr_gem->validate_array_size) {
- int new_size = bufmgr_gem->validate_array_size * 2;
+ if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) {
+ int new_size = bufmgr_gem->exec_size * 2;
if (new_size == 0)
new_size = 5;
- bufmgr_gem->validate_array =
- realloc(bufmgr_gem->validate_array,
- sizeof(*bufmgr_gem->validate_array) * new_size);
- bufmgr_gem->validate_bo =
- realloc(bufmgr_gem->validate_bo,
- sizeof(*bufmgr_gem->validate_bo) * new_size);
- bufmgr_gem->validate_array_size = new_size;
+ bufmgr_gem->exec_objects =
+ realloc(bufmgr_gem->exec_objects,
+ sizeof(*bufmgr_gem->exec_objects) * new_size);
+ bufmgr_gem->exec_bos =
+ realloc(bufmgr_gem->exec_bos,
+ sizeof(*bufmgr_gem->exec_bos) * new_size);
+ bufmgr_gem->exec_size = new_size;
}
- index = bufmgr_gem->validate_count;
+ index = bufmgr_gem->exec_count;
bo_gem->validate_index = index;
/* Fill in array entry */
- bufmgr_gem->validate_array[index].buffer_handle = bo_gem->gem_handle;
- bufmgr_gem->validate_array[index].relocation_count = bo_gem->reloc_count;
- bufmgr_gem->validate_array[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
- bufmgr_gem->validate_array[index].alignment = 0;
- bufmgr_gem->validate_array[index].buffer_offset = 0;
- bufmgr_gem->validate_bo[index] = bo;
+ bufmgr_gem->exec_objects[index].handle = bo_gem->gem_handle;
+ bufmgr_gem->exec_objects[index].relocation_count = bo_gem->reloc_count;
+ bufmgr_gem->exec_objects[index].relocs_ptr = (uintptr_t)bo_gem->relocs;
+ bufmgr_gem->exec_objects[index].alignment = 0;
+ bufmgr_gem->exec_objects[index].offset = 0;
+ bufmgr_gem->exec_bos[index] = bo;
dri_bo_reference(bo);
- bufmgr_gem->validate_count++;
+ bufmgr_gem->exec_count++;
}
@@ -309,13 +309,13 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
}
if (!alloc_from_cache) {
- struct drm_gem_alloc alloc;
+ struct drm_gem_create create;
- memset(&alloc, 0, sizeof(alloc));
- alloc.size = bo_gem->bo.size;
+ memset(&create, 0, sizeof(create));
+ create.size = bo_gem->bo.size;
- ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_ALLOC, &alloc);
- bo_gem->gem_handle = alloc.handle;
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CREATE, &create);
+ bo_gem->gem_handle = create.handle;
if (ret != 0) {
free(bo_gem);
return NULL;
@@ -439,14 +439,14 @@ dri_gem_bo_unreference(dri_bo *bo)
bucket->tail = &entry->next;
bucket->num_entries++;
} else {
- struct drm_gem_unreference unref;
+ struct drm_gem_close close;
- /* Decrement the kernel refcount for the buffer. */
- unref.handle = bo_gem->gem_handle;
- ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_UNREFERENCE, &unref);
+ /* Close this object */
+ close.handle = bo_gem->gem_handle;
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
if (ret != 0) {
fprintf(stderr,
- "DRM_IOCTL_GEM_UNREFERENCE %d failed (%s): %s\n",
+ "DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n",
bo_gem->gem_handle, bo_gem->name, strerror(-ret));
}
}
@@ -537,14 +537,62 @@ dri_gem_bo_unmap(dri_bo *bo)
return 0;
}
+static int
+dri_gem_bo_subdata (dri_bo *bo, unsigned long offset,
+ unsigned long size, const void *data)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+ struct drm_gem_pwrite pwrite;
+ int ret;
+
+ memset (&pwrite, 0, sizeof (pwrite));
+ pwrite.handle = bo_gem->gem_handle;
+ pwrite.offset = offset;
+ pwrite.size = size;
+ pwrite.data_ptr = (uint64_t) (uintptr_t) data;
+ ret = ioctl (bufmgr_gem->fd, DRM_IOCTL_GEM_PWRITE, &pwrite);
+ if (ret != 0) {
+ fprintf (stderr, "%s:%d: Error writing data to buffer %d: (%d %d) %s .\n",
+ __FILE__, __LINE__,
+ bo_gem->gem_handle, (int) offset, (int) size,
+ strerror (errno));
+ }
+ return 0;
+}
+
+static int
+dri_gem_bo_get_subdata (dri_bo *bo, unsigned long offset,
+ unsigned long size, void *data)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+ struct drm_gem_pread pread;
+ int ret;
+
+ memset (&pread, 0, sizeof (pread));
+ pread.handle = bo_gem->gem_handle;
+ pread.offset = offset;
+ pread.size = size;
+ pread.data_ptr = (uint64_t) (uintptr_t) data;
+ ret = ioctl (bufmgr_gem->fd, DRM_IOCTL_GEM_PREAD, &pread);
+ if (ret != 0) {
+ fprintf (stderr, "%s:%d: Error reading data from buffer %d: (%d %d) %s .\n",
+ __FILE__, __LINE__,
+ bo_gem->gem_handle, (int) offset, (int) size,
+ strerror (errno));
+ }
+ return 0;
+}
+
static void
dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
{
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
int i;
- free(bufmgr_gem->validate_array);
- free(bufmgr_gem->validate_bo);
+ free(bufmgr_gem->exec_objects);
+ free(bufmgr_gem->exec_bos);
/* Free any cached buffer objects we were going to reuse */
for (i = 0; i < INTEL_GEM_BO_BUCKETS; i++) {
@@ -552,7 +600,7 @@ dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
struct dri_gem_bo_bucket_entry *entry;
while ((entry = bucket->head) != NULL) {
- struct drm_gem_unreference unref;
+ struct drm_gem_close close;
int ret;
bucket->head = entry->next;
@@ -560,11 +608,11 @@ dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
bucket->tail = &bucket->head;
bucket->num_entries--;
- /* Decrement the kernel refcount for the buffer. */
- unref.handle = entry->gem_handle;
- ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_UNREFERENCE, &unref);
+ /* Close this object */
+ close.handle = entry->gem_handle;
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
if (ret != 0) {
- fprintf(stderr, "DRM_IOCTL_GEM_UNREFERENCE failed: %s\n",
+ fprintf(stderr, "DRM_IOCTL_GEM_CLOSE failed: %s\n",
strerror(-ret));
}
@@ -655,9 +703,10 @@ dri_gem_process_reloc(dri_bo *batch_buf)
*/
intel_add_validate_buffer(batch_buf);
- bufmgr_gem->exec_arg.buffers_ptr = (uintptr_t)bufmgr_gem->validate_array;
- bufmgr_gem->exec_arg.buffer_count = bufmgr_gem->validate_count;
- bufmgr_gem->exec_arg.batch_start_offset = bufmgr_gem->validate_count;
+ bufmgr_gem->exec_arg.buffers_ptr = (uintptr_t)bufmgr_gem->exec_objects;
+ bufmgr_gem->exec_arg.buffer_count = bufmgr_gem->exec_count;
+ bufmgr_gem->exec_arg.batch_start_offset = 0;
+ bufmgr_gem->exec_arg.batch_len = 0; /* written in intel_exec_ioctl */
return &bufmgr_gem->exec_arg;
}
@@ -667,16 +716,16 @@ intel_update_buffer_offsets (dri_bufmgr_gem *bufmgr_gem)
{
int i;
- for (i = 0; i < bufmgr_gem->validate_count; i++) {
- dri_bo *bo = bufmgr_gem->validate_bo[i];
+ for (i = 0; i < bufmgr_gem->exec_count; i++) {
+ dri_bo *bo = bufmgr_gem->exec_bos[i];
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
/* Update the buffer offset */
- if (bufmgr_gem->validate_array[i].buffer_offset != bo->offset) {
+ if (bufmgr_gem->exec_objects[i].offset != bo->offset) {
DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
bo_gem->gem_handle, bo_gem->name, bo->offset,
- bufmgr_gem->validate_array[i].buffer_offset);
- bo->offset = bufmgr_gem->validate_array[i].buffer_offset;
+ bufmgr_gem->exec_objects[i].offset);
+ bo->offset = bufmgr_gem->exec_objects[i].offset;
}
}
}
@@ -692,16 +741,16 @@ dri_gem_post_submit(dri_bo *batch_buf)
if (bufmgr_gem->bufmgr.debug)
dri_gem_dump_validation_list(bufmgr_gem);
- for (i = 0; i < bufmgr_gem->validate_count; i++) {
- dri_bo *bo = bufmgr_gem->validate_bo[i];
+ for (i = 0; i < bufmgr_gem->exec_count; i++) {
+ dri_bo *bo = bufmgr_gem->exec_bos[i];
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
/* Disconnect the buffer from the validate list */
bo_gem->validate_index = -1;
dri_bo_unreference(bo);
- bufmgr_gem->validate_bo[i] = NULL;
+ bufmgr_gem->exec_bos[i] = NULL;
}
- bufmgr_gem->validate_count = 0;
+ bufmgr_gem->exec_count = 0;
}
/**
@@ -762,6 +811,8 @@ intel_bufmgr_gem_init(int fd, int batch_size)
bufmgr_gem->bufmgr.bo_unreference = dri_gem_bo_unreference;
bufmgr_gem->bufmgr.bo_map = dri_gem_bo_map;
bufmgr_gem->bufmgr.bo_unmap = dri_gem_bo_unmap;
+ bufmgr_gem->bufmgr.bo_subdata = dri_gem_bo_subdata;
+ bufmgr_gem->bufmgr.bo_get_subdata = dri_gem_bo_get_subdata;
bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy;
bufmgr_gem->bufmgr.emit_reloc = dri_gem_emit_reloc;
bufmgr_gem->bufmgr.process_relocs = dri_gem_process_reloc;