summaryrefslogtreecommitdiff
path: root/src/sna/gen5_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/gen5_render.c')
-rw-r--r--src/sna/gen5_render.c147
1 files changed, 113 insertions, 34 deletions
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 6347b3c7..573478d3 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -349,37 +349,104 @@ static void gen5_vertex_flush(struct sna *sna)
gen5_magic_ca_pass(sna, sna->render.op);
}
-static void gen5_vertex_finish(struct sna *sna, Bool last)
+static int gen5_vertex_finish(struct sna *sna)
{
struct kgem_bo *bo;
- unsigned int i, delta;
+ unsigned int i;
gen5_vertex_flush(sna);
if (!sna->render.vertex_used)
- return;
+ return sna->render.vertex_size;
/* Note: we only need dword alignment (currently) */
- if (last && sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
- DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
- sna->render.vertex_used, sna->kgem.nbatch));
- memcpy(sna->kgem.batch + sna->kgem.nbatch,
+ bo = sna->render.vbo;
+ if (bo) {
+ for (i = 0; i < ARRAY_SIZE(sna->render.vertex_reloc); i++) {
+ if (sna->render.vertex_reloc[i]) {
+ DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
+ i, sna->render.vertex_reloc[i]));
+
+ sna->kgem.batch[sna->render.vertex_reloc[i]] =
+ kgem_add_reloc(&sna->kgem,
+ sna->render.vertex_reloc[i],
+ bo,
+ I915_GEM_DOMAIN_VERTEX << 16,
+ 0);
+ sna->kgem.batch[sna->render.vertex_reloc[i]+1] =
+ kgem_add_reloc(&sna->kgem,
+ sna->render.vertex_reloc[i]+1,
+ bo,
+ I915_GEM_DOMAIN_VERTEX << 16,
+ sna->render.vertex_used * 4 - 1);
+ sna->render.vertex_reloc[i] = 0;
+ }
+ }
+
+ sna->render.vertex_used = 0;
+ sna->render.vertex_index = 0;
+ sna->render_state.gen5.vb_id = 0;
+
+ kgem_bo_destroy(&sna->kgem, bo);
+ }
+
+ sna->render.vertices = NULL;
+ sna->render.vbo = kgem_create_linear(&sna->kgem, 256*1024);
+ if (sna->render.vbo)
+ sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
+ if (sna->render.vertices == NULL) {
+ kgem_bo_destroy(&sna->kgem, sna->render.vbo);
+ sna->render.vbo = NULL;
+ return 0;
+ }
+
+ if (sna->render.vertex_used) {
+ memcpy(sna->render.vertices,
sna->render.vertex_data,
- sna->render.vertex_used * 4);
- delta = sna->kgem.nbatch * 4;
- bo = NULL;
- sna->kgem.nbatch += sna->render.vertex_used;
- } else {
- bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used);
- if (bo && !kgem_bo_write(&sna->kgem, bo,
- sna->render.vertex_data,
- 4*sna->render.vertex_used)) {
- kgem_bo_destroy(&sna->kgem, bo);
- return;
+ sizeof(float)*sna->render.vertex_used);
+ }
+ sna->render.vertex_size = 64 * 1024 - 1;
+ return sna->render.vertex_size - sna->render.vertex_used;
+}
+
+static void gen5_vertex_close(struct sna *sna)
+{
+ struct kgem_bo *bo;
+ unsigned int i, delta = 0;
+
+ gen5_vertex_flush(sna);
+ if (!sna->render.vertex_used) {
+ assert(sna->render.vbo == NULL);
+ assert(sna->render.vertices == sna->render.vertex_data);
+ assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
+ return;
+ }
+
+ DBG(("%s: used=%d\n", __FUNCTION__, sna->render.vertex_used));
+
+ bo = sna->render.vbo;
+ if (bo == NULL) {
+
+ if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
+ DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
+ sna->render.vertex_used, sna->kgem.nbatch));
+ memcpy(sna->kgem.batch + sna->kgem.nbatch,
+ sna->render.vertex_data,
+ sna->render.vertex_used * 4);
+ delta = sna->kgem.nbatch * 4;
+ bo = NULL;
+ sna->kgem.nbatch += sna->render.vertex_used;
+ } else {
+ bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used);
+ if (bo && !kgem_bo_write(&sna->kgem, bo,
+ sna->render.vertex_data,
+ 4*sna->render.vertex_used)) {
+ kgem_bo_destroy(&sna->kgem, bo);
+ goto reset;
+ }
+ DBG(("%s: new vbo: %d\n", __FUNCTION__,
+ sna->render.vertex_used));
}
- delta = 0;
- DBG(("%s: new vbo: %d\n", __FUNCTION__,
- sna->render.vertex_used));
}
for (i = 0; i < ARRAY_SIZE(sna->render.vertex_reloc); i++) {
@@ -406,9 +473,14 @@ static void gen5_vertex_finish(struct sna *sna, Bool last)
if (bo)
kgem_bo_destroy(&sna->kgem, bo);
+reset:
sna->render.vertex_used = 0;
sna->render.vertex_index = 0;
sna->render_state.gen5.vb_id = 0;
+
+ sna->render.vbo = NULL;
+ sna->render.vertices = sna->render.vertex_data;
+ sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
}
static uint32_t gen5_get_blend(int op,
@@ -727,7 +799,7 @@ gen5_emit_composite_primitive_solid(struct sna *sna,
float f;
} dst;
- v = sna->render.vertex_data + sna->render.vertex_used;
+ v = sna->render.vertices + sna->render.vertex_used;
sna->render.vertex_used += 9;
dst.p.x = r->dst.x + r->width;
@@ -759,7 +831,7 @@ gen5_emit_composite_primitive_identity_source(struct sna *sna,
float f;
} dst;
- v = sna->render.vertex_data + sna->render.vertex_used;
+ v = sna->render.vertices + sna->render.vertex_used;
sna->render.vertex_used += 9;
sx = r->src.x + op->src.offset[0];
@@ -793,7 +865,7 @@ gen5_emit_composite_primitive_affine_source(struct sna *sna,
} dst;
float *v;
- v = sna->render.vertex_data + sna->render.vertex_used;
+ v = sna->render.vertices + sna->render.vertex_used;
sna->render.vertex_used += 9;
dst.p.x = r->dst.x + r->width;
@@ -846,7 +918,7 @@ gen5_emit_composite_primitive_identity_source_mask(struct sna *sna,
w = r->width;
h = r->height;
- v = sna->render.vertex_data + sna->render.vertex_used;
+ v = sna->render.vertices + sna->render.vertex_used;
sna->render.vertex_used += 15;
dst.p.x = r->dst.x + r->width;
@@ -1082,10 +1154,7 @@ static int gen5_get_rectangles__flush(struct sna *sna)
if (sna->kgem.nreloc > KGEM_RELOC_SIZE(&sna->kgem) - 1)
return 0;
- gen5_vertex_finish(sna, FALSE);
- sna->render.vertex_index = 0;
-
- return ARRAY_SIZE(sna->render.vertex_data);
+ return gen5_vertex_finish(sna);
}
inline static int gen5_get_rectangles(struct sna *sna,
@@ -1094,9 +1163,9 @@ inline static int gen5_get_rectangles(struct sna *sna,
{
int rem = vertex_space(sna);
- if (rem < 3*op->floats_per_vertex) {
+ if (rem < op->floats_per_rect) {
DBG(("flushing vbo for %s: %d < %d\n",
- __FUNCTION__, rem, 3*op->floats_per_vertex));
+ __FUNCTION__, rem, op->floats_per_rect));
rem = gen5_get_rectangles__flush(sna);
if (rem == 0)
return 0;
@@ -1105,8 +1174,8 @@ inline static int gen5_get_rectangles(struct sna *sna,
if (!gen5_rectangle_begin(sna, op))
return 0;
- if (want * op->floats_per_vertex*3 > rem)
- want = rem / (3*op->floats_per_vertex);
+ if (want * op->floats_per_rect > rem)
+ want = rem / op->floats_per_rect;
sna->render.vertex_index += 3*want;
return want;
@@ -1233,6 +1302,9 @@ static void
gen5_align_vertex(struct sna *sna, const struct sna_composite_op *op)
{
if (op->floats_per_vertex != sna->render_state.gen5.floats_per_vertex) {
+ if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
+ gen5_vertex_finish(sna);
+
DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
sna->render_state.gen5.floats_per_vertex,
op->floats_per_vertex,
@@ -1674,6 +1746,7 @@ gen5_render_video(struct sna *sna,
tmp.u.gen5.ve_id = 1;
tmp.is_affine = TRUE;
tmp.floats_per_vertex = 3;
+ tmp.floats_per_rect = 9;
if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL))
kgem_submit(&sna->kgem);
@@ -2226,6 +2299,7 @@ gen5_render_composite(struct sna *sna,
tmp->floats_per_vertex = 3 + !tmp->is_affine;
}
+ tmp->floats_per_rect = 3*tmp->floats_per_vertex;
tmp->u.gen5.wm_kernel =
gen5_choose_composite_kernel(tmp->op,
@@ -2668,6 +2742,7 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
tmp.is_affine = TRUE;
tmp.floats_per_vertex = 3;
+ tmp.floats_per_rect = 9;
tmp.u.gen5.wm_kernel = WM_KERNEL;
tmp.u.gen5.ve_id = 1;
@@ -2810,6 +2885,7 @@ gen5_render_copy(struct sna *sna, uint8_t alu,
op->base.is_affine = true;
op->base.floats_per_vertex = 3;
+ op->base.floats_per_rect = 9;
op->base.u.gen5.wm_kernel = WM_KERNEL;
op->base.u.gen5.ve_id = 1;
@@ -2957,6 +3033,7 @@ gen5_render_fill_boxes(struct sna *sna,
tmp.is_affine = TRUE;
tmp.floats_per_vertex = 3;
+ tmp.floats_per_rect = 9;
tmp.u.gen5.wm_kernel = WM_KERNEL;
tmp.u.gen5.ve_id = 1;
@@ -3144,6 +3221,7 @@ gen5_render_fill(struct sna *sna, uint8_t alu,
op->base.is_affine = TRUE;
op->base.floats_per_vertex = 3;
+ op->base.floats_per_rect = 9;
op->base.u.gen5.wm_kernel = WM_KERNEL;
op->base.u.gen5.ve_id = 1;
@@ -3229,6 +3307,7 @@ gen5_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
tmp.is_affine = TRUE;
tmp.floats_per_vertex = 3;
+ tmp.floats_per_rect = 9;
tmp.has_component_alpha = 0;
tmp.need_magic_ca_pass = FALSE;
@@ -3269,7 +3348,7 @@ gen5_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
static void
gen5_render_flush(struct sna *sna)
{
- gen5_vertex_finish(sna, TRUE);
+ gen5_vertex_close(sna);
}
static void