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 /src/sna/gen4_render.c | |
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>
Diffstat (limited to 'src/sna/gen4_render.c')
-rw-r--r-- | src/sna/gen4_render.c | 803 |
1 files changed, 106 insertions, 697 deletions
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; |