diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-01-26 21:24:16 +0100 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2010-01-26 21:24:16 +0100 |
commit | 4a7d7ecac228d4b848f050072510650c040ac1b7 (patch) | |
tree | f91b4fef5ecd9856b64b9e2331735e2d0e446c30 | |
parent | 10aca66380eec42850cc9fb31fc04f1cb9f3109f (diff) |
add blend state
-rw-r--r-- | r600_atom.c | 132 | ||||
-rw-r--r-- | r600_atom_api.h | 26 | ||||
-rw-r--r-- | radeon_atom.h | 14 | ||||
-rw-r--r-- | radeon_device.c | 10 | ||||
-rw-r--r-- | radeon_device.h | 4 | ||||
-rw-r--r-- | test.c | 31 |
6 files changed, 196 insertions, 21 deletions
diff --git a/r600_atom.c b/r600_atom.c index aa986ea..3d20503 100644 --- a/r600_atom.c +++ b/r600_atom.c @@ -84,18 +84,17 @@ static int r600_cb_emit(struct radeon_device *rdev, cb->pkts[16] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]); cb->pkts[21] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]); cb->pkts[26] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]); - cb->pkts[259] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[264] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[277] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[282] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[298] = radeon_ib_reloc(ib, cb->psshader1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[303] = radeon_ib_reloc(ib, cb->psshader1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[346] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[357] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[364] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[375] = radeon_ib_reloc(ib, cb->vbo1, RADEON_GEM_DOMAIN_GTT); - cb->pkts[397] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]); - + cb->pkts[250] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); + cb->pkts[255] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); + cb->pkts[268] = radeon_ib_reloc(ib, cb->vsshader1, RADEON_GEM_DOMAIN_GTT); + 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[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); + cb->pkts[388] = radeon_ib_reloc(ib, cb->bo, cb->placements[0] | cb->placements[1]); r = radeon_ib_copy(ib, cb->pkts, atom->npkts); return r; } @@ -655,6 +654,70 @@ out_err: return r; } +/* + * r600_blend + */ +struct r600_blend { + struct radeon_atom atom; + u32 pkts[16]; + struct r600_atoms *atoms; +}; + +static void r600_blend_release(struct kref *kref) +{ + struct radeon_atom *atom = container_of(kref, struct radeon_atom, kref); + struct r600_blend *blend = container_of(atom, struct r600_blend, atom); + + mutex_lock(&blend->atoms->mutex); + list_del_init(&blend->atom.list); + mutex_unlock(&blend->atoms->mutex); + kfree(blend); +} + +static int r600_blend_create(struct radeon_device *rdev, + struct r600_atoms *atoms, + struct drm_radeon_atom *patom, + struct radeon_atom **atom) +{ + struct drm_r600_blend pblend; + struct r600_blend *blend; + int r; + + blend = kmalloc(sizeof(*blend), GFP_KERNEL); + if (blend == NULL) + return -ENOMEM; + /* make sure structure properly initialized */ + memset(blend, 0, sizeof(*blend)); + r = radeon_atom_init(&blend->atom, &atoms->idr, &r600_blend_release, + &radeon_atom_emit_default, &r600_atom_process_default, + blend->pkts); + if (r) + goto out_err; + /* KERNEL use get user data */ + memcpy(&pblend, (void*)(unsigned long)patom->data, sizeof(struct drm_r600_blend)); + /* CB_BLEND0_CONTROL */ + blend->pkts[blend->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 8); + blend->pkts[blend->atom.npkts++] = 0x000001E0; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend0_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend1_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend2_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend3_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend4_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend5_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend6_control; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend7_control; + /* CB_BLEND_CONTROL */ + blend->pkts[blend->atom.npkts++] = PKT3(PKT3_SET_CONTEXT_REG, 1); + blend->pkts[blend->atom.npkts++] = 0x00000201; + blend->pkts[blend->atom.npkts++] = pblend.cb_blend_control; + *atom = &blend->atom; +fprintf(stderr, "%s %d pkts\n", __func__, (*atom)->npkts); + return 0; +out_err: + radeon_atom_put(&blend->atom); + *atom = NULL; + return r; +} /* * r600 atom core functions @@ -704,6 +767,13 @@ int r600_atom_create(struct radeon_device *rdev, atom->type = patom->type; list_add_tail(&atom->list, &atoms->vport_atoms); break; + case R600_ATOM_BLEND: + r = r600_blend_create(rdev, atoms, patom, &atom); + if (r) + return r; + atom->type = patom->type; + list_add_tail(&atom->list, &atoms->blend_atoms); + break; default: dev_err(rdev->dev, "unknown R600 atom type 0x%08X\n", patom->type); return -EINVAL; @@ -727,7 +797,8 @@ 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->npkts = 0; + /* blend color (6dw) + clear color (6dw) + fog color (5 dw) */ + rbatch->npkts = 17; *batch = rbatch; return 0; } @@ -756,6 +827,23 @@ static int r600_batches_flush_locked(struct radeon_device *rdev, struct r600_bat struct r600_batch *batch; int r, i; + batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_SET_CONTEXT_REG, 4); + batches->ib->ptr[batches->ib->cpkts++] = 0x00000048; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_clear_red; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_clear_green; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_clear_blue; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_clear_alpha; + batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_SET_CONTEXT_REG, 4); + batches->ib->ptr[batches->ib->cpkts++] = 0x00000105; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_blend_red; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_blend_green; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_blend_blue; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_blend_alpha; + batches->ib->ptr[batches->ib->cpkts++] = PKT3(PKT3_SET_CONTEXT_REG, 3); + batches->ib->ptr[batches->ib->cpkts++] = 0x00000109; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_fog_red; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_fog_green; + batches->ib->ptr[batches->ib->cpkts++] = batch->cb_fog_blue; list_for_each_entry(batch, &batches->batches, list) { for (i = 0; i < R600_BATCH_NATOMS; i++) { r = batch->atoms[i]->emit(rdev, batch->atoms[i], batch, batches->ib); @@ -784,7 +872,22 @@ int r600_batches_queue(struct radeon_device *rdev, if (r) return r; mutex_lock(&atoms->mutex); + rbatch->cb_clear_alpha = batch->cb_clear_alpha; + rbatch->cb_clear_blue = batch->cb_clear_blue; + rbatch->cb_clear_green = batch->cb_clear_green; + rbatch->cb_clear_red = batch->cb_clear_red; + rbatch->cb_blend_alpha = batch->cb_blend_alpha; + rbatch->cb_blend_blue = batch->cb_blend_blue; + rbatch->cb_blend_green = batch->cb_blend_green; + rbatch->cb_blend_red = batch->cb_blend_red; + rbatch->cb_fog_blue = batch->cb_fog_blue; + 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) @@ -875,6 +978,7 @@ int r600_batches_flush(struct radeon_device *rdev, struct r600_atoms *atoms) int r600_atoms_init(struct radeon_device *rdev, struct r600_atoms *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->pa_atoms); @@ -986,6 +1090,7 @@ void r600_tflat(struct radeon_atom *atom) WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1)); WPKT(0x000001E8); WPKT(0x00000003); +#if 0 WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1)); WPKT(0x000001E0); WPKT(0x00010001); @@ -995,6 +1100,7 @@ void r600_tflat(struct radeon_atom *atom) WPKT(0x00000000); WPKT(0x00000000); WPKT(0x00000000); +#endif WPKT(PKT3(PKT3_SET_CONTEXT_REG, 1)); WPKT(0x000000D4); WPKT(0x00000000); diff --git a/r600_atom_api.h b/r600_atom_api.h index 8b2522c..16938c7 100644 --- a/r600_atom_api.h +++ b/r600_atom_api.h @@ -32,6 +32,7 @@ struct drm_radeon_atom { #define R600_ATOM_PA 3 #define R600_ATOM_CB_CNTL 4 #define R600_ATOM_VPORT 5 +#define R600_ATOM_BLEND 6 struct drm_r600_cb { u32 pitch; @@ -114,12 +115,37 @@ struct drm_r600_vport { u32 pa_sc_generic_scissor_br; }; +/* blend - blending */ +struct drm_r600_blend { + u32 cb_blend0_control; + u32 cb_blend1_control; + u32 cb_blend2_control; + u32 cb_blend3_control; + u32 cb_blend4_control; + u32 cb_blend5_control; + u32 cb_blend6_control; + u32 cb_blend7_control; + u32 cb_blend_control; +}; + 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; + u32 cb_blend_red; + u32 cb_clear_alpha; + u32 cb_clear_blue; + u32 cb_clear_green; + u32 cb_clear_red; + u32 cb_fog_blue; + u32 cb_fog_green; + u32 cb_fog_red; }; diff --git a/radeon_atom.h b/radeon_atom.h index 2491113..9f696ba 100644 --- a/radeon_atom.h +++ b/radeon_atom.h @@ -53,13 +53,24 @@ struct radeon_atom { }; /* R600 */ -#define R600_BATCH_NATOMS 5 +#define R600_BATCH_NATOMS 6 struct r600_batch { struct list_head list; struct list_head pre_flushes; struct list_head post_flushes; struct radeon_atom *atoms[R600_BATCH_NATOMS]; u32 npkts; + u32 cb_blend_alpha; + u32 cb_blend_blue; + u32 cb_blend_green; + u32 cb_blend_red; + u32 cb_clear_alpha; + u32 cb_clear_blue; + u32 cb_clear_green; + u32 cb_clear_red; + u32 cb_fog_blue; + u32 cb_fog_green; + u32 cb_fog_red; }; struct r600_batches { @@ -70,6 +81,7 @@ struct r600_batches { }; struct r600_atoms { + struct list_head blend_atoms; struct list_head cb_atoms; struct list_head cb_cntl_atoms; struct list_head pa_atoms; diff --git a/radeon_device.c b/radeon_device.c index 3ff29c2..21ec4d6 100644 --- a/radeon_device.c +++ b/radeon_device.c @@ -57,8 +57,8 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) if (lib == NULL) return -ENOMEM; memset(lib, sizeof(*lib), 0); - lib->pkts = malloc(64 * 1024); - if (lib->pkts == NULL) { + lib->ptr = malloc(64 * 1024); + if (lib->ptr == NULL) { free(lib); return -ENOMEM; } @@ -66,7 +66,7 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) lib->length_dw = 64 * 1024 / 4; lib->relocs = malloc(64 * 1024); if (lib->relocs == NULL) { - free(lib->pkts); + free(lib->ptr); free(lib); return -ENOMEM; } @@ -80,7 +80,7 @@ void radeon_ib_free(struct radeon_ib *ib) { if (ib == NULL) return; - free(ib->pkts); + free(ib->ptr); free(ib->relocs); free(ib); } @@ -96,7 +96,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) drmib.chunks = (uint64_t)(uintptr_t)chunk_array; chunks[0].chunk_id = RADEON_CHUNK_ID_IB; chunks[0].length_dw = ib->cpkts; - chunks[0].chunk_data = (uint64_t)(uintptr_t)ib->pkts; + chunks[0].chunk_data = (uint64_t)(uintptr_t)ib->ptr; chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS; chunks[1].length_dw = ib->crelocs * 4; chunks[1].chunk_data = (uint64_t)(uintptr_t)ib->relocs; diff --git a/radeon_device.h b/radeon_device.h index 036e176..c0e2ba8 100644 --- a/radeon_device.h +++ b/radeon_device.h @@ -44,7 +44,7 @@ struct radeon_device { }; struct radeon_ib { - u32 *pkts; + u32 *ptr; u32 cpkts; u32 length_dw; u32 *relocs; @@ -68,7 +68,7 @@ static inline int radeon_ib_copy(struct radeon_ib *ib, u32 *pkts, u32 ndw) { if ((ib->cpkts + ndw) > ib->length_dw) return -ENOMEM; - memcpy(&ib->pkts[ib->cpkts], pkts, ndw * 4); + memcpy(&ib->ptr[ib->cpkts], pkts, ndw * 4); ib->cpkts += ndw; return 0; } @@ -47,6 +47,7 @@ int main(void) int r600_tri_flat(struct radeon *radeon) { struct radeon_device *rdev; + struct drm_r600_blend blend; struct drm_r600_cb cb; struct drm_r600_cb_cntl cb_cntl; struct drm_r600_pa pa; @@ -163,6 +164,36 @@ int r600_tri_flat(struct radeon *radeon) if (r) return r; batch.vport_id = atom.id; + /* blend */ + blend.cb_blend0_control = 0x00010001; + blend.cb_blend1_control = 0x00000000; + blend.cb_blend2_control = 0x00000000; + blend.cb_blend3_control = 0x00000000; + blend.cb_blend4_control = 0x00000000; + blend.cb_blend5_control = 0x00000000; + blend.cb_blend6_control = 0x00000000; + blend.cb_blend7_control = 0x00000000; + blend.cb_blend_control = 0x00010001; + atom.type = R600_ATOM_BLEND; + atom.id = 0; + atom.data = (uint64_t)(uintptr_t)&blend; + r = radeon_atom_create(rdev, &atom); + if (r) + return r; + batch.blend_id = atom.id; + + /* batch */ + batch.cb_clear_alpha = 0x00000000; + batch.cb_clear_blue = 0x00000000; + batch.cb_clear_green = 0x00000000; + batch.cb_clear_red = 0x00000000; + batch.cb_blend_alpha = 0x00000000; + batch.cb_blend_blue = 0x00000000; + batch.cb_blend_green = 0x00000000; + batch.cb_blend_red = 0x00000000; + batch.cb_fog_blue = 0x00000000; + batch.cb_fog_green = 0x00000000; + batch.cb_fog_red = 0x00000000; r = radeon_batches_queue(rdev, &batch); if (r) |