xf86-video-intel: 4 commits - src/i830_exa.c src/i830.h src/i830_render.c src/i915_3d.h src/i915_reg.h src/i915_render.c src/i965_render.c
Keith Packard
keithp at kemper.freedesktop.org
Tue Mar 18 14:18:05 PDT 2008
src/i830.h | 7 ++
src/i830_exa.c | 39 +++++++++++
src/i830_render.c | 185 ++++++++++++++++++++++++++++++++++++------------------
src/i915_3d.h | 5 +
src/i915_reg.h | 10 ++
src/i915_render.c | 22 ++++--
src/i965_render.c | 2
7 files changed, 204 insertions(+), 66 deletions(-)
New commits:
commit 4b9b7b007d729f94b01b0031d8ae478134b501da
Author: Keith Packard <keithp at keithp.com>
Date: Tue Mar 18 14:08:19 2008 -0700
Handle projective transforms on 9xx for Composite.
Projective transforms require un-normalized texture coordinates and the use
of the texldp instruction. The coordinates are passed as x/y/z/w (the z is
unused, but there isn't a vertext format for just x/y/w).
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 0206ab9..f9df277 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -363,7 +363,7 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
}
}
-**
+/**
* Returns the un-normalized floating-point coordinates transformed by the given transform.
*
* transform may be null.
diff --git a/src/i830_render.c b/src/i830_render.c
index 78ae40a..87543ef 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -395,6 +395,7 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
uint32_t dst_format, dst_offset, dst_pitch;
+ Bool is_affine_src, is_affine_mask;
IntelEmitInvarientState(pScrn);
*pI830->last_3d = LAST_3D_RENDER;
@@ -415,6 +416,12 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
pI830->scale_units[1][1] = -1;
}
+ is_affine_src = i830_transform_is_affine (pI830->transform[0]);
+ is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
+
+ if (!is_affine_src || !is_affine_mask)
+ I830FALLBACK("non-affine transform unsupported on 8xx hardware\n");
+
{
uint32_t cblend, ablend, blendctl, vf2;
@@ -556,7 +563,6 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture,
return TRUE;
}
-
/**
* Do a single rectangle composite operation.
*
@@ -569,79 +575,138 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
Bool has_mask;
- float src_x[3], src_y[3], mask_x[3], mask_y[3];
-
- i830_get_transformed_coordinates(srcX, srcY,
- pI830->transform[0],
- &src_x[0], &src_y[0]);
- i830_get_transformed_coordinates(srcX, srcY + h,
- pI830->transform[0],
- &src_x[1], &src_y[1]);
- i830_get_transformed_coordinates(srcX + w, srcY + h,
- pI830->transform[0],
- &src_x[2], &src_y[2]);
+ Bool is_affine_src, is_affine_mask;
+ int per_vertex, num_floats;
+ float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
+
+ is_affine_src = i830_transform_is_affine (pI830->transform[0]);
+ is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) {
has_mask = FALSE;
} else {
has_mask = TRUE;
- i830_get_transformed_coordinates(maskX, maskY,
- pI830->transform[1],
- &mask_x[0], &mask_y[0]);
- i830_get_transformed_coordinates(maskX, maskY + h,
- pI830->transform[1],
- &mask_x[1], &mask_y[1]);
- i830_get_transformed_coordinates(maskX + w, maskY + h,
- pI830->transform[1],
- &mask_x[2], &mask_y[2]);
}
+ per_vertex = 2; /* dest x/y */
+ if (is_affine_src)
{
- int vertex_count;
-
- if (has_mask)
- vertex_count = 3*6;
- else
- vertex_count = 3*4;
-
- BEGIN_BATCH(6+vertex_count);
-
- OUT_BATCH(MI_NOOP);
- OUT_BATCH(MI_NOOP);
- OUT_BATCH(MI_NOOP);
- OUT_BATCH(MI_NOOP);
- OUT_BATCH(MI_NOOP);
-
- OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1));
+ i830_get_transformed_coordinates(srcX, srcY,
+ pI830->transform[0],
+ &src_x[0], &src_y[0]);
+ i830_get_transformed_coordinates(srcX, srcY + h,
+ pI830->transform[0],
+ &src_x[1], &src_y[1]);
+ i830_get_transformed_coordinates(srcX + w, srcY + h,
+ pI830->transform[0],
+ &src_x[2], &src_y[2]);
+ per_vertex += 2; /* src x/y */
+ } else {
+ i830_get_transformed_coordinates_3d(srcX, srcY,
+ pI830->transform[0],
+ &src_x[0], &src_y[0],
+ &src_w[0]);
+ i830_get_transformed_coordinates_3d(srcX, srcY + h,
+ pI830->transform[0],
+ &src_x[1], &src_y[1],
+ &src_w[1]);
+ i830_get_transformed_coordinates_3d(srcX + w, srcY + h,
+ pI830->transform[0],
+ &src_x[2], &src_y[2],
+ &src_w[2]);
+ per_vertex += 4; /* src x/y/z/w */
+ }
+ if (has_mask) {
+ if (is_affine_mask) {
+ i830_get_transformed_coordinates(maskX, maskY,
+ pI830->transform[1],
+ &mask_x[0], &mask_y[0]);
+ i830_get_transformed_coordinates(maskX, maskY + h,
+ pI830->transform[1],
+ &mask_x[1], &mask_y[1]);
+ i830_get_transformed_coordinates(maskX + w, maskY + h,
+ pI830->transform[1],
+ &mask_x[2], &mask_y[2]);
+ per_vertex += 2; /* mask x/y */
+ } else {
+ i830_get_transformed_coordinates_3d(maskX, maskY,
+ pI830->transform[1],
+ &mask_x[0], &mask_y[0],
+ &mask_w[0]);
+ i830_get_transformed_coordinates_3d(maskX, maskY + h,
+ pI830->transform[1],
+ &mask_x[1], &mask_y[1],
+ &mask_w[1]);
+ i830_get_transformed_coordinates_3d(maskX + w, maskY + h,
+ pI830->transform[1],
+ &mask_x[2], &mask_y[2],
+ &mask_w[2]);
+ per_vertex += 4; /* mask x/y/z/w */
+ }
+ }
- OUT_BATCH_F(-0.125 + dstX + w);
- OUT_BATCH_F(-0.125 + dstY + h);
- OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]);
- OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]);
- if (has_mask) {
- OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]);
- OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]);
+ num_floats = 3 * per_vertex;
+ BEGIN_BATCH(6 + num_floats);
+
+ OUT_BATCH(MI_NOOP);
+ OUT_BATCH(MI_NOOP);
+ OUT_BATCH(MI_NOOP);
+ OUT_BATCH(MI_NOOP);
+ OUT_BATCH(MI_NOOP);
+
+ OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (num_floats-1));
+ OUT_BATCH_F(-0.125 + dstX + w);
+ OUT_BATCH_F(-0.125 + dstY + h);
+ OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]);
+ OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]);
+ if (!is_affine_src) {
+ OUT_BATCH_F(0.0);
+ OUT_BATCH_F(src_w[2]);
+ }
+ if (has_mask) {
+ OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]);
+ OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]);
+ if (!is_affine_mask) {
+ OUT_BATCH_F(0.0);
+ OUT_BATCH_F(mask_w[2]);
}
+ }
- OUT_BATCH_F(-0.125 + dstX);
- OUT_BATCH_F(-0.125 + dstY + h);
- OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]);
- OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]);
- if (has_mask) {
- OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]);
- OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]);
+ OUT_BATCH_F(-0.125 + dstX);
+ OUT_BATCH_F(-0.125 + dstY + h);
+ OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]);
+ OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]);
+ if (!is_affine_src) {
+ OUT_BATCH_F(0.0);
+ OUT_BATCH_F(src_w[1]);
+ }
+ if (has_mask) {
+ OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]);
+ OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]);
+ if (!is_affine_mask) {
+ OUT_BATCH_F(0.0);
+ OUT_BATCH_F(mask_w[1]);
}
+ }
- OUT_BATCH_F(-0.125 + dstX);
- OUT_BATCH_F(-0.125 + dstY);
- OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]);
- OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]);
- if (has_mask) {
- OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]);
- OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]);
+ OUT_BATCH_F(-0.125 + dstX);
+ OUT_BATCH_F(-0.125 + dstY);
+ OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]);
+ OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]);
+ if (!is_affine_src) {
+ OUT_BATCH_F(0.0);
+ OUT_BATCH_F(src_w[0]);
+ }
+ if (has_mask) {
+ OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]);
+ OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]);
+ if (!is_affine_mask) {
+ OUT_BATCH_F(0.0);
+ OUT_BATCH_F(mask_w[0]);
}
- ADVANCE_BATCH();
}
+
+ ADVANCE_BATCH();
}
/**
diff --git a/src/i915_3d.h b/src/i915_3d.h
index c2efe9a..1a0bd45 100644
--- a/src/i915_3d.h
+++ b/src/i915_3d.h
@@ -236,6 +236,11 @@ do { \
FS_OUT(_i915_fs_texld(T0_TEXLD, dest_reg, sampler_reg, address_reg)); \
} while (0)
+#define i915_fs_texldp(dest_reg, sampler_reg, address_reg) \
+do { \
+ FS_OUT(_i915_fs_texld(T0_TEXLDP, dest_reg, sampler_reg, address_reg)); \
+} while (0)
+
static inline struct i915_fs_op
_i915_fs_texld(int load_op, int dest_reg, int sampler_reg, int address_reg)
{
diff --git a/src/i915_render.c b/src/i915_render.c
index 8ac1b78..9c6da09 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -320,6 +320,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
uint32_t blendctl;
int out_reg = FS_OC;
FS_LOCALS(20);
+ Bool is_affine_src, is_affine_mask;
IntelEmitInvarientState(pScrn);
*pI830->last_3d = LAST_3D_RENDER;
@@ -339,6 +340,8 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
pI830->scale_units[1][0] = -1;
pI830->scale_units[1][1] = -1;
}
+ is_affine_src = i830_transform_is_affine (pI830->transform[0]);
+ is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
if (pMask == NULL) {
BEGIN_BATCH(10);
@@ -389,9 +392,9 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
- ss2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+ ss2 = S2_TEXCOORD_FMT(0, is_affine_src ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
if (pMask)
- ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+ ss2 |= S2_TEXCOORD_FMT(1, is_affine_mask ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
else
ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
@@ -435,7 +438,12 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
i915_fs_dcl(FS_T1);
/* Load the pSrcPicture texel */
- i915_fs_texld(FS_R0, FS_S0, FS_T0);
+ if (is_affine_src) {
+ i915_fs_texld(FS_R0, FS_S0, FS_T0);
+ } else {
+ i915_fs_texldp(FS_R0, FS_S0, FS_T0);
+ }
+
/* If the texture lacks an alpha channel, force the alpha to 1. */
if (PICT_FORMAT_A(pSrcPicture->format) == 0)
i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
@@ -445,7 +453,11 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
i915_fs_mov(out_reg, i915_fs_operand_reg(FS_R0));
} else {
/* Load the pMaskPicture texel */
- i915_fs_texld(FS_R1, FS_S1, FS_T1);
+ if (is_affine_mask) {
+ i915_fs_texld(FS_R1, FS_S1, FS_T1);
+ } else {
+ i915_fs_texldp(FS_R1, FS_S1, FS_T1);
+ }
/* If the texture lacks an alpha channel, force the alpha to 1. */
if (PICT_FORMAT_A(pMaskPicture->format) == 0)
i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
commit f699389818f1f11f3edddcdddcd0a43be21ba4c0
Author: Keith Packard <keithp at keithp.com>
Date: Tue Mar 18 14:06:47 2008 -0700
Add i830_transform_is_affine and i830_get_transformed_coordinates_3d.
These are needed to deal with projective transforms in the composite
operation.
diff --git a/src/i830.h b/src/i830.h
index ee0f03a..512938c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -790,6 +790,9 @@ Bool i830_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
Bool i830_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
PicturePtr pDst, PixmapPtr pSrcPixmap,
PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+Bool
+i830_transform_is_affine (PictTransformPtr t);
+
void i830_composite(PixmapPtr pDst, int srcX, int srcY,
int maskX, int maskY, int dstX, int dstY, int w, int h);
void i830_done_composite(PixmapPtr pDst);
@@ -812,6 +815,10 @@ void
i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
float *x_out, float *y_out);
+void
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+ float *x_out, float *y_out, float *z_out);
+
void i830_enter_render(ScrnInfoPtr);
static inline int i830_fb_compression_supported(I830Ptr pI830)
diff --git a/src/i830_exa.c b/src/i830_exa.c
index bf9fc66..0206ab9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -363,6 +363,45 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
}
}
+**
+ * Returns the un-normalized floating-point coordinates transformed by the given transform.
+ *
+ * transform may be null.
+ */
+void
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+ float *x_out, float *y_out, float *w_out)
+{
+ if (transform == NULL) {
+ *x_out = x;
+ *y_out = y;
+ *w_out = 1;
+ } else {
+ PictVector v;
+
+ v.vector[0] = IntToxFixed(x);
+ v.vector[1] = IntToxFixed(y);
+ v.vector[2] = xFixed1;
+ PictureTransformPoint3d(transform, &v);
+ *x_out = xFixedToFloat(v.vector[0]);
+ *y_out = xFixedToFloat(v.vector[1]);
+ *w_out = xFixedToFloat(v.vector[2]);
+ }
+}
+
+/**
+ * Returns whether the provided transform is affine.
+ *
+ * transform may be null.
+ */
+Bool
+i830_transform_is_affine (PictTransformPtr t)
+{
+ if (t == NULL)
+ return TRUE;
+ return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
+}
+
/*
* TODO:
* - Dual head?
commit a55974b435224fe5726fa44298d051c71e4056a5
Author: Keith Packard <keithp at keithp.com>
Date: Tue Mar 18 13:47:20 2008 -0700
Add defines for 9xx S3 word in 3D_STATE_LOAD_STATE_IMMEDIATE
These aren't used at this point, but what the heck.
diff --git a/src/i915_reg.h b/src/i915_reg.h
index 682a157..4340de9 100644
--- a/src/i915_reg.h
+++ b/src/i915_reg.h
@@ -360,6 +360,16 @@
#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4))
#define S2_TEXCOORD_NONE (~0)
+#define TEXCOORD_WRAP_SHORTEST_TCX 8
+#define TEXCOORD_WRAP_SHORTEST_TCY 4
+#define TEXCOORD_WRAP_SHORTEST_TCZ 2
+#define TEXCOORD_PERSPECTIVE_DISABLE 1
+
+#define S3_WRAP_SHORTEST_TCX(unit) (TEXCOORD_WRAP_SHORTEST_TCX << ((unit) * 4))
+#define S3_WRAP_SHORTEST_TCY(unit) (TEXCOORD_WRAP_SHORTEST_TCY << ((unit) * 4))
+#define S3_WRAP_SHORTEST_TCZ(unit) (TEXCOORD_WRAP_SHORTEST_TCZ << ((unit) * 4))
+#define S3_PERSPECTIVE_DISABLE(unit) (TEXCOORD_PERSPECTIVE_DISABLE << ((unit) * 4))
+
/* S3 not interesting */
#define S4_POINT_WIDTH_SHIFT 23
commit 4f5500abe209b92b39ae1f2d7a1118362ac95034
Author: Keith Packard <keithp at keithp.com>
Date: Tue Mar 18 13:45:46 2008 -0700
8xx/9xx can handle textures to 2kx2k. 965 can do 8kx8k
diff --git a/src/i830_render.c b/src/i830_render.c
index 949c700..78ae40a 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -231,7 +231,7 @@ static Bool i830_check_composite_texture(PicturePtr pPict, int unit)
int h = pPict->pDrawable->height;
int i;
- if ((w > 0x7ff) || (h > 0x7ff))
+ if ((w > 2048) || (h > 2048))
I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
diff --git a/src/i915_render.c b/src/i915_render.c
index b15beef..8ac1b78 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -188,7 +188,7 @@ static Bool i915_check_composite_texture(PicturePtr pPict, int unit)
int h = pPict->pDrawable->height;
int i;
- if ((w > 0x7ff) || (h > 0x7ff))
+ if ((w > 2048) || (h > 2048))
I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
diff --git a/src/i965_render.c b/src/i965_render.c
index 7f798e6..ada3919 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -182,7 +182,7 @@ static Bool i965_check_composite_texture(PicturePtr pPict, int unit)
int h = pPict->pDrawable->height;
int i;
- if ((w > 0x7ff) || (h > 0x7ff))
+ if ((w > 8192) || (h > 8192))
I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
More information about the xorg-commit
mailing list