summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-01-29 22:06:17 +0100
committerJerome Glisse <jglisse@redhat.com>2010-01-29 22:06:17 +0100
commit2a518e1274130fed9ba13c87b95ae055211d2331 (patch)
tree272bdc3bf110e672d087dfc4dac5bc9c06254611
parent67ede082cffb7a4a82486d81cd12fb8e564bf530 (diff)
add constants atom and convert to use ptr
-rw-r--r--lwrapper.h2
-rw-r--r--r600_atom.c167
-rw-r--r--r600_atom_api.h22
-rw-r--r--r600_winsys.h3
-rw-r--r--radeon_atom.c6
-rw-r--r--radeon_atom.h8
-rw-r--r--test.c39
7 files changed, 170 insertions, 77 deletions
diff --git a/lwrapper.h b/lwrapper.h
index 93bf02b..409078b 100644
--- a/lwrapper.h
+++ b/lwrapper.h
@@ -49,7 +49,7 @@ extern void idr_destroy(struct idr *idp);
extern void idr_init(struct idr *idp);
#include "list.h"
-#define dev_err(d, p, args...) fprintf(stderr, p, args)
+#define dev_err(d, p, args...) fprintf(stderr, p, ##args)
struct kref {
int refcount;
diff --git a/r600_atom.c b/r600_atom.c
index d5ef81e..04af0f4 100644
--- a/r600_atom.c
+++ b/r600_atom.c
@@ -105,10 +105,10 @@ static int r600_cb_emit(struct radeon_device *rdev,
cb->pkts[273] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT);
cb->pkts[289] = radeon_ib_reloc(ib, cb->psshader1, RADEON_GEM_DOMAIN_GTT);
cb->pkts[294] = radeon_ib_reloc(ib, cb->psshader1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[319] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
+ cb->pkts[330] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
cb->pkts[337] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
cb->pkts[348] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
- cb->pkts[355] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
- cb->pkts[366] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT);
r = radeon_ib_copy(ib, cb->pkts, atom->npkts);
return r;
}
@@ -733,11 +733,73 @@ out_err:
}
/*
+ * r600_constant
+ */
+struct r600_constants {
+ struct radeon_atom atom;
+ u32 pkts[1024];
+ struct r600_atoms *atoms;
+};
+
+static void r600_constants_release(struct kref *kref)
+{
+ struct radeon_atom *atom = container_of(kref, struct radeon_atom, kref);
+ struct r600_constants *constants = container_of(atom, struct r600_constants, atom);
+
+ mutex_lock(&constants->atoms->mutex);
+ list_del_init(&constants->atom.list);
+ mutex_unlock(&constants->atoms->mutex);
+ kfree(constants);
+}
+
+static int r600_constants_create(struct radeon_device *rdev,
+ struct r600_atoms *atoms,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atom)
+{
+ struct drm_r600_constants pconstants;
+ struct r600_constants *constants;
+ int r;
+
+ constants = kmalloc(sizeof(*constants), GFP_KERNEL);
+ if (constants == NULL)
+ return -ENOMEM;
+ /* make sure structure properly initialized */
+ memset(constants, 0, sizeof(*constants));
+ r = radeon_atom_init(&constants->atom, &atoms->idr, &r600_constants_release,
+ &radeon_atom_emit_default, &r600_atom_process_default,
+ constants->pkts);
+ if (r)
+ goto out_err;
+ /* KERNEL use get user data */
+ memcpy(&pconstants, (void*)(unsigned long)patom->data, sizeof(struct drm_r600_constants));
+ if ((pconstants.nconstants & 0x3) || (pconstants.offset & 0x3)) {
+ dev_err(rdev->dev, "invalid offset or number of constants (0x%08X %d)\n",
+ pconstants.offset, pconstants.nconstants);
+ return -EINVAL;
+ }
+ /* constants */
+ constants->pkts[constants->atom.npkts++] = PKT3(PKT3_SET_ALU_CONST, pconstants.nconstants * 4);
+ constants->pkts[constants->atom.npkts++] = pconstants.offset;
+ memcpy(&constants->pkts[constants->atom.npkts],
+ (void*)(unsigned long)pconstants.constants,
+ pconstants.nconstants * 4 * 4);
+ constants->atom.npkts += pconstants.nconstants * 4;
+ *atom = &constants->atom;
+ return 0;
+out_err:
+ radeon_atom_put(&constants->atom);
+ *atom = NULL;
+ return r;
+}
+
+/*
* r600 atom core functions
*/
int r600_atom_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
- struct drm_radeon_atom *patom)
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atomptr)
{
struct radeon_atom *atom;
int r;
@@ -787,11 +849,19 @@ int r600_atom_create(struct radeon_device *rdev,
atom->type = patom->type;
list_add_tail(&atom->list, &atoms->blend_atoms);
break;
+ case R600_ATOM_CONSTANTS:
+ r = r600_constants_create(rdev, atoms, patom, &atom);
+ if (r)
+ return r;
+ atom->type = patom->type;
+ list_add_tail(&atom->list, &atoms->constants_atoms);
+ 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;
}
@@ -810,6 +880,7 @@ static int r600_batch_alloc(struct r600_batch **batch)
INIT_LIST_HEAD(&rbatch->list);
INIT_LIST_HEAD(&rbatch->pre_flushes);
INIT_LIST_HEAD(&rbatch->post_flushes);
+ rbatch->nemit_atoms = 0;
*batch = rbatch;
return 0;
}
@@ -824,7 +895,8 @@ static void r600_batches_clear_locked(struct radeon_device *rdev, struct r600_ba
list_for_each_entry_safe(batch, n, &batches->batches, list) {
for (i = 0; i < R600_BATCH_NATOMS; i++) {
- radeon_atom_put(batch->atoms[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);
@@ -862,8 +934,8 @@ static int r600_batches_flush_locked(struct radeon_device *rdev, struct r600_bat
list_for_each_entry(flush, &batch->pre_flushes, list) {
r600_emit_flush(rdev, batches->ib, flush->bo, flush->flags);
}
- for (i = 0; i < R600_BATCH_NATOMS; i++) {
- r = batch->atoms[i]->emit(rdev, batch->atoms[i], batch, batches->ib);
+ 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;
}
@@ -910,30 +982,30 @@ int r600_batches_queue(struct radeon_device *rdev,
rbatch->cb_fog_green = batch->cb_fog_green;
rbatch->cb_fog_red = batch->cb_fog_red;
i = 0;
- r = radeon_atom_find_locked(&atoms->blend_atoms, batch->blend_id,
- R600_ATOM_BLEND, &rbatch->atoms[i++]);
- if (r)
- goto out_err;
- r = radeon_atom_find_locked(&atoms->cb_cntl_atoms, batch->cb_cntl_id,
- R600_ATOM_CB_CNTL, &rbatch->atoms[i++]);
- if (r)
- goto out_err;
- r = radeon_atom_find_locked(&atoms->pa_atoms, batch->pa_id,
- R600_ATOM_PA, &rbatch->atoms[i++]);
- if (r)
- goto out_err;
- r = radeon_atom_find_locked(&atoms->tp_atoms, batch->tp_id,
- R600_ATOM_TP, &rbatch->atoms[i++]);
- if (r)
- goto out_err;
- r = radeon_atom_find_locked(&atoms->vport_atoms, batch->vport_id,
- R600_ATOM_VPORT, &rbatch->atoms[i++]);
- if (r)
- goto out_err;
- r = radeon_atom_find_locked(&atoms->cb_atoms, batch->cb_id,
- R600_ATOM_CB, &rbatch->atoms[i++]);
- if (r)
- goto out_err;
+ if (batch->blend == NULL || batch->cb_cntl == NULL ||
+ batch->pa == NULL || batch->vport == NULL ||
+ batch->tp == NULL || batch->cb == NULL) {
+ dev_err(rdev->dev, "invalid batch\n");
+ return -EINVAL;
+ }
+ 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->tp;
+ kref_get(&batch->tp->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->cb;
+ kref_get(&batch->cb->kref);
reprocess:
radeon_atom_flush_cleanup(&rbatch->pre_flushes);
radeon_atom_flush_cleanup(&rbatch->post_flushes);
@@ -943,10 +1015,14 @@ reprocess:
/* flush + wait until = 5dw */
rbatch->npkts += 5;
for (i = 0; i < R600_BATCH_NATOMS; i++) {
- r = rbatch->atoms[i]->process(rdev, rbatch->atoms[i], batches->last_id[i], rbatch);
- if (r)
- goto out_err;
- rbatch->nflushes += rbatch->atoms[i]->nflushes;
+ if (rbatch->atoms[i]) {
+ r = rbatch->atoms[i]->process(rdev, rbatch->atoms[i], batches->last_id[i], rbatch);
+ if (r)
+ goto out_err;
+ rbatch->nflushes += rbatch->atoms[i]->nflushes;
+ 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;
@@ -967,7 +1043,9 @@ reprocess:
}
/* batch is queued */
for (i = 0; i < R600_BATCH_NATOMS; i++) {
- batches->last_id[i] = rbatch->atoms[i]->id;
+ if (rbatch->atoms[i]) {
+ batches->last_id[i] = rbatch->atoms[i]->id;
+ }
}
batches->npkts += rbatch->npkts;
list_add_tail(&rbatch->list, &batches->batches);
@@ -1017,6 +1095,7 @@ int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *atoms)
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->pa_atoms);
INIT_LIST_HEAD(&atoms->sq_atoms);
INIT_LIST_HEAD(&atoms->tp_atoms);
@@ -1328,24 +1407,6 @@ void r600_tflat(struct radeon_atom *atom)
WPKT(PKT3(PKT3_SET_LOOP_CONST, 1));
WPKT(0x00000000);
WPKT(0x01000FFF);
- WPKT(PKT3(PKT3_SET_ALU_CONST, 16));
- WPKT(0x00000400);
- WPKT(0x3C03126F);
- WPKT(0x00000000);
- WPKT(0x00000000);
- WPKT(0xBF800000);
- WPKT(0x00000000);
- WPKT(0x3C03126F);
- WPKT(0x00000000);
- WPKT(0xBF800000);
- WPKT(0x00000000);
- WPKT(0x00000000);
- WPKT(0xBF800000);
- WPKT(0x00000000);
- WPKT(0x00000000);
- WPKT(0x00000000);
- WPKT(0x00000000);
- WPKT(0x3F800000);
WPKT(PKT3(PKT3_SET_CTL_CONST, 1));
WPKT(0x00000000);
WPKT(0x00000000);
diff --git a/r600_atom_api.h b/r600_atom_api.h
index 16938c7..ecc3e9c 100644
--- a/r600_atom_api.h
+++ b/r600_atom_api.h
@@ -33,6 +33,7 @@ struct drm_radeon_atom {
#define R600_ATOM_CB_CNTL 4
#define R600_ATOM_VPORT 5
#define R600_ATOM_BLEND 6
+#define R600_ATOM_CONSTANTS 7
struct drm_r600_cb {
u32 pitch;
@@ -128,13 +129,14 @@ struct drm_r600_blend {
u32 cb_blend_control;
};
+/* constant */
+struct drm_r600_constants {
+ u32 offset;
+ u32 nconstants;
+ u64 constants;
+};
+
struct drm_r600_batch {
- u32 blend_id;
- u32 cb_id;
- u32 cb_cntl_id;
- u32 pa_id;
- u32 tp_id;
- u32 vport_id;
u32 cb_blend_alpha;
u32 cb_blend_blue;
u32 cb_blend_green;
@@ -146,6 +148,14 @@ struct drm_r600_batch {
u32 cb_fog_blue;
u32 cb_fog_green;
u32 cb_fog_red;
+ struct radeon_atom *vs_constants;
+ struct radeon_atom *ps_constants;
+ struct radeon_atom *blend;
+ struct radeon_atom *cb;
+ struct radeon_atom *cb_cntl;
+ struct radeon_atom *pa;
+ struct radeon_atom *tp;
+ struct radeon_atom *vport;
};
diff --git a/r600_winsys.h b/r600_winsys.h
index 708b46f..616be8a 100644
--- a/r600_winsys.h
+++ b/r600_winsys.h
@@ -21,9 +21,10 @@
/* opaque structure */
struct radeon_device *rdev;
+struct radeon_atom *atom;
/* atom */
-extern int radeon_atom_create(struct radeon_device*, struct drm_radeon_atom*);
+extern int radeon_atom_create(struct radeon_device*, struct drm_radeon_atom*, struct radeon_atom **atom);
extern int radeon_batches_queue(struct radeon_device *rdev, void *batch);
extern int radeon_batches_flush(struct radeon_device *rdev);
diff --git a/radeon_atom.c b/radeon_atom.c
index ca6923c..989d18c 100644
--- a/radeon_atom.c
+++ b/radeon_atom.c
@@ -100,11 +100,13 @@ int radeon_atom_emit_default(struct radeon_device *rdev,
return radeon_ib_copy(ib, atom->pkts, atom->npkts);
}
-int radeon_atom_create(struct radeon_device *rdev, struct drm_radeon_atom *patom)
+int radeon_atom_create(struct radeon_device *rdev,
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atom)
{
struct r600_atoms *atoms = &rdev->asic.r700.atoms;
- return r600_atom_create(rdev, atoms, patom);
+ return r600_atom_create(rdev, atoms, patom, atom);
}
int radeon_batches_queue(struct radeon_device *rdev, void *batch)
diff --git a/radeon_atom.h b/radeon_atom.h
index e3befa2..3f16d15 100644
--- a/radeon_atom.h
+++ b/radeon_atom.h
@@ -53,12 +53,14 @@ struct radeon_atom {
};
/* R600 */
-#define R600_BATCH_NATOMS 6
+#define R600_BATCH_NATOMS 8
struct r600_batch {
struct list_head list;
struct list_head pre_flushes;
struct list_head post_flushes;
struct radeon_atom *atoms[R600_BATCH_NATOMS];
+ struct radeon_atom *emit_atoms[R600_BATCH_NATOMS];
+ u32 nemit_atoms;
u32 nflushes;
u32 npkts;
u32 cb_blend_alpha;
@@ -85,6 +87,7 @@ struct r600_atoms {
struct list_head blend_atoms;
struct list_head cb_atoms;
struct list_head cb_cntl_atoms;
+ struct list_head constants_atoms;
struct list_head pa_atoms;
struct list_head sq_atoms;
struct list_head tp_atoms;
@@ -122,7 +125,8 @@ extern int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *atoms)
extern void r600_atoms_release(struct radeon_device *rdev, struct r600_atoms *atoms);
extern int r600_atom_create(struct radeon_device *rdev,
struct r600_atoms *atoms,
- struct drm_radeon_atom *patom);
+ struct drm_radeon_atom *patom,
+ struct radeon_atom **atomptr);
extern int r600_batches_queue(struct radeon_device *rdev,
struct r600_atoms *atoms,
struct drm_r600_batch *batch);
diff --git a/test.c b/test.c
index 5bda074..33424fe 100644
--- a/test.c
+++ b/test.c
@@ -44,6 +44,13 @@ int main(void)
return 0;
}
+static u32 vsconstants[16] = {
+ 0x3C03126F, 0x00000000, 0x00000000, 0xBF800000,
+ 0x00000000, 0x3C03126F, 0x00000000, 0xBF800000,
+ 0x00000000, 0x00000000, 0xBF800000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x3F800000,
+};
+
int r600_tri_flat(struct radeon *radeon)
{
struct radeon_device *rdev;
@@ -53,6 +60,7 @@ int r600_tri_flat(struct radeon *radeon)
struct drm_r600_pa pa;
struct drm_r600_tp tp;
struct drm_r600_vport vport;
+ struct drm_r600_constants vs_constants;
struct drm_r600_batch batch;
struct drm_radeon_atom atom;
int r;
@@ -71,19 +79,17 @@ int r600_tri_flat(struct radeon *radeon)
atom.type = R600_ATOM_CB;
atom.id = 0;
atom.data = (uint64_t)(uintptr_t)&cb;
- r = radeon_atom_create(rdev, &atom);
+ r = radeon_atom_create(rdev, &atom, &batch.cb);
if (r)
return r;
- batch.cb_id = atom.id;
/* build tp */
tp.ta_cntl_aux = 0x07000002;
atom.type = R600_ATOM_TP;
atom.id = 0;
atom.data = (uint64_t)(uintptr_t)&tp;
- r = radeon_atom_create(rdev, &atom);
+ r = radeon_atom_create(rdev, &atom, &batch.tp);
if (r)
return r;
- batch.tp_id = atom.id;
/* build pa */
pa.pa_sc_mpass_ps_cntl = 0x00000000;
pa.pa_sc_mode_cntl = 0x00514000;
@@ -113,10 +119,9 @@ int r600_tri_flat(struct radeon *radeon)
atom.type = R600_ATOM_PA;
atom.id = 0;
atom.data = (uint64_t)(uintptr_t)&pa;
- r = radeon_atom_create(rdev, &atom);
+ r = radeon_atom_create(rdev, &atom, &batch.pa);
if (r)
return r;
- batch.pa_id = atom.id;
/* cb control */
cb_cntl.cb_target_mask = 0x0000000f;
cb_cntl.cb_shader_mask = 0x0000000f;
@@ -128,10 +133,9 @@ int r600_tri_flat(struct radeon *radeon)
atom.type = R600_ATOM_CB_CNTL;
atom.id = 0;
atom.data = (uint64_t)(uintptr_t)&cb_cntl;
- r = radeon_atom_create(rdev, &atom);
+ r = radeon_atom_create(rdev, &atom, &batch.cb_cntl);
if (r)
return r;
- batch.cb_cntl_id = atom.id;
/* viewport */
vport.pa_sc_vport_zmin_0 = 0x00000000;
vport.pa_sc_vport_zmax_0 = 0x3f800000;
@@ -160,10 +164,9 @@ int r600_tri_flat(struct radeon *radeon)
atom.type = R600_ATOM_VPORT;
atom.id = 0;
atom.data = (uint64_t)(uintptr_t)&vport;
- r = radeon_atom_create(rdev, &atom);
+ r = radeon_atom_create(rdev, &atom, &batch.vport);
if (r)
return r;
- batch.vport_id = atom.id;
/* blend */
blend.cb_blend0_control = 0x00010001;
blend.cb_blend1_control = 0x00000000;
@@ -177,10 +180,22 @@ int r600_tri_flat(struct radeon *radeon)
atom.type = R600_ATOM_BLEND;
atom.id = 0;
atom.data = (uint64_t)(uintptr_t)&blend;
- r = radeon_atom_create(rdev, &atom);
+ r = radeon_atom_create(rdev, &atom, &batch.blend);
+ if (r)
+ return r;
+ /* ps constant */
+ batch.ps_constants = NULL;
+ /* vs constant */
+ vs_constants.nconstants = 4;
+ vs_constants.offset = 0x400;
+ vs_constants.constants = (uintptr_t)vsconstants;
+ batch.vs_constants = NULL;
+ atom.type = R600_ATOM_CONSTANTS;
+ atom.id = 0;
+ atom.data = (uint64_t)(uintptr_t)&vs_constants;
+ r = radeon_atom_create(rdev, &atom, &batch.vs_constants);
if (r)
return r;
- batch.blend_id = atom.id;
/* batch */
batch.cb_clear_alpha = 0x00000000;