summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-01-26 21:24:16 +0100
committerJerome Glisse <jglisse@redhat.com>2010-01-26 21:24:16 +0100
commit4a7d7ecac228d4b848f050072510650c040ac1b7 (patch)
treef91b4fef5ecd9856b64b9e2331735e2d0e446c30
parent10aca66380eec42850cc9fb31fc04f1cb9f3109f (diff)
add blend state
-rw-r--r--r600_atom.c132
-rw-r--r--r600_atom_api.h26
-rw-r--r--radeon_atom.h14
-rw-r--r--radeon_device.c10
-rw-r--r--radeon_device.h4
-rw-r--r--test.c31
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;
}
diff --git a/test.c b/test.c
index 1503bfb..5bda074 100644
--- a/test.c
+++ b/test.c
@@ -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)