summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-02-16 22:49:46 +0100
committerJerome Glisse <jglisse@redhat.com>2010-02-16 22:49:46 +0100
commit84d9dae08b7b2b70ae71d469248c2da5769b26e1 (patch)
treee204a28a6106564fed75f186766ce7a76391b75b
parentf2891214515d6f5e2f46d31402c7d21ee13467a7 (diff)
split code that is kernel/userspace agnostic
-rw-r--r--Makefile2
-rw-r--r--r600_atom.c471
-rw-r--r--r600_atom_api.h20
-rw-r--r--r600_batch.c521
4 files changed, 536 insertions, 478 deletions
diff --git a/Makefile b/Makefile
index 80bc022..cb3d879 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
OBJECTS = radeon.o mode.o test.o r700_atom.o radeon_device.o radeon_atom.o\
- r600_atom.o r600_shader.o
+ r600_atom.o r600_shader.o r600_batch.o
CFLAGS = -g3 -O0 -std=gnu99 -I/usr/include/drm
LDFLAGS = -ldrm -ldrm_radeon
DEPS = radeon.h
diff --git a/r600_atom.c b/r600_atom.c
index daf5db7..7685810 100644
--- a/r600_atom.c
+++ b/r600_atom.c
@@ -19,55 +19,9 @@
#include "r600d.h"
/*
- * helpers functions
- */
-static void r600_emit_flush(struct radeon_device *rdev,
- struct radeon_ib *ib,
- struct radeon_bo *bo,
- u32 flags)
-{
- ib->ptr[ib->cpkts++] = PKT3(PKT3_SURFACE_SYNC, 3);
- ib->ptr[ib->cpkts++] = flags;
- ib->ptr[ib->cpkts++] = radeon_bo_size(bo) >> 8;
- ib->ptr[ib->cpkts++] = 0x00000000;
- ib->ptr[ib->cpkts++] = 0x0000000A;
- ib->ptr[ib->cpkts++] = PKT3(PKT3_NOP, 0);
- ib->ptr[ib->cpkts++] = radeon_ib_reloc(ib, bo, RADEON_GEM_DOMAIN_VRAM |
- RADEON_GEM_DOMAIN_GTT);
-}
-
-static void r600_emit_resources(struct radeon_device *rdev,
- struct radeon_ib *ib,
- struct radeon_bo *bo,
- u32 dw0, u32 dw1, u32 dw2, u32 dw3,
- u32 dw4, u32 dw5, u32 dw6, u32 dw7)
-{
- ib->ptr[ib->cpkts++] = PKT3(PKT3_SURFACE_SYNC, 3);
- ib->ptr[ib->cpkts++] = 0x01000000;
- ib->ptr[ib->cpkts++] = radeon_bo_size(bo) >> 8;
- ib->ptr[ib->cpkts++] = 0x00000000;
- ib->ptr[ib->cpkts++] = 0x0000000A;
- ib->ptr[ib->cpkts++] = PKT3(PKT3_NOP, 0);
- ib->ptr[ib->cpkts++] = radeon_ib_reloc(ib, bo, RADEON_GEM_DOMAIN_VRAM |
- RADEON_GEM_DOMAIN_GTT);
- ib->ptr[ib->cpkts++] = PKT3(PKT3_SET_RESOURCE, 7);
- ib->ptr[ib->cpkts++] = dw0;
- ib->ptr[ib->cpkts++] = dw1;
- ib->ptr[ib->cpkts++] = dw2;
- ib->ptr[ib->cpkts++] = dw3;
- ib->ptr[ib->cpkts++] = dw4;
- ib->ptr[ib->cpkts++] = dw5;
- ib->ptr[ib->cpkts++] = dw6;
- ib->ptr[ib->cpkts++] = dw7;
- ib->ptr[ib->cpkts++] = PKT3(PKT3_NOP, 0);
- ib->ptr[ib->cpkts++] = radeon_ib_reloc(ib, bo, RADEON_GEM_DOMAIN_VRAM |
- RADEON_GEM_DOMAIN_GTT);
-}
-
-/*
* r600_cb
*/
-static int r600_cb_emit(struct radeon_device *rdev,
+int r600_cb_emit(struct radeon_device *rdev,
struct radeon_atom *atom,
void *data,
struct radeon_ib *ib)
@@ -84,7 +38,7 @@ static int r600_cb_emit(struct radeon_device *rdev,
/* FIXME delete */
void r600_tflat(struct radeon_atom *atom);
-static int r600_cb_create(struct radeon_device *rdev,
+int r600_cb_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -269,7 +223,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_cb_cntl
*/
-static int r600_cb_cntl_create(struct radeon_device *rdev,
+int r600_cb_cntl_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -328,7 +282,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_pa
*/
-static int r600_pa_create(struct radeon_device *rdev,
+int r600_pa_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -421,7 +375,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_vport
*/
-static int r600_vport_create(struct radeon_device *rdev,
+int r600_vport_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -483,7 +437,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_blend
*/
-static int r600_blend_create(struct radeon_device *rdev,
+int r600_blend_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -521,7 +475,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_constant
*/
-static int r600_constants_create(struct radeon_device *rdev,
+int r600_constants_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -555,7 +509,7 @@ static int r600_constants_create(struct radeon_device *rdev,
/*
* r600_db
*/
-static int r600_db_emit(struct radeon_device *rdev,
+int r600_db_emit(struct radeon_device *rdev,
struct radeon_atom *atom,
void *data,
struct radeon_ib *ib)
@@ -570,7 +524,7 @@ static int r600_db_emit(struct radeon_device *rdev,
return r;
}
-static int r600_db_create(struct radeon_device *rdev,
+int r600_db_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -683,7 +637,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_db_cntl
*/
-static int r600_db_cntl_create(struct radeon_device *rdev,
+int r600_db_cntl_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -738,7 +692,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_vs_shader
*/
-static int r600_vs_shader_emit(struct radeon_device *rdev,
+int r600_vs_shader_emit(struct radeon_device *rdev,
struct radeon_atom *atom,
void *data,
struct radeon_ib *ib)
@@ -763,7 +717,7 @@ static int r600_vs_shader_emit(struct radeon_device *rdev,
return r;
}
-static int r600_vs_shader_create(struct radeon_device *rdev,
+int r600_vs_shader_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -841,7 +795,7 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
/*
* r600_ps_shader
*/
-static int r600_ps_shader_emit(struct radeon_device *rdev,
+int r600_ps_shader_emit(struct radeon_device *rdev,
struct radeon_atom *atom,
void *data,
struct radeon_ib *ib)
@@ -859,7 +813,7 @@ static int r600_ps_shader_emit(struct radeon_device *rdev,
return r;
}
-static int r600_ps_shader_create(struct radeon_device *rdev,
+int r600_ps_shader_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct radeon_atom *atom,
void *data)
@@ -906,403 +860,6 @@ fprintf(stderr, "%s %d pkts\n", __func__, atom->npkts);
return 0;
}
-/*
- * r600 atom core functions
- */
-int r600_atom_create(struct radeon_device *rdev,
- struct r600_atoms *atoms,
- struct drm_radeon_atom *patom,
- struct radeon_atom **atomptr)
-{
- struct radeon_atom *atom;
- struct r600_state_container *cont;
- int r;
-
- *atomptr = NULL;
- atom = malloc(sizeof(struct radeon_atom));
- if (atom == NULL)
- return -ENOMEM;
- memset(atom, 0, sizeof(struct radeon_atom));
- cont = patom->data;
- patom->id = 0;
- radeon_device_set_bo_list(rdev, cont->nbo, cont->bo);
- atom->type = patom->type;
- mutex_lock(&atoms->mutex);
- switch (patom->type) {
- case R600_ATOM_CB:
- r = r600_cb_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_CB_CNTL:
- r = r600_cb_cntl_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_PA:
- r = r600_pa_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_VPORT:
- r = r600_vport_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_BLEND:
- r = r600_blend_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_CONSTANTS:
- r = r600_constants_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_DB:
- r = r600_db_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_DB_CNTL:
- r = r600_db_cntl_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_VS_SHADER:
- r = r600_vs_shader_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- case R600_ATOM_PS_SHADER:
- r = r600_ps_shader_create(rdev, atoms, atom, cont->data);
- if (r)
- return r;
- break;
- default:
- dev_err(rdev->dev, "unknown R600 atom type 0x%08X\n", patom->type);
- return -EINVAL;
- }
- patom->id = atom->id;
- *atomptr = atom;
- mutex_unlock(&atoms->mutex);
- return 0;
-}
-
-/*
- * r600_batch
- */
-static int r600_batch_alloc(struct r600_batch **batch)
-{
- struct r600_batch *rbatch;
-
- *batch = NULL;
- rbatch = malloc(sizeof(*rbatch));
- if (rbatch == NULL)
- return -ENOMEM;
- INIT_LIST_HEAD(&rbatch->list);
- INIT_LIST_HEAD(&rbatch->pre_flushes);
- INIT_LIST_HEAD(&rbatch->post_flushes);
- rbatch->nemit_atoms = 0;
- rbatch->shaders_idx = 0;
- rbatch->nfs_resources = 0;
- *batch = rbatch;
- return 0;
-}
-
-/*
- * r600_batches
- */
-static int r600_batches_fs_resource_is_present(struct radeon_device *rdev,
- struct r600_batches *batches,
- struct drm_r600_vs_buffer *buffer)
-{
- int i;
-
- for (i = 0; i < batches->nfs_resources; i++) {
- if (!memcmp(&batches->fs_resource[i], buffer, sizeof(struct drm_r600_vs_buffer))) {
- buffer->resource_id = i;
- return 1;
- }
- }
- return 0;
-}
-
-static int r600_batches_fs_resource_add(struct radeon_device *rdev,
- struct r600_batches *batches,
- struct drm_r600_vs_buffer *buffer)
-{
- int i = batches->nfs_resources++;
-
- buffer->resource_id = i;
- memcpy(&batches->fs_resource[i].drm, buffer, sizeof(struct drm_r600_vs_buffer));
- batches->fs_resource[i].bo = radeon_bo_lookup(rdev, buffer->handle);
- if (batches->fs_resource[i].bo == NULL)
- return -EINVAL;
- return 0;
-}
-
-static void r600_batches_clear_locked(struct radeon_device *rdev, struct r600_batches *batches)
-{
- struct r600_batch *batch, *n;
- int i;
-
- list_for_each_entry_safe(batch, n, &batches->batches, list) {
- for (i = 0; i < R600_BATCH_NATOMS; i++) {
- if (batch->atoms[i])
- radeon_atom_put(batch->atoms[i]);
- }
- radeon_atom_flush_cleanup(&batch->pre_flushes);
- radeon_atom_flush_cleanup(&batch->post_flushes);
- list_del(&batch->list);
- radeon_bo_unmap(batch->shaders);
- radeon_bo_unref(batch->shaders);
- kfree(batch);
- }
- INIT_LIST_HEAD(&batches->batches);
- for (i = 0; i < batches->nfs_resources; i++) {
- radeon_bo_unref(batches->fs_resource[i].bo);
- }
- batches->nfs_resources = 0;
- r700_batches_states_default(rdev, batches);
- batches->npkts = batches->ib->cpkts;
-}
-
-static int r600_batches_flush_locked(struct radeon_device *rdev, struct r600_batches *batches)
-{
- struct r600_batch *batch;
- struct radeon_atom_flush *flush;
- int r, i;
-
- for (i = 0; i < batches->nfs_resources; i++) {
- r600_emit_resources(rdev, batches->ib, batches->fs_resource[i].bo,
- (batches->fs_resource[i].drm.resource_id + 160) * 7,
- batches->fs_resource[i].drm.sq_vtx_constant_word0,
- radeon_bo_size(batches->fs_resource[i].bo) -
- batches->fs_resource[i].drm.sq_vtx_constant_word0,
- batches->fs_resource[i].drm.sq_vtx_constant_word2,
- batches->fs_resource[i].drm.sq_vtx_constant_word3,
- 0, 0, 0xC0000000);
- }
- list_for_each_entry(batch, &batches->batches, list) {
- list_for_each_entry(flush, &batch->pre_flushes, list) {
- r600_emit_flush(rdev, batches->ib, flush->bo, flush->flags);
- }
- /* FIXME shader flush should be conditional */
- r600_emit_flush(rdev, batches->ib, batch->shaders, 0x08000000);
- for (i = 0; i < batch->nemit_atoms; i++) {
- r = batch->emit_atoms[i]->emit(rdev, batch->emit_atoms[i], batch, batches->ib);
- if (r)
- goto out_err;
- }
- /* flush + wait until */
- batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_EVENT_WRITE, 0);
- batches->ib->ptr[batches->ib->cpkts++] = 0x00000016;
- batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_SET_CONFIG_REG, 1);
- batches->ib->ptr[batches->ib->cpkts++] = 0x00000010;
- batches->ib->ptr[batches->ib->cpkts++] = 0x00028000;
- list_for_each_entry(flush, &batch->post_flushes, list) {
- r600_emit_flush(rdev, batches->ib, flush->bo, flush->flags);
- }
- }
- r = radeon_ib_schedule(rdev, batches->ib);
-out_err:
- /* FIXME helper function */
- batches->ib->cpkts = 0;
- batches->ib->nrelocs = 0;
- r600_batches_clear_locked(rdev, batches);
- return r;
-}
-
-int r600_batches_queue(struct radeon_device *rdev,
- struct r600_atoms *atoms,
- struct drm_r600_batch *batch)
-{
- struct r600_batch *rbatch;
- struct r600_batches *batches = &atoms->batches;
- int r, i, j;
-
- r = r600_batch_alloc(&rbatch);
- if (r)
- return r;
- memcpy(&rbatch->inputs, &batch->inputs, sizeof(struct r600_vs_input));
- mutex_lock(&atoms->mutex);
- i = 0;
- if (batch->blend == NULL || batch->cb_cntl == NULL ||
- batch->pa == NULL || batch->vport == NULL ||
- batch->cb == NULL || batch->db_cntl == NULL ||
- batch->vs_shader == NULL || batch->ps_shader == NULL) {
- mutex_unlock(&atoms->mutex);
- free(rbatch);
- dev_err(rdev->dev, "invalid batch\n");
- return -EINVAL;
- }
- rbatch->shaders = radeon_bo_open(rdev->radeon->bom, 0, R600_SHADER_SIZE, 0, RADEON_GEM_DOMAIN_GTT, 0);
- if (rbatch->shaders == NULL) {
- mutex_unlock(&atoms->mutex);
- kfree(rbatch);
- dev_err(rdev->dev, "can't create buffer for shaders\n");
- return -ENOMEM;
- }
- r = radeon_bo_map(rbatch->shaders, 1);
- if (r) {
- mutex_unlock(&atoms->mutex);
- kfree(rbatch);
- dev_err(rdev->dev, "can't map buffer for shaders\n");
- return r;
- }
- rbatch->atoms[i++] = batch->blend; kref_get(&batch->blend->kref);
- rbatch->atoms[i++] = batch->cb_cntl; kref_get(&batch->cb_cntl->kref);
- rbatch->atoms[i++] = batch->pa; kref_get(&batch->pa->kref);
- rbatch->atoms[i++] = batch->vport; kref_get(&batch->vport->kref);
- rbatch->atoms[i++] = batch->vs_shader; kref_get(&batch->vs_shader->kref);
- rbatch->atoms[i++] = batch->ps_shader; kref_get(&batch->ps_shader->kref);
- rbatch->atoms[i++] = batch->db_cntl; kref_get(&batch->db_cntl->kref);
- rbatch->atoms[i++] = batch->vs_constants;
- if (batch->vs_constants)
- kref_get(&batch->vs_constants->kref);
- rbatch->atoms[i++] = batch->ps_constants;
- if (batch->ps_constants)
- kref_get(&batch->ps_constants->kref);
- rbatch->atoms[i++] = batch->db;
- if (batch->db)
- kref_get(&batch->db->kref);
- rbatch->atoms[i++] = batch->cb; kref_get(&batch->cb->kref);
-reprocess:
- radeon_atom_flush_cleanup(&rbatch->pre_flushes);
- radeon_atom_flush_cleanup(&rbatch->post_flushes);
- rbatch->nflushes = 0;
- rbatch->npkts = 0;
- /* flush + wait until = 5dw */
- rbatch->npkts += 5;
- for (i = 0; i < rbatch->inputs.drm.nbuffers; i++) {
- if (!r600_batches_fs_resource_is_present(rdev, batches, &rbatch->inputs.drm.buffers[i])) {
- rbatch->nfs_resources += 1;
- rbatch->inputs.drm.buffers[i].resource_id = -1;
- }
- }
- rbatch->npkts += rbatch->nfs_resources * 18;
- for (i = 0; i < R600_BATCH_NATOMS; i++) {
- if (rbatch->atoms[i]) {
- for (j = 0; j < rbatch->atoms[i]->nbo; j++) {
- r = radeon_atom_flush_add(&rbatch->pre_flushes, rbatch->atoms[i]->bo[j], rbatch->atoms[i]->flags[j]);
- if (r < 0)
- goto out_err;
- }
- rbatch->nflushes += rbatch->atoms[i]->nbo;
- if (batches->last_id[i] != rbatch->atoms[i]->id)
- rbatch->emit_atoms[rbatch->nemit_atoms++] = rbatch->atoms[i];
- }
- }
- /* add flush */
- rbatch->npkts += rbatch->nflushes * 7;
- /* FIXME shader flush should be conditional only if we change shaders */
- rbatch->npkts += 7;
- /* if batch is bigger than ib size it's an invalid one, this should
- * not happen
- */
- if (rbatch->npkts > batches->ib->length_dw) {
- dev_err(rdev->dev, "single batch to big (%d) to fit into ib (%d)\n",
- rbatch->npkts, batches->ib->length_dw);
- goto out_err;
- }
- /* flush or not ? */
- if (batches->npkts + rbatch->npkts > batches->ib->length_dw) {
- r = r600_batches_flush_locked(rdev, batches);
- if (r)
- goto out_err;
- goto reprocess;
- }
- /* batch is queued */
- for (i = 0; i < R600_BATCH_NATOMS; i++) {
- if (rbatch->atoms[i]) {
- batches->last_id[i] = rbatch->atoms[i]->id;
- }
- }
- radeon_device_set_bo_list(rdev, rbatch->inputs.nbo, rbatch->inputs.bo);
- for (i = 0; i < rbatch->inputs.drm.nbuffers; i++) {
- if (rbatch->inputs.drm.buffers[i].resource_id == -1) {
- r = r600_batches_fs_resource_add(rdev, batches, &rbatch->inputs.drm.buffers[i]);
- if (r)
- goto out_err;
- }
- }
- batches->npkts += rbatch->npkts;
- list_add_tail(&rbatch->list, &batches->batches);
- mutex_unlock(&atoms->mutex);
- return 0;
-out_err:
- for (i = 0; i < R600_BATCH_NATOMS; i++) {
- if (rbatch->atoms[i])
- radeon_atom_put(rbatch->atoms[i]);
- }
- mutex_unlock(&rdev->asic.r700.atom.mutex);
- radeon_bo_unmap(rbatch->shaders);
- radeon_bo_unref(rbatch->shaders);
- free(rbatch);
- return r;
-}
-
-static int r600_batches_init(struct radeon_device *rdev, struct r600_batches *batches)
-{
- int r;
-
- memset(batches, 0 , sizeof(struct r600_batches));
- INIT_LIST_HEAD(&batches->batches);
- r = radeon_ib_get(rdev, &batches->ib);
- if (r)
- return r;
- r700_batches_states_default(rdev, batches);
- batches->npkts = batches->ib->cpkts;
- return 0;
-}
-
-static void r600_batches_cleanup_locked(struct radeon_device *rdev, struct r600_batches *batches)
-{
- r600_batches_clear_locked(rdev, batches);
- radeon_ib_free(batches->ib);
- batches->ib = NULL;
-}
-
-int r600_batches_flush(struct radeon_device *rdev, struct r600_atoms *atoms)
-{
- int r;
-
- mutex_lock(&atoms->mutex);
- r = r600_batches_flush_locked(rdev, &atoms->batches);
- mutex_unlock(&atoms->mutex);
- return r;
-}
-
-int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *atoms)
-{
- memset(atoms, 0, sizeof(*atoms));
- mutex_init(&atoms->mutex);
- INIT_LIST_HEAD(&atoms->blend_atoms);
- INIT_LIST_HEAD(&atoms->cb_atoms);
- INIT_LIST_HEAD(&atoms->cb_cntl_atoms);
- INIT_LIST_HEAD(&atoms->constants_atoms);
- INIT_LIST_HEAD(&atoms->db_atoms);
- INIT_LIST_HEAD(&atoms->db_cntl_atoms);
- INIT_LIST_HEAD(&atoms->pa_atoms);
- INIT_LIST_HEAD(&atoms->sq_atoms);
- INIT_LIST_HEAD(&atoms->vport_atoms);
- INIT_LIST_HEAD(&atoms->vs_shader_atoms);
- INIT_LIST_HEAD(&atoms->ps_shader_atoms);
- idr_init(&atoms->idr);
- atoms->npipes = 2;
- atoms->nbanks = 4;
- atoms->group_bytes = 256;
- return r600_batches_init(rdev, &atoms->batches);
-}
-
-void r600_atoms_release(struct radeon_device *rdev, struct r600_atoms *atoms)
-{
- mutex_lock(&atoms->mutex);
- r600_batches_cleanup_locked(rdev, &atoms->batches);
- idr_destroy(&atoms->idr);
- mutex_unlock(&atoms->mutex);
-}
diff --git a/r600_atom_api.h b/r600_atom_api.h
deleted file mode 100644
index 0ee7208..0000000
--- a/r600_atom_api.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-#ifndef R600_ATOM_API_H
-#define R600_ATOM_API_H
-
-#endif
diff --git a/r600_batch.c b/r600_batch.c
new file mode 100644
index 0000000..db44a0b
--- /dev/null
+++ b/r600_batch.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "radeon.h"
+#include "radeon_device.h"
+#include "r600d.h"
+
+/* state creation functions prototype */
+int r600_cb_emit(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib);
+int r600_cb_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_cb_cntl_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_pa_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_vport_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_blend_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_constants_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_db_emit(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib);
+int r600_db_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_db_cntl_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_vs_shader_emit(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib);
+int r600_vs_shader_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+int r600_ps_shader_emit(struct radeon_device *rdev,
+ struct radeon_atom *atom,
+ void *data,
+ struct radeon_ib *ib);
+int r600_ps_shader_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct radeon_atom *atom,
+ void *data);
+
+/*
+ * helpers functions
+ */
+static void r600_emit_flush(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ struct radeon_bo *bo,
+ u32 flags)
+{
+ ib->ptr[ib->cpkts++] = PKT3(PKT3_SURFACE_SYNC, 3);
+ ib->ptr[ib->cpkts++] = flags;
+ ib->ptr[ib->cpkts++] = radeon_bo_size(bo) >> 8;
+ ib->ptr[ib->cpkts++] = 0x00000000;
+ ib->ptr[ib->cpkts++] = 0x0000000A;
+ ib->ptr[ib->cpkts++] = PKT3(PKT3_NOP, 0);
+ ib->ptr[ib->cpkts++] = radeon_ib_reloc(ib, bo, RADEON_GEM_DOMAIN_VRAM |
+ RADEON_GEM_DOMAIN_GTT);
+}
+
+static void r600_emit_resources(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ struct radeon_bo *bo,
+ u32 dw0, u32 dw1, u32 dw2, u32 dw3,
+ u32 dw4, u32 dw5, u32 dw6, u32 dw7)
+{
+ ib->ptr[ib->cpkts++] = PKT3(PKT3_SURFACE_SYNC, 3);
+ ib->ptr[ib->cpkts++] = 0x01000000;
+ ib->ptr[ib->cpkts++] = radeon_bo_size(bo) >> 8;
+ ib->ptr[ib->cpkts++] = 0x00000000;
+ ib->ptr[ib->cpkts++] = 0x0000000A;
+ ib->ptr[ib->cpkts++] = PKT3(PKT3_NOP, 0);
+ ib->ptr[ib->cpkts++] = radeon_ib_reloc(ib, bo, RADEON_GEM_DOMAIN_VRAM |
+ RADEON_GEM_DOMAIN_GTT);
+ ib->ptr[ib->cpkts++] = PKT3(PKT3_SET_RESOURCE, 7);
+ ib->ptr[ib->cpkts++] = dw0;
+ ib->ptr[ib->cpkts++] = dw1;
+ ib->ptr[ib->cpkts++] = dw2;
+ ib->ptr[ib->cpkts++] = dw3;
+ ib->ptr[ib->cpkts++] = dw4;
+ ib->ptr[ib->cpkts++] = dw5;
+ ib->ptr[ib->cpkts++] = dw6;
+ ib->ptr[ib->cpkts++] = dw7;
+ ib->ptr[ib->cpkts++] = PKT3(PKT3_NOP, 0);
+ ib->ptr[ib->cpkts++] = radeon_ib_reloc(ib, bo, RADEON_GEM_DOMAIN_VRAM |
+ RADEON_GEM_DOMAIN_GTT);
+}
+
+/*
+ * r600_batch
+ */
+static int r600_batch_alloc(struct r600_batch **batch)
+{
+ struct r600_batch *rbatch;
+
+ *batch = NULL;
+ rbatch = malloc(sizeof(*rbatch));
+ if (rbatch == NULL)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&rbatch->list);
+ INIT_LIST_HEAD(&rbatch->pre_flushes);
+ INIT_LIST_HEAD(&rbatch->post_flushes);
+ rbatch->nemit_atoms = 0;
+ rbatch->shaders_idx = 0;
+ rbatch->nfs_resources = 0;
+ *batch = rbatch;
+ return 0;
+}
+
+/*
+ * r600_batches
+ */
+static int r600_batches_fs_resource_is_present(struct radeon_device *rdev,
+ struct r600_batches *batches,
+ struct drm_r600_vs_buffer *buffer)
+{
+ int i;
+
+ for (i = 0; i < batches->nfs_resources; i++) {
+ if (!memcmp(&batches->fs_resource[i], buffer, sizeof(struct drm_r600_vs_buffer))) {
+ buffer->resource_id = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int r600_batches_fs_resource_add(struct radeon_device *rdev,
+ struct r600_batches *batches,
+ struct drm_r600_vs_buffer *buffer)
+{
+ int i = batches->nfs_resources++;
+
+ buffer->resource_id = i;
+ memcpy(&batches->fs_resource[i].drm, buffer, sizeof(struct drm_r600_vs_buffer));
+ batches->fs_resource[i].bo = radeon_bo_lookup(rdev, buffer->handle);
+ if (batches->fs_resource[i].bo == NULL)
+ return -EINVAL;
+ return 0;
+}
+
+static void r600_batches_clear_locked(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ struct r600_batch *batch, *n;
+ int i;
+
+ list_for_each_entry_safe(batch, n, &batches->batches, list) {
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ if (batch->atoms[i])
+ radeon_atom_put(batch->atoms[i]);
+ }
+ radeon_atom_flush_cleanup(&batch->pre_flushes);
+ radeon_atom_flush_cleanup(&batch->post_flushes);
+ list_del(&batch->list);
+ radeon_bo_unmap(batch->shaders);
+ radeon_bo_unref(batch->shaders);
+ kfree(batch);
+ }
+ INIT_LIST_HEAD(&batches->batches);
+ for (i = 0; i < batches->nfs_resources; i++) {
+ radeon_bo_unref(batches->fs_resource[i].bo);
+ }
+ batches->nfs_resources = 0;
+ r700_batches_states_default(rdev, batches);
+ batches->npkts = batches->ib->cpkts;
+}
+
+static int r600_batches_flush_locked(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ struct r600_batch *batch;
+ struct radeon_atom_flush *flush;
+ int r, i;
+
+ for (i = 0; i < batches->nfs_resources; i++) {
+ r600_emit_resources(rdev, batches->ib, batches->fs_resource[i].bo,
+ (batches->fs_resource[i].drm.resource_id + 160) * 7,
+ batches->fs_resource[i].drm.sq_vtx_constant_word0,
+ radeon_bo_size(batches->fs_resource[i].bo) -
+ batches->fs_resource[i].drm.sq_vtx_constant_word0,
+ batches->fs_resource[i].drm.sq_vtx_constant_word2,
+ batches->fs_resource[i].drm.sq_vtx_constant_word3,
+ 0, 0, 0xC0000000);
+ }
+ list_for_each_entry(batch, &batches->batches, list) {
+ list_for_each_entry(flush, &batch->pre_flushes, list) {
+ r600_emit_flush(rdev, batches->ib, flush->bo, flush->flags);
+ }
+ /* FIXME shader flush should be conditional */
+ r600_emit_flush(rdev, batches->ib, batch->shaders, 0x08000000);
+ for (i = 0; i < batch->nemit_atoms; i++) {
+ r = batch->emit_atoms[i]->emit(rdev, batch->emit_atoms[i], batch, batches->ib);
+ if (r)
+ goto out_err;
+ }
+ /* flush + wait until */
+ batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_EVENT_WRITE, 0);
+ batches->ib->ptr[batches->ib->cpkts++] = 0x00000016;
+ batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_SET_CONFIG_REG, 1);
+ batches->ib->ptr[batches->ib->cpkts++] = 0x00000010;
+ batches->ib->ptr[batches->ib->cpkts++] = 0x00028000;
+ list_for_each_entry(flush, &batch->post_flushes, list) {
+ r600_emit_flush(rdev, batches->ib, flush->bo, flush->flags);
+ }
+ }
+ r = radeon_ib_schedule(rdev, batches->ib);
+out_err:
+ /* FIXME helper function */
+ batches->ib->cpkts = 0;
+ batches->ib->nrelocs = 0;
+ r600_batches_clear_locked(rdev, batches);
+ return r;
+}
+
+int r600_batches_queue(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_r600_batch *batch)
+{
+ struct r600_batch *rbatch;
+ struct r600_batches *batches = &atoms->batches;
+ int r, i, j;
+
+ r = r600_batch_alloc(&rbatch);
+ if (r)
+ return r;
+ memcpy(&rbatch->inputs, &batch->inputs, sizeof(struct r600_vs_input));
+ mutex_lock(&atoms->mutex);
+ i = 0;
+ if (batch->blend == NULL || batch->cb_cntl == NULL ||
+ batch->pa == NULL || batch->vport == NULL ||
+ batch->cb == NULL || batch->db_cntl == NULL ||
+ batch->vs_shader == NULL || batch->ps_shader == NULL) {
+ mutex_unlock(&atoms->mutex);
+ free(rbatch);
+ dev_err(rdev->dev, "invalid batch\n");
+ return -EINVAL;
+ }
+ rbatch->shaders = radeon_bo_open(rdev->radeon->bom, 0, R600_SHADER_SIZE, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ if (rbatch->shaders == NULL) {
+ mutex_unlock(&atoms->mutex);
+ kfree(rbatch);
+ dev_err(rdev->dev, "can't create buffer for shaders\n");
+ return -ENOMEM;
+ }
+ r = radeon_bo_map(rbatch->shaders, 1);
+ if (r) {
+ mutex_unlock(&atoms->mutex);
+ kfree(rbatch);
+ dev_err(rdev->dev, "can't map buffer for shaders\n");
+ return r;
+ }
+ rbatch->atoms[i++] = batch->blend; kref_get(&batch->blend->kref);
+ rbatch->atoms[i++] = batch->cb_cntl; kref_get(&batch->cb_cntl->kref);
+ rbatch->atoms[i++] = batch->pa; kref_get(&batch->pa->kref);
+ rbatch->atoms[i++] = batch->vport; kref_get(&batch->vport->kref);
+ rbatch->atoms[i++] = batch->vs_shader; kref_get(&batch->vs_shader->kref);
+ rbatch->atoms[i++] = batch->ps_shader; kref_get(&batch->ps_shader->kref);
+ rbatch->atoms[i++] = batch->db_cntl; kref_get(&batch->db_cntl->kref);
+ rbatch->atoms[i++] = batch->vs_constants;
+ if (batch->vs_constants)
+ kref_get(&batch->vs_constants->kref);
+ rbatch->atoms[i++] = batch->ps_constants;
+ if (batch->ps_constants)
+ kref_get(&batch->ps_constants->kref);
+ rbatch->atoms[i++] = batch->db;
+ if (batch->db)
+ kref_get(&batch->db->kref);
+ rbatch->atoms[i++] = batch->cb; kref_get(&batch->cb->kref);
+reprocess:
+ radeon_atom_flush_cleanup(&rbatch->pre_flushes);
+ radeon_atom_flush_cleanup(&rbatch->post_flushes);
+ rbatch->nflushes = 0;
+ rbatch->npkts = 0;
+ /* flush + wait until = 5dw */
+ rbatch->npkts += 5;
+ for (i = 0; i < rbatch->inputs.drm.nbuffers; i++) {
+ if (!r600_batches_fs_resource_is_present(rdev, batches, &rbatch->inputs.drm.buffers[i])) {
+ rbatch->nfs_resources += 1;
+ rbatch->inputs.drm.buffers[i].resource_id = -1;
+ }
+ }
+ rbatch->npkts += rbatch->nfs_resources * 18;
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ if (rbatch->atoms[i]) {
+ for (j = 0; j < rbatch->atoms[i]->nbo; j++) {
+ r = radeon_atom_flush_add(&rbatch->pre_flushes, rbatch->atoms[i]->bo[j], rbatch->atoms[i]->flags[j]);
+ if (r < 0)
+ goto out_err;
+ }
+ rbatch->nflushes += rbatch->atoms[i]->nbo;
+ if (batches->last_id[i] != rbatch->atoms[i]->id)
+ rbatch->emit_atoms[rbatch->nemit_atoms++] = rbatch->atoms[i];
+ }
+ }
+ /* add flush */
+ rbatch->npkts += rbatch->nflushes * 7;
+ /* FIXME shader flush should be conditional only if we change shaders */
+ rbatch->npkts += 7;
+ /* if batch is bigger than ib size it's an invalid one, this should
+ * not happen
+ */
+ if (rbatch->npkts > batches->ib->length_dw) {
+ dev_err(rdev->dev, "single batch to big (%d) to fit into ib (%d)\n",
+ rbatch->npkts, batches->ib->length_dw);
+ goto out_err;
+ }
+ /* flush or not ? */
+ if (batches->npkts + rbatch->npkts > batches->ib->length_dw) {
+ r = r600_batches_flush_locked(rdev, batches);
+ if (r)
+ goto out_err;
+ goto reprocess;
+ }
+ /* batch is queued */
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ if (rbatch->atoms[i]) {
+ batches->last_id[i] = rbatch->atoms[i]->id;
+ }
+ }
+ radeon_device_set_bo_list(rdev, rbatch->inputs.nbo, rbatch->inputs.bo);
+ for (i = 0; i < rbatch->inputs.drm.nbuffers; i++) {
+ if (rbatch->inputs.drm.buffers[i].resource_id == -1) {
+ r = r600_batches_fs_resource_add(rdev, batches, &rbatch->inputs.drm.buffers[i]);
+ if (r)
+ goto out_err;
+ }
+ }
+ batches->npkts += rbatch->npkts;
+ list_add_tail(&rbatch->list, &batches->batches);
+ mutex_unlock(&atoms->mutex);
+ return 0;
+out_err:
+ for (i = 0; i < R600_BATCH_NATOMS; i++) {
+ if (rbatch->atoms[i])
+ radeon_atom_put(rbatch->atoms[i]);
+ }
+ mutex_unlock(&rdev->asic.r700.atom.mutex);
+ radeon_bo_unmap(rbatch->shaders);
+ radeon_bo_unref(rbatch->shaders);
+ free(rbatch);
+ return r;
+}
+
+static int r600_batches_init(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ int r;
+
+ memset(batches, 0 , sizeof(struct r600_batches));
+ INIT_LIST_HEAD(&batches->batches);
+ r = radeon_ib_get(rdev, &batches->ib);
+ if (r)
+ return r;
+ r700_batches_states_default(rdev, batches);
+ batches->npkts = batches->ib->cpkts;
+ return 0;
+}
+
+static void r600_batches_cleanup_locked(struct radeon_device *rdev, struct r600_batches *batches)
+{
+ r600_batches_clear_locked(rdev, batches);
+ radeon_ib_free(batches->ib);
+ batches->ib = NULL;
+}
+
+int r600_batches_flush(struct radeon_device *rdev, struct r600_atoms *atoms)
+{
+ int r;
+
+ mutex_lock(&atoms->mutex);
+ r = r600_batches_flush_locked(rdev, &atoms->batches);
+ mutex_unlock(&atoms->mutex);
+ return r;
+}
+
+int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *atoms)
+{
+ memset(atoms, 0, sizeof(*atoms));
+ mutex_init(&atoms->mutex);
+ INIT_LIST_HEAD(&atoms->blend_atoms);
+ INIT_LIST_HEAD(&atoms->cb_atoms);
+ INIT_LIST_HEAD(&atoms->cb_cntl_atoms);
+ INIT_LIST_HEAD(&atoms->constants_atoms);
+ INIT_LIST_HEAD(&atoms->db_atoms);
+ INIT_LIST_HEAD(&atoms->db_cntl_atoms);
+ INIT_LIST_HEAD(&atoms->pa_atoms);
+ INIT_LIST_HEAD(&atoms->sq_atoms);
+ INIT_LIST_HEAD(&atoms->vport_atoms);
+ INIT_LIST_HEAD(&atoms->vs_shader_atoms);
+ INIT_LIST_HEAD(&atoms->ps_shader_atoms);
+ idr_init(&atoms->idr);
+ atoms->npipes = 2;
+ atoms->nbanks = 4;
+ atoms->group_bytes = 256;
+ return r600_batches_init(rdev, &atoms->batches);
+}
+
+void r600_atoms_release(struct radeon_device *rdev, struct r600_atoms *atoms)
+{
+ mutex_lock(&atoms->mutex);
+ r600_batches_cleanup_locked(rdev, &atoms->batches);
+ idr_destroy(&atoms->idr);
+ mutex_unlock(&atoms->mutex);
+}
+
+/*
+ * r600 atom core functions
+ */
+int r600_atom_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atomptr)
+{
+ struct radeon_atom *atom;
+ struct r600_state_container *cont;
+ int r;
+
+ *atomptr = NULL;
+ atom = malloc(sizeof(struct radeon_atom));
+ if (atom == NULL)
+ return -ENOMEM;
+ memset(atom, 0, sizeof(struct radeon_atom));
+ cont = patom->data;
+ patom->id = 0;
+ radeon_device_set_bo_list(rdev, cont->nbo, cont->bo);
+ atom->type = patom->type;
+ mutex_lock(&atoms->mutex);
+ switch (patom->type) {
+ case R600_ATOM_CB:
+ r = r600_cb_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_CB_CNTL:
+ r = r600_cb_cntl_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_PA:
+ r = r600_pa_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_VPORT:
+ r = r600_vport_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_BLEND:
+ r = r600_blend_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_CONSTANTS:
+ r = r600_constants_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_DB:
+ r = r600_db_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_DB_CNTL:
+ r = r600_db_cntl_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_VS_SHADER:
+ r = r600_vs_shader_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ case R600_ATOM_PS_SHADER:
+ r = r600_ps_shader_create(rdev, atoms, atom, cont->data);
+ if (r)
+ return r;
+ break;
+ default:
+ dev_err(rdev->dev, "unknown R600 atom type 0x%08X\n", patom->type);
+ return -EINVAL;
+ }
+ patom->id = atom->id;
+ *atomptr = atom;
+ mutex_unlock(&atoms->mutex);
+ return 0;
+}