diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-20 12:00:00 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-20 19:11:04 +0000 |
commit | 0f84ecfc3cd7dfe7f43ff99a6498d2ceccd90225 (patch) | |
tree | a78f7d5a969afc132fe838ef6bc7a77c258f26e6 | |
parent | 1f4ede0ef8f8a8d07e11781ad05617ecdfcd3faf (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.ac | 2 | ||||
-rw-r--r-- | src/sna/Makefile.am | 2 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 803 | ||||
-rw-r--r-- | src/sna/gen4_render.h | 17 | ||||
-rw-r--r-- | src/sna/gen4_vertex.c | 896 | ||||
-rw-r--r-- | src/sna/gen4_vertex.h | 39 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 833 | ||||
-rw-r--r-- | src/sna/gen5_render.h | 17 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 727 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 701 | ||||
-rw-r--r-- | src/sna/kgem.c | 9 | ||||
-rw-r--r-- | src/sna/kgem.h | 7 | ||||
-rw-r--r-- | src/sna/kgem_debug.c | 9 | ||||
-rw-r--r-- | src/sna/kgem_debug.h | 2 | ||||
-rw-r--r-- | src/sna/kgem_debug_gen5.c | 21 | ||||
-rw-r--r-- | src/sna/sna_render.c | 4 | ||||
-rw-r--r-- | src/sna/sna_render.h | 13 | ||||
-rw-r--r-- | src/sna/sna_render_inline.h | 27 | ||||
-rw-r--r-- | src/sna/sna_trapezoids.c | 2 |
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; } |