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>
This commit is contained in:
Chris Wilson 2012-12-20 12:00:00 +00:00
parent 1f4ede0ef8
commit 0f84ecfc3c
19 changed files with 1297 additions and 2834 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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;

View File

@ -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

896
src/sna/gen4_vertex.c Normal file
View File

@ -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;
}

39
src/sna/gen4_vertex.h Normal file
View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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];

View File

@ -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);

View File

@ -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? */

View File

@ -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),

View File

@ -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;

View File

@ -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)

View File

@ -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;
}