summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-12-20 12:00:00 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-12-20 19:11:04 +0000
commit0f84ecfc3cd7dfe7f43ff99a6498d2ceccd90225 (patch)
treea78f7d5a969afc132fe838ef6bc7a77c258f26e6
parent1f4ede0ef8f8a8d07e11781ad05617ecdfcd3faf (diff)
sna/gen4+: Amalgamate all the gen4-7 vertex buffer emission
Having reduced all the vb code for these generations to the same set of routines, we can refactor them into a single set of functions. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--configure.ac2
-rw-r--r--src/sna/Makefile.am2
-rw-r--r--src/sna/gen4_render.c803
-rw-r--r--src/sna/gen4_render.h17
-rw-r--r--src/sna/gen4_vertex.c896
-rw-r--r--src/sna/gen4_vertex.h39
-rw-r--r--src/sna/gen5_render.c833
-rw-r--r--src/sna/gen5_render.h17
-rw-r--r--src/sna/gen6_render.c727
-rw-r--r--src/sna/gen7_render.c701
-rw-r--r--src/sna/kgem.c9
-rw-r--r--src/sna/kgem.h7
-rw-r--r--src/sna/kgem_debug.c9
-rw-r--r--src/sna/kgem_debug.h2
-rw-r--r--src/sna/kgem_debug_gen5.c21
-rw-r--r--src/sna/sna_render.c4
-rw-r--r--src/sna/sna_render.h13
-rw-r--r--src/sna/sna_render_inline.h27
-rw-r--r--src/sna/sna_trapezoids.c2
19 files changed, 1297 insertions, 2834 deletions
diff --git a/configure.ac b/configure.ac
index 93544372..52db4e4c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -409,7 +409,7 @@ if test "x$UMS_ONLY" = xyes; then
fi
AM_CONDITIONAL(DEBUG, test x$DEBUG != xno)
-AM_CONDITIONAL(FULL_DEBUG, test x$FULL_DEBUG = xfull)
+AM_CONDITIONAL(FULL_DEBUG, test x$DEBUG = xfull)
if test "x$DEBUG" = xno; then
AC_DEFINE(NDEBUG,1,[Disable internal debugging])
fi
diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index 306996b5..8b654d76 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -73,6 +73,8 @@ libsna_la_SOURCES = \
gen3_render.h \
gen4_render.c \
gen4_render.h \
+ gen4_vertex.c \
+ gen4_vertex.h \
gen5_render.c \
gen5_render.h \
gen6_render.c \
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 3f120623..8f4f1d4e 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -42,6 +42,7 @@
#include "brw/brw.h"
#include "gen4_render.h"
+#include "gen4_vertex.h"
/* gen4 has a serious issue with its shaders that we need to flush
* after every rectangle... So until that is resolved, prefer
@@ -236,154 +237,6 @@ static void gen4_magic_ca_pass(struct sna *sna,
state->last_primitive = sna->kgem.nbatch;
}
-static void gen4_vertex_flush(struct sna *sna)
-{
- if (sna->render_state.gen4.vertex_offset == 0)
- return;
-
- DBG(("%s[%x] = %d\n", __FUNCTION__,
- 4*sna->render_state.gen4.vertex_offset,
- sna->render.vertex_index - sna->render.vertex_start));
- sna->kgem.batch[sna->render_state.gen4.vertex_offset] =
- sna->render.vertex_index - sna->render.vertex_start;
- sna->render_state.gen4.vertex_offset = 0;
-}
-
-static int gen4_vertex_finish(struct sna *sna)
-{
- struct kgem_bo *bo;
- unsigned int i;
-
- assert(sna->render.vertex_used);
- assert(sna->render.nvertex_reloc);
-
- /* Note: we only need dword alignment (currently) */
-
- bo = sna->render.vbo;
- if (bo) {
- gen4_vertex_flush(sna);
-
- for (i = 0; i < sna->render.nvertex_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->render.vbo = NULL;
- sna->render.nvertex_reloc = 0;
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- sna->render_state.gen4.vb_id = 0;
-
- kgem_bo_destroy(&sna->kgem, bo);
- }
-
- sna->render.vertices = NULL;
- sna->render.vbo = kgem_create_linear(&sna->kgem,
- 256*1024, CREATE_GTT_MAP);
- if (sna->render.vbo)
- sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
- if (sna->render.vertices == NULL) {
- if (sna->render.vbo)
- 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,
- sizeof(float)*sna->render.vertex_used);
- }
- sna->render.vertex_size = 64 * 1024 - 1;
- return sna->render.vertex_size - sna->render.vertex_used;
-}
-
-static void gen4_vertex_close(struct sna *sna)
-{
- struct kgem_bo *bo, *free_bo = NULL;
- unsigned int i, delta = 0;
-
- assert(sna->render_state.gen4.vertex_offset == 0);
- if (!sna->render_state.gen4.vb_id)
- return;
-
- DBG(("%s: used=%d, vbo active? %d\n",
- __FUNCTION__, sna->render.vertex_used, sna->render.vbo != NULL));
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render.vertex_size - sna->render.vertex_used < 64) {
- DBG(("%s: discarding full vbo\n", __FUNCTION__));
- sna->render.vbo = NULL;
- sna->render.vertices = sna->render.vertex_data;
- sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
- free_bo = bo;
- } else if (IS_CPU_MAP(bo->map)) {
- DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
- sna->render.vertices =
- kgem_bo_map__gtt(&sna->kgem, sna->render.vbo);
- if (sna->render.vertices == NULL) {
- sna->render.vbo = NULL;
- sna->render.vertices = sna->render.vertex_data;
- sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
- free_bo = bo;
- }
- }
- } else {
- 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,
- CREATE_NO_THROTTLE);
- if (bo && !kgem_bo_write(&sna->kgem, bo,
- sna->render.vertex_data,
- 4*sna->render.vertex_used)) {
- kgem_bo_destroy(&sna->kgem, bo);
- bo = NULL;
- }
- DBG(("%s: new vbo: %d\n", __FUNCTION__,
- sna->render.vertex_used));
- free_bo = bo;
- }
- }
-
- assert(sna->render.nvertex_reloc);
- for (i = 0; i < sna->render.nvertex_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,
- delta);
- }
- sna->render.nvertex_reloc = 0;
-
- if (sna->render.vbo == NULL) {
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- }
-
- if (free_bo)
- kgem_bo_destroy(&sna->kgem, free_bo);
-}
-
-
static uint32_t gen4_get_blend(int op,
bool has_component_alpha,
uint32_t dst_format)
@@ -674,345 +527,6 @@ gen4_bind_bo(struct sna *sna,
return offset * sizeof(uint32_t);
}
-fastcall static void
-gen4_emit_composite_primitive_solid(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = 1.;
- v[2] = 1.;
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- v[4] = 0.;
- v[5] = 1.;
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- v[7] = 0.;
- v[8] = 0.;
-}
-
-fastcall static void
-gen4_emit_composite_primitive_identity_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- const float *sf = op->src.scale;
- float sx, sy, *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- sx = r->src.x + op->src.offset[0];
- sy = r->src.y + op->src.offset[1];
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = (sx + r->width) * sf[0];
- v[2] = (sy + r->height) * sf[1];
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- v[4] = sx * sf[0];
- v[5] = v[2];
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- v[7] = v[4];
- v[8] = sy * sf[1];
-}
-
-fastcall static void
-gen4_emit_composite_primitive_affine_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float *v;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[1], &v[2]);
- v[1] *= op->src.scale[0];
- v[2] *= op->src.scale[1];
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[4], &v[5]);
- v[4] *= op->src.scale[0];
- v[5] *= op->src.scale[1];
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y,
- op->src.transform,
- &v[7], &v[8]);
- v[7] *= op->src.scale[0];
- v[8] *= op->src.scale[1];
-}
-
-fastcall static void
-gen4_emit_composite_primitive_identity_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[13] = v[8] = msk_x * op->mask.scale[0];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[14] = msk_y * op->mask.scale[1];
-
- v[7] = v[2] = v[1] = 1;
- v[12] = v[11] = v[6] = 0;
-}
-
-fastcall static void
-gen4_emit_composite_primitive_identity_source_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float src_x, src_y;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- src_x = r->src.x + op->src.offset[0];
- src_y = r->src.y + op->src.offset[1];
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = (src_x + w) * op->src.scale[0];
- v[2] = (src_y + h) * op->src.scale[1];
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[6] = src_x * op->src.scale[0];
- v[7] = v[2];
- v[8] = msk_x * op->mask.scale[0];
- v[9] = v[4];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[11] = v[6];
- v[12] = src_y * op->src.scale[1];
- v[13] = v[8];
- v[14] = msk_y * op->mask.scale[1];
-}
-
-fastcall static void
-gen4_emit_composite_primitive(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
- bool is_affine = op->is_affine;
- const float *src_sf = op->src.scale;
- const float *mask_sf = op->mask.scale;
- bool has_mask = op->u.gen4.ve_id & 2;
-
- if (op->src.is_solid) {
- src_x[0] = 0;
- src_y[0] = 0;
- src_x[1] = 0;
- src_y[1] = 1;
- src_x[2] = 1;
- src_y[2] = 1;
- src_w[0] = src_w[1] = src_w[2] = 1;
- } else if (is_affine) {
- sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1],
- op->src.transform,
- &src_x[0],
- &src_y[0]);
-
- sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[1],
- &src_y[1]);
-
- sna_get_transformed_coordinates(r->src.x + op->src.offset[0] + r->width,
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[2],
- &src_y[2]);
- } else {
- sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1],
- op->src.transform,
- &src_x[0],
- &src_y[0],
- &src_w[0]);
- sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[1],
- &src_y[1],
- &src_w[1]);
- sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0] + r->width,
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[2],
- &src_y[2],
- &src_w[2]);
- }
-
- if (has_mask) {
- if (op->mask.is_solid) {
- mask_x[0] = 0;
- mask_y[0] = 0;
- mask_x[1] = 0;
- mask_y[1] = 1;
- mask_x[2] = 1;
- mask_y[2] = 1;
- mask_w[0] = mask_w[1] = mask_w[2] = 1;
- } else if (is_affine) {
- sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1],
- op->mask.transform,
- &mask_x[0],
- &mask_y[0]);
-
- sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[1],
- &mask_y[1]);
-
- sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0] + r->width,
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[2],
- &mask_y[2]);
- } else {
- sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1],
- op->mask.transform,
- &mask_x[0],
- &mask_y[0],
- &mask_w[0]);
- sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[1],
- &mask_y[1],
- &mask_w[1]);
- sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0] + r->width,
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[2],
- &mask_y[2],
- &mask_w[2]);
- }
- }
-
- OUT_VERTEX(r->dst.x + r->width, r->dst.y + r->height);
- OUT_VERTEX_F(src_x[2] * src_sf[0]);
- OUT_VERTEX_F(src_y[2] * src_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(src_w[2]);
- if (has_mask) {
- OUT_VERTEX_F(mask_x[2] * mask_sf[0]);
- OUT_VERTEX_F(mask_y[2] * mask_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(mask_w[2]);
- }
-
- OUT_VERTEX(r->dst.x, r->dst.y + r->height);
- OUT_VERTEX_F(src_x[1] * src_sf[0]);
- OUT_VERTEX_F(src_y[1] * src_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(src_w[1]);
- if (has_mask) {
- OUT_VERTEX_F(mask_x[1] * mask_sf[0]);
- OUT_VERTEX_F(mask_y[1] * mask_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(mask_w[1]);
- }
-
- OUT_VERTEX(r->dst.x, r->dst.y);
- OUT_VERTEX_F(src_x[0] * src_sf[0]);
- OUT_VERTEX_F(src_y[0] * src_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(src_w[0]);
- if (has_mask) {
- OUT_VERTEX_F(mask_x[0] * mask_sf[0]);
- OUT_VERTEX_F(mask_y[0] * mask_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(mask_w[0]);
- }
-}
-
static void gen4_emit_vertex_buffer(struct sna *sna,
const struct sna_composite_op *op)
{
@@ -1026,13 +540,13 @@ static void gen4_emit_vertex_buffer(struct sna *sna,
OUT_BATCH(0);
OUT_BATCH(0);
- sna->render_state.gen4.vb_id |= 1 << id;
+ sna->render.vb_id |= 1 << id;
}
static void gen4_emit_primitive(struct sna *sna)
{
if (sna->kgem.nbatch == sna->render_state.gen4.last_primitive) {
- sna->render_state.gen4.vertex_offset = sna->kgem.nbatch - 5;
+ sna->render.vertex_offset = sna->kgem.nbatch - 5;
return;
}
@@ -1041,7 +555,7 @@ static void gen4_emit_primitive(struct sna *sna)
(_3DPRIM_RECTLIST << GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT) |
(0 << 9) |
4);
- sna->render_state.gen4.vertex_offset = sna->kgem.nbatch;
+ sna->render.vertex_offset = sna->kgem.nbatch;
OUT_BATCH(0); /* vertex count, to be filled in later */
OUT_BATCH(sna->render.vertex_index);
OUT_BATCH(1); /* single instance */
@@ -1060,15 +574,15 @@ static bool gen4_rectangle_begin(struct sna *sna,
/* 7xpipelined pointers + 6xprimitive + 1xflush */
ndwords = op->need_magic_ca_pass? 20 : 6;
- if ((sna->render_state.gen4.vb_id & (1 << id)) == 0)
+ if ((sna->render.vb_id & (1 << id)) == 0)
ndwords += 5;
if (!kgem_check_batch(&sna->kgem, ndwords))
return false;
- if ((sna->render_state.gen4.vb_id & (1 << id)) == 0)
+ if ((sna->render.vb_id & (1 << id)) == 0)
gen4_emit_vertex_buffer(sna, op);
- if (sna->render_state.gen4.vertex_offset == 0)
+ if (sna->render.vertex_offset == 0)
gen4_emit_primitive(sna);
return true;
@@ -1105,7 +619,7 @@ start:
goto flush;
}
- if (unlikely(sna->render_state.gen4.vertex_offset == 0 &&
+ if (unlikely(sna->render.vertex_offset == 0 &&
!gen4_rectangle_begin(sna, op)))
goto flush;
@@ -1116,7 +630,7 @@ start:
return want;
flush:
- if (sna->render_state.gen4.vertex_offset) {
+ if (sna->render.vertex_offset) {
gen4_vertex_flush(sna);
gen4_magic_ca_pass(sna, op);
}
@@ -1346,26 +860,14 @@ gen4_emit_vertex_elements(struct sna *sna,
* texture coordinate 1 if (has_mask is true): same as above
*/
struct gen4_render_state *render = &sna->render_state.gen4;
+ uint32_t src_format, dw;
+ int src_offset, dst_offset;
int id = op->u.gen4.ve_id;
- uint32_t w_component;
- uint32_t src_format;
- int selem;
if (render->ve_id == id)
return;
-
render->ve_id = id;
- if (id & 1) {
- src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT;
- w_component = GEN4_VFCOMPONENT_STORE_1_FLT;
- selem = 2;
- } else {
- src_format = GEN4_SURFACEFORMAT_R32G32B32_FLOAT;
- w_component = GEN4_VFCOMPONENT_STORE_SRC;
- selem = 3;
- }
-
/* The VUE layout
* dword 0-3: position (x, y, 1.0, 1.0),
* dword 4-7: texture coordinate 0 (u0, v0, w0, 1.0)
@@ -1376,39 +878,89 @@ gen4_emit_vertex_elements(struct sna *sna,
/* x,y */
OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
GEN4_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
- 0 << VE0_OFFSET_SHIFT); /* offsets vb in bytes */
- OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
- GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
- GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
- GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
- (1*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); /* VUE offset in dwords */
+ 0 << VE0_OFFSET_SHIFT);
+ OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
+ VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
+ VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
+ VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
+ (1*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);
+ src_offset = 4;
+ dst_offset = 8;
/* u0, v0, w0 */
+ /* u0, v0, w0 */
+ DBG(("%s: first channel %d floats, offset=%d\n", __FUNCTION__,
+ id & 3, src_offset));
+ dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
+ switch (id & 3) {
+ case 1:
+ src_format = GEN4_SURFACEFORMAT_R32_FLOAT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ default:
+ assert(0);
+ case 2:
+ src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ case 3:
+ src_format = GEN4_SURFACEFORMAT_R32G32B32_FLOAT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ }
OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
src_format << VE0_FORMAT_SHIFT |
- 4 << VE0_OFFSET_SHIFT); /* offset vb in bytes */
- OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
- GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
- w_component << VE1_VFCOMPONENT_2_SHIFT |
- GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
- (2*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); /* VUE offset in dwords */
+ src_offset << VE0_OFFSET_SHIFT);
+ OUT_BATCH(dw | dst_offset << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);
+ src_offset += (id & 3) * sizeof(float);
+ dst_offset += 4;
/* u1, v1, w1 */
- OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
- src_format << VE0_FORMAT_SHIFT |
- ((1 + selem) * 4) << VE0_OFFSET_SHIFT); /* vb offset in bytes */
- if (id & 2) {
- OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
- GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
- w_component << VE1_VFCOMPONENT_2_SHIFT |
- GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
- (3*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); /* VUE offset in dwords */
+ if (id >> 2) {
+ DBG(("%s: second channel %d floats, offset=%d\n", __FUNCTION__,
+ (id >> 2) & 3, src_offset));
+ dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
+ switch ((id >> 2) & 3) {
+ case 1:
+ src_format = GEN4_SURFACEFORMAT_R32_FLOAT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ default:
+ assert(0);
+ case 2:
+ src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ case 3:
+ src_format = GEN4_SURFACEFORMAT_R32G32B32_FLOAT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ }
+ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
+ src_format << VE0_FORMAT_SHIFT |
+ src_offset << VE0_OFFSET_SHIFT);
+ OUT_BATCH(dw | dst_offset << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);
} else {
- OUT_BATCH(GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
- GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
- GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
- GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
- (3*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); /* VUE offset in dwords */
+ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
+ GEN4_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
+ 0 << VE0_OFFSET_SHIFT);
+ OUT_BATCH(VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
+ VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
+ VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
+ VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
+ dst_offset << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);
}
}
@@ -1701,7 +1253,7 @@ gen4_render_video(struct sna *sna,
tmp.mask.bo = NULL;
tmp.u.gen4.wm_kernel =
is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED;
- tmp.u.gen4.ve_id = 1;
+ tmp.u.gen4.ve_id = 2;
tmp.is_affine = true;
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
@@ -2014,7 +1566,7 @@ gen4_render_composite_done(struct sna *sna,
{
DBG(("%s()\n", __FUNCTION__));
- if (sna->render_state.gen4.vertex_offset) {
+ if (sna->render.vertex_offset) {
gen4_vertex_flush(sna);
gen4_magic_ca_pass(sna, op);
}
@@ -2382,7 +1934,6 @@ gen4_render_composite(struct sna *sna,
tmp->need_magic_ca_pass = false;
tmp->u.gen4.sf = 0;
- tmp->prim_emit = gen4_emit_composite_primitive;
if (mask) {
if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
tmp->has_component_alpha = true;
@@ -2427,35 +1978,19 @@ gen4_render_composite(struct sna *sna,
}
tmp->is_affine &= tmp->mask.is_affine;
-
- if (tmp->src.transform == NULL && tmp->mask.transform == NULL) {
- if (tmp->src.is_solid)
- tmp->prim_emit = gen4_emit_composite_primitive_identity_mask;
- else
- tmp->prim_emit = gen4_emit_composite_primitive_identity_source_mask;
- }
-
- tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
- } else {
- if (tmp->src.is_solid) {
- tmp->prim_emit = gen4_emit_composite_primitive_solid;
- } else if (tmp->src.transform == NULL) {
- tmp->prim_emit = gen4_emit_composite_primitive_identity_source;
- /* XXX using more then one thread causes corruption? */
- tmp->u.gen4.sf = 1;
- } else if (tmp->src.is_affine)
- tmp->prim_emit = gen4_emit_composite_primitive_affine_source;
-
- tmp->floats_per_vertex = 3 + !tmp->is_affine;
}
- tmp->floats_per_rect = 3*tmp->floats_per_vertex;
+ gen4_choose_composite_emitter(tmp);
+
+ if (tmp->mask.bo == NULL && tmp->src.transform == NULL)
+ /* XXX using more then one thread causes corruption? */
+ tmp->u.gen4.sf = 1;
tmp->u.gen4.wm_kernel =
gen4_choose_composite_kernel(tmp->op,
tmp->mask.bo != NULL,
tmp->has_component_alpha,
tmp->is_affine);
- tmp->u.gen4.ve_id = (tmp->mask.bo != NULL) << 1 | tmp->is_affine;
+ tmp->u.gen4.ve_id = gen4_choose_composite_vertex_buffer(tmp);
tmp->blt = gen4_render_composite_blt;
tmp->box = gen4_render_composite_box;
@@ -2490,122 +2025,6 @@ cleanup_dst:
/* A poor man's span interface. But better than nothing? */
#if !NO_COMPOSITE_SPANS
-inline static void
-gen4_emit_composite_texcoord(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- float t[3];
-
- if (channel->is_affine) {
- sna_get_transformed_coordinates(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
- } else {
- t[0] = t[1] = 0; t[2] = 1;
- sna_get_transformed_coordinates_3d(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1], &t[2]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
- OUT_VERTEX_F(t[2]);
- }
-}
-
-inline static void
-gen4_emit_composite_texcoord_affine(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- float t[2];
-
- sna_get_transformed_coordinates(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
-}
-
-inline static void
-gen4_emit_composite_spans_vertex(struct sna *sna,
- const struct sna_composite_spans_op *op,
- int16_t x, int16_t y)
-{
- OUT_VERTEX(x, y);
- gen4_emit_composite_texcoord(sna, &op->base.src, x, y);
-}
-
-fastcall static void
-gen4_emit_composite_spans_primitive(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- gen4_emit_composite_spans_vertex(sna, op, box->x2, box->y2);
- OUT_VERTEX_F(opacity);
- OUT_VERTEX_F(1);
- if (!op->base.is_affine)
- OUT_VERTEX_F(1);
-
- gen4_emit_composite_spans_vertex(sna, op, box->x1, box->y2);
- OUT_VERTEX_F(opacity);
- OUT_VERTEX_F(1);
- if (!op->base.is_affine)
- OUT_VERTEX_F(1);
-
- gen4_emit_composite_spans_vertex(sna, op, box->x1, box->y1);
- OUT_VERTEX_F(opacity);
- OUT_VERTEX_F(0);
- if (!op->base.is_affine)
- OUT_VERTEX_F(1);
-}
-
-fastcall static void
-gen4_emit_composite_spans_solid(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- OUT_VERTEX_F(1); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y2);
- OUT_VERTEX_F(0); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y1);
- OUT_VERTEX_F(0); OUT_VERTEX_F(0);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
-}
-
-fastcall static void
-gen4_emit_composite_spans_affine(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- gen4_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x2, box->y2);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y2);
- gen4_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y2);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y1);
- gen4_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y1);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
-}
-
fastcall static void
gen4_render_composite_spans_box(struct sna *sna,
const struct sna_composite_spans_op *op,
@@ -2758,23 +2177,11 @@ gen4_render_composite_spans(struct sna *sna,
tmp->base.has_component_alpha = false;
tmp->base.need_magic_ca_pass = false;
- tmp->base.u.gen4.sf = 1;
- if (tmp->base.src.is_solid) {
- DBG(("%s: using solid fast emitter\n", __FUNCTION__));
- tmp->prim_emit = gen4_emit_composite_spans_solid;
- tmp->base.u.gen4.sf = 0;
- } else if (tmp->base.is_affine) {
- DBG(("%s: using affine fast emitter\n", __FUNCTION__));
- tmp->prim_emit = gen4_emit_composite_spans_affine;
- } else {
- DBG(("%s: using general emitter\n", __FUNCTION__));
- tmp->prim_emit = gen4_emit_composite_spans_primitive;
- }
- tmp->base.floats_per_vertex = 5 + 2*!tmp->base.is_affine;
- tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
+ tmp->base.u.gen4.sf = !tmp->base.src.is_solid;
+ gen4_choose_spans_emitter(tmp);
tmp->base.u.gen4.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine;
- tmp->base.u.gen4.ve_id = 1 << 1 | tmp->base.is_affine;
+ tmp->base.u.gen4.ve_id = gen4_choose_spans_vertex_buffer(&tmp->base);
tmp->box = gen4_render_composite_spans_box;
tmp->boxes = gen4_render_composite_spans_boxes;
@@ -2984,7 +2391,7 @@ fallback_blt:
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
tmp.u.gen4.wm_kernel = WM_KERNEL;
- tmp.u.gen4.ve_id = 1;
+ tmp.u.gen4.ve_id = 2;
tmp.u.gen4.sf = 0;
if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
@@ -3117,7 +2524,7 @@ fallback:
op->base.floats_per_vertex = 3;
op->base.floats_per_rect = 9;
op->base.u.gen4.wm_kernel = WM_KERNEL;
- op->base.u.gen4.ve_id = 1;
+ op->base.u.gen4.ve_id = 2;
op->base.u.gen4.sf = 0;
if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
@@ -3240,7 +2647,7 @@ gen4_render_fill_boxes(struct sna *sna,
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
tmp.u.gen4.wm_kernel = WM_KERNEL;
- tmp.u.gen4.ve_id = 1;
+ tmp.u.gen4.ve_id = 2;
tmp.u.gen4.sf = 0;
if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
@@ -3346,7 +2753,7 @@ gen4_render_fill(struct sna *sna, uint8_t alu,
op->base.floats_per_vertex = 3;
op->base.floats_per_rect = 9;
op->base.u.gen4.wm_kernel = WM_KERNEL;
- op->base.u.gen4.ve_id = 1;
+ op->base.u.gen4.ve_id = 2;
op->base.u.gen4.sf = 0;
if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
@@ -3426,7 +2833,7 @@ gen4_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
tmp.need_magic_ca_pass = false;
tmp.u.gen4.wm_kernel = WM_KERNEL;
- tmp.u.gen4.ve_id = 1;
+ tmp.u.gen4.ve_id = 2;
tmp.u.gen4.sf = 0;
if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
@@ -3449,6 +2856,9 @@ static void
gen4_render_flush(struct sna *sna)
{
gen4_vertex_close(sna);
+
+ assert(sna->render.vb_id == 0);
+ assert(sna->render.vertex_offset == 0);
}
static void
@@ -3491,7 +2901,6 @@ static void gen4_render_reset(struct sna *sna)
{
sna->render_state.gen4.needs_invariant = true;
sna->render_state.gen4.needs_urb = true;
- sna->render_state.gen4.vb_id = 0;
sna->render_state.gen4.ve_id = -1;
sna->render_state.gen4.last_primitive = -1;
sna->render_state.gen4.last_pipelined_pointers = -1;
diff --git a/src/sna/gen4_render.h b/src/sna/gen4_render.h
index 49d232e8..2eae1ec4 100644
--- a/src/sna/gen4_render.h
+++ b/src/sna/gen4_render.h
@@ -661,15 +661,14 @@
#define GEN4_VERTEXBUFFER_ACCESS_VERTEXDATA 0
#define GEN4_VERTEXBUFFER_ACCESS_INSTANCEDATA 1
-#define GEN4_VFCOMPONENT_NOSTORE 0
-#define GEN4_VFCOMPONENT_STORE_SRC 1
-#define GEN4_VFCOMPONENT_STORE_0 2
-#define GEN4_VFCOMPONENT_STORE_1_FLT 3
-#define GEN4_VFCOMPONENT_STORE_1_INT 4
-#define GEN4_VFCOMPONENT_STORE_VID 5
-#define GEN4_VFCOMPONENT_STORE_IID 6
-#define GEN4_VFCOMPONENT_STORE_PID 7
-
+#define VFCOMPONENT_NOSTORE 0
+#define VFCOMPONENT_STORE_SRC 1
+#define VFCOMPONENT_STORE_0 2
+#define VFCOMPONENT_STORE_1_FLT 3
+#define VFCOMPONENT_STORE_1_INT 4
+#define VFCOMPONENT_STORE_VID 5
+#define VFCOMPONENT_STORE_IID 6
+#define VFCOMPONENT_STORE_PID 7
/* Execution Unit (EU) defines
diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
new file mode 100644
index 00000000..b3022330
--- /dev/null
+++ b/src/sna/gen4_vertex.c
@@ -0,0 +1,896 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sna.h"
+#include "sna_render.h"
+#include "sna_render_inline.h"
+#include "gen4_vertex.h"
+
+void gen4_vertex_flush(struct sna *sna)
+{
+ assert(sna->render.vertex_offset);
+ assert(sna->render.vertex_index > sna->render.vertex_start);
+
+ DBG(("%s[%x] = %d\n", __FUNCTION__,
+ 4*sna->render.vertex_offset,
+ sna->render.vertex_index - sna->render.vertex_start));
+ sna->kgem.batch[sna->render.vertex_offset] =
+ sna->render.vertex_index - sna->render.vertex_start;
+ sna->render.vertex_offset = 0;
+}
+
+int gen4_vertex_finish(struct sna *sna)
+{
+ struct kgem_bo *bo;
+ unsigned int i;
+ unsigned hint, size;
+
+ DBG(("%s: used=%d / %d\n", __FUNCTION__,
+ sna->render.vertex_used, sna->render.vertex_size));
+ assert(sna->render.vertex_used);
+ assert(sna->render.nvertex_reloc);
+
+ /* Note: we only need dword alignment (currently) */
+
+ bo = sna->render.vbo;
+ if (bo) {
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
+
+ for (i = 0; i < sna->render.nvertex_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->render.nvertex_reloc = 0;
+ sna->render.vertex_used = 0;
+ sna->render.vertex_index = 0;
+ sna->render.vbo = NULL;
+ sna->render.vb_id = 0;
+
+ kgem_bo_destroy(&sna->kgem, bo);
+ }
+
+ hint = CREATE_GTT_MAP;
+ if (bo)
+ hint |= CREATE_CACHED | CREATE_NO_THROTTLE;
+
+ size = 256*1024;
+ sna->render.vertices = NULL;
+ sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint);
+ while (sna->render.vbo == NULL && size > 16*1024) {
+ size /= 2;
+ sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint);
+ }
+ if (sna->render.vbo == NULL)
+ sna->render.vbo = kgem_create_linear(&sna->kgem,
+ 256*1024, CREATE_GTT_MAP);
+ if (sna->render.vbo)
+ sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
+ if (sna->render.vertices == NULL) {
+ if (sna->render.vbo) {
+ kgem_bo_destroy(&sna->kgem, sna->render.vbo);
+ sna->render.vbo = NULL;
+ }
+ sna->render.vertices = sna->render.vertex_data;
+ sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
+ return 0;
+ }
+
+ if (sna->render.vertex_used) {
+ DBG(("%s: copying initial buffer x %d to handle=%d\n",
+ __FUNCTION__,
+ sna->render.vertex_used,
+ sna->render.vbo->handle));
+ assert(sizeof(float)*sna->render.vertex_used <=
+ __kgem_bo_size(sna->render.vbo));
+ memcpy(sna->render.vertices,
+ sna->render.vertex_data,
+ sizeof(float)*sna->render.vertex_used);
+ }
+
+ size = __kgem_bo_size(sna->render.vbo)/4;
+ if (size >= UINT16_MAX)
+ size = UINT16_MAX - 1;
+
+ DBG(("%s: create vbo handle=%d, size=%d\n",
+ __FUNCTION__, sna->render.vbo->handle, size));
+
+ sna->render.vertex_size = size;
+ return sna->render.vertex_size - sna->render.vertex_used;
+}
+
+void gen4_vertex_close(struct sna *sna)
+{
+ struct kgem_bo *bo, *free_bo = NULL;
+ unsigned int i, delta = 0;
+
+ assert(sna->render.vertex_offset == 0);
+ if (!sna->render.vb_id)
+ return;
+
+ DBG(("%s: used=%d, vbo active? %d, vb=%x, nreloc=%d\n",
+ __FUNCTION__, sna->render.vertex_used, sna->render.vbo ? sna->render.vbo->handle : 0,
+ sna->render.vb_id, sna->render.nvertex_reloc));
+
+ bo = sna->render.vbo;
+ if (bo) {
+ if (sna->render.vertex_size - sna->render.vertex_used < 64) {
+ DBG(("%s: discarding vbo (full), handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
+ sna->render.vbo = NULL;
+ sna->render.vertices = sna->render.vertex_data;
+ sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
+ free_bo = bo;
+ } else if (IS_CPU_MAP(bo->map) && !sna->kgem.has_llc) {
+ DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
+ sna->render.vertices =
+ kgem_bo_map__gtt(&sna->kgem, sna->render.vbo);
+ if (sna->render.vertices == NULL) {
+ sna->render.vbo = NULL;
+ sna->render.vertices = sna->render.vertex_data;
+ sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
+ free_bo = bo;
+ }
+
+ }
+ } else {
+ 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,
+ CREATE_NO_THROTTLE);
+ if (bo && !kgem_bo_write(&sna->kgem, bo,
+ sna->render.vertex_data,
+ 4*sna->render.vertex_used)) {
+ kgem_bo_destroy(&sna->kgem, bo);
+ bo = NULL;
+ }
+ DBG(("%s: new vbo: %d\n", __FUNCTION__,
+ sna->render.vertex_used));
+ free_bo = bo;
+ }
+ }
+
+ assert(sna->render.nvertex_reloc);
+ for (i = 0; i < sna->render.nvertex_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,
+ delta);
+ }
+ sna->render.nvertex_reloc = 0;
+ sna->render.vb_id = 0;
+
+ if (sna->render.vbo == NULL) {
+ sna->render.vertex_used = 0;
+ sna->render.vertex_index = 0;
+ assert(sna->render.vertices == sna->render.vertex_data);
+ assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
+ }
+
+ if (free_bo)
+ kgem_bo_destroy(&sna->kgem, free_bo);
+}
+
+/* specialised vertex emission routines */
+
+#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) /* XXX assert(!too_large(x, y)); */
+#define OUT_VERTEX_F(v) vertex_emit(sna, v)
+
+inline static void
+emit_texcoord(struct sna *sna,
+ const struct sna_composite_channel *channel,
+ int16_t x, int16_t y)
+{
+ if (channel->is_solid) {
+ OUT_VERTEX_F(x);
+ OUT_VERTEX_F(y);
+ return;
+ }
+
+ x += channel->offset[0];
+ y += channel->offset[1];
+
+ if (channel->is_affine) {
+ float s, t;
+
+ sna_get_transformed_coordinates(x, y,
+ channel->transform,
+ &s, &t);
+ OUT_VERTEX_F(s * channel->scale[0]);
+ OUT_VERTEX_F(t * channel->scale[1]);
+ } else {
+ float s, t, w;
+
+ sna_get_transformed_coordinates_3d(x, y,
+ channel->transform,
+ &s, &t, &w);
+ OUT_VERTEX_F(s * channel->scale[0]);
+ OUT_VERTEX_F(t * channel->scale[1]);
+ OUT_VERTEX_F(w);
+ }
+}
+
+inline static void
+emit_vertex(struct sna *sna,
+ const struct sna_composite_op *op,
+ int16_t srcX, int16_t srcY,
+ int16_t mskX, int16_t mskY,
+ int16_t dstX, int16_t dstY)
+{
+ OUT_VERTEX(dstX, dstY);
+ emit_texcoord(sna, &op->src, srcX, srcY);
+}
+
+fastcall static void
+emit_primitive(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ emit_vertex(sna, op,
+ r->src.x + r->width, r->src.y + r->height,
+ r->mask.x + r->width, r->mask.y + r->height,
+ r->dst.x + r->width, r->dst.y + r->height);
+ emit_vertex(sna, op,
+ r->src.x, r->src.y + r->height,
+ r->mask.x, r->mask.y + r->height,
+ r->dst.x, r->dst.y + r->height);
+ emit_vertex(sna, op,
+ r->src.x, r->src.y,
+ r->mask.x, r->mask.y,
+ r->dst.x, r->dst.y);
+}
+
+inline static void
+emit_vertex_mask(struct sna *sna,
+ const struct sna_composite_op *op,
+ int16_t srcX, int16_t srcY,
+ int16_t mskX, int16_t mskY,
+ int16_t dstX, int16_t dstY)
+{
+ OUT_VERTEX(dstX, dstY);
+ emit_texcoord(sna, &op->src, srcX, srcY);
+ emit_texcoord(sna, &op->mask, mskX, mskY);
+}
+
+fastcall static void
+emit_primitive_mask(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ emit_vertex_mask(sna, op,
+ r->src.x + r->width, r->src.y + r->height,
+ r->mask.x + r->width, r->mask.y + r->height,
+ r->dst.x + r->width, r->dst.y + r->height);
+ emit_vertex_mask(sna, op,
+ r->src.x, r->src.y + r->height,
+ r->mask.x, r->mask.y + r->height,
+ r->dst.x, r->dst.y + r->height);
+ emit_vertex_mask(sna, op,
+ r->src.x, r->src.y,
+ r->mask.x, r->mask.y,
+ r->dst.x, r->dst.y);
+}
+
+fastcall static void
+emit_primitive_solid(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ float *v;
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+
+ assert(op->floats_per_rect == 9);
+ assert((sna->render.vertex_used % 3) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 9;
+ assert(sna->render.vertex_used <= sna->render.vertex_size);
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ dst.p.x = r->dst.x;
+ v[3] = dst.f;
+ dst.p.y = r->dst.y;
+ v[6] = dst.f;
+
+ v[5] = v[2] = v[1] = 1.;
+ v[8] = v[7] = v[4] = 0.;
+}
+
+fastcall static void
+emit_primitive_identity_source(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+ float *v;
+
+ assert(op->floats_per_rect == 9);
+ assert((sna->render.vertex_used % 3) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 9;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ dst.p.x = r->dst.x;
+ v[3] = dst.f;
+ dst.p.y = r->dst.y;
+ v[6] = dst.f;
+
+ v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0];
+ v[1] = v[4] + r->width * op->src.scale[0];
+
+ v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1];
+ v[5] = v[2] = v[8] + r->height * op->src.scale[1];
+}
+
+fastcall static void
+emit_primitive_simple_source(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ float *v;
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+
+ float xx = op->src.transform->matrix[0][0];
+ float x0 = op->src.transform->matrix[0][2];
+ float yy = op->src.transform->matrix[1][1];
+ float y0 = op->src.transform->matrix[1][2];
+ float sx = op->src.scale[0];
+ float sy = op->src.scale[1];
+ int16_t tx = op->src.offset[0];
+ int16_t ty = op->src.offset[1];
+
+ assert(op->floats_per_rect == 9);
+ assert((sna->render.vertex_used % 3) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 3*3;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx;
+ v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy;
+
+ dst.p.x = r->dst.x;
+ v[3] = dst.f;
+ v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx;
+
+ dst.p.y = r->dst.y;
+ v[6] = dst.f;
+ v[8] = ((r->src.y + ty) * yy + y0) * sy;
+}
+
+fastcall static void
+emit_primitive_affine_source(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+ float *v;
+
+ assert(op->floats_per_rect == 9);
+ assert((sna->render.vertex_used % 3) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 9;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
+ op->src.offset[1] + r->src.y + r->height,
+ op->src.transform,
+ &v[1], &v[2]);
+ v[1] *= op->src.scale[0];
+ v[2] *= op->src.scale[1];
+
+ dst.p.x = r->dst.x;
+ v[3] = dst.f;
+ _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
+ op->src.offset[1] + r->src.y + r->height,
+ op->src.transform,
+ &v[4], &v[5]);
+ v[4] *= op->src.scale[0];
+ v[5] *= op->src.scale[1];
+
+ dst.p.y = r->dst.y;
+ v[6] = dst.f;
+ _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
+ op->src.offset[1] + r->src.y,
+ op->src.transform,
+ &v[7], &v[8]);
+ v[7] *= op->src.scale[0];
+ v[8] *= op->src.scale[1];
+}
+
+fastcall static void
+emit_primitive_identity_mask(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+ float msk_x, msk_y;
+ float w, h;
+ float *v;
+
+ msk_x = r->mask.x + op->mask.offset[0];
+ msk_y = r->mask.y + op->mask.offset[1];
+ w = r->width;
+ h = r->height;
+
+ DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n",
+ __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h));
+
+ assert(op->floats_per_rect == 15);
+ assert((sna->render.vertex_used % 5) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 15;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ v[3] = (msk_x + w) * op->mask.scale[0];
+ v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
+
+ dst.p.x = r->dst.x;
+ v[5] = dst.f;
+ v[13] = v[8] = msk_x * op->mask.scale[0];
+
+ dst.p.y = r->dst.y;
+ v[10] = dst.f;
+ v[14] = msk_y * op->mask.scale[1];
+
+ v[7] = v[2] = v[1] = 1;
+ v[12] = v[11] = v[6] = 0;
+}
+
+fastcall static void
+emit_primitive_identity_source_mask(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+ float src_x, src_y;
+ float msk_x, msk_y;
+ float w, h;
+ float *v;
+
+ src_x = r->src.x + op->src.offset[0];
+ src_y = r->src.y + op->src.offset[1];
+ msk_x = r->mask.x + op->mask.offset[0];
+ msk_y = r->mask.y + op->mask.offset[1];
+ w = r->width;
+ h = r->height;
+
+ assert(op->floats_per_rect == 15);
+ assert((sna->render.vertex_used % 5) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 15;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ v[1] = (src_x + w) * op->src.scale[0];
+ v[2] = (src_y + h) * op->src.scale[1];
+ v[3] = (msk_x + w) * op->mask.scale[0];
+ v[4] = (msk_y + h) * op->mask.scale[1];
+
+ dst.p.x = r->dst.x;
+ v[5] = dst.f;
+ v[6] = src_x * op->src.scale[0];
+ v[7] = v[2];
+ v[8] = msk_x * op->mask.scale[0];
+ v[9] = v[4];
+
+ dst.p.y = r->dst.y;
+ v[10] = dst.f;
+ v[11] = v[6];
+ v[12] = src_y * op->src.scale[1];
+ v[13] = v[8];
+ v[14] = msk_y * op->mask.scale[1];
+}
+
+fastcall static void
+emit_primitive_simple_source_identity(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ float *v;
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+
+ float xx = op->src.transform->matrix[0][0];
+ float x0 = op->src.transform->matrix[0][2];
+ float yy = op->src.transform->matrix[1][1];
+ float y0 = op->src.transform->matrix[1][2];
+ float sx = op->src.scale[0];
+ float sy = op->src.scale[1];
+ int16_t tx = op->src.offset[0];
+ int16_t ty = op->src.offset[1];
+ float msk_x = r->mask.x + op->mask.offset[0];
+ float msk_y = r->mask.y + op->mask.offset[1];
+ float w = r->width, h = r->height;
+
+ assert(op->floats_per_rect == 15);
+ assert((sna->render.vertex_used % 5) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 3*5;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx;
+ v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy;
+ v[3] = (msk_x + w) * op->mask.scale[0];
+ v[4] = (msk_y + h) * op->mask.scale[1];
+
+ dst.p.x = r->dst.x;
+ v[5] = dst.f;
+ v[6] = ((r->src.x + tx) * xx + x0) * sx;
+ v[7] = v[2];
+ v[8] = msk_x * op->mask.scale[0];
+ v[9] = v[4];
+
+ dst.p.y = r->dst.y;
+ v[10] = dst.f;
+ v[11] = v[6];
+ v[12] = ((r->src.y + ty) * yy + y0) * sy;
+ v[13] = v[8];
+ v[14] = msk_y * op->mask.scale[1];
+}
+
+fastcall static void
+emit_primitive_affine_source_identity(struct sna *sna,
+ const struct sna_composite_op *op,
+ const struct sna_composite_rectangles *r)
+{
+ float *v;
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+ float msk_x = r->mask.x + op->mask.offset[0];
+ float msk_y = r->mask.y + op->mask.offset[1];
+ float w = r->width, h = r->height;
+
+ assert(op->floats_per_rect == 15);
+ assert((sna->render.vertex_used % 5) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 3*5;
+
+ dst.p.x = r->dst.x + r->width;
+ dst.p.y = r->dst.y + r->height;
+ v[0] = dst.f;
+ _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
+ op->src.offset[1] + r->src.y + r->height,
+ op->src.transform,
+ &v[1], &v[2]);
+ v[1] *= op->src.scale[0];
+ v[2] *= op->src.scale[1];
+ v[3] = (msk_x + w) * op->mask.scale[0];
+ v[4] = (msk_y + h) * op->mask.scale[1];
+
+ dst.p.x = r->dst.x;
+ v[5] = dst.f;
+ _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
+ op->src.offset[1] + r->src.y + r->height,
+ op->src.transform,
+ &v[6], &v[7]);
+ v[6] *= op->src.scale[0];
+ v[7] *= op->src.scale[1];
+ v[8] = msk_x * op->mask.scale[0];
+ v[9] = v[4];
+
+ dst.p.y = r->dst.y;
+ v[10] = dst.f;
+ _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
+ op->src.offset[1] + r->src.y,
+ op->src.transform,
+ &v[11], &v[12]);
+ v[11] *= op->src.scale[0];
+ v[12] *= op->src.scale[1];
+ v[13] = v[8];
+ v[14] = msk_y * op->mask.scale[1];
+}
+
+inline static void
+emit_composite_texcoord_affine(struct sna *sna,
+ const struct sna_composite_channel *channel,
+ int16_t x, int16_t y)
+{
+ float t[2];
+
+ sna_get_transformed_coordinates(x + channel->offset[0],
+ y + channel->offset[1],
+ channel->transform,
+ &t[0], &t[1]);
+ OUT_VERTEX_F(t[0] * channel->scale[0]);
+ OUT_VERTEX_F(t[1] * channel->scale[1]);
+}
+
+void gen4_choose_composite_emitter(struct sna_composite_op *tmp)
+{
+ tmp->prim_emit = emit_primitive;
+ tmp->floats_per_vertex = 1 + 2 + !tmp->src.is_affine;
+ if (tmp->mask.bo) {
+ tmp->floats_per_vertex += 2 + !tmp->mask.is_affine;
+ tmp->prim_emit = emit_primitive_mask;
+ if (tmp->mask.transform == NULL) {
+ if (tmp->src.is_solid) {
+ DBG(("%s: solid, identity mask\n", __FUNCTION__));
+ tmp->prim_emit = emit_primitive_identity_mask;
+ } else if (tmp->src.transform == NULL) {
+ DBG(("%s: identity source, identity mask\n", __FUNCTION__));
+ tmp->prim_emit = emit_primitive_identity_source_mask;
+ } else if (tmp->src.is_affine) {
+ if (tmp->src.transform->matrix[0][1] == 0 &&
+ tmp->src.transform->matrix[1][0] == 0) {
+ DBG(("%s: simple src, identity mask\n", __FUNCTION__));
+ tmp->src.scale[0] /= tmp->src.transform->matrix[2][2];
+ tmp->src.scale[1] /= tmp->src.transform->matrix[2][2];
+ tmp->prim_emit = emit_primitive_simple_source_identity;
+ } else {
+ DBG(("%s: affine src, identity mask\n", __FUNCTION__));
+ tmp->prim_emit = emit_primitive_affine_source_identity;
+ }
+ }
+ }
+ } else {
+ if (tmp->src.is_solid) {
+ DBG(("%s: solid, no mask\n", __FUNCTION__));
+ tmp->prim_emit = emit_primitive_solid;
+ if (tmp->src.is_opaque && tmp->op == PictOpOver)
+ tmp->op = PictOpSrc;
+ } else if (tmp->src.transform == NULL) {
+ DBG(("%s: identity src, no mask\n", __FUNCTION__));
+ tmp->prim_emit = emit_primitive_identity_source;
+ } else if (tmp->src.is_affine) {
+ if (tmp->src.transform->matrix[0][1] == 0 &&
+ tmp->src.transform->matrix[1][0] == 0) {
+ DBG(("%s: simple src, no mask\n", __FUNCTION__));
+ tmp->src.scale[0] /= tmp->src.transform->matrix[2][2];
+ tmp->src.scale[1] /= tmp->src.transform->matrix[2][2];
+ tmp->prim_emit = emit_primitive_simple_source;
+ } else {
+ DBG(("%s: affine src, no mask\n", __FUNCTION__));
+ tmp->prim_emit = emit_primitive_affine_source;
+ }
+ }
+ }
+ tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
+}
+
+inline static void
+emit_spans_vertex(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ int16_t x, int16_t y)
+{
+ OUT_VERTEX(x, y);
+ emit_texcoord(sna, &op->base.src, x, y);
+}
+
+fastcall static void
+emit_composite_spans_primitive(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ emit_spans_vertex(sna, op, box->x2, box->y2);
+ OUT_VERTEX_F(opacity);
+
+ emit_spans_vertex(sna, op, box->x1, box->y2);
+ OUT_VERTEX_F(opacity);
+
+ emit_spans_vertex(sna, op, box->x1, box->y1);
+ OUT_VERTEX_F(opacity);
+}
+
+fastcall static void
+emit_spans_solid(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ OUT_VERTEX(box->x2, box->y2);
+ OUT_VERTEX_F(1); OUT_VERTEX_F(1);
+ OUT_VERTEX_F(opacity);
+
+ OUT_VERTEX(box->x1, box->y2);
+ OUT_VERTEX_F(0); OUT_VERTEX_F(1);
+ OUT_VERTEX_F(opacity);
+
+ OUT_VERTEX(box->x1, box->y1);
+ OUT_VERTEX_F(0); OUT_VERTEX_F(0);
+ OUT_VERTEX_F(opacity);
+}
+
+fastcall static void
+emit_spans_identity(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ float *v;
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+
+ float sx = op->base.src.scale[0];
+ float sy = op->base.src.scale[1];
+ int16_t tx = op->base.src.offset[0];
+ int16_t ty = op->base.src.offset[1];
+
+ assert(op->base.floats_per_rect == 12);
+ assert((sna->render.vertex_used % 4) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 3*4;
+ assert(sna->render.vertex_used <= sna->render.vertex_size);
+
+ dst.p.x = box->x2;
+ dst.p.y = box->y2;
+ v[0] = dst.f;
+ v[1] = (box->x2 + tx) * sx;
+ v[6] = v[2] = (box->y2 + ty) * sy;
+
+ dst.p.x = box->x1;
+ v[4] = dst.f;
+ v[9] = v[5] = (box->x1 + tx) * sx;
+
+ dst.p.y = box->y1;
+ v[8] = dst.f;
+ v[10] = (box->y1 + ty) * sy;
+
+ v[11] = v[7] = v[3] = opacity;
+}
+
+fastcall static void
+emit_spans_simple(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ float *v;
+ union {
+ struct sna_coordinate p;
+ float f;
+ } dst;
+
+ float xx = op->base.src.transform->matrix[0][0];
+ float x0 = op->base.src.transform->matrix[0][2];
+ float yy = op->base.src.transform->matrix[1][1];
+ float y0 = op->base.src.transform->matrix[1][2];
+ float sx = op->base.src.scale[0];
+ float sy = op->base.src.scale[1];
+ int16_t tx = op->base.src.offset[0];
+ int16_t ty = op->base.src.offset[1];
+
+ assert(op->base.floats_per_rect == 12);
+ assert((sna->render.vertex_used % 4) == 0);
+ v = sna->render.vertices + sna->render.vertex_used;
+ sna->render.vertex_used += 3*4;
+ assert(sna->render.vertex_used <= sna->render.vertex_size);
+
+ dst.p.x = box->x2;
+ dst.p.y = box->y2;
+ v[0] = dst.f;
+ v[1] = ((box->x2 + tx) * xx + x0) * sx;
+ v[6] = v[2] = ((box->y2 + ty) * yy + y0) * sy;
+
+ dst.p.x = box->x1;
+ v[4] = dst.f;
+ v[9] = v[5] = ((box->x1 + tx) * xx + x0) * sx;
+
+ dst.p.y = box->y1;
+ v[8] = dst.f;
+ v[10] = ((box->y1 + ty) * yy + y0) * sy;
+
+ v[11] = v[7] = v[3] = opacity;
+}
+
+fastcall static void
+emit_spans_affine(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
+{
+ OUT_VERTEX(box->x2, box->y2);
+ emit_composite_texcoord_affine(sna, &op->base.src, box->x2, box->y2);
+ OUT_VERTEX_F(opacity);
+
+ OUT_VERTEX(box->x1, box->y2);
+ emit_composite_texcoord_affine(sna, &op->base.src, box->x1, box->y2);
+ OUT_VERTEX_F(opacity);
+
+ OUT_VERTEX(box->x1, box->y1);
+ emit_composite_texcoord_affine(sna, &op->base.src, box->x1, box->y1);
+ OUT_VERTEX_F(opacity);
+}
+
+void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp)
+{
+ tmp->prim_emit = emit_composite_spans_primitive;
+ if (tmp->base.src.is_solid) {
+ tmp->prim_emit = emit_spans_solid;
+ } else if (tmp->base.src.transform == NULL) {
+ tmp->prim_emit = emit_spans_identity;
+ } else if (tmp->base.is_affine) {
+ if (tmp->base.src.transform->matrix[0][1] == 0 &&
+ tmp->base.src.transform->matrix[1][0] == 0) {
+ tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2];
+ tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2];
+ tmp->prim_emit = emit_spans_simple;
+ } else
+ tmp->prim_emit = emit_spans_affine;
+ }
+ tmp->base.floats_per_vertex = 4 + !tmp->base.is_affine;
+ tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
+}
diff --git a/src/sna/gen4_vertex.h b/src/sna/gen4_vertex.h
new file mode 100644
index 00000000..418bdef1
--- /dev/null
+++ b/src/sna/gen4_vertex.h
@@ -0,0 +1,39 @@
+#ifndef GEN4_VERTEX_H
+#define GEN4_VERTEX_H
+
+#include "compiler.h"
+
+#include "sna.h"
+#include "sna_render.h"
+
+void gen4_vertex_flush(struct sna *sna);
+int gen4_vertex_finish(struct sna *sna);
+void gen4_vertex_close(struct sna *sna);
+
+inline static uint32_t
+gen4_choose_composite_vertex_buffer(const struct sna_composite_op *op)
+{
+ int id = 2 + !op->src.is_affine;
+ if (op->mask.bo)
+ id |= (2 + !op->mask.is_affine) << 2;
+ DBG(("%s: id=%x (%d, %d)\n", __FUNCTION__, id,
+ 2 + !op->src.is_affine,
+ op->mask.bo ? 2 + !op->mask.is_affine : 0));
+ assert(id > 0 && id < 16);
+ return id;
+}
+
+inline inline static uint32_t
+gen4_choose_spans_vertex_buffer(const struct sna_composite_op *op)
+{
+ DBG(("%s: id=%x (%d, 1)\n", __FUNCTION__,
+ 1 << 2 | (2+!op->src.is_affine),
+ 2 + !op->src.is_affine));
+ return 1 << 2 | (2+!op->src.is_affine);
+}
+
+void gen4_choose_composite_emitter(struct sna_composite_op *tmp);
+void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp);
+
+
+#endif /* GEN4_VERTEX_H */
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 8f5ea2f9..f013e09b 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -42,7 +42,9 @@
#include "brw/brw.h"
#include "gen5_render.h"
+#include "gen4_vertex.h"
+#define NO_COMPOSITE 0
#define NO_COMPOSITE_SPANS 0
#define PREFER_BLT_FILL 1
@@ -227,154 +229,6 @@ static void gen5_magic_ca_pass(struct sna *sna,
state->last_primitive = sna->kgem.nbatch;
}
-static void gen5_vertex_flush(struct sna *sna)
-{
- assert(sna->render_state.gen5.vertex_offset);
- assert(sna->render.vertex_index > sna->render.vertex_start);
-
- DBG(("%s[%x] = %d\n", __FUNCTION__,
- 4*sna->render_state.gen5.vertex_offset,
- sna->render.vertex_index - sna->render.vertex_start));
- sna->kgem.batch[sna->render_state.gen5.vertex_offset] =
- sna->render.vertex_index - sna->render.vertex_start;
- sna->render_state.gen5.vertex_offset = 0;
-}
-
-static int gen5_vertex_finish(struct sna *sna)
-{
- struct kgem_bo *bo;
- unsigned int i;
-
- assert(sna->render.vertex_used);
- assert(sna->render.nvertex_reloc);
-
- /* Note: we only need dword alignment (currently) */
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render_state.gen5.vertex_offset)
- gen5_vertex_flush(sna);
-
- for (i = 0; i < sna->render.nvertex_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->render.nvertex_reloc = 0;
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- sna->render.vbo = NULL;
- 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, CREATE_GTT_MAP);
- if (sna->render.vbo)
- sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
- if (sna->render.vertices == NULL) {
- if (sna->render.vbo)
- 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,
- 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, *free_bo = NULL;
- unsigned int i, delta = 0;
-
- assert(sna->render_state.gen5.vertex_offset == 0);
- if (!sna->render_state.gen5.vb_id)
- return;
-
- DBG(("%s: used=%d, vbo active? %d\n",
- __FUNCTION__, sna->render.vertex_used, sna->render.vbo != NULL));
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render.vertex_size - sna->render.vertex_used < 64) {
- DBG(("%s: discarding full vbo\n", __FUNCTION__));
- sna->render.vbo = NULL;
- sna->render.vertices = sna->render.vertex_data;
- sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
- free_bo = bo;
- } else if (IS_CPU_MAP(bo->map)) {
- DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
- sna->render.vertices =
- kgem_bo_map__gtt(&sna->kgem, sna->render.vbo);
- if (sna->render.vertices == NULL) {
- sna->render.vbo = NULL;
- sna->render.vertices = sna->render.vertex_data;
- sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
- free_bo = bo;
- }
- }
- } else {
- 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,
- CREATE_NO_THROTTLE);
- if (bo && !kgem_bo_write(&sna->kgem, bo,
- sna->render.vertex_data,
- 4*sna->render.vertex_used)) {
- kgem_bo_destroy(&sna->kgem, bo);
- bo = NULL;
- }
- DBG(("%s: new vbo: %d\n", __FUNCTION__,
- sna->render.vertex_used));
- free_bo = bo;
- }
- }
-
- assert(sna->render.nvertex_reloc);
- for (i = 0; i < sna->render.nvertex_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,
- delta);
- }
- sna->render.nvertex_reloc = 0;
-
- if (sna->render.vbo == NULL) {
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- }
-
- if (free_bo)
- kgem_bo_destroy(&sna->kgem, free_bo);
-}
-
static uint32_t gen5_get_blend(int op,
bool has_component_alpha,
uint32_t dst_format)
@@ -671,365 +525,29 @@ gen5_bind_bo(struct sna *sna,
return offset * sizeof(uint32_t);
}
-fastcall static void
-gen5_emit_composite_primitive_solid(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = 1.;
- v[2] = 1.;
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- v[4] = 0.;
- v[5] = 1.;
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- v[7] = 0.;
- v[8] = 0.;
-}
-
-fastcall static void
-gen5_emit_composite_primitive_identity_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- const float *sf = op->src.scale;
- float sx, sy, *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- sx = r->src.x + op->src.offset[0];
- sy = r->src.y + op->src.offset[1];
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = (sx + r->width) * sf[0];
- v[5] = v[2] = (sy + r->height) * sf[1];
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- v[7] = v[4] = sx * sf[0];
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- v[8] = sy * sf[1];
-}
-
-fastcall static void
-gen5_emit_composite_primitive_affine_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float *v;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[1], &v[2]);
- v[1] *= op->src.scale[0];
- v[2] *= op->src.scale[1];
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[4], &v[5]);
- v[4] *= op->src.scale[0];
- v[5] *= op->src.scale[1];
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y,
- op->src.transform,
- &v[7], &v[8]);
- v[7] *= op->src.scale[0];
- v[8] *= op->src.scale[1];
-}
-
-fastcall static void
-gen5_emit_composite_primitive_identity_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[13] = v[8] = msk_x * op->mask.scale[0];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[14] = msk_y * op->mask.scale[1];
-
- v[7] = v[2] = v[1] = 1;
- v[12] = v[11] = v[6] = 0;
-}
-
-fastcall static void
-gen5_emit_composite_primitive_identity_source_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float src_x, src_y;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- src_x = r->src.x + op->src.offset[0];
- src_y = r->src.y + op->src.offset[1];
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = (src_x + w) * op->src.scale[0];
- v[2] = (src_y + h) * op->src.scale[1];
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[6] = src_x * op->src.scale[0];
- v[7] = v[2];
- v[8] = msk_x * op->mask.scale[0];
- v[9] = v[4];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[11] = v[6];
- v[12] = src_y * op->src.scale[1];
- v[13] = v[8];
- v[14] = msk_y * op->mask.scale[1];
-}
-
-fastcall static void
-gen5_emit_composite_primitive(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
- bool is_affine = op->is_affine;
- const float *src_sf = op->src.scale;
- const float *mask_sf = op->mask.scale;
-
- if (op->src.is_solid) {
- src_x[0] = 0;
- src_y[0] = 0;
- src_x[1] = 0;
- src_y[1] = 1;
- src_x[2] = 1;
- src_y[2] = 1;
- src_w[0] = src_w[1] = src_w[2] = 1;
- } else if (is_affine) {
- sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1],
- op->src.transform,
- &src_x[0],
- &src_y[0]);
-
- sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[1],
- &src_y[1]);
-
- sna_get_transformed_coordinates(r->src.x + op->src.offset[0] + r->width,
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[2],
- &src_y[2]);
- } else {
- sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1],
- op->src.transform,
- &src_x[0],
- &src_y[0],
- &src_w[0]);
- sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[1],
- &src_y[1],
- &src_w[1]);
- sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0] + r->width,
- r->src.y + op->src.offset[1] + r->height,
- op->src.transform,
- &src_x[2],
- &src_y[2],
- &src_w[2]);
- }
-
- if (op->mask.bo) {
- if (op->mask.is_solid) {
- mask_x[0] = 0;
- mask_y[0] = 0;
- mask_x[1] = 0;
- mask_y[1] = 1;
- mask_x[2] = 1;
- mask_y[2] = 1;
- mask_w[0] = mask_w[1] = mask_w[2] = 1;
- } else if (is_affine) {
- sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1],
- op->mask.transform,
- &mask_x[0],
- &mask_y[0]);
-
- sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[1],
- &mask_y[1]);
-
- sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0] + r->width,
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[2],
- &mask_y[2]);
- } else {
- sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1],
- op->mask.transform,
- &mask_x[0],
- &mask_y[0],
- &mask_w[0]);
-
- sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[1],
- &mask_y[1],
- &mask_w[1]);
- sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0] + r->width,
- r->mask.y + op->mask.offset[1] + r->height,
- op->mask.transform,
- &mask_x[2],
- &mask_y[2],
- &mask_w[2]);
- }
- }
-
- OUT_VERTEX(r->dst.x + r->width, r->dst.y + r->height);
- OUT_VERTEX_F(src_x[2] * src_sf[0]);
- OUT_VERTEX_F(src_y[2] * src_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(src_w[2]);
- if (op->mask.bo) {
- OUT_VERTEX_F(mask_x[2] * mask_sf[0]);
- OUT_VERTEX_F(mask_y[2] * mask_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(mask_w[2]);
- }
-
- OUT_VERTEX(r->dst.x, r->dst.y + r->height);
- OUT_VERTEX_F(src_x[1] * src_sf[0]);
- OUT_VERTEX_F(src_y[1] * src_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(src_w[1]);
- if (op->mask.bo) {
- OUT_VERTEX_F(mask_x[1] * mask_sf[0]);
- OUT_VERTEX_F(mask_y[1] * mask_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(mask_w[1]);
- }
-
- OUT_VERTEX(r->dst.x, r->dst.y);
- OUT_VERTEX_F(src_x[0] * src_sf[0]);
- OUT_VERTEX_F(src_y[0] * src_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(src_w[0]);
- if (op->mask.bo) {
- OUT_VERTEX_F(mask_x[0] * mask_sf[0]);
- OUT_VERTEX_F(mask_y[0] * mask_sf[1]);
- if (!is_affine)
- OUT_VERTEX_F(mask_w[0]);
- }
-}
-
static void gen5_emit_vertex_buffer(struct sna *sna,
const struct sna_composite_op *op)
{
int id = op->u.gen5.ve_id;
- assert((unsigned)id <= 3);
+ assert((sna->render.vb_id & (1 << id)) == 0);
OUT_BATCH(GEN5_3DSTATE_VERTEX_BUFFERS | 3);
- OUT_BATCH((id << VB0_BUFFER_INDEX_SHIFT) | VB0_VERTEXDATA |
+ OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA |
(4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT));
+ assert(sna->render.nvertex_reloc < ARRAY_SIZE(sna->render.vertex_reloc));
sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch;
OUT_BATCH(0);
OUT_BATCH(~0); /* max address: disabled */
OUT_BATCH(0);
- sna->render_state.gen5.vb_id |= 1 << id;
+ sna->render.vb_id |= 1 << id;
}
static void gen5_emit_primitive(struct sna *sna)
{
if (sna->kgem.nbatch == sna->render_state.gen5.last_primitive) {
- sna->render_state.gen5.vertex_offset = sna->kgem.nbatch - 5;
+ sna->render.vertex_offset = sna->kgem.nbatch - 5;
return;
}
@@ -1038,7 +556,7 @@ static void gen5_emit_primitive(struct sna *sna)
(_3DPRIM_RECTLIST << GEN5_3DPRIMITIVE_TOPOLOGY_SHIFT) |
(0 << 9) |
4);
- sna->render_state.gen5.vertex_offset = sna->kgem.nbatch;
+ sna->render.vertex_offset = sna->kgem.nbatch;
OUT_BATCH(0); /* vertex count, to be filled in later */
OUT_BATCH(sna->render.vertex_index);
OUT_BATCH(1); /* single instance */
@@ -1055,18 +573,16 @@ static bool gen5_rectangle_begin(struct sna *sna,
int id = op->u.gen5.ve_id;
int ndwords;
- assert((unsigned)id <= 3);
-
ndwords = op->need_magic_ca_pass ? 20 : 6;
- if ((sna->render_state.gen5.vb_id & (1 << id)) == 0)
+ if ((sna->render.vb_id & (1 << id)) == 0)
ndwords += 5;
if (!kgem_check_batch(&sna->kgem, ndwords))
return false;
- if ((sna->render_state.gen5.vb_id & (1 << id)) == 0)
+ if ((sna->render.vb_id & (1 << id)) == 0)
gen5_emit_vertex_buffer(sna, op);
- if (sna->render_state.gen5.vertex_offset == 0)
+ if (sna->render.vertex_offset == 0)
gen5_emit_primitive(sna);
return true;
@@ -1085,7 +601,7 @@ static int gen5_get_rectangles__flush(struct sna *sna,
if (op->need_magic_ca_pass && sna->render.vbo)
return 0;
- return gen5_vertex_finish(sna);
+ return gen4_vertex_finish(sna);
}
inline static int gen5_get_rectangles(struct sna *sna,
@@ -1106,7 +622,7 @@ start:
goto flush;
}
- if (unlikely(sna->render_state.gen5.vertex_offset == 0 &&
+ if (unlikely(sna->render.vertex_offset == 0 &&
!gen5_rectangle_begin(sna, op)))
goto flush;
@@ -1117,8 +633,8 @@ start:
return want;
flush:
- if (sna->render_state.gen5.vertex_offset) {
- gen5_vertex_flush(sna);
+ if (sna->render.vertex_offset) {
+ gen4_vertex_flush(sna);
gen5_magic_ca_pass(sna, op);
}
_kgem_submit(&sna->kgem);
@@ -1249,7 +765,7 @@ 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);
+ gen4_vertex_finish(sna);
DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
sna->render_state.gen5.floats_per_vertex,
@@ -1349,28 +865,17 @@ gen5_emit_vertex_elements(struct sna *sna,
* texture coordinate 1 if (has_mask is true): same as above
*/
struct gen5_render_state *render = &sna->render_state.gen5;
- bool has_mask = op->mask.bo != NULL;
- bool is_affine = op->is_affine;
- int nelem = has_mask ? 2 : 1;
- int selem = is_affine ? 2 : 3;
- uint32_t w_component;
- uint32_t src_format;
int id = op->u.gen5.ve_id;
+ bool has_mask = id >> 2;
+ uint32_t format, dw;
+ int offset;
- assert((unsigned)id <= 3);
if (!DBG_NO_STATE_CACHE && render->ve_id == id)
return;
+ DBG(("%s: changing %d -> %d\n", __FUNCTION__, render->ve_id, id));
render->ve_id = id;
- if (is_affine) {
- src_format = GEN5_SURFACEFORMAT_R32G32_FLOAT;
- w_component = GEN5_VFCOMPONENT_STORE_1_FLT;
- } else {
- src_format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT;
- w_component = GEN5_VFCOMPONENT_STORE_SRC;
- }
-
/* The VUE layout
* dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
* dword 4-7: position (x, y, 1.0, 1.0),
@@ -1380,43 +885,87 @@ gen5_emit_vertex_elements(struct sna *sna,
* dword 4-15 are fetched from vertex buffer
*/
OUT_BATCH(GEN5_3DSTATE_VERTEX_ELEMENTS |
- ((2 * (2 + nelem)) + 1 - 2));
+ ((2 * (has_mask ? 4 : 3)) + 1 - 2));
OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
(GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT) |
(0 << VE0_OFFSET_SHIFT));
- OUT_BATCH((GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT));
+ OUT_BATCH((VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) |
+ (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) |
+ (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
+ (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT));
/* x,y */
- OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
- (GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT) |
- (0 << VE0_OFFSET_SHIFT)); /* offsets vb in bytes */
- OUT_BATCH((GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
+ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
+ GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
+ 0 << VE0_OFFSET_SHIFT);
+ OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
+ VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
+ VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
+ VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
+ offset = 4;
/* u0, v0, w0 */
- OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
- (src_format << VE0_FORMAT_SHIFT) |
- (4 << VE0_OFFSET_SHIFT)); /* offset vb in bytes */
- OUT_BATCH((GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
- (w_component << VE1_VFCOMPONENT_2_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
+ DBG(("%s: id=%d, first channel %d floats, offset=%d\n", __FUNCTION__,
+ id, id & 3, offset));
+ dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
+ switch (id & 3) {
+ case 1:
+ format = GEN5_SURFACEFORMAT_R32_FLOAT << VE0_FORMAT_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ default:
+ assert(0);
+ case 2:
+ format = GEN5_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ case 3:
+ format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT << VE0_FORMAT_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ }
+ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
+ format | offset << VE0_OFFSET_SHIFT);
+ OUT_BATCH(dw);
/* u1, v1, w1 */
if (has_mask) {
- OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
- (src_format << VE0_FORMAT_SHIFT) |
- (((1 + selem) * 4) << VE0_OFFSET_SHIFT)); /* vb offset in bytes */
- OUT_BATCH((GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
- (w_component << VE1_VFCOMPONENT_2_SHIFT) |
- (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
+ offset += (id & 3) * sizeof(float);
+ DBG(("%s: id=%x, second channel %d floats, offset=%d\n", __FUNCTION__,
+ id, (id >> 2) & 3, offset));
+ dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
+ switch ((id >> 2) & 3) {
+ case 1:
+ format = GEN5_SURFACEFORMAT_R32_FLOAT << VE0_FORMAT_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ default:
+ assert(0);
+ case 2:
+ format = GEN5_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ case 3:
+ format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT << VE0_FORMAT_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
+ dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
+ break;
+ }
+ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
+ format | offset << VE0_OFFSET_SHIFT);
+ OUT_BATCH(dw);
}
}
@@ -1698,7 +1247,7 @@ gen5_render_video(struct sna *sna,
tmp.mask.bo = NULL;
tmp.u.gen5.wm_kernel =
is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED;
- tmp.u.gen5.ve_id = 1;
+ tmp.u.gen5.ve_id = 2;
tmp.is_affine = true;
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
@@ -1759,7 +1308,7 @@ gen5_render_video(struct sna *sna,
}
priv->clear = false;
- gen5_vertex_flush(sna);
+ gen4_vertex_flush(sna);
return true;
}
@@ -2001,8 +1550,8 @@ static void
gen5_render_composite_done(struct sna *sna,
const struct sna_composite_op *op)
{
- if (sna->render_state.gen5.vertex_offset) {
- gen5_vertex_flush(sna);
+ if (sna->render.vertex_offset) {
+ gen4_vertex_flush(sna);
gen5_magic_ca_pass(sna,op);
}
@@ -2388,7 +1937,6 @@ gen5_render_composite(struct sna *sna,
tmp->has_component_alpha = false;
tmp->need_magic_ca_pass = false;
- tmp->prim_emit = gen5_emit_composite_primitive;
if (mask) {
if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
tmp->has_component_alpha = true;
@@ -2432,33 +1980,15 @@ gen5_render_composite(struct sna *sna,
}
tmp->is_affine &= tmp->mask.is_affine;
-
- if (tmp->src.transform == NULL && tmp->mask.transform == NULL) {
- if (tmp->src.is_solid)
- tmp->prim_emit = gen5_emit_composite_primitive_identity_mask;
- else
- tmp->prim_emit = gen5_emit_composite_primitive_identity_source_mask;
- }
-
- tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
- } else {
- if (tmp->src.is_solid)
- tmp->prim_emit = gen5_emit_composite_primitive_solid;
- else if (tmp->src.transform == NULL)
- tmp->prim_emit = gen5_emit_composite_primitive_identity_source;
- else if (tmp->src.is_affine)
- tmp->prim_emit = gen5_emit_composite_primitive_affine_source;
-
- tmp->floats_per_vertex = 3 + !tmp->is_affine;
}
- tmp->floats_per_rect = 3*tmp->floats_per_vertex;
+ gen4_choose_composite_emitter(tmp);
tmp->u.gen5.wm_kernel =
gen5_choose_composite_kernel(tmp->op,
tmp->mask.bo != NULL,
tmp->has_component_alpha,
tmp->is_affine);
- tmp->u.gen5.ve_id = (tmp->mask.bo != NULL) << 1 | tmp->is_affine;
+ tmp->u.gen5.ve_id = gen4_choose_composite_vertex_buffer(tmp);
tmp->blt = gen5_render_composite_blt;
tmp->box = gen5_render_composite_box;
@@ -2490,122 +2020,6 @@ cleanup_dst:
}
#if !NO_COMPOSITE_SPANS
-inline static void
-gen5_emit_composite_texcoord(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- float t[3];
-
- if (channel->is_affine) {
- sna_get_transformed_coordinates(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
- } else {
- t[0] = t[1] = 0; t[2] = 1;
- sna_get_transformed_coordinates_3d(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1], &t[2]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
- OUT_VERTEX_F(t[2]);
- }
-}
-
-inline static void
-gen5_emit_composite_texcoord_affine(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- float t[2];
-
- sna_get_transformed_coordinates(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
-}
-
-inline static void
-gen5_emit_composite_spans_vertex(struct sna *sna,
- const struct sna_composite_spans_op *op,
- int16_t x, int16_t y)
-{
- OUT_VERTEX(x, y);
- gen5_emit_composite_texcoord(sna, &op->base.src, x, y);
-}
-
-fastcall static void
-gen5_emit_composite_spans_primitive(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- gen5_emit_composite_spans_vertex(sna, op, box->x2, box->y2);
- OUT_VERTEX_F(opacity);
- OUT_VERTEX_F(1);
- if (!op->base.is_affine)
- OUT_VERTEX_F(1);
-
- gen5_emit_composite_spans_vertex(sna, op, box->x1, box->y2);
- OUT_VERTEX_F(opacity);
- OUT_VERTEX_F(1);
- if (!op->base.is_affine)
- OUT_VERTEX_F(1);
-
- gen5_emit_composite_spans_vertex(sna, op, box->x1, box->y1);
- OUT_VERTEX_F(opacity);
- OUT_VERTEX_F(0);
- if (!op->base.is_affine)
- OUT_VERTEX_F(1);
-}
-
-fastcall static void
-gen5_emit_composite_spans_solid(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- OUT_VERTEX_F(1); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y2);
- OUT_VERTEX_F(0); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y1);
- OUT_VERTEX_F(0); OUT_VERTEX_F(0);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
-}
-
-fastcall static void
-gen5_emit_composite_spans_affine(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- gen5_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x2, box->y2);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y2);
- gen5_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y2);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
- OUT_VERTEX(box->x1, box->y1);
- gen5_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y1);
- OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
-}
-
fastcall static void
gen5_render_composite_spans_box(struct sna *sna,
const struct sna_composite_spans_op *op,
@@ -2658,15 +2072,12 @@ fastcall static void
gen5_render_composite_spans_done(struct sna *sna,
const struct sna_composite_spans_op *op)
{
- if (sna->render_state.gen5.vertex_offset)
- gen5_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
DBG(("%s()\n", __FUNCTION__));
- kgem_bo_destroy(&sna->kgem, op->base.mask.bo);
- if (op->base.src.bo)
- kgem_bo_destroy(&sna->kgem, op->base.src.bo);
-
+ kgem_bo_destroy(&sna->kgem, op->base.src.bo);
sna_render_composite_redirect_done(sna, &op->base);
}
@@ -2757,24 +2168,16 @@ gen5_render_composite_spans(struct sna *sna,
break;
}
- tmp->base.mask.bo = sna_render_get_solid(sna, 0);
- if (tmp->base.mask.bo == NULL)
- goto cleanup_src;
+ tmp->base.mask.bo = NULL;
tmp->base.is_affine = tmp->base.src.is_affine;
tmp->base.has_component_alpha = false;
tmp->base.need_magic_ca_pass = false;
- tmp->prim_emit = gen5_emit_composite_spans_primitive;
- if (tmp->base.src.is_solid)
- tmp->prim_emit = gen5_emit_composite_spans_solid;
- else if (tmp->base.is_affine)
- tmp->prim_emit = gen5_emit_composite_spans_affine;
- tmp->base.floats_per_vertex = 5 + 2*!tmp->base.is_affine;
- tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
+ gen4_choose_spans_emitter(tmp);
tmp->base.u.gen5.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine;
- tmp->base.u.gen5.ve_id = 1 << 1 | tmp->base.is_affine;
+ tmp->base.u.gen5.ve_id = gen4_choose_spans_vertex_buffer(&tmp->base);
tmp->box = gen5_render_composite_spans_box;
tmp->boxes = gen5_render_composite_spans_boxes;
@@ -2952,7 +2355,7 @@ fallback_blt:
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
tmp.u.gen5.wm_kernel = WM_KERNEL;
- tmp.u.gen5.ve_id = 1;
+ tmp.u.gen5.ve_id = 2;
if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
kgem_submit(&sna->kgem);
@@ -2998,7 +2401,7 @@ fallback_blt:
} while (--n_this_time);
} while (n);
- gen5_vertex_flush(sna);
+ gen4_vertex_flush(sna);
sna_render_composite_redirect_done(sna, &tmp);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
@@ -3044,8 +2447,8 @@ static void
gen5_render_copy_done(struct sna *sna,
const struct sna_copy_op *op)
{
- if (sna->render_state.gen5.vertex_offset)
- gen5_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
DBG(("%s()\n", __FUNCTION__));
}
@@ -3108,7 +2511,7 @@ fallback:
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;
+ op->base.u.gen5.ve_id = 2;
if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
kgem_submit(&sna->kgem);
@@ -3255,7 +2658,7 @@ gen5_render_fill_boxes(struct sna *sna,
tmp.floats_per_vertex = 3;
tmp.floats_per_rect = 9;
tmp.u.gen5.wm_kernel = WM_KERNEL;
- tmp.u.gen5.ve_id = 1;
+ tmp.u.gen5.ve_id = 2;
if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
kgem_submit(&sna->kgem);
@@ -3291,7 +2694,7 @@ gen5_render_fill_boxes(struct sna *sna,
} while (--n_this_time);
} while (n);
- gen5_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
}
@@ -3378,8 +2781,8 @@ static void
gen5_render_fill_op_done(struct sna *sna,
const struct sna_fill_op *op)
{
- if (sna->render_state.gen5.vertex_offset)
- gen5_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, op->base.src.bo);
DBG(("%s()\n", __FUNCTION__));
@@ -3437,7 +2840,7 @@ gen5_render_fill(struct sna *sna, uint8_t alu,
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;
+ op->base.u.gen5.ve_id = 2;
if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
kgem_submit(&sna->kgem);
@@ -3528,7 +2931,7 @@ gen5_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
tmp.need_magic_ca_pass = false;
tmp.u.gen5.wm_kernel = WM_KERNEL;
- tmp.u.gen5.ve_id = 1;
+ tmp.u.gen5.ve_id = 2;
if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
_kgem_submit(&sna->kgem);
@@ -3553,7 +2956,7 @@ gen5_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
OUT_VERTEX_F(0);
OUT_VERTEX_F(0);
- gen5_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
@@ -3562,7 +2965,10 @@ gen5_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
static void
gen5_render_flush(struct sna *sna)
{
- gen5_vertex_close(sna);
+ gen4_vertex_close(sna);
+
+ assert(sna->render.vb_id == 0);
+ assert(sna->render.vertex_offset == 0);
}
static void
@@ -3633,7 +3039,6 @@ gen5_render_expire(struct kgem *kgem)
static void gen5_render_reset(struct sna *sna)
{
sna->render_state.gen5.needs_invariant = true;
- sna->render_state.gen5.vb_id = 0;
sna->render_state.gen5.ve_id = -1;
sna->render_state.gen5.last_primitive = -1;
sna->render_state.gen5.last_pipelined_pointers = 0;
@@ -3899,7 +3304,9 @@ bool gen5_render_init(struct sna *sna)
sna->kgem.retire = gen5_render_retire;
sna->kgem.expire = gen5_render_expire;
+#if !NO_COMPOSITE
sna->render.composite = gen5_render_composite;
+#endif
#if !NO_COMPOSITE_SPANS
sna->render.check_composite_spans = gen5_check_composite_spans;
sna->render.composite_spans = gen5_render_composite_spans;
diff --git a/src/sna/gen5_render.h b/src/sna/gen5_render.h
index b6e5b0c2..31caafc7 100644
--- a/src/sna/gen5_render.h
+++ b/src/sna/gen5_render.h
@@ -749,15 +749,14 @@
#define GEN5_VERTEXBUFFER_ACCESS_VERTEXDATA 0
#define GEN5_VERTEXBUFFER_ACCESS_INSTANCEDATA 1
-#define GEN5_VFCOMPONENT_NOSTORE 0
-#define GEN5_VFCOMPONENT_STORE_SRC 1
-#define GEN5_VFCOMPONENT_STORE_0 2
-#define GEN5_VFCOMPONENT_STORE_1_FLT 3
-#define GEN5_VFCOMPONENT_STORE_1_INT 4
-#define GEN5_VFCOMPONENT_STORE_VID 5
-#define GEN5_VFCOMPONENT_STORE_IID 6
-#define GEN5_VFCOMPONENT_STORE_PID 7
-
+#define VFCOMPONENT_NOSTORE 0
+#define VFCOMPONENT_STORE_SRC 1
+#define VFCOMPONENT_STORE_0 2
+#define VFCOMPONENT_STORE_1_FLT 3
+#define VFCOMPONENT_STORE_1_INT 4
+#define VFCOMPONENT_STORE_VID 5
+#define VFCOMPONENT_STORE_IID 6
+#define VFCOMPONENT_STORE_PID 7
/* Execution Unit (EU) defines
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 5a60787d..647ef503 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -42,6 +42,7 @@
#include "brw/brw.h"
#include "gen6_render.h"
+#include "gen4_vertex.h"
#define NO_COMPOSITE 0
#define NO_COMPOSITE_SPANS 0
@@ -947,155 +948,6 @@ static void gen6_magic_ca_pass(struct sna *sna,
state->last_primitive = sna->kgem.nbatch;
}
-static void gen6_vertex_flush(struct sna *sna)
-{
- assert(sna->render_state.gen6.vertex_offset);
-
- DBG(("%s[%x] = %d\n", __FUNCTION__,
- 4*sna->render_state.gen6.vertex_offset,
- sna->render.vertex_index - sna->render.vertex_start));
- sna->kgem.batch[sna->render_state.gen6.vertex_offset] =
- sna->render.vertex_index - sna->render.vertex_start;
- sna->render_state.gen6.vertex_offset = 0;
-}
-
-static int gen6_vertex_finish(struct sna *sna)
-{
- struct kgem_bo *bo;
- unsigned int i;
-
- DBG(("%s: used=%d / %d\n", __FUNCTION__,
- sna->render.vertex_used, sna->render.vertex_size));
- assert(sna->render.vertex_used);
- assert(sna->render.nvertex_reloc);
-
- /* Note: we only need dword alignment (currently) */
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render_state.gen6.vertex_offset)
- gen6_vertex_flush(sna);
-
- for (i = 0; i < sna->render.nvertex_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->render.nvertex_reloc = 0;
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- sna->render.vbo = NULL;
- sna->render_state.gen6.vb_id = 0;
-
- kgem_bo_destroy(&sna->kgem, bo);
- }
-
- sna->render.vertices = NULL;
- sna->render.vbo = kgem_create_linear(&sna->kgem,
- 256*1024, CREATE_GTT_MAP);
- if (sna->render.vbo)
- sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
- if (sna->render.vertices == NULL) {
- if (sna->render.vbo)
- kgem_bo_destroy(&sna->kgem, sna->render.vbo);
- sna->render.vbo = NULL;
- return 0;
- }
-
- DBG(("%s: create vbo handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
-
- kgem_bo_sync__cpu(&sna->kgem, sna->render.vbo);
- if (sna->render.vertex_used) {
- DBG(("%s: copying initial buffer x %d to handle=%d\n",
- __FUNCTION__,
- sna->render.vertex_used,
- sna->render.vbo->handle));
- memcpy(sna->render.vertices,
- sna->render.vertex_data,
- sizeof(float)*sna->render.vertex_used);
- }
- sna->render.vertex_size = 64 * 1024 - 1;
- return sna->render.vertex_size - sna->render.vertex_used;
-}
-
-static void gen6_vertex_close(struct sna *sna)
-{
- struct kgem_bo *bo, *free_bo = NULL;
- unsigned int i, delta = 0;
-
- assert(sna->render_state.gen6.vertex_offset == 0);
-
- if (!sna->render_state.gen6.vb_id)
- return;
-
- DBG(("%s: used=%d, vbo active? %d\n",
- __FUNCTION__, sna->render.vertex_used, sna->render.vbo ? sna->render.vbo->handle : 0));
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render.vertex_size - sna->render.vertex_used < 64) {
- DBG(("%s: discarding vbo (full), handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
- sna->render.vbo = NULL;
- sna->render.vertices = sna->render.vertex_data;
- sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
- free_bo = bo;
- }
- } else {
- 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,
- CREATE_NO_THROTTLE);
- if (bo && !kgem_bo_write(&sna->kgem, bo,
- sna->render.vertex_data,
- 4*sna->render.vertex_used)) {
- kgem_bo_destroy(&sna->kgem, bo);
- bo = NULL;
- }
- DBG(("%s: new vbo: %d\n", __FUNCTION__,
- sna->render.vertex_used));
- free_bo = bo;
- }
- }
-
- assert(sna->render.nvertex_reloc);
- for (i = 0; i < sna->render.nvertex_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,
- delta);
- }
- sna->render.nvertex_reloc = 0;
-
- if (sna->render.vbo == NULL) {
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- assert(sna->render.vertices == sna->render.vertex_data);
- assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
- }
-
- if (free_bo)
- kgem_bo_destroy(&sna->kgem, free_bo);
-}
-
typedef struct gen6_surface_state_padded {
struct gen6_surface_state state;
char pad[32 - sizeof(struct gen6_surface_state)];
@@ -1259,293 +1111,6 @@ gen6_bind_bo(struct sna *sna,
return offset * sizeof(uint32_t);
}
-fastcall static void
-gen6_emit_composite_primitive_solid(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- DBG(("%s: [%d+9] = (%d, %d)x(%d, %d)\n", __FUNCTION__,
- sna->render.vertex_used, r->dst.x, r->dst.y, r->width, r->height));
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
- assert(sna->render.vertex_used <= sna->render.vertex_size);
- assert(!too_large(op->dst.x + r->dst.x + r->width,
- op->dst.y + r->dst.y + r->height));
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- dst.p.y = r->dst.y;
- v[6] = dst.f;
-
- v[5] = v[2] = v[1] = 1.;
- v[8] = v[7] = v[4] = 0.;
-}
-
-fastcall static void
-gen6_emit_composite_primitive_identity_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float *v;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- dst.p.y = r->dst.y;
- v[6] = dst.f;
-
- v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0];
- v[1] = v[4] + r->width * op->src.scale[0];
-
- v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1];
- v[5] = v[2] = v[8] + r->height * op->src.scale[1];
-}
-
-fastcall static void
-gen6_emit_composite_primitive_simple_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- float xx = op->src.transform->matrix[0][0];
- float x0 = op->src.transform->matrix[0][2];
- float yy = op->src.transform->matrix[1][1];
- float y0 = op->src.transform->matrix[1][2];
- float sx = op->src.scale[0];
- float sy = op->src.scale[1];
- int16_t tx = op->src.offset[0];
- int16_t ty = op->src.offset[1];
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 3*3;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx;
- v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy;
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx;
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- v[8] = ((r->src.y + ty) * yy + y0) * sy;
-}
-
-fastcall static void
-gen6_emit_composite_primitive_affine_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float *v;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[1], &v[2]);
- v[1] *= op->src.scale[0];
- v[2] *= op->src.scale[1];
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[4], &v[5]);
- v[4] *= op->src.scale[0];
- v[5] *= op->src.scale[1];
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y,
- op->src.transform,
- &v[7], &v[8]);
- v[7] *= op->src.scale[0];
- v[8] *= op->src.scale[1];
-}
-
-fastcall static void
-gen6_emit_composite_primitive_identity_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[13] = v[8] = msk_x * op->mask.scale[0];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[14] = msk_y * op->mask.scale[1];
-
- v[7] = v[2] = v[1] = 1;
- v[12] = v[11] = v[6] = 0;
-}
-
-fastcall static void
-gen6_emit_composite_primitive_identity_source_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float src_x, src_y;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- src_x = r->src.x + op->src.offset[0];
- src_y = r->src.y + op->src.offset[1];
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = (src_x + w) * op->src.scale[0];
- v[2] = (src_y + h) * op->src.scale[1];
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[6] = src_x * op->src.scale[0];
- v[7] = v[2];
- v[8] = msk_x * op->mask.scale[0];
- v[9] = v[4];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[11] = v[6];
- v[12] = src_y * op->src.scale[1];
- v[13] = v[8];
- v[14] = msk_y * op->mask.scale[1];
-}
-
-inline static void
-gen6_emit_composite_texcoord(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- x += channel->offset[0];
- y += channel->offset[1];
-
- if (channel->is_affine) {
- float s, t;
-
- sna_get_transformed_coordinates(x, y,
- channel->transform,
- &s, &t);
- OUT_VERTEX_F(s * channel->scale[0]);
- OUT_VERTEX_F(t * channel->scale[1]);
- } else {
- float s, t, w;
-
- sna_get_transformed_coordinates_3d(x, y,
- channel->transform,
- &s, &t, &w);
- OUT_VERTEX_F(s * channel->scale[0]);
- OUT_VERTEX_F(t * channel->scale[1]);
- OUT_VERTEX_F(w);
- }
-}
-
-static void
-gen6_emit_composite_vertex(struct sna *sna,
- const struct sna_composite_op *op,
- int16_t srcX, int16_t srcY,
- int16_t mskX, int16_t mskY,
- int16_t dstX, int16_t dstY)
-{
- OUT_VERTEX(dstX, dstY);
- gen6_emit_composite_texcoord(sna, &op->src, srcX, srcY);
- gen6_emit_composite_texcoord(sna, &op->mask, mskX, mskY);
-}
-
-fastcall static void
-gen6_emit_composite_primitive(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- gen6_emit_composite_vertex(sna, op,
- r->src.x + r->width, r->src.y + r->height,
- r->mask.x + r->width, r->mask.y + r->height,
- r->dst.x + r->width, r->dst.y + r->height);
- gen6_emit_composite_vertex(sna, op,
- r->src.x, r->src.y + r->height,
- r->mask.x, r->mask.y + r->height,
- r->dst.x, r->dst.y + r->height);
- gen6_emit_composite_vertex(sna, op,
- r->src.x, r->src.y,
- r->mask.x, r->mask.y,
- r->dst.x, r->dst.y);
-}
-
static void gen6_emit_vertex_buffer(struct sna *sna,
const struct sna_composite_op *op)
{
@@ -1559,7 +1124,7 @@ static void gen6_emit_vertex_buffer(struct sna *sna,
OUT_BATCH(~0); /* max address: disabled */
OUT_BATCH(0);
- sna->render_state.gen6.vb_id |= 1 << id;
+ sna->render.vb_id |= 1 << id;
}
static void gen6_emit_primitive(struct sna *sna)
@@ -1569,7 +1134,7 @@ static void gen6_emit_primitive(struct sna *sna)
__FUNCTION__,
sna->render.vertex_start,
sna->render.vertex_index));
- sna->render_state.gen6.vertex_offset = sna->kgem.nbatch - 5;
+ sna->render.vertex_offset = sna->kgem.nbatch - 5;
return;
}
@@ -1578,7 +1143,7 @@ static void gen6_emit_primitive(struct sna *sna)
_3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
0 << 9 |
4);
- sna->render_state.gen6.vertex_offset = sna->kgem.nbatch;
+ sna->render.vertex_offset = sna->kgem.nbatch;
OUT_BATCH(0); /* vertex count, to be filled in later */
OUT_BATCH(sna->render.vertex_index);
OUT_BATCH(1); /* single instance */
@@ -1598,12 +1163,12 @@ static bool gen6_rectangle_begin(struct sna *sna,
int ndwords;
ndwords = op->need_magic_ca_pass ? 60 : 6;
- if ((sna->render_state.gen6.vb_id & id) == 0)
+ if ((sna->render.vb_id & id) == 0)
ndwords += 5;
if (!kgem_check_batch(&sna->kgem, ndwords))
return false;
- if ((sna->render_state.gen6.vb_id & id) == 0)
+ if ((sna->render.vb_id & id) == 0)
gen6_emit_vertex_buffer(sna, op);
gen6_emit_primitive(sna);
@@ -1615,15 +1180,15 @@ static int gen6_get_rectangles__flush(struct sna *sna,
{
if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
return 0;
- if (!kgem_check_exec(&sna->kgem, 1))
+ if (!kgem_check_exec(&sna->kgem, 2))
return 0;
- if (!kgem_check_reloc(&sna->kgem, 2))
+ if (!kgem_check_reloc(&sna->kgem, 4))
return 0;
if (op->need_magic_ca_pass && sna->render.vbo)
return 0;
- return gen6_vertex_finish(sna);
+ return gen4_vertex_finish(sna);
}
inline static int gen6_get_rectangles(struct sna *sna,
@@ -1643,7 +1208,7 @@ start:
goto flush;
}
- if (unlikely(sna->render_state.gen6.vertex_offset == 0 &&
+ if (unlikely(sna->render.vertex_offset == 0 &&
!gen6_rectangle_begin(sna, op)))
goto flush;
@@ -1655,8 +1220,8 @@ start:
return want;
flush:
- if (sna->render_state.gen6.vertex_offset) {
- gen6_vertex_flush(sna);
+ if (sna->render.vertex_offset) {
+ gen4_vertex_flush(sna);
gen6_magic_ca_pass(sna, op);
}
_kgem_submit(&sna->kgem);
@@ -1681,16 +1246,6 @@ inline static uint32_t *gen6_composite_get_binding_table(struct sna *sna,
return table;
}
-static uint32_t
-gen6_choose_composite_vertex_buffer(const struct sna_composite_op *op)
-{
- int id = 2 + !op->is_affine;
- if (op->mask.bo)
- id |= id << 2;
- assert(id > 0 && id < 16);
- return id;
-}
-
static bool
gen6_get_batch(struct sna *sna, const struct sna_composite_op *op)
{
@@ -1755,11 +1310,10 @@ static void gen6_emit_composite_state(struct sna *sna,
static void
gen6_align_vertex(struct sna *sna, const struct sna_composite_op *op)
{
- assert (sna->render_state.gen6.vertex_offset == 0);
+ assert (sna->render.vertex_offset == 0);
if (op->floats_per_vertex != sna->render_state.gen6.floats_per_vertex) {
if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
- /* XXX propagate failure */
- gen6_vertex_finish(sna);
+ gen4_vertex_finish(sna);
DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
sna->render_state.gen6.floats_per_vertex,
@@ -2085,7 +1639,7 @@ gen6_render_video(struct sna *sna,
}
priv->clear = false;
- gen6_vertex_flush(sna);
+ gen4_vertex_flush(sna);
return true;
}
@@ -2335,8 +1889,8 @@ static void gen6_render_composite_done(struct sna *sna,
{
DBG(("%s\n", __FUNCTION__));
- if (sna->render_state.gen6.vertex_offset) {
- gen6_vertex_flush(sna);
+ if (sna->render.vertex_offset) {
+ gen4_vertex_flush(sna);
gen6_magic_ca_pass(sna, op);
}
@@ -2758,7 +2312,6 @@ gen6_render_composite(struct sna *sna,
tmp->mask.filter = SAMPLER_FILTER_NEAREST;
tmp->mask.repeat = SAMPLER_EXTEND_NONE;
- tmp->prim_emit = gen6_emit_composite_primitive;
if (mask) {
if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
tmp->has_component_alpha = true;
@@ -2798,44 +2351,8 @@ gen6_render_composite(struct sna *sna,
}
tmp->is_affine &= tmp->mask.is_affine;
-
- if (tmp->src.transform == NULL && tmp->mask.transform == NULL) {
- if (tmp->src.is_solid)
- tmp->prim_emit = gen6_emit_composite_primitive_identity_mask;
- else
- tmp->prim_emit = gen6_emit_composite_primitive_identity_source_mask;
- }
-
- tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
- } else {
- if (tmp->src.is_solid) {
- DBG(("%s: choosing gen6_emit_composite_primitive_solid\n",
- __FUNCTION__));
- tmp->prim_emit = gen6_emit_composite_primitive_solid;
- if (tmp->src.is_opaque && op == PictOpOver)
- tmp->op = PictOpSrc;
- } else if (tmp->src.transform == NULL) {
- DBG(("%s: choosing gen6_emit_composite_primitive_identity_source\n",
- __FUNCTION__));
- tmp->prim_emit = gen6_emit_composite_primitive_identity_source;
- } else if (tmp->src.is_affine) {
- if (tmp->src.transform->matrix[0][1] == 0 &&
- tmp->src.transform->matrix[1][0] == 0) {
- tmp->src.scale[0] /= tmp->src.transform->matrix[2][2];
- tmp->src.scale[1] /= tmp->src.transform->matrix[2][2];
- DBG(("%s: choosing gen6_emit_composite_primitive_simple_source\n",
- __FUNCTION__));
- tmp->prim_emit = gen6_emit_composite_primitive_simple_source;
- } else {
- DBG(("%s: choosing gen6_emit_composite_primitive_affine_source\n",
- __FUNCTION__));
- tmp->prim_emit = gen6_emit_composite_primitive_affine_source;
- }
- }
-
- tmp->floats_per_vertex = 3 + !tmp->is_affine;
}
- tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
+ gen4_choose_composite_emitter(tmp);
tmp->u.gen6.flags =
GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
@@ -2849,7 +2366,7 @@ gen6_render_composite(struct sna *sna,
tmp->mask.bo != NULL,
tmp->has_component_alpha,
tmp->is_affine),
- gen6_choose_composite_vertex_buffer(tmp));
+ gen4_choose_composite_vertex_buffer(tmp));
tmp->blt = gen6_render_composite_blt;
tmp->box = gen6_render_composite_box;
@@ -2885,167 +2402,6 @@ cleanup_dst:
}
#if !NO_COMPOSITE_SPANS
-inline static void
-gen6_emit_composite_texcoord_affine(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- float t[2];
-
- sna_get_transformed_coordinates(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
-}
-
-inline static void
-gen6_emit_composite_spans_vertex(struct sna *sna,
- const struct sna_composite_spans_op *op,
- int16_t x, int16_t y)
-{
- OUT_VERTEX(x, y);
- gen6_emit_composite_texcoord(sna, &op->base.src, x, y);
-}
-
-fastcall static void
-gen6_emit_composite_spans_primitive(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- gen6_emit_composite_spans_vertex(sna, op, box->x2, box->y2);
- OUT_VERTEX_F(opacity);
-
- gen6_emit_composite_spans_vertex(sna, op, box->x1, box->y2);
- OUT_VERTEX_F(opacity);
-
- gen6_emit_composite_spans_vertex(sna, op, box->x1, box->y1);
- OUT_VERTEX_F(opacity);
-}
-
-fastcall static void
-gen6_emit_composite_spans_solid(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- OUT_VERTEX_F(1); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y2);
- OUT_VERTEX_F(0); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y1);
- OUT_VERTEX_F(0); OUT_VERTEX_F(0);
- OUT_VERTEX_F(opacity);
-}
-
-fastcall static void
-gen6_emit_composite_spans_identity(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- float sx = op->base.src.scale[0];
- float sy = op->base.src.scale[1];
- int16_t tx = op->base.src.offset[0];
- int16_t ty = op->base.src.offset[1];
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 3*4;
- assert(sna->render.vertex_used <= sna->render.vertex_size);
-
- dst.p.x = box->x2;
- dst.p.y = box->y2;
- v[0] = dst.f;
- v[1] = (box->x2 + tx) * sx;
- v[6] = v[2] = (box->y2 + ty) * sy;
-
- dst.p.x = box->x1;
- v[4] = dst.f;
- v[9] = v[5] = (box->x1 + tx) * sx;
-
- dst.p.y = box->y1;
- v[8] = dst.f;
- v[10] = (box->y1 + ty) * sy;
-
- v[11] = v[7] = v[3] = opacity;
-}
-
-fastcall static void
-gen6_emit_composite_spans_simple(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- float xx = op->base.src.transform->matrix[0][0];
- float x0 = op->base.src.transform->matrix[0][2];
- float yy = op->base.src.transform->matrix[1][1];
- float y0 = op->base.src.transform->matrix[1][2];
- float sx = op->base.src.scale[0];
- float sy = op->base.src.scale[1];
- int16_t tx = op->base.src.offset[0];
- int16_t ty = op->base.src.offset[1];
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 3*4;
- assert(sna->render.vertex_used <= sna->render.vertex_size);
-
- dst.p.x = box->x2;
- dst.p.y = box->y2;
- v[0] = dst.f;
- v[1] = ((box->x2 + tx) * xx + x0) * sx;
- v[6] = v[2] = ((box->y2 + ty) * yy + y0) * sy;
-
- dst.p.x = box->x1;
- v[4] = dst.f;
- v[9] = v[5] = ((box->x1 + tx) * xx + x0) * sx;
-
- dst.p.y = box->y1;
- v[8] = dst.f;
- v[10] = ((box->y1 + ty) * yy + y0) * sy;
-
- v[11] = v[7] = v[3] = opacity;
-}
-
-fastcall static void
-gen6_emit_composite_spans_affine(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- gen6_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x2, box->y2);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y2);
- gen6_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y2);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y1);
- gen6_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y1);
- OUT_VERTEX_F(opacity);
-}
-
fastcall static void
gen6_render_composite_spans_box(struct sna *sna,
const struct sna_composite_spans_op *op,
@@ -3100,8 +2456,8 @@ gen6_render_composite_spans_done(struct sna *sna,
{
DBG(("%s()\n", __FUNCTION__));
- if (sna->render_state.gen6.vertex_offset)
- gen6_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
if (op->base.src.bo)
kgem_bo_destroy(&sna->kgem, op->base.src.bo);
@@ -3200,22 +2556,7 @@ gen6_render_composite_spans(struct sna *sna,
tmp->base.is_affine = tmp->base.src.is_affine;
tmp->base.need_magic_ca_pass = false;
- tmp->prim_emit = gen6_emit_composite_spans_primitive;
- if (tmp->base.src.is_solid) {
- tmp->prim_emit = gen6_emit_composite_spans_solid;
- } else if (tmp->base.src.transform == NULL) {
- tmp->prim_emit = gen6_emit_composite_spans_identity;
- } else if (tmp->base.is_affine) {
- if (tmp->base.src.transform->matrix[0][1] == 0 &&
- tmp->base.src.transform->matrix[1][0] == 0) {
- tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2];
- tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2];
- tmp->prim_emit = gen6_emit_composite_spans_simple;
- } else
- tmp->prim_emit = gen6_emit_composite_spans_affine;
- }
- tmp->base.floats_per_vertex = 4 + !tmp->base.is_affine;
- tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
+ gen4_choose_spans_emitter(tmp);
tmp->base.u.gen6.flags =
GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter,
@@ -3224,7 +2565,7 @@ gen6_render_composite_spans(struct sna *sna,
SAMPLER_EXTEND_PAD),
gen6_get_blend(tmp->base.op, false, tmp->base.dst.format),
GEN6_WM_KERNEL_OPACITY | !tmp->base.is_affine,
- 1 << 2 | (2+!tmp->base.is_affine));
+ gen4_choose_spans_vertex_buffer(&tmp->base));
tmp->box = gen6_render_composite_spans_box;
tmp->boxes = gen6_render_composite_spans_boxes;
@@ -3541,7 +2882,7 @@ fallback_blt:
} while (--n_this_time);
} while (n);
- gen6_vertex_flush(sna);
+ gen4_vertex_flush(sna);
sna_render_composite_redirect_done(sna, &tmp);
if (tmp.src.bo != src_bo)
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
@@ -3588,8 +2929,8 @@ gen6_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
{
DBG(("%s()\n", __FUNCTION__));
- if (sna->render_state.gen6.vertex_offset)
- gen6_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
}
static bool
@@ -3844,7 +3185,7 @@ gen6_render_fill_boxes(struct sna *sna,
} while (--n_this_time);
} while (n);
- gen6_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
sna_render_composite_redirect_done(sna, &tmp);
return true;
@@ -3937,8 +3278,8 @@ gen6_render_op_fill_done(struct sna *sna, const struct sna_fill_op *op)
{
DBG(("%s()\n", __FUNCTION__));
- if (sna->render_state.gen6.vertex_offset)
- gen6_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, op->base.src.bo);
}
@@ -4092,7 +3433,7 @@ gen6_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
v[7] = v[2] = v[3] = 1;
v[6] = v[10] = v[11] = 0;
- gen6_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
@@ -4174,7 +3515,7 @@ gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
v[7] = v[2] = v[3] = 1;
v[6] = v[10] = v[11] = 0;
- gen6_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
@@ -4182,7 +3523,10 @@ gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
static void gen6_render_flush(struct sna *sna)
{
- gen6_vertex_close(sna);
+ gen4_vertex_close(sna);
+
+ assert(sna->render.vb_id == 0);
+ assert(sna->render.vertex_offset == 0);
}
static void
@@ -4234,7 +3578,6 @@ static void gen6_render_reset(struct sna *sna)
{
sna->render_state.gen6.needs_invariant = true;
sna->render_state.gen6.first_state_packet = true;
- sna->render_state.gen6.vb_id = 0;
sna->render_state.gen6.ve_id = 3 << 2;
sna->render_state.gen6.last_primitive = -1;
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index cc3199d5..04ffdc52 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -42,6 +42,7 @@
#include "brw/brw.h"
#include "gen7_render.h"
+#include "gen4_vertex.h"
#define NO_COMPOSITE 0
#define NO_COMPOSITE_SPANS 0
@@ -1092,147 +1093,6 @@ static void gen7_magic_ca_pass(struct sna *sna,
state->last_primitive = sna->kgem.nbatch;
}
-static void gen7_vertex_flush(struct sna *sna)
-{
- assert(sna->render_state.gen7.vertex_offset);
-
- DBG(("%s[%x] = %d\n", __FUNCTION__,
- 4*sna->render_state.gen7.vertex_offset,
- sna->render.vertex_index - sna->render.vertex_start));
- sna->kgem.batch[sna->render_state.gen7.vertex_offset] =
- sna->render.vertex_index - sna->render.vertex_start;
- sna->render_state.gen7.vertex_offset = 0;
-}
-
-static int gen7_vertex_finish(struct sna *sna)
-{
- struct kgem_bo *bo;
- unsigned int i;
-
- assert(sna->render.vertex_used);
- assert(sna->render.nvertex_reloc);
-
- /* Note: we only need dword alignment (currently) */
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render_state.gen7.vertex_offset)
- gen7_vertex_flush(sna);
-
- for (i = 0; i < sna->render.nvertex_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->render.nvertex_reloc = 0;
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- sna->render.vbo = NULL;
- sna->render_state.gen7.vb_id = 0;
-
- kgem_bo_destroy(&sna->kgem, bo);
- }
-
- sna->render.vertices = NULL;
- sna->render.vbo = kgem_create_linear(&sna->kgem,
- 256*1024, CREATE_GTT_MAP);
- if (sna->render.vbo)
- sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
- if (sna->render.vertices == NULL) {
- if (sna->render.vbo)
- kgem_bo_destroy(&sna->kgem, sna->render.vbo);
- sna->render.vbo = NULL;
- return 0;
- }
-
- kgem_bo_sync__cpu(&sna->kgem, sna->render.vbo);
- if (sna->render.vertex_used) {
- memcpy(sna->render.vertices,
- sna->render.vertex_data,
- sizeof(float)*sna->render.vertex_used);
- }
- sna->render.vertex_size = 64 * 1024 - 1;
- return sna->render.vertex_size - sna->render.vertex_used;
-}
-
-static void gen7_vertex_close(struct sna *sna)
-{
- struct kgem_bo *bo, *free_bo = NULL;
- unsigned int i, delta = 0;
-
- assert(sna->render_state.gen7.vertex_offset == 0);
-
- if (!sna->render_state.gen7.vb_id)
- return;
-
- DBG(("%s: used=%d, vbo active? %d\n",
- __FUNCTION__, sna->render.vertex_used, sna->render.vbo ? sna->render.vbo->handle : 0));
-
- bo = sna->render.vbo;
- if (bo) {
- if (sna->render.vertex_size - sna->render.vertex_used < 64) {
- DBG(("%s: discarding vbo (full), handle=%d\n", __FUNCTION__, sna->render.vbo->handle));
- sna->render.vbo = NULL;
- sna->render.vertices = sna->render.vertex_data;
- sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
- free_bo = bo;
- }
- } else {
- 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,
- CREATE_NO_THROTTLE);
- if (bo && !kgem_bo_write(&sna->kgem, bo,
- sna->render.vertex_data,
- 4*sna->render.vertex_used)) {
- kgem_bo_destroy(&sna->kgem, bo);
- bo = NULL;
- }
- DBG(("%s: new vbo: %d\n", __FUNCTION__,
- sna->render.vertex_used));
- free_bo = bo;
- }
- }
-
- assert(sna->render.nvertex_reloc);
- for (i = 0; i < sna->render.nvertex_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,
- delta);
- }
- sna->render.nvertex_reloc = 0;
-
- if (sna->render.vbo == NULL) {
- sna->render.vertex_used = 0;
- sna->render.vertex_index = 0;
- assert(sna->render.vertices == sna->render.vertex_data);
- assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
- }
-
- if (free_bo)
- kgem_bo_destroy(&sna->kgem, free_bo);
-}
-
static void null_create(struct sna_static_stream *stream)
{
/* A bunch of zeros useful for legacy border color and depth-stencil */
@@ -1384,290 +1244,6 @@ gen7_bind_bo(struct sna *sna,
return offset * sizeof(uint32_t);
}
-fastcall static void
-gen7_emit_composite_primitive_solid(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
- assert(sna->render.vertex_used <= sna->render.vertex_size);
- assert(!too_large(op->dst.x + r->dst.x + r->width,
- op->dst.y + r->dst.y + r->height));
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- dst.p.y = r->dst.y;
- v[6] = dst.f;
-
- v[5] = v[2] = v[1] = 1.;
- v[8] = v[7] = v[4] = 0.;
-}
-
-fastcall static void
-gen7_emit_composite_primitive_identity_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float *v;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- dst.p.y = r->dst.y;
- v[6] = dst.f;
-
- v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0];
- v[1] = v[4] + r->width * op->src.scale[0];
-
- v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1];
- v[5] = v[2] = v[8] + r->height * op->src.scale[1];
-}
-
-fastcall static void
-gen7_emit_composite_primitive_simple_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- float xx = op->src.transform->matrix[0][0];
- float x0 = op->src.transform->matrix[0][2];
- float yy = op->src.transform->matrix[1][1];
- float y0 = op->src.transform->matrix[1][2];
- float sx = op->src.scale[0];
- float sy = op->src.scale[1];
- int16_t tx = op->src.offset[0];
- int16_t ty = op->src.offset[1];
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 3*3;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx;
- v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy;
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx;
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- v[8] = ((r->src.y + ty) * yy + y0) * sy;
-}
-
-fastcall static void
-gen7_emit_composite_primitive_affine_source(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float *v;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 9;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[1], &v[2]);
- v[1] *= op->src.scale[0];
- v[2] *= op->src.scale[1];
-
- dst.p.x = r->dst.x;
- v[3] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y + r->height,
- op->src.transform,
- &v[4], &v[5]);
- v[4] *= op->src.scale[0];
- v[5] *= op->src.scale[1];
-
- dst.p.y = r->dst.y;
- v[6] = dst.f;
- _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
- op->src.offset[1] + r->src.y,
- op->src.transform,
- &v[7], &v[8]);
- v[7] *= op->src.scale[0];
- v[8] *= op->src.scale[1];
-}
-
-fastcall static void
-gen7_emit_composite_primitive_identity_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[13] = v[8] = msk_x * op->mask.scale[0];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[14] = msk_y * op->mask.scale[1];
-
- v[7] = v[2] = v[1] = 1;
- v[12] = v[11] = v[6] = 0;
-}
-
-fastcall static void
-gen7_emit_composite_primitive_identity_source_mask(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- union {
- struct sna_coordinate p;
- float f;
- } dst;
- float src_x, src_y;
- float msk_x, msk_y;
- float w, h;
- float *v;
-
- src_x = r->src.x + op->src.offset[0];
- src_y = r->src.y + op->src.offset[1];
- msk_x = r->mask.x + op->mask.offset[0];
- msk_y = r->mask.y + op->mask.offset[1];
- w = r->width;
- h = r->height;
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 15;
-
- dst.p.x = r->dst.x + r->width;
- dst.p.y = r->dst.y + r->height;
- v[0] = dst.f;
- v[1] = (src_x + w) * op->src.scale[0];
- v[2] = (src_y + h) * op->src.scale[1];
- v[3] = (msk_x + w) * op->mask.scale[0];
- v[4] = (msk_y + h) * op->mask.scale[1];
-
- dst.p.x = r->dst.x;
- v[5] = dst.f;
- v[6] = src_x * op->src.scale[0];
- v[7] = v[2];
- v[8] = msk_x * op->mask.scale[0];
- v[9] = v[4];
-
- dst.p.y = r->dst.y;
- v[10] = dst.f;
- v[11] = v[6];
- v[12] = src_y * op->src.scale[1];
- v[13] = v[8];
- v[14] = msk_y * op->mask.scale[1];
-}
-
-inline static void
-gen7_emit_composite_texcoord(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- x += channel->offset[0];
- y += channel->offset[1];
-
- if (channel->is_affine) {
- float s, t;
-
- sna_get_transformed_coordinates(x, y,
- channel->transform,
- &s, &t);
- OUT_VERTEX_F(s * channel->scale[0]);
- OUT_VERTEX_F(t * channel->scale[1]);
- } else {
- float s, t, w;
-
- sna_get_transformed_coordinates_3d(x, y,
- channel->transform,
- &s, &t, &w);
- OUT_VERTEX_F(s * channel->scale[0]);
- OUT_VERTEX_F(t * channel->scale[1]);
- OUT_VERTEX_F(w);
- }
-}
-
-static void
-gen7_emit_composite_vertex(struct sna *sna,
- const struct sna_composite_op *op,
- int16_t srcX, int16_t srcY,
- int16_t mskX, int16_t mskY,
- int16_t dstX, int16_t dstY)
-{
- OUT_VERTEX(dstX, dstY);
- gen7_emit_composite_texcoord(sna, &op->src, srcX, srcY);
- gen7_emit_composite_texcoord(sna, &op->mask, mskX, mskY);
-}
-
-fastcall static void
-gen7_emit_composite_primitive(struct sna *sna,
- const struct sna_composite_op *op,
- const struct sna_composite_rectangles *r)
-{
- gen7_emit_composite_vertex(sna, op,
- r->src.x + r->width, r->src.y + r->height,
- r->mask.x + r->width, r->mask.y + r->height,
- r->dst.x + r->width, r->dst.y + r->height);
- gen7_emit_composite_vertex(sna, op,
- r->src.x, r->src.y + r->height,
- r->mask.x, r->mask.y + r->height,
- r->dst.x, r->dst.y + r->height);
- gen7_emit_composite_vertex(sna, op,
- r->src.x, r->src.y,
- r->mask.x, r->mask.y,
- r->dst.x, r->dst.y);
-}
-
static void gen7_emit_vertex_buffer(struct sna *sna,
const struct sna_composite_op *op)
{
@@ -1683,19 +1259,19 @@ static void gen7_emit_vertex_buffer(struct sna *sna,
OUT_BATCH(~0); /* max address: disabled */
OUT_BATCH(0);
- sna->render_state.gen7.vb_id |= 1 << id;
+ sna->render.vb_id |= 1 << id;
}
static void gen7_emit_primitive(struct sna *sna)
{
if (sna->kgem.nbatch == sna->render_state.gen7.last_primitive) {
- sna->render_state.gen7.vertex_offset = sna->kgem.nbatch - 5;
+ sna->render.vertex_offset = sna->kgem.nbatch - 5;
return;
}
OUT_BATCH(GEN7_3DPRIMITIVE | (7- 2));
OUT_BATCH(GEN7_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST);
- sna->render_state.gen7.vertex_offset = sna->kgem.nbatch;
+ sna->render.vertex_offset = sna->kgem.nbatch;
OUT_BATCH(0); /* vertex count, to be filled in later */
OUT_BATCH(sna->render.vertex_index);
OUT_BATCH(1); /* single instance */
@@ -1713,12 +1289,12 @@ static bool gen7_rectangle_begin(struct sna *sna,
int ndwords;
ndwords = op->need_magic_ca_pass ? 60 : 6;
- if ((sna->render_state.gen7.vb_id & id) == 0)
+ if ((sna->render.vb_id & id) == 0)
ndwords += 5;
if (!kgem_check_batch(&sna->kgem, ndwords))
return false;
- if ((sna->render_state.gen7.vb_id & id) == 0)
+ if ((sna->render.vb_id & id) == 0)
gen7_emit_vertex_buffer(sna, op);
gen7_emit_primitive(sna);
@@ -1738,7 +1314,7 @@ static int gen7_get_rectangles__flush(struct sna *sna,
if (op->need_magic_ca_pass && sna->render.vbo)
return 0;
- return gen7_vertex_finish(sna);
+ return gen4_vertex_finish(sna);
}
inline static int gen7_get_rectangles(struct sna *sna,
@@ -1758,7 +1334,7 @@ start:
goto flush;
}
- if (unlikely(sna->render_state.gen7.vertex_offset == 0 &&
+ if (unlikely(sna->render.vertex_offset == 0 &&
!gen7_rectangle_begin(sna, op)))
goto flush;
@@ -1770,8 +1346,8 @@ start:
return want;
flush:
- if (sna->render_state.gen7.vertex_offset) {
- gen7_vertex_flush(sna);
+ if (sna->render.vertex_offset) {
+ gen4_vertex_flush(sna);
gen7_magic_ca_pass(sna, op);
}
_kgem_submit(&sna->kgem);
@@ -1796,16 +1372,6 @@ inline static uint32_t *gen7_composite_get_binding_table(struct sna *sna,
return table;
}
-static uint32_t
-gen7_choose_composite_vertex_buffer(const struct sna_composite_op *op)
-{
- int id = 2 + !op->is_affine;
- if (op->mask.bo)
- id |= id << 2;
- assert(id > 0 && id < 16);
- return id;
-}
-
static void
gen7_get_batch(struct sna *sna, const struct sna_composite_op *op)
{
@@ -1872,7 +1438,7 @@ gen7_align_vertex(struct sna *sna, const struct sna_composite_op *op)
{
if (op->floats_per_vertex != sna->render_state.gen7.floats_per_vertex) {
if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
- gen7_vertex_finish(sna);
+ gen4_vertex_finish(sna);
DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
sna->render_state.gen7.floats_per_vertex,
@@ -2197,7 +1763,7 @@ gen7_render_video(struct sna *sna,
}
priv->clear = false;
- gen7_vertex_flush(sna);
+ gen4_vertex_flush(sna);
return true;
}
@@ -2445,8 +2011,8 @@ static void gen7_composite_channel_convert(struct sna_composite_channel *channel
static void gen7_render_composite_done(struct sna *sna,
const struct sna_composite_op *op)
{
- if (sna->render_state.gen7.vertex_offset) {
- gen7_vertex_flush(sna);
+ if (sna->render.vertex_offset) {
+ gen4_vertex_flush(sna);
gen7_magic_ca_pass(sna, op);
}
@@ -2875,7 +2441,6 @@ gen7_render_composite(struct sna *sna,
tmp->mask.filter = SAMPLER_FILTER_NEAREST;
tmp->mask.repeat = SAMPLER_EXTEND_NONE;
- tmp->prim_emit = gen7_emit_composite_primitive;
if (mask) {
if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
tmp->has_component_alpha = true;
@@ -2915,35 +2480,9 @@ gen7_render_composite(struct sna *sna,
}
tmp->is_affine &= tmp->mask.is_affine;
-
- if (tmp->src.transform == NULL && tmp->mask.transform == NULL) {
- if (tmp->src.is_solid)
- tmp->prim_emit = gen7_emit_composite_primitive_identity_mask;
- else
- tmp->prim_emit = gen7_emit_composite_primitive_identity_source_mask;
- }
-
- tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
- } else {
- if (tmp->src.is_solid) {
- tmp->prim_emit = gen7_emit_composite_primitive_solid;
- if (tmp->src.is_opaque && op == PictOpOver)
- tmp->op = PictOpSrc;
- } else if (tmp->src.transform == NULL)
- tmp->prim_emit = gen7_emit_composite_primitive_identity_source;
- else if (tmp->src.is_affine) {
- if (tmp->src.transform->matrix[0][1] == 0 &&
- tmp->src.transform->matrix[1][0] == 0) {
- tmp->src.scale[0] /= tmp->src.transform->matrix[2][2];
- tmp->src.scale[1] /= tmp->src.transform->matrix[2][2];
- tmp->prim_emit = gen7_emit_composite_primitive_simple_source;
- } else
- tmp->prim_emit = gen7_emit_composite_primitive_affine_source;
- }
-
- tmp->floats_per_vertex = 3 + !tmp->is_affine;
}
- tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
+
+ gen4_choose_composite_emitter(tmp);
tmp->u.gen7.flags =
GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
@@ -2957,7 +2496,7 @@ gen7_render_composite(struct sna *sna,
tmp->mask.bo != NULL,
tmp->has_component_alpha,
tmp->is_affine),
- gen7_choose_composite_vertex_buffer(tmp));
+ gen4_choose_composite_vertex_buffer(tmp));
tmp->blt = gen7_render_composite_blt;
tmp->box = gen7_render_composite_box;
@@ -2993,167 +2532,6 @@ cleanup_dst:
}
#if !NO_COMPOSITE_SPANS
-inline static void
-gen7_emit_composite_texcoord_affine(struct sna *sna,
- const struct sna_composite_channel *channel,
- int16_t x, int16_t y)
-{
- float t[2];
-
- sna_get_transformed_coordinates(x + channel->offset[0],
- y + channel->offset[1],
- channel->transform,
- &t[0], &t[1]);
- OUT_VERTEX_F(t[0] * channel->scale[0]);
- OUT_VERTEX_F(t[1] * channel->scale[1]);
-}
-
-inline static void
-gen7_emit_composite_spans_vertex(struct sna *sna,
- const struct sna_composite_spans_op *op,
- int16_t x, int16_t y)
-{
- OUT_VERTEX(x, y);
- gen7_emit_composite_texcoord(sna, &op->base.src, x, y);
-}
-
-fastcall static void
-gen7_emit_composite_spans_primitive(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- gen7_emit_composite_spans_vertex(sna, op, box->x2, box->y2);
- OUT_VERTEX_F(opacity);
-
- gen7_emit_composite_spans_vertex(sna, op, box->x1, box->y2);
- OUT_VERTEX_F(opacity);
-
- gen7_emit_composite_spans_vertex(sna, op, box->x1, box->y1);
- OUT_VERTEX_F(opacity);
-}
-
-fastcall static void
-gen7_emit_composite_spans_solid(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- OUT_VERTEX_F(1); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y2);
- OUT_VERTEX_F(0); OUT_VERTEX_F(1);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y1);
- OUT_VERTEX_F(0); OUT_VERTEX_F(0);
- OUT_VERTEX_F(opacity);
-}
-
-fastcall static void
-gen7_emit_composite_spans_identity(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- float sx = op->base.src.scale[0];
- float sy = op->base.src.scale[1];
- int16_t tx = op->base.src.offset[0];
- int16_t ty = op->base.src.offset[1];
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 3*4;
- assert(sna->render.vertex_used <= sna->render.vertex_size);
-
- dst.p.x = box->x2;
- dst.p.y = box->y2;
- v[0] = dst.f;
- v[1] = (box->x2 + tx) * sx;
- v[6] = v[2] = (box->y2 + ty) * sy;
-
- dst.p.x = box->x1;
- v[4] = dst.f;
- v[9] = v[5] = (box->x1 + tx) * sx;
-
- dst.p.y = box->y1;
- v[8] = dst.f;
- v[10] = (box->y1 + ty) * sy;
-
- v[11] = v[7] = v[3] = opacity;
-}
-
-fastcall static void
-gen7_emit_composite_spans_simple(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- float *v;
- union {
- struct sna_coordinate p;
- float f;
- } dst;
-
- float xx = op->base.src.transform->matrix[0][0];
- float x0 = op->base.src.transform->matrix[0][2];
- float yy = op->base.src.transform->matrix[1][1];
- float y0 = op->base.src.transform->matrix[1][2];
- float sx = op->base.src.scale[0];
- float sy = op->base.src.scale[1];
- int16_t tx = op->base.src.offset[0];
- int16_t ty = op->base.src.offset[1];
-
- v = sna->render.vertices + sna->render.vertex_used;
- sna->render.vertex_used += 3*4;
- assert(sna->render.vertex_used <= sna->render.vertex_size);
-
- dst.p.x = box->x2;
- dst.p.y = box->y2;
- v[0] = dst.f;
- v[1] = ((box->x2 + tx) * xx + x0) * sx;
- v[6] = v[2] = ((box->y2 + ty) * yy + y0) * sy;
-
- dst.p.x = box->x1;
- v[4] = dst.f;
- v[9] = v[5] = ((box->x1 + tx) * xx + x0) * sx;
-
- dst.p.y = box->y1;
- v[8] = dst.f;
- v[10] = ((box->y1 + ty) * yy + y0) * sy;
-
- v[11] = v[7] = v[3] = opacity;
-}
-
-fastcall static void
-gen7_emit_composite_spans_affine(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
-{
- OUT_VERTEX(box->x2, box->y2);
- gen7_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x2, box->y2);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y2);
- gen7_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y2);
- OUT_VERTEX_F(opacity);
-
- OUT_VERTEX(box->x1, box->y1);
- gen7_emit_composite_texcoord_affine(sna, &op->base.src,
- box->x1, box->y1);
- OUT_VERTEX_F(opacity);
-}
-
fastcall static void
gen7_render_composite_spans_box(struct sna *sna,
const struct sna_composite_spans_op *op,
@@ -3206,8 +2584,8 @@ fastcall static void
gen7_render_composite_spans_done(struct sna *sna,
const struct sna_composite_spans_op *op)
{
- if (sna->render_state.gen7.vertex_offset)
- gen7_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
DBG(("%s()\n", __FUNCTION__));
@@ -3288,22 +2666,7 @@ gen7_render_composite_spans(struct sna *sna,
tmp->base.is_affine = tmp->base.src.is_affine;
tmp->base.need_magic_ca_pass = false;
- tmp->prim_emit = gen7_emit_composite_spans_primitive;
- if (tmp->base.src.is_solid) {
- tmp->prim_emit = gen7_emit_composite_spans_solid;
- } else if (tmp->base.src.transform == NULL) {
- tmp->prim_emit = gen7_emit_composite_spans_identity;
- } else if (tmp->base.is_affine) {
- if (tmp->base.src.transform->matrix[0][1] == 0 &&
- tmp->base.src.transform->matrix[1][0] == 0) {
- tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2];
- tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2];
- tmp->prim_emit = gen7_emit_composite_spans_simple;
- } else
- tmp->prim_emit = gen7_emit_composite_spans_affine;
- }
- tmp->base.floats_per_vertex = 4 + !tmp->base.is_affine;
- tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
+ gen4_choose_spans_emitter(tmp);
tmp->base.u.gen7.flags =
GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter,
@@ -3312,7 +2675,7 @@ gen7_render_composite_spans(struct sna *sna,
SAMPLER_EXTEND_PAD),
gen7_get_blend(tmp->base.op, false, tmp->base.dst.format),
GEN7_WM_KERNEL_OPACITY | !tmp->base.is_affine,
- 1 << 2 | (2+!tmp->base.is_affine));
+ gen4_choose_spans_vertex_buffer(&tmp->base));
tmp->box = gen7_render_composite_spans_box;
tmp->boxes = gen7_render_composite_spans_boxes;
@@ -3618,7 +2981,7 @@ fallback_blt:
} while (--n_this_time);
} while (n);
- gen7_vertex_flush(sna);
+ gen4_vertex_flush(sna);
sna_render_composite_redirect_done(sna, &tmp);
if (tmp.src.bo != src_bo)
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
@@ -3663,8 +3026,8 @@ gen7_render_copy_blt(struct sna *sna,
static void
gen7_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
{
- if (sna->render_state.gen7.vertex_offset)
- gen7_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
}
static bool
@@ -3916,7 +3279,7 @@ gen7_render_fill_boxes(struct sna *sna,
} while (--n_this_time);
} while (n);
- gen7_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
sna_render_composite_redirect_done(sna, &tmp);
return true;
@@ -4007,8 +3370,8 @@ gen7_render_fill_op_boxes(struct sna *sna,
static void
gen7_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op)
{
- if (sna->render_state.gen7.vertex_offset)
- gen7_vertex_flush(sna);
+ if (sna->render.vertex_offset)
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, op->base.src.bo);
}
@@ -4158,7 +3521,7 @@ gen7_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
v[7] = v[2] = v[3] = 1;
v[6] = v[10] = v[11] = 0;
- gen7_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
@@ -4238,7 +3601,7 @@ gen7_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
v[7] = v[2] = v[3] = 1;
v[6] = v[10] = v[11] = 0;
- gen7_vertex_flush(sna);
+ gen4_vertex_flush(sna);
kgem_bo_destroy(&sna->kgem, tmp.src.bo);
return true;
@@ -4246,7 +3609,10 @@ gen7_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
static void gen7_render_flush(struct sna *sna)
{
- gen7_vertex_close(sna);
+ gen4_vertex_close(sna);
+
+ assert(sna->render.vb_id == 0);
+ assert(sna->render.vertex_offset == 0);
}
static void
@@ -4299,7 +3665,6 @@ static void gen7_render_reset(struct sna *sna)
{
sna->render_state.gen7.emit_flush = false;
sna->render_state.gen7.needs_invariant = true;
- sna->render_state.gen7.vb_id = 0;
sna->render_state.gen7.ve_id = 3 << 2;
sna->render_state.gen7.last_primitive = -1;
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 974201e2..adeead10 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -533,6 +533,7 @@ static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo,
bo->refcnt = 1;
bo->handle = handle;
+ bo->target_handle = -1;
num_pages(bo) = num_pages;
bucket(bo) = cache_bucket(num_pages);
bo->reusable = true;
@@ -2044,6 +2045,7 @@ static void kgem_commit(struct kgem *kgem)
bo->presumed_offset = bo->exec->offset;
bo->exec = NULL;
+ bo->target_handle = -1;
if (!bo->refcnt && !bo->reusable) {
assert(!bo->snoop);
@@ -2312,6 +2314,7 @@ void kgem_reset(struct kgem *kgem)
bo->binding.offset = 0;
bo->exec = NULL;
+ bo->target_handle = -1;
bo->dirty = false;
bo->rq = NULL;
bo->domain = DOMAIN_NONE;
@@ -2469,7 +2472,7 @@ void _kgem_submit(struct kgem *kgem)
kgem_finish_buffers(kgem);
-#if HAS_DEBUG_FULL && SHOW_BATCH
+#if SHOW_BATCH
__kgem_batch_debug(kgem, batch_end);
#endif
@@ -3137,10 +3140,14 @@ struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
size = (size + PAGE_SIZE - 1) / PAGE_SIZE;
bo = search_linear_cache(kgem, size, CREATE_INACTIVE | flags);
if (bo) {
+ assert(!kgem_busy(kgem, bo->handle));
bo->refcnt = 1;
return bo;
}
+ if (flags & CREATE_CACHED)
+ return NULL;
+
handle = gem_create(kgem->fd, size);
if (handle == 0)
return NULL;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index c5199c2d..1b14c203 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -260,8 +260,9 @@ enum {
CREATE_SCANOUT = 0x10,
CREATE_PRIME = 0x20,
CREATE_TEMPORARY = 0x40,
- CREATE_NO_RETIRE = 0x80,
- CREATE_NO_THROTTLE = 0x100,
+ CREATE_CACHED = 0x80,
+ CREATE_NO_RETIRE = 0x100,
+ CREATE_NO_THROTTLE = 0x200,
};
struct kgem_bo *kgem_create_2d(struct kgem *kgem,
int width,
@@ -631,7 +632,7 @@ bool kgem_expire_cache(struct kgem *kgem);
void kgem_purge_cache(struct kgem *kgem);
void kgem_cleanup_cache(struct kgem *kgem);
-#if HAS_EXTRA_DEBUG
+#if HAS_DEBUG_FULL
void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
#else
static inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch)
diff --git a/src/sna/kgem_debug.c b/src/sna/kgem_debug.c
index 595c20f6..48c75889 100644
--- a/src/sna/kgem_debug.c
+++ b/src/sna/kgem_debug.c
@@ -62,7 +62,7 @@ kgem_debug_get_bo_for_reloc_entry(struct kgem *kgem,
return NULL;
list_for_each_entry(bo, &kgem->next_request->buffers, request)
- if (bo->handle == reloc->target_handle && bo->proxy == NULL)
+ if (bo->target_handle == reloc->target_handle && bo->proxy == NULL)
break;
assert(&bo->request != &kgem->next_request->buffers);
@@ -74,6 +74,9 @@ static int kgem_debug_handle_is_fenced(struct kgem *kgem, uint32_t handle)
{
int i;
+ if (kgem->has_handle_lut)
+ return kgem->exec[handle].flags & EXEC_OBJECT_NEEDS_FENCE;
+
for (i = 0; i < kgem->nexec; i++)
if (kgem->exec[i].handle == handle)
return kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE;
@@ -86,7 +89,7 @@ static int kgem_debug_handle_tiling(struct kgem *kgem, uint32_t handle)
struct kgem_bo *bo;
list_for_each_entry(bo, &kgem->next_request->buffers, request)
- if (bo->handle == handle)
+ if (bo->target_handle == handle)
return bo->tiling;
return 0;
@@ -95,7 +98,7 @@ static int kgem_debug_handle_tiling(struct kgem *kgem, uint32_t handle)
void
kgem_debug_print(const uint32_t *data,
uint32_t offset, unsigned int index,
- char *fmt, ...)
+ const char *fmt, ...)
{
va_list va;
char buf[240];
diff --git a/src/sna/kgem_debug.h b/src/sna/kgem_debug.h
index 82d6f666..a0c9fc17 100644
--- a/src/sna/kgem_debug.h
+++ b/src/sna/kgem_debug.h
@@ -4,7 +4,7 @@
void
kgem_debug_print(const uint32_t *data,
uint32_t offset, unsigned int index,
- char *fmt, ...);
+ const char *fmt, ...);
struct drm_i915_gem_relocation_entry *
kgem_debug_get_reloc_entry(struct kgem *kgem, uint32_t offset);
diff --git a/src/sna/kgem_debug_gen5.c b/src/sna/kgem_debug_gen5.c
index e23ceb1f..8b55dd91 100644
--- a/src/sna/kgem_debug_gen5.c
+++ b/src/sna/kgem_debug_gen5.c
@@ -73,7 +73,7 @@ static void gen5_update_vertex_buffer(struct kgem *kgem, const uint32_t *data)
int i, size;
reloc = kgem_debug_get_reloc_entry(kgem, &data[1] - kgem->batch);
- if (reloc->target_handle == 0) {
+ if (reloc->target_handle == -1) {
base = kgem->batch;
size = kgem->nbatch * sizeof(uint32_t);
} else {
@@ -529,20 +529,19 @@ int kgem_gen5_decode_3d(struct kgem *kgem, uint32_t offset)
for (i = 1; i < len;) {
gen5_update_vertex_elements(kgem, (i - 1)/2, data + i);
- kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, "
- "src offset 0x%04x bytes\n",
- data[i] >> 27,
- data[i] & (1 << 26) ? "" : "in",
- (data[i] >> 16) & 0x1ff,
- data[i] & 0x07ff);
+ kgem_debug_print(data, offset, i,
+ "buffer %d: %svalid, type 0x%04x, "
+ "src offset 0x%04x bytes\n",
+ data[i] >> 27,
+ data[i] & (1 << 26) ? "" : "in",
+ (data[i] >> 16) & 0x1ff,
+ data[i] & 0x07ff);
i++;
- kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), "
- "dst offset 0x%02x bytes\n",
+ kgem_debug_print(data, offset, i, "(%s, %s, %s, %s)\n",
get_965_element_component(data[i], 0),
get_965_element_component(data[i], 1),
get_965_element_component(data[i], 2),
- get_965_element_component(data[i], 3),
- (data[i] & 0xff) * 4);
+ get_965_element_component(data[i], 3));
i++;
}
state.num_ve = (len - 1) / 2; /* XXX? */
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index e92c4530..90e6e235 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1704,7 +1704,7 @@ sna_render_picture_convert(struct sna *sna,
PICT_FORMAT_B(picture->format));
DBG(("%s: converting to %08x from %08x using composite alpha-fixup\n",
- __FUNCTION__, picture->format));
+ __FUNCTION__, (unsigned)picture->format));
tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, 0);
if (tmp == NULL)
@@ -1993,7 +1993,7 @@ sna_render_composite_redirect_done(struct sna *sna,
}
if (t->damage) {
DBG(("%s: combining damage (all? %d), offset=(%d, %d)\n",
- __FUNCTION__, DAMAGE_IS_ALL(t->damage),
+ __FUNCTION__, (int)DAMAGE_IS_ALL(t->damage),
t->box.x1, t->box.y1));
sna_damage_combine(t->real_damage,
DAMAGE_PTR(t->damage),
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index ea1d781b..51f155a5 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -5,6 +5,9 @@
#include <picturestr.h>
+#include <stdbool.h>
+#include <stdint.h>
+
#define GRADIENT_CACHE_SIZE 16
#define GXinvalid 0xff
@@ -284,6 +287,8 @@ struct sna_render {
pixman_glyph_cache_t *glyph_cache;
#endif
+ uint16_t vb_id;
+ uint16_t vertex_offset;
uint16_t vertex_start;
uint16_t vertex_index;
uint16_t vertex_used;
@@ -341,9 +346,7 @@ struct gen4_render_state {
int ve_id;
uint32_t drawrect_offset;
uint32_t drawrect_limit;
- uint32_t vb_id;
uint32_t last_pipelined_pointers;
- uint16_t vertex_offset;
uint16_t last_primitive;
int16_t floats_per_vertex;
uint16_t surface_table;
@@ -363,8 +366,6 @@ struct gen5_render_state {
int ve_id;
uint32_t drawrect_offset;
uint32_t drawrect_limit;
- uint32_t vb_id;
- uint16_t vertex_offset;
uint16_t last_primitive;
int16_t floats_per_vertex;
uint16_t surface_table;
@@ -414,9 +415,7 @@ struct gen6_render_state {
uint32_t kernel;
uint16_t num_sf_outputs;
- uint16_t vb_id;
uint16_t ve_id;
- uint16_t vertex_offset;
uint16_t last_primitive;
int16_t floats_per_vertex;
uint16_t surface_table;
@@ -466,9 +465,7 @@ struct gen7_render_state {
uint32_t kernel;
uint16_t num_sf_outputs;
- uint16_t vb_id;
uint16_t ve_id;
- uint16_t vertex_offset;
uint16_t last_primitive;
int16_t floats_per_vertex;
uint16_t surface_table;
diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 51c78bc2..7314889d 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -17,6 +17,17 @@ static inline bool need_redirect(struct sna *sna, PixmapPtr dst)
dst->drawable.height > sna->render.max_3d_size);
}
+static inline float pack_2s(int16_t x, int16_t y)
+{
+ union {
+ struct sna_coordinate p;
+ float f;
+ } u;
+ u.p.x = x;
+ u.p.y = y;
+ return u.f;
+}
+
static inline int vertex_space(struct sna *sna)
{
return sna->render.vertex_size - sna->render.vertex_used;
@@ -28,21 +39,7 @@ static inline void vertex_emit(struct sna *sna, float v)
}
static inline void vertex_emit_2s(struct sna *sna, int16_t x, int16_t y)
{
- int16_t *v = (int16_t *)&sna->render.vertices[sna->render.vertex_used++];
- assert(sna->render.vertex_used <= sna->render.vertex_size);
- v[0] = x;
- v[1] = y;
-}
-
-static inline float pack_2s(int16_t x, int16_t y)
-{
- union {
- struct sna_coordinate p;
- float f;
- } u;
- u.p.x = x;
- u.p.y = y;
- return u.f;
+ vertex_emit(sna, pack_2s(x, y));
}
static inline int batch_space(struct sna *sna)
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 81ae9c41..8cd987e9 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -5552,7 +5552,7 @@ sna_composite_trapezoids(CARD8 op,
dst->pDrawable->width,
dst->pDrawable->height,
too_small(priv),
- DAMAGE_IS_ALL(priv->cpu_damage),
+ (int)DAMAGE_IS_ALL(priv->cpu_damage),
!picture_is_gpu(src)));
force_fallback = true;
}