diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-01-29 22:06:17 +0100 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2010-01-29 22:06:17 +0100 |
commit | 2a518e1274130fed9ba13c87b95ae055211d2331 (patch) | |
tree | 272bdc3bf110e672d087dfc4dac5bc9c06254611 | |
parent | 67ede082cffb7a4a82486d81cd12fb8e564bf530 (diff) |
add constants atom and convert to use ptr
-rw-r--r-- | lwrapper.h | 2 | ||||
-rw-r--r-- | r600_atom.c | 167 | ||||
-rw-r--r-- | r600_atom_api.h | 22 | ||||
-rw-r--r-- | r600_winsys.h | 3 | ||||
-rw-r--r-- | radeon_atom.c | 6 | ||||
-rw-r--r-- | radeon_atom.h | 8 | ||||
-rw-r--r-- | test.c | 39 |
7 files changed, 170 insertions, 77 deletions
@@ -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); @@ -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; |