summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <anholt@FreeBSD.org>2006-05-16 15:21:17 -0700
committerEric Anholt <anholt@FreeBSD.org>2006-05-16 15:21:17 -0700
commitb0ac5303f33f75dc607cf0c705c23db1da836983 (patch)
tree16af9140d0c18dde7b829d7fc63fe727c15c946b /src
parent4c727254da354cfd6f35148a334d046d67a50e99 (diff)
parentc2cd10e1fba0e75c0ed3db5d17211bddf7ab1e33 (diff)
Merge branch 'textured-video' into broadwater-video
Conflicts: src/i830_video.c
Diffstat (limited to 'src')
-rw-r--r--src/common.h12
-rw-r--r--src/i810_reg.h618
-rw-r--r--src/i830_rotate.c172
-rw-r--r--src/i830_video.c968
4 files changed, 1624 insertions, 146 deletions
diff --git a/src/common.h b/src/common.h
index 70f58a94..c8e4fb6b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -125,13 +125,17 @@ extern void I830DPRINTF_stub(const char *filename, int line,
#define ADVANCE_LP_RING() do { \
if (ringused > needed) \
- ErrorF("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ", \
- __FUNCTION__, ringused, needed); \
+ FatalError("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ", \
+ __FUNCTION__, ringused, needed); \
+ else if (ringused < needed) \
+ FatalError("%s: ADVANCE_LP_RING: under-used allocation %d/%d\n ", \
+ __FUNCTION__, ringused, needed); \
RecPtr->LpRing->tail = outring; \
RecPtr->LpRing->space -= ringused; \
if (outring & 0x07) \
- ErrorF("ADVANCE_LP_RING: " \
- "outring (0x%x) isn't on a QWord boundary\n", outring); \
+ FatalError("%s: ADVANCE_LP_RING: " \
+ "outring (0x%x) isn't on a QWord boundary\n", \
+ __FUNCTION__, outring); \
OUTREG(LP_RING + RING_TAIL, outring); \
} while (0)
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 6acdda95..5b9654b2 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -912,6 +912,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I852_GME 0x2
#define I852_GM 0x5
+#define CMD_MI (0 << 29)
+#define CMD_2D (2 << 29)
+#define CMD_3D (3 << 29)
/* BLT commands */
#define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3))
#define COLOR_BLT_WRITE_ALPHA (1<<21)
@@ -942,14 +945,623 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XY_MONO_SRC_BLT_WRITE_RGB (1<<20)
/* 3d state */
+#define STATE3D_ANTI_ALIASING (CMD_3D | (0x06<<24))
+#define LINE_CAP_WIDTH_MODIFY (1 << 16)
+#define LINE_CAP_WIDTH_1_0 (0x1 << 14)
+#define LINE_WIDTH_MODIFY (1 << 8)
+#define LINE_WIDTH_1_0 (0x1 << 6)
+
+#define STATE3D_RASTERIZATION_RULES (CMD_3D | (0x07<<24))
+#define ENABLE_POINT_RASTER_RULE (1<<15)
+#define OGL_POINT_RASTER_RULE (1<<13)
+#define ENABLE_TEXKILL_3D_4D (1<<10)
+#define TEXKILL_3D (0<<9)
+#define TEXKILL_4D (1<<9)
+#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
+#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
+#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
+
+#define STATE3D_INDEPENDENT_ALPHA_BLEND (CMD_3D | (0x0b<<24))
+#define IAB_MODIFY_ENABLE (1<<23)
+#define IAB_ENABLE (1<<22)
+#define IAB_MODIFY_FUNC (1<<21)
+#define IAB_FUNC_SHIFT 16
+#define IAB_MODIFY_SRC_FACTOR (1<<11)
+#define IAB_SRC_FACTOR_SHIFT 6
+#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6)
+#define IAB_MODIFY_DST_FACTOR (1<<5)
+#define IAB_DST_FACTOR_SHIFT 0
+#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0)
+
+#define BLENDFUNC_ADD 0x0
+#define BLENDFUNC_SUBTRACT 0x1
+#define BLENDFUNC_REVERSE_SUBTRACT 0x2
+#define BLENDFUNC_MIN 0x3
+#define BLENDFUNC_MAX 0x4
+#define BLENDFUNC_MASK 0x7
+
+#define BLENDFACT_ZERO 0x01
+#define BLENDFACT_ONE 0x02
+#define BLENDFACT_SRC_COLR 0x03
+#define BLENDFACT_INV_SRC_COLR 0x04
+#define BLENDFACT_SRC_ALPHA 0x05
+#define BLENDFACT_INV_SRC_ALPHA 0x06
+#define BLENDFACT_DST_ALPHA 0x07
+#define BLENDFACT_INV_DST_ALPHA 0x08
+#define BLENDFACT_DST_COLR 0x09
+#define BLENDFACT_INV_DST_COLR 0x0a
+#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b
+#define BLENDFACT_CONST_COLOR 0x0c
+#define BLENDFACT_INV_CONST_COLOR 0x0d
+#define BLENDFACT_CONST_ALPHA 0x0e
+#define BLENDFACT_INV_CONST_ALPHA 0x0f
+#define BLENDFACT_MASK 0x0f
+
+#define STATE3D_MODES_4 (CMD_3D | (0x0d<<24))
+#define ENABLE_LOGIC_OP_FUNC (1<<23)
+#define LOGIC_OP_FUNC(x) ((x)<<18)
+#define LOGICOP_MASK (0xf<<18)
+#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
+#define ENABLE_STENCIL_TEST_MASK (1<<17)
+#define STENCIL_TEST_MASK(x) ((x)<<8)
+#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
+#define ENABLE_STENCIL_WRITE_MASK (1<<16)
+#define STENCIL_WRITE_MASK(x) ((x)&0xff)
+
+#define LOGICOP_CLEAR 0
+#define LOGICOP_NOR 0x1
+#define LOGICOP_AND_INV 0x2
+#define LOGICOP_COPY_INV 0x3
+#define LOGICOP_AND_RVRSE 0x4
+#define LOGICOP_INV 0x5
+#define LOGICOP_XOR 0x6
+#define LOGICOP_NAND 0x7
+#define LOGICOP_AND 0x8
+#define LOGICOP_EQUIV 0x9
+#define LOGICOP_NOOP 0xa
+#define LOGICOP_OR_INV 0xb
+#define LOGICOP_COPY 0xc
+#define LOGICOP_OR_RVRSE 0xd
+#define LOGICOP_OR 0xe
+#define LOGICOP_SET 0xf
+
+#define STATE3D_COORD_SET_BINDINGS (CMD_3D | (0x16<<24))
+#define CSB_TCB(iunit,eunit) ((eunit) << ((iunit) * 3))
+
+#define STATE3D_SCISSOR_ENABLE (CMD_3D | (0x1c<<24)|(0x10<<19))
+#define ENABLE_SCISSOR_RECT ((1<<1) | 1)
+#define DISABLE_SCISSOR_RECT ((1<<1) | 0)
+
+#define STATE3D_MAP_STATE (CMD_3D | (0x1d<<24)|(0x00<<16))
+
+#define MS1_MAPMASK_SHIFT 0
+#define MS1_MAPMASK_MASK (0x8fff<<0)
+
+#define MS2_UNTRUSTED_SURFACE (1<<31)
+#define MS2_ADDRESS_MASK 0xfffffffc
+#define MS2_VERTICAL_LINE_STRIDE (1<<1)
+#define MS2_VERTICAL_OFFSET (1<<1)
+
+#define MS3_HEIGHT_SHIFT 21
+#define MS3_WIDTH_SHIFT 10
+#define MS3_PALETTE_SELECT (1<<9)
+#define MS3_MAPSURF_FORMAT_SHIFT 7
+#define MS3_MAPSURF_FORMAT_MASK (0x7<<7)
+#define MAPSURF_8BIT (1<<7)
+#define MAPSURF_16BIT (2<<7)
+#define MAPSURF_32BIT (3<<7)
+#define MAPSURF_422 (5<<7)
+#define MAPSURF_COMPRESSED (6<<7)
+#define MAPSURF_4BIT_INDEXED (7<<7)
+#define MS3_MT_FORMAT_MASK (0x7 << 3)
+#define MS3_MT_FORMAT_SHIFT 3
+#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */
+#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */
+#define MT_8BIT_L8 (1<<3)
+#define MT_8BIT_A8 (4<<3)
+#define MT_8BIT_MONO8 (5<<3)
+#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */
+#define MT_16BIT_ARGB1555 (1<<3)
+#define MT_16BIT_ARGB4444 (2<<3)
+#define MT_16BIT_AY88 (3<<3)
+#define MT_16BIT_88DVDU (5<<3)
+#define MT_16BIT_BUMP_655LDVDU (6<<3)
+#define MT_16BIT_I16 (7<<3)
+#define MT_16BIT_L16 (8<<3)
+#define MT_16BIT_A16 (9<<3)
+#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */
+#define MT_32BIT_ABGR8888 (1<<3)
+#define MT_32BIT_XRGB8888 (2<<3)
+#define MT_32BIT_XBGR8888 (3<<3)
+#define MT_32BIT_QWVU8888 (4<<3)
+#define MT_32BIT_AXVU8888 (5<<3)
+#define MT_32BIT_LXVU8888 (6<<3)
+#define MT_32BIT_XLVU8888 (7<<3)
+#define MT_32BIT_ARGB2101010 (8<<3)
+#define MT_32BIT_ABGR2101010 (9<<3)
+#define MT_32BIT_AWVU2101010 (0xA<<3)
+#define MT_32BIT_GR1616 (0xB<<3)
+#define MT_32BIT_VU1616 (0xC<<3)
+#define MT_32BIT_xI824 (0xD<<3)
+#define MT_32BIT_xA824 (0xE<<3)
+#define MT_32BIT_xL824 (0xF<<3)
+#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */
+#define MT_422_YCRCB_NORMAL (1<<3)
+#define MT_422_YCRCB_SWAPUV (2<<3)
+#define MT_422_YCRCB_SWAPUVY (3<<3)
+#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */
+#define MT_COMPRESS_DXT2_3 (1<<3)
+#define MT_COMPRESS_DXT4_5 (2<<3)
+#define MT_COMPRESS_FXT1 (3<<3)
+#define MT_COMPRESS_DXT1_RGB (4<<3)
+#define MS3_USE_FENCE_REGS (1<<2)
+#define MS3_TILED_SURFACE (1<<1)
+#define MS3_TILE_WALK (1<<0)
+
+#define MS4_PITCH_SHIFT 21
+#define MS4_CUBE_FACE_ENA_NEGX (1<<20)
+#define MS4_CUBE_FACE_ENA_POSX (1<<19)
+#define MS4_CUBE_FACE_ENA_NEGY (1<<18)
+#define MS4_CUBE_FACE_ENA_POSY (1<<17)
+#define MS4_CUBE_FACE_ENA_NEGZ (1<<16)
+#define MS4_CUBE_FACE_ENA_POSZ (1<<15)
+#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15)
+#define MS4_MAX_LOD_SHIFT 9
+#define MS4_MAX_LOD_MASK (0x3f<<9)
+#define MS4_MIP_LAYOUT_LEGACY (0<<8)
+#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8)
+#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8)
+#define MS4_VOLUME_DEPTH_SHIFT 0
+#define MS4_VOLUME_DEPTH_MASK (0xff<<0)
+
+#define STATE3D_SAMPLER_STATE (CMD_3D | (0x1d<<24)|(0x01<<16))
+
+#define SS1_MAPMASK_SHIFT 0
+#define SS1_MAPMASK_MASK (0x8fff<<0)
+
+#define SS2_REVERSE_GAMMA_ENABLE (1<<31)
+#define SS2_PLANAR_TO_PACKED_ENABLE (1<<30)
+#define SS2_COLORSPACE_CONVERSION (1<<29)
+#define SS2_CHROMAKEY_SHIFT 27
+#define SS2_BASE_MIP_LEVEL_SHIFT 22
+#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22)
+#define SS2_MIP_FILTER_SHIFT 20
+#define SS2_MIP_FILTER_MASK (0x3<<20)
+#define MIPFILTER_NONE 0
+#define MIPFILTER_NEAREST 1
+#define MIPFILTER_LINEAR 3
+#define SS2_MAG_FILTER_SHIFT 17
+#define SS2_MAG_FILTER_MASK (0x7<<17)
+#define FILTER_NEAREST 0
+#define FILTER_LINEAR 1
+#define FILTER_ANISOTROPIC 2
+#define FILTER_4X4_1 3
+#define FILTER_4X4_2 4
+#define FILTER_4X4_FLAT 5
+#define FILTER_6X5_MONO 6 /* XXX - check */
+#define SS2_MIN_FILTER_SHIFT 14
+#define SS2_MIN_FILTER_MASK (0x7<<14)
+#define SS2_LOD_BIAS_SHIFT 5
+#define SS2_LOD_BIAS_ONE (0x10<<5)
+#define SS2_LOD_BIAS_MASK (0x1ff<<5)
+/* Shadow requires:
+ * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format
+ * FILTER_4X4_x MIN and MAG filters
+ */
+#define SS2_SHADOW_ENABLE (1<<4)
+#define SS2_MAX_ANISO_MASK (1<<3)
+#define SS2_MAX_ANISO_2 (0<<3)
+#define SS2_MAX_ANISO_4 (1<<3)
+#define SS2_SHADOW_FUNC_SHIFT 0
+#define SS2_SHADOW_FUNC_MASK (0x7<<0)
+/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */
+
+#define SS3_MIN_LOD_SHIFT 24
+#define SS3_MIN_LOD_ONE (0x10<<24)
+#define SS3_MIN_LOD_MASK (0xff<<24)
+#define SS3_KILL_PIXEL_ENABLE (1<<17)
+#define SS3_TCX_ADDR_MODE_SHIFT 12
+#define SS3_TCX_ADDR_MODE_MASK (0x7<<12)
+#define TEXCOORDMODE_WRAP 0
+#define TEXCOORDMODE_MIRROR 1
+#define TEXCOORDMODE_CLAMP_EDGE 2
+#define TEXCOORDMODE_CUBE 3
+#define TEXCOORDMODE_CLAMP_BORDER 4
+#define TEXCOORDMODE_MIRROR_ONCE 5
+#define SS3_TCY_ADDR_MODE_SHIFT 9
+#define SS3_TCY_ADDR_MODE_MASK (0x7<<9)
+#define SS3_TCZ_ADDR_MODE_SHIFT 6
+#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6)
+#define SS3_NORMALIZED_COORDS (1<<5)
+#define SS3_TEXTUREMAP_INDEX_SHIFT 1
+#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1)
+#define SS3_DEINTERLACER_ENABLE (1<<0)
+
+#define SS4_BORDER_COLOR_MASK (~0)
+
+#define STATE3D_LOAD_STATE_IMMEDIATE_1 (CMD_3D | (0x1d<<24)|(0x04<<16))
+#define I1_LOAD_S(n) (1 << (4 + n))
+
+#define S0_VB_OFFSET_MASK 0xffffffc
+#define S0_AUTO_CACHE_INV_DISABLE (1<<0)
+
+#define S1_VERTEX_WIDTH_SHIFT 24
+#define S1_VERTEX_WIDTH_MASK (0x3f<<24)
+#define S1_VERTEX_PITCH_SHIFT 16
+#define S1_VERTEX_PITCH_MASK (0x3f<<16)
+
+#define TEXCOORDFMT_2D 0x0
+#define TEXCOORDFMT_3D 0x1
+#define TEXCOORDFMT_4D 0x2
+#define TEXCOORDFMT_1D 0x3
+#define TEXCOORDFMT_2D_16 0x4
+#define TEXCOORDFMT_4D_16 0x5
+#define TEXCOORDFMT_NOT_PRESENT 0xf
+#define S2_TEXCOORD_FMT0_MASK 0xf
+#define S2_TEXCOORD_FMT1_SHIFT 4
+#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4))
+#define S2_TEXCOORD_NONE (~0)
+
+/* S3 not interesting */
+
+#define S4_POINT_WIDTH_SHIFT 23
+#define S4_POINT_WIDTH_MASK (0x1ff<<23)
+#define S4_LINE_WIDTH_SHIFT 19
+#define S4_LINE_WIDTH_ONE (0x2<<19)
+#define S4_LINE_WIDTH_MASK (0xf<<19)
+#define S4_FLATSHADE_ALPHA (1<<18)
+#define S4_FLATSHADE_FOG (1<<17)
+#define S4_FLATSHADE_SPECULAR (1<<16)
+#define S4_FLATSHADE_COLOR (1<<15)
+#define S4_CULLMODE_BOTH (0<<13)
+#define S4_CULLMODE_NONE (1<<13)
+#define S4_CULLMODE_CW (2<<13)
+#define S4_CULLMODE_CCW (3<<13)
+#define S4_CULLMODE_MASK (3<<13)
+#define S4_VFMT_POINT_WIDTH (1<<12)
+#define S4_VFMT_SPEC_FOG (1<<11)
+#define S4_VFMT_COLOR (1<<10)
+#define S4_VFMT_DEPTH_OFFSET (1<<9)
+#define S4_VFMT_XYZ (1<<6)
+#define S4_VFMT_XYZW (2<<6)
+#define S4_VFMT_XY (3<<6)
+#define S4_VFMT_XYW (4<<6)
+#define S4_VFMT_XYZW_MASK (7<<6)
+#define S4_FORCE_DEFAULT_DIFFUSE (1<<5)
+#define S4_FORCE_DEFAULT_SPECULAR (1<<4)
+#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3)
+#define S4_VFMT_FOG_PARAM (1<<2)
+#define S4_SPRITE_POINT_ENABLE (1<<1)
+#define S4_LINE_ANTIALIAS_ENABLE (1<<0)
+
+#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \
+ S4_VFMT_SPEC_FOG | \
+ S4_VFMT_COLOR | \
+ S4_VFMT_DEPTH_OFFSET | \
+ S4_VFMT_XYZW_MASK | \
+ S4_VFMT_FOG_PARAM)
+
+
+#define S5_WRITEDISABLE_ALPHA (1<<31)
+#define S5_WRITEDISABLE_RED (1<<30)
+#define S5_WRITEDISABLE_GREEN (1<<29)
+#define S5_WRITEDISABLE_BLUE (1<<28)
+#define S5_WRITEDISABLE_MASK (0xf<<28)
+#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27)
+#define S5_LAST_PIXEL_ENABLE (1<<26)
+#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25)
+#define S5_FOG_ENABLE (1<<24)
+#define S5_STENCIL_REF_SHIFT 16
+#define S5_STENCIL_REF_MASK (0xff<<16)
+#define S5_STENCIL_TEST_FUNC_SHIFT 13
+#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13)
+#define S5_STENCIL_FAIL_SHIFT 10
+#define S5_STENCIL_FAIL_MASK (0x7<<10)
+#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7
+#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7)
+#define S5_STENCIL_PASS_Z_PASS_SHIFT 4
+#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4)
+#define S5_STENCIL_WRITE_ENABLE (1<<3)
+#define S5_STENCIL_TEST_ENABLE (1<<2)
+#define S5_COLOR_DITHER_ENABLE (1<<1)
+#define S5_LOGICOP_ENABLE (1<<0)
+
+
+#define S6_ALPHA_TEST_ENABLE (1<<31)
+#define S6_ALPHA_TEST_FUNC_SHIFT 28
+#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28)
+#define S6_ALPHA_REF_SHIFT 20
+#define S6_ALPHA_REF_MASK (0xff<<20)
+#define S6_DEPTH_TEST_ENABLE (1<<19)
+#define S6_DEPTH_TEST_FUNC_SHIFT 16
+#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16)
+#define S6_CBUF_BLEND_ENABLE (1<<15)
+#define S6_CBUF_BLEND_FUNC_SHIFT 12
+#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12)
+#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8
+#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8)
+#define S6_CBUF_DST_BLEND_FACT_SHIFT 4
+#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4)
+#define S6_DEPTH_WRITE_ENABLE (1<<3)
+#define S6_COLOR_WRITE_ENABLE (1<<2)
+#define S6_TRISTRIP_PV_SHIFT 0
+#define S6_TRISTRIP_PV_MASK (0x3<<0)
+
+#define S7_DEPTH_OFFSET_CONST_MASK ~0
+
+#define STATE3D_PIXEL_SHADER_PROGRAM (CMD_3D | (0x1d<<24)|(0x05<<16))
+
+#define REG_TYPE_R 0 /* temporary regs, no need to
+ * dcl, must be written before
+ * read -- Preserved between
+ * phases.
+ */
+#define REG_TYPE_T 1 /* Interpolated values, must be
+ * dcl'ed before use.
+ *
+ * 0..7: texture coord,
+ * 8: diffuse spec,
+ * 9: specular color,
+ * 10: fog parameter in w.
+ */
+#define REG_TYPE_CONST 2 /* Restriction: only one const
+ * can be referenced per
+ * instruction, though it may be
+ * selected for multiple inputs.
+ * Constants not initialized
+ * default to zero.
+ */
+#define REG_TYPE_S 3 /* sampler */
+#define REG_TYPE_OC 4 /* output color (rgba) */
+#define REG_TYPE_OD 5 /* output depth (w), xyz are
+ * temporaries. If not written,
+ * interpolated depth is used?
+ */
+#define REG_TYPE_U 6 /* unpreserved temporaries */
+#define REG_TYPE_MASK 0x7
+#define REG_NR_MASK 0xf
+
+
+/* REG_TYPE_T:
+ */
+#define T_TEX0 0
+#define T_TEX1 1
+#define T_TEX2 2
+#define T_TEX3 3
+#define T_TEX4 4
+#define T_TEX5 5
+#define T_TEX6 6
+#define T_TEX7 7
+#define T_DIFFUSE 8
+#define T_SPECULAR 9
+#define T_FOG_W 10 /* interpolated fog is in W coord */
+
+/* Arithmetic instructions */
+
+/* .replicate_swizzle == selection and replication of a particular
+ * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww
+ */
+#define A0_NOP (0x0<<24) /* no operation */
+#define A0_ADD (0x1<<24) /* dst = src0 + src1 */
+#define A0_MOV (0x2<<24) /* dst = src0 */
+#define A0_MUL (0x3<<24) /* dst = src0 * src1 */
+#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */
+#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
+#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */
+#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */
+#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */
+#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */
+#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
+#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */
+#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
+#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */
+#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */
+#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */
+#define A0_FLR (0x10<<24) /* dst = floor(src0) */
+#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */
+#define A0_TRC (0x12<<24) /* dst = int(src0) */
+#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */
+#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */
+#define A0_DEST_SATURATE (1<<22)
+#define A0_DEST_TYPE_SHIFT 19
+/* Allow: R, OC, OD, U */
+#define A0_DEST_NR_SHIFT 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define A0_DEST_CHANNEL_X (1<<10)
+#define A0_DEST_CHANNEL_Y (2<<10)
+#define A0_DEST_CHANNEL_Z (4<<10)
+#define A0_DEST_CHANNEL_W (8<<10)
+#define A0_DEST_CHANNEL_ALL (0xf<<10)
+#define A0_DEST_CHANNEL_SHIFT 10
+#define A0_SRC0_TYPE_SHIFT 7
+#define A0_SRC0_NR_SHIFT 2
+
+#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
+#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
+
+
+#define SRC_X 0
+#define SRC_Y 1
+#define SRC_Z 2
+#define SRC_W 3
+#define SRC_ZERO 4
+#define SRC_ONE 5
+
+#define A1_SRC0_CHANNEL_X_NEGATE (1<<31)
+#define A1_SRC0_CHANNEL_X_SHIFT 28
+#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27)
+#define A1_SRC0_CHANNEL_Y_SHIFT 24
+#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23)
+#define A1_SRC0_CHANNEL_Z_SHIFT 20
+#define A1_SRC0_CHANNEL_W_NEGATE (1<<19)
+#define A1_SRC0_CHANNEL_W_SHIFT 16
+#define A1_SRC1_TYPE_SHIFT 13
+#define A1_SRC1_NR_SHIFT 8
+#define A1_SRC1_CHANNEL_X_NEGATE (1<<7)
+#define A1_SRC1_CHANNEL_X_SHIFT 4
+#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3)
+#define A1_SRC1_CHANNEL_Y_SHIFT 0
+
+#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31)
+#define A2_SRC1_CHANNEL_Z_SHIFT 28
+#define A2_SRC1_CHANNEL_W_NEGATE (1<<27)
+#define A2_SRC1_CHANNEL_W_SHIFT 24
+#define A2_SRC2_TYPE_SHIFT 21
+#define A2_SRC2_NR_SHIFT 16
+#define A2_SRC2_CHANNEL_X_NEGATE (1<<15)
+#define A2_SRC2_CHANNEL_X_SHIFT 12
+#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11)
+#define A2_SRC2_CHANNEL_Y_SHIFT 8
+#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7)
+#define A2_SRC2_CHANNEL_Z_SHIFT 4
+#define A2_SRC2_CHANNEL_W_NEGATE (1<<3)
+#define A2_SRC2_CHANNEL_W_SHIFT 0
+
+
+
+/* Texture instructions */
+#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared
+ * sampler and address, and output
+ * filtered texel data to destination
+ * register */
+#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a
+ * perspective divide of the texture
+ * coordinate .xyz values by .w before
+ * sampling. */
+#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the
+ * computed LOD by w. Only S4.6 two's
+ * comp is used. This implies that a
+ * float to fixed conversion is
+ * done. */
+#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling
+ * operation. Simply kills the pixel
+ * if any channel of the address
+ * register is < 0.0. */
+#define T0_DEST_TYPE_SHIFT 19
+/* Allow: R, OC, OD, U */
+/* Note: U (unpreserved) regs do not retain their values between
+ * phases (cannot be used for feedback)
+ *
+ * Note: oC and OD registers can only be used as the destination of a
+ * texture instruction once per phase (this is an implementation
+ * restriction).
+ */
+#define T0_DEST_NR_SHIFT 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */
+#define T0_SAMPLER_NR_MASK (0xf<<0)
+
+#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */
+/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
+#define T1_ADDRESS_REG_NR_SHIFT 17
+#define T2_MBZ 0
+
+/* Declaration instructions */
+#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib)
+ * register or an s (sampler)
+ * register. */
+#define D0_SAMPLE_TYPE_SHIFT 22
+#define D0_SAMPLE_TYPE_2D (0x0<<22)
+#define D0_SAMPLE_TYPE_CUBE (0x1<<22)
+#define D0_SAMPLE_TYPE_VOLUME (0x2<<22)
+#define D0_SAMPLE_TYPE_MASK (0x3<<22)
+
+#define D0_TYPE_SHIFT 19
+/* Allow: T, S */
+#define D0_NR_SHIFT 14
+/* Allow T: 0..10, S: 0..15 */
+#define D0_CHANNEL_X (1<<10)
+#define D0_CHANNEL_Y (2<<10)
+#define D0_CHANNEL_Z (4<<10)
+#define D0_CHANNEL_W (8<<10)
+#define D0_CHANNEL_ALL (0xf<<10)
+#define D0_CHANNEL_NONE (0<<10)
+
+#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y)
+#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z)
+/* End description of STATE3D_PIXEL_SHADER_PROGRAM */
+
+#define STATE3D_PIXEL_SHADER_CONSTANTS (CMD_3D | (0x1d<<24)|(0x06<<16))
+
+#define STATE3D_DRAWING_RECTANGLE (CMD_3D | (0x1d<<24)|(0x80<<16)|3)
+
+#define STATE3D_SCISSOR_RECTANGLE (CMD_3D | (0x1d<<24)|(0x81<<16)|1)
+
+#define STATE3D_STIPPLE (CMD_3D | (0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE (1<<16)
+#define ST1_MASK (0xffff)
+
+#define STATE3D_DEST_BUFFER_VARIABLES (CMD_3D | (0x1d<<24)|(0x85<<16))
+#define TEX_DEFAULT_COLOR_OGL (0<<30)
+#define TEX_DEFAULT_COLOR_D3D (1<<30)
+#define ZR_EARLY_DEPTH (1<<29)
+#define LOD_PRECLAMP_OGL (1<<28)
+#define LOD_PRECLAMP_D3D (0<<28)
+#define DITHER_FULL_ALWAYS (0<<26)
+#define DITHER_FULL_ON_FB_BLEND (1<<26)
+#define DITHER_CLAMPED_ALWAYS (2<<26)
+#define LINEAR_GAMMA_BLEND_32BPP (1<<25)
+#define DEBUG_DISABLE_ENH_DITHER (1<<24)
+#define DSTORG_HORIZ_BIAS(x) ((x)<<20)
+#define DSTORG_VERT_BIAS(x) ((x)<<16)
+#define COLOR_4_2_2_CHNL_WRT_ALL 0
+#define COLOR_4_2_2_CHNL_WRT_Y (1<<12)
+#define COLOR_4_2_2_CHNL_WRT_CR (2<<12)
+#define COLOR_4_2_2_CHNL_WRT_CB (3<<12)
+#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12)
+#define COLR_BUF_8BIT 0
+#define COLR_BUF_RGB555 (1<<8)
+#define COLR_BUF_RGB565 (2<<8)
+#define COLR_BUF_ARGB8888 (3<<8)
+#define DEPTH_FRMT_16_FIXED 0
+#define DEPTH_FRMT_16_FLOAT (1<<2)
+#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2)
+#define VERT_LINE_STRIDE_1 (1<<1)
+#define VERT_LINE_STRIDE_0 (0<<1)
+#define VERT_LINE_STRIDE_OFS_1 1
+#define VERT_LINE_STRIDE_OFS_0 0
+
+#define STATE3D_CONST_BLEND_COLOR (CMD_3D | (0x1d<<24)|(0x88<<16))
+
#define STATE3D_FOG_MODE ((3<<29)|(0x1d<<24)|(0x89<<16)|2)
#define FOG_MODE_VERTEX (1<<31)
#define STATE3D_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16))
+
+#define STATE3D_BUFFER_INFO (CMD_3D | (0x1d<<24)|(0x8e<<16)|1)
+#define BUFFERID_COLOR_BACK (3 << 24)
+#define BUFFERID_COLOR_AUX (4 << 24)
+#define BUFFERID_MC_INTRA_CORR (5 << 24)
+#define BUFFERID_DEPTH (7 << 24)
+#define BUFFER_USE_FENCES (1 << 23)
+
+#define STATE3D_DFLT_Z_CMD (CMD_3D | (0x1d<<24)|(0x98<<16))
+
+#define STATE3D_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24)|(0x99<<16))
+
+#define STATE3D_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24)|(0x9a<<16))
+
+#define PRIMITIVE3D (CMD_3D | (0x1f<<24))
+#define PRIM3D_INLINE (0<<23)
+#define PRIM3D_INDIRECT (1<<23)
+#define PRIM3D_TRILIST (0x0<<18)
+#define PRIM3D_TRISTRIP (0x1<<18)
+#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
+#define PRIM3D_TRIFAN (0x3<<18)
+#define PRIM3D_POLY (0x4<<18)
+#define PRIM3D_LINELIST (0x5<<18)
+#define PRIM3D_LINESTRIP (0x6<<18)
+#define PRIM3D_RECTLIST (0x7<<18)
+#define PRIM3D_POINTLIST (0x8<<18)
+#define PRIM3D_DIB (0x9<<18)
+#define PRIM3D_CLEAR_RECT (0xa<<18)
+#define PRIM3D_ZONE_INIT (0xd<<18)
+#define PRIM3D_MASK (0x1f<<18)
+
+
#define DISABLE_TEX_TRANSFORM (1<<28)
#define TEXTURE_SET(x) (x<<29)
-#define STATE3D_RASTERIZATION_RULES ((3<<29)|(0x07<<24))
-#define POINT_RASTER_ENABLE (1<<15)
-#define POINT_RASTER_OGL (1<<13)
+
#define STATE3D_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16))
#define DISABLE_VIEWPORT_TRANSFORM (1<<31)
#define DISABLE_PERSPECTIVE_DIVIDE (1<<29)
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index 82b2c5d9..e211b369 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -214,6 +214,7 @@ I915UpdateRotate (ScreenPtr pScreen,
drm_context_t myContext = 0;
#endif
Bool didLock = FALSE;
+ CARD32 format;
if (I830IsPrimary(pScrn)) {
pI8301 = pI830;
@@ -267,86 +268,139 @@ I915UpdateRotate (ScreenPtr pScreen,
BEGIN_LP_RING(64);
/* invarient state */
OUT_RING(MI_NOOP);
- OUT_RING(0x66014140);
- OUT_RING(0x7d990000);
- OUT_RING(0x00000000);
- OUT_RING(0x7d9a0000);
+ OUT_RING(STATE3D_ANTI_ALIASING |
+ LINE_CAP_WIDTH_MODIFY | LINE_CAP_WIDTH_1_0 |
+ LINE_WIDTH_MODIFY | LINE_WIDTH_1_0);
+
+ OUT_RING(STATE3D_DFLT_DIFFUSE_CMD);
OUT_RING(0x00000000);
- OUT_RING(0x7d980000);
+
+ OUT_RING(STATE3D_DFLT_SPEC_CMD);
OUT_RING(0x00000000);
- OUT_RING(0x76fac688);
- OUT_RING(0x6700a770);
- OUT_RING(0x7d040081);
+
+ OUT_RING(STATE3D_DFLT_Z_CMD);
OUT_RING(0x00000000);
+
+ OUT_RING(STATE3D_COORD_SET_BINDINGS | CSB_TCB(0, 0) | CSB_TCB(1, 1) |
+ CSB_TCB(2,2) | CSB_TCB(3,3) | CSB_TCB(4,4) | CSB_TCB(5,5) |
+ CSB_TCB(6,6) | CSB_TCB(7,7));
+
+ OUT_RING(STATE3D_RASTERIZATION_RULES |
+ ENABLE_TRI_FAN_PROVOKE_VRTX | TRI_FAN_PROVOKE_VRTX(2) |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) |
+ ENABLE_TEXKILL_3D_4D | TEXKILL_4D |
+ ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
+
+ OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
+ OUT_RING(0x00000000); /* texture coordinate wrap */
+
/* flush map & render cache */
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(0x00000000);
+
/* draw rect */
- OUT_RING(0x7d800003);
- OUT_RING(0x00000000);
- OUT_RING(0x00000000);
- OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16);
- OUT_RING(0x00000000);
- OUT_RING(0x00000000);
+ OUT_RING(STATE3D_DRAWING_RECTANGLE);
+ OUT_RING(0x00000000); /* flags */
+ OUT_RING(0x00000000); /* ymin, xmin */
+ OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+ OUT_RING(0x00000000); /* yorigin, xorigin */
+ OUT_RING(MI_NOOP);
+
/* scissor */
- OUT_RING(0x7c800002);
- OUT_RING(0x7d810001);
- OUT_RING(0x00000000);
- OUT_RING(0x00000000);
- OUT_RING(0x7c000003);
+ OUT_RING(STATE3D_SCISSOR_ENABLE | DISABLE_SCISSOR_RECT);
+ OUT_RING(STATE3D_SCISSOR_RECTANGLE);
+ OUT_RING(0x00000000); /* ymin, xmin */
+ OUT_RING(0x00000000); /* ymax, xmax */
+
+ OUT_RING(0x7c000003); /* unknown command */
OUT_RING(0x7d070000);
OUT_RING(0x00000000);
OUT_RING(0x68000002);
+
/* context setup */
- OUT_RING(0x6db3ffff);
- OUT_RING(0x7d040744);
- OUT_RING(0xfffffff0);
- OUT_RING(0x00902c80);
+ OUT_RING(STATE3D_MODES_4 |
+ ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
+ ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
+ ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
+
+ OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
+ I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
+ OUT_RING(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
+ S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
+ OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
+ S4_CULLMODE_NONE | S4_VFMT_SPEC_FOG | S4_VFMT_COLOR |
+ S4_VFMT_XYZW);
+ OUT_RING(0x00000000); /* S5 -- enable bits */
+ OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
+ (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+ (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE |
+ (2 << S6_TRISTRIP_PV_SHIFT));
+
+ OUT_RING(STATE3D_INDEPENDENT_ALPHA_BLEND |
+ IAB_MODIFY_ENABLE |
+ IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
+ IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) |
+ IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT));
+
+ OUT_RING(STATE3D_CONST_BLEND_COLOR);
OUT_RING(0x00000000);
- OUT_RING(0x00020216);
- OUT_RING(0x6ba008a1);
- OUT_RING(0x7d880000);
- OUT_RING(0x00000000);
- /* dv0 */
- OUT_RING(0x7d850000);
- /* dv1 */
+
+ OUT_RING(STATE3D_DEST_BUFFER_VARIABLES);
if (pI830->cpp == 1)
- OUT_RING(0x10880000);
+ format = COLR_BUF_8BIT;
else if (pI830->cpp == 2)
- OUT_RING(0x10880200);
- else
- OUT_RING(0x10880308);
- /* stipple */
- OUT_RING(0x7d830000);
+ format = COLR_BUF_RGB565;
+ else
+ format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
+
+ OUT_RING(LOD_PRECLAMP_OGL |
+ DSTORG_HORIZ_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
+
+ OUT_RING(STATE3D_STIPPLE);
OUT_RING(0x00000000);
+
/* fragment program - texture blend replace*/
- OUT_RING(0x7d050008);
- OUT_RING(0x19180000);
+ OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
+ OUT_RING(D0_DCL | (REG_TYPE_S << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT));
OUT_RING(0x00000000);
OUT_RING(0x00000000);
- OUT_RING(0x19083c00);
+
+ OUT_RING(D0_DCL | (REG_TYPE_T << D0_TYPE_SHIFT) | (0 << D0_NR_SHIFT) |
+ D0_CHANNEL_ALL);
OUT_RING(0x00000000);
OUT_RING(0x00000000);
- OUT_RING(0x15200000);
- OUT_RING(0x01000000);
+
+ OUT_RING(T0_TEXLD | (REG_TYPE_OC << T0_DEST_TYPE_SHIFT) |
+ (0 << T0_SAMPLER_NR_SHIFT));
+ OUT_RING((REG_TYPE_T << T1_ADDRESS_REG_TYPE_SHIFT) |
+ (0 << T1_ADDRESS_REG_NR_SHIFT));
OUT_RING(0x00000000);
- /* texture sampler state */
- OUT_RING(0x7d010003);
+ /* End fragment program */
+
+ OUT_RING(STATE3D_SAMPLER_STATE | 3);
OUT_RING(0x00000001);
OUT_RING(0x00000000);
OUT_RING(0x00000000);
OUT_RING(0x00000000);
+
/* front buffer, pitch, offset */
- OUT_RING(0x7d8e0001);
- OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+ OUT_RING(STATE3D_BUFFER_INFO);
+ OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
+ (((pI830->displayWidth * pI830->cpp) / 4) << 2));
if (I830IsPrimary(pScrn))
OUT_RING(pI830->FrontBuffer.Start);
else
OUT_RING(pI8301->FrontBuffer2.Start);
/* Set the entire frontbuffer up as a texture */
- OUT_RING(0x7d000003);
- OUT_RING(0x00000001);
+ OUT_RING(STATE3D_MAP_STATE | 3);
+ OUT_RING(0x00000001); /* texture map #1 */
if (I830IsPrimary(pScrn))
OUT_RING(pI830->RotatedMem.Start);
@@ -356,15 +410,15 @@ I915UpdateRotate (ScreenPtr pScreen,
if (pI830->disableTiling)
use_fence = 0;
else
- use_fence = 4;
+ use_fence = MS3_USE_FENCE_REGS;
if (pI830->cpp == 1)
- use_fence |= 0x80; /* MAPSURF_8BIT */
+ use_fence |= MAPSURF_8BIT;
else
if (pI830->cpp == 2)
- use_fence |= 0x100; /* MAPSURF_16BIT */
+ use_fence |= MAPSURF_16BIT;
else
- use_fence |= 0x180; /* MAPSURF_32BIT */
+ use_fence |= MAPSURF_32BIT;
OUT_RING(use_fence | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10);
OUT_RING(((((pScrn->displayWidth * pI830->cpp) / 4) - 1) << 21));
ADVANCE_LP_RING();
@@ -395,7 +449,7 @@ I915UpdateRotate (ScreenPtr pScreen,
OUT_RING(MI_NOOP);
/* vertex data */
- OUT_RING(0x7f0c001f);
+ OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN | (32 - 1));
verts[0][0] = box_x1; verts[0][1] = box_y1;
verts[1][0] = box_x2; verts[1][1] = box_y1;
verts[2][0] = box_x2; verts[2][1] = box_y2;
@@ -520,15 +574,15 @@ I830UpdateRotate (ScreenPtr pScreen,
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(0x00000000);
/* draw rect */
- OUT_RING(0x7d800003);
- OUT_RING(0x00000000);
- OUT_RING(0x00000000);
- OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16);
- OUT_RING(0x00000000);
- OUT_RING(0x00000000);
+ OUT_RING(STATE3D_DRAWING_RECTANGLE);
+ OUT_RING(0x00000000); /* flags */
+ OUT_RING(0x00000000); /* ymin, xmin */
+ OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+ OUT_RING(0x00000000); /* yorigin, xorigin */
+ OUT_RING(MI_NOOP);
/* front buffer */
- OUT_RING(0x7d8e0001);
+ OUT_RING(STATE3D_BUFFER_INFO);
OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
if (I830IsPrimary(pScrn))
OUT_RING(pI830->FrontBuffer.Start);
diff --git a/src/i830_video.c b/src/i830_video.c
index 8ae19062..dc0f8e17 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -99,7 +99,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void I830InitOffscreenImages(ScreenPtr);
-static XF86VideoAdaptorPtr I830SetupImageVideo(ScreenPtr);
+static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr);
+static XF86VideoAdaptorPtr I830SetupImageVideoTextured(ScreenPtr);
static void I830StopVideo(ScrnInfoPtr, pointer, Bool);
static int I830SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
static int I830GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
@@ -109,8 +110,10 @@ static void I830QueryBestSize(ScrnInfoPtr, Bool,
static int I830PutImage(ScrnInfoPtr, short, short, short, short, short, short,
short, short, int, unsigned char *, short, short,
Bool, RegionPtr, pointer, DrawablePtr);
-static int I830QueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
- unsigned short *, int *, int *);
+static int I830QueryImageAttributesOverlay(ScrnInfoPtr, int, unsigned short *,
+ unsigned short *, int *, int *);
+static int I830QueryImageAttributesTextured(ScrnInfoPtr, int, unsigned short *,
+ unsigned short *, int *, int *);
static void I830BlockHandler(int, pointer, pointer, pointer);
@@ -286,6 +289,12 @@ static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
};
+#define NUM_TEXTURED_ATTRIBUTES 2
+static XF86AttributeRec TexturedAttributes[NUM_ATTRIBUTES] = {
+ {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+};
+
#define GAMMA_ATTRIBUTES 6
static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
@@ -394,6 +403,7 @@ typedef struct {
Bool overlayOK;
int oneLineMode;
int scaleRatio;
+ Bool textured;
} I830PortPrivRec, *I830PortPrivPtr;
#define GET_PORT_PRIVATE(pScrn) \
@@ -424,8 +434,9 @@ void
I830InitVideo(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
- XF86VideoAdaptorPtr newAdaptor = NULL;
+ XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
int num_adaptors;
DPRINTF(PFX, "I830InitVideo\n");
@@ -444,35 +455,54 @@ I830InitVideo(ScreenPtr pScreen)
}
#endif
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+ /* Give our adaptor list enough space for the overlay and/or texture video
+ * adaptors.
+ */
+ newAdaptors = xalloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
+ if (newAdaptors == NULL)
+ return;
+
+ memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ adaptors = newAdaptors;
+
+ /* Add the adaptors supported by our hardware. First, set up the atoms
+ * that will be used by both output adaptors.
+ */
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+
+ /* Set up overlay video if we can do it at this depth. */
if (pScrn->bitsPerPixel != 8) {
- newAdaptor = I830SetupImageVideo(pScreen);
+ overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
+ if (overlayAdaptor != NULL) {
+ adaptors[num_adaptors++] = overlayAdaptor;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to set up overlay video\n");
+ }
I830InitOffscreenImages(pScreen);
}
- num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
-
- if (newAdaptor) {
- if (!num_adaptors) {
- num_adaptors = 1;
- adaptors = &newAdaptor;
+ /* Set up textured video if we can do it at this depth and we are on
+ * supported hardware.
+ */
+ if (pScrn->bitsPerPixel >= 16 && IS_I9XX(pI830)) {
+ texturedAdaptor = I830SetupImageVideoTextured(pScreen);
+ if (texturedAdaptor != NULL) {
+ adaptors[num_adaptors++] = texturedAdaptor;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
} else {
- newAdaptors = /* need to free this someplace */
- xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
- if (newAdaptors) {
- memcpy(newAdaptors, adaptors, num_adaptors *
- sizeof(XF86VideoAdaptorPtr));
- newAdaptors[num_adaptors] = newAdaptor;
- adaptors = newAdaptors;
- num_adaptors++;
- }
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to set up textured video\n");
}
}
if (num_adaptors)
xf86XVScreenInit(pScreen, adaptors, num_adaptors);
- if (newAdaptors)
- xfree(newAdaptors);
+ xfree(adaptors);
}
static void
@@ -644,7 +674,7 @@ I830UpdateGamma(ScrnInfoPtr pScrn)
}
static XF86VideoAdaptorPtr
-I830SetupImageVideo(ScreenPtr pScreen)
+I830SetupImageVideoOverlay(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
@@ -652,7 +682,7 @@ I830SetupImageVideo(ScreenPtr pScreen)
I830PortPrivPtr pPriv;
XF86AttributePtr att;
- DPRINTF(PFX, "I830SetupImageVideo\n");
+ DPRINTF(PFX, "I830SetupImageVideoOverlay\n");
if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
sizeof(I830PortPrivRec) + sizeof(DevUnion))))
@@ -705,8 +735,9 @@ I830SetupImageVideo(ScreenPtr pScreen)
adapt->GetPortAttribute = I830GetPortAttribute;
adapt->QueryBestSize = I830QueryBestSize;
adapt->PutImage = I830PutImage;
- adapt->QueryImageAttributes = I830QueryImageAttributes;
+ adapt->QueryImageAttributes = I830QueryImageAttributesOverlay;
+ pPriv->textured = FALSE;
pPriv->colorKey = pI830->colorKey & ((1 << pScrn->depth) - 1);
pPriv->videoStatus = 0;
pPriv->brightness = 0;
@@ -744,8 +775,6 @@ I830SetupImageVideo(ScreenPtr pScreen)
pScreen->BlockHandler = I830BlockHandler;
xvColorKey = MAKE_ATOM("XV_COLORKEY");
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
/* Allow the pipe to be switched from pipe A to B when in clone mode */
@@ -768,6 +797,86 @@ I830SetupImageVideo(ScreenPtr pScreen)
return adapt;
}
+static XF86VideoAdaptorPtr
+I830SetupImageVideoTextured(ScreenPtr pScreen)
+{
+ XF86VideoAdaptorPtr adapt;
+ XF86VideoEncodingPtr encoding;
+ XF86AttributePtr attrs;
+ I830PortPrivPtr portPrivs;
+ DevUnion *devUnions;
+ int nports = 16, i;
+ int nAttributes;
+
+ DPRINTF(PFX, "I830SetupImageVideoOverlay\n");
+
+ nAttributes = NUM_TEXTURED_ATTRIBUTES;
+
+ adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec));
+ portPrivs = xcalloc(nports, sizeof(I830PortPrivRec));
+ devUnions = xcalloc(nports, sizeof(DevUnion));
+ encoding = xcalloc(1, sizeof(XF86VideoEncodingRec));
+ attrs = xcalloc(nAttributes, sizeof(XF86AttributeRec));
+ if (adapt == NULL || portPrivs == NULL || devUnions == NULL ||
+ encoding == NULL || attrs == NULL)
+ {
+ xfree(adapt);
+ xfree(portPrivs);
+ xfree(devUnions);
+ xfree(encoding);
+ xfree(attrs);
+ return NULL;
+ }
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = 0;
+ adapt->name = "Intel(R) Textured Video";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = encoding;
+ adapt->pEncodings[0].id = 0;
+ adapt->pEncodings[0].name = "XV_IMAGE";
+ adapt->pEncodings[0].width = 2048;
+ adapt->pEncodings[0].height = 2048;
+ adapt->pEncodings[0].rate.numerator = 1;
+ adapt->pEncodings[0].rate.denominator = 1;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = nports;
+ adapt->pPortPrivates = devUnions;
+ adapt->nAttributes = nAttributes;
+ adapt->pAttributes = attrs;
+ memcpy(attrs, TexturedAttributes, nAttributes * sizeof(XF86AttributeRec));
+ adapt->nImages = NUM_IMAGES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = I830StopVideo;
+ adapt->SetPortAttribute = I830SetPortAttribute;
+ adapt->GetPortAttribute = I830GetPortAttribute;
+ adapt->QueryBestSize = I830QueryBestSize;
+ adapt->PutImage = I830PutImage;
+ adapt->QueryImageAttributes = I830QueryImageAttributesTextured;
+
+ for (i = 0; i < nports; i++) {
+ I830PortPrivPtr pPriv = &portPrivs[i];
+
+ pPriv->textured = TRUE;
+ pPriv->videoStatus = 0;
+ pPriv->linear = NULL;
+ pPriv->currentBuf = 0;
+ pPriv->doubleBuffer = 0;
+
+ /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
+ REGION_NULL(pScreen, &pPriv->clip);
+
+ adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
+ }
+
+ return adapt;
+}
+
static Bool
RegionsEqual(RegionPtr A, RegionPtr B)
{
@@ -805,6 +914,9 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
I830OverlayRegPtr overlay =
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ if (pPriv->textured)
+ return;
+
DPRINTF(PFX, "I830StopVideo\n");
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
@@ -844,6 +956,14 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
I830OverlayRegPtr overlay =
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ if (pPriv->textured) {
+ /* XXX: Currently the brightness/saturation attributes aren't hooked up.
+ * However, apps expect them to be there, and the spec seems to let us
+ * sneak out of actually implementing them for now.
+ */
+ return Success;
+ }
+
if (attribute == xvBrightness) {
if ((value < -128) || (value > 127))
return BadValue;
@@ -996,13 +1116,12 @@ I830QueryBestSize(ScrnInfoPtr pScrn,
}
static void
-I830CopyPackedData(ScrnInfoPtr pScrn,
+I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
unsigned char *buf,
int srcPitch,
int dstPitch, int top, int left, int h, int w)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
unsigned char *src, *dst;
int i,j;
unsigned char *s;
@@ -1090,13 +1209,72 @@ I830CopyPackedData(ScrnInfoPtr pScrn,
}
}
+/* Copies planar data in *buf to UYVY-packed data in the screen atYBufXOffset.
+ */
+static void
+I830CopyPlanarToPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+ unsigned char *buf, int srcPitch,
+ int srcPitch2, int dstPitch, int srcH,
+ int top, int left, int h, int w, int id)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD8 *dst1, *srcy, *srcu, *srcv;
+ int y;
+
+ if (pPriv->currentBuf == 0)
+ dst1 = pI830->FbBase + pPriv->YBuf0offset;
+ else
+ dst1 = pI830->FbBase + pPriv->YBuf1offset;
+
+ srcy = buf + (top * srcPitch) + left;
+ if (id == FOURCC_YV12) {
+ srcu = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
+ srcv = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
+ ((top / 2) * srcPitch2) + (left / 2);
+ } else {
+ srcv = buf + (srcH * srcPitch) + ((top / 2) * srcPitch2) + (left / 2);
+ srcu = buf + (srcH * srcPitch) + ((srcH / 2) * srcPitch2) +
+ ((top / 2) * srcPitch2) + (left / 2);
+ }
+
+ for (y = 0; y < h; y++) {
+ CARD32 *dst = (CARD32 *)dst1;
+ CARD8 *sy = srcy;
+ CARD8 *su = srcu;
+ CARD8 *sv = srcv;
+ int i;
+
+ i = w / 2;
+ while(i > 4) {
+ dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
+ dst[1] = sy[2] | (sy[3] << 16) | (sv[1] << 8) | (su[1] << 24);
+ dst[2] = sy[4] | (sy[5] << 16) | (sv[2] << 8) | (su[2] << 24);
+ dst[3] = sy[6] | (sy[7] << 16) | (sv[3] << 8) | (su[3] << 24);
+ dst += 4; su += 4; sv += 4; sy += 8;
+ i -= 4;
+ }
+ while(i--) {
+ dst[0] = sy[0] | (sy[1] << 16) | (sv[0] << 8) | (su[0] << 24);
+ dst++; su++; sv++;
+ sy += 2;
+ }
+
+ dst1 += dstPitch;
+ srcy += srcPitch;
+ if (y & 1) {
+ srcu += srcPitch2;
+ srcv += srcPitch2;
+ }
+ }
+}
+
static void
-I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
+I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+ unsigned char *buf, int srcPitch,
int srcPitch2, int dstPitch, int srcH, int top, int left,
int h, int w, int id)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
int i, j = 0;
unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
unsigned char *s;
@@ -1866,6 +2044,569 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
OVERLAY_UPDATE;
}
+/* Doesn't matter on the order for our purposes */
+typedef struct {
+ unsigned char red, green, blue, alpha;
+} intel_color_t;
+
+/* Vertex format */
+typedef union {
+ struct {
+ float x, y, z, w;
+ intel_color_t color;
+ intel_color_t specular;
+ float u0, v0;
+ float u1, v1;
+ float u2, v2;
+ float u3, v3;
+ } v;
+ float f[24];
+ unsigned int ui[24];
+ unsigned char ub4[24][4];
+} intelVertex, *intelVertexPtr;
+
+static void draw_poly(CARD32 *vb,
+ float verts[][2],
+ float texcoords[][2],
+ float texcoords2[][2])
+{
+ int vertex_size;
+ intelVertex tmp;
+ int i, k;
+
+ if (texcoords2 != NULL)
+ vertex_size = 10;
+ else
+ vertex_size = 8;
+
+ /* initial constant vertex fields */
+ tmp.v.z = 1.0;
+ tmp.v.w = 1.0;
+ tmp.v.color.red = 255;
+ tmp.v.color.green = 255;
+ tmp.v.color.blue = 255;
+ tmp.v.color.alpha = 255;
+ tmp.v.specular.red = 0;
+ tmp.v.specular.green = 0;
+ tmp.v.specular.blue = 0;
+ tmp.v.specular.alpha = 0;
+
+ for (k = 0; k < 4; k++) {
+ tmp.v.x = verts[k][0];
+ tmp.v.y = verts[k][1];
+ tmp.v.u0 = texcoords[k][0];
+ tmp.v.v0 = texcoords[k][1];
+ if (texcoords2 != NULL) {
+ tmp.v.u1 = texcoords2[k][0];
+ tmp.v.v1 = texcoords2[k][1];
+ }
+
+ for (i = 0 ; i < vertex_size ; i++)
+ vb[i] = tmp.ui[i];
+
+ vb += vertex_size;
+ }
+}
+
+union intfloat {
+ CARD32 ui;
+ float f;
+};
+
+#define OUT_RING_F(x) do { \
+ union intfloat _tmp; \
+ _tmp.f = x; \
+ OUT_RING(_tmp.ui); \
+} while (0)
+
+#define OUT_DCL(type, nr) do { \
+ CARD32 chans = 0; \
+ if (REG_TYPE_##type == REG_TYPE_T) \
+ chans = D0_CHANNEL_ALL; \
+ else if (REG_TYPE_##type != REG_TYPE_S) \
+ FatalError("wrong reg type %d to declare\n", REG_TYPE_##type); \
+ OUT_RING(D0_DCL | \
+ (REG_TYPE_##type << D0_TYPE_SHIFT) | (nr << D0_NR_SHIFT) | \
+ chans); \
+ OUT_RING(0x00000000); \
+ OUT_RING(0x00000000); \
+} while (0)
+
+#define OUT_TEXLD(dest_type, dest_nr, sampler_nr, addr_type, addr_nr) \
+do { \
+ OUT_RING(T0_TEXLD | \
+ (REG_TYPE_##dest_type << T0_DEST_TYPE_SHIFT) | \
+ (dest_nr << T0_DEST_NR_SHIFT) | \
+ (sampler_nr << T0_SAMPLER_NR_SHIFT)); \
+ OUT_RING((REG_TYPE_##addr_type << T1_ADDRESS_REG_TYPE_SHIFT) | \
+ (addr_nr << T1_ADDRESS_REG_NR_SHIFT)); \
+ OUT_RING(0x00000000); \
+} while (0)
+
+/* Move the dest_chan from src0 to dest, leaving the other channels alone */
+#define OUT_MOV_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr, \
+ dest_chan) \
+do { \
+ OUT_RING(A0_MOV | A0_DEST_CHANNEL_##dest_chan | \
+ (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) | \
+ (dest_nr << A0_DEST_NR_SHIFT) | \
+ (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) | \
+ (src0_nr << A0_SRC0_NR_SHIFT)); \
+ OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \
+ (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \
+ (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \
+ (SRC_W << A1_SRC0_CHANNEL_W_SHIFT)); \
+ OUT_RING(0); \
+} while (0)
+
+/* Dot3-product src0 and src1, storing the result in dest_chan of the dest.
+ * Saturates, in case we have out-of-range YUV values.
+ */
+#define OUT_DP3_TO_CHANNEL(dest_type, dest_nr, src0_type, src0_nr, \
+ src1_type, src1_nr, dest_chan) \
+do { \
+ OUT_RING(A0_DP3 | A0_DEST_CHANNEL_##dest_chan | A0_DEST_SATURATE | \
+ (REG_TYPE_##dest_type << A0_DEST_TYPE_SHIFT) | \
+ (dest_nr << A0_DEST_NR_SHIFT) | \
+ (REG_TYPE_##src0_type << A0_SRC0_TYPE_SHIFT) | \
+ (src0_nr << A0_SRC0_NR_SHIFT)); \
+ OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \
+ (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \
+ (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \
+ (SRC_W << A1_SRC0_CHANNEL_W_SHIFT) | \
+ (REG_TYPE_##src1_type << A1_SRC1_TYPE_SHIFT) | \
+ (src1_nr << A1_SRC1_TYPE_SHIFT) | \
+ (SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | \
+ (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT)); \
+ OUT_RING((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | \
+ (SRC_W << A2_SRC1_CHANNEL_W_SHIFT)); \
+} while (0)
+
+static void
+I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
+ RegionPtr dstRegion,
+ short width, short height, int video_pitch,
+ int x1, int y1, int x2, int y2,
+ short src_w, short src_h, short drw_w, short drw_h,
+ DrawablePtr pDraw)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 format, ms3, s2;
+ BoxPtr pbox;
+ int nbox, dxo, dyo;
+ Bool planar;
+
+ ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
+ video_pitch);
+
+ switch (id) {
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ planar = FALSE;
+ break;
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ planar = TRUE;
+ break;
+ default:
+ ErrorF("Unknown format 0x%x\n", id);
+ planar = FALSE;
+ break;
+ }
+
+ /* Tell the rotation code that we have stomped its invariant state by
+ * setting a high bit. We don't use any invariant 3D state for video, so we
+ * don't have to worry about it ourselves.
+ */
+ *pI830->used3D |= 1 << 30;
+
+ BEGIN_LP_RING(44);
+
+ /* invarient state */
+ OUT_RING(MI_NOOP);
+ OUT_RING(STATE3D_ANTI_ALIASING |
+ LINE_CAP_WIDTH_MODIFY | LINE_CAP_WIDTH_1_0 |
+ LINE_WIDTH_MODIFY | LINE_WIDTH_1_0);
+
+ OUT_RING(STATE3D_DFLT_DIFFUSE_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(STATE3D_DFLT_SPEC_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(STATE3D_DFLT_Z_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(STATE3D_COORD_SET_BINDINGS | CSB_TCB(0, 0) | CSB_TCB(1, 1) |
+ CSB_TCB(2,2) | CSB_TCB(3,3) | CSB_TCB(4,4) | CSB_TCB(5,5) |
+ CSB_TCB(6,6) | CSB_TCB(7,7));
+
+ OUT_RING(STATE3D_RASTERIZATION_RULES |
+ ENABLE_TRI_FAN_PROVOKE_VRTX | TRI_FAN_PROVOKE_VRTX(2) |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) |
+ ENABLE_TEXKILL_3D_4D | TEXKILL_4D |
+ ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE);
+
+ OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1);
+ OUT_RING(0x00000000); /* texture coordinate wrap */
+
+ /* flush map & render cache */
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+
+ /* draw rect -- just clipping */
+ OUT_RING(STATE3D_DRAWING_RECTANGLE);
+ OUT_RING(0x00000000); /* flags */
+ OUT_RING(0x00000000); /* ymin, xmin */
+ OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+ OUT_RING(0x00000000); /* yorigin, xorigin */
+ OUT_RING(MI_NOOP);
+
+ /* scissor */
+ OUT_RING(STATE3D_SCISSOR_ENABLE | DISABLE_SCISSOR_RECT);
+ OUT_RING(STATE3D_SCISSOR_RECTANGLE);
+ OUT_RING(0x00000000); /* ymin, xmin */
+ OUT_RING(0x00000000); /* ymax, xmax */
+
+ OUT_RING(0x7c000003); /* unknown command */
+ OUT_RING(0x7d070000);
+ OUT_RING(0x00000000);
+ OUT_RING(0x68000002);
+
+ /* context setup */
+ OUT_RING(STATE3D_MODES_4 |
+ ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
+ ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
+ ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
+
+ OUT_RING(STATE3D_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
+ I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4);
+ s2 = S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D);
+ if (planar)
+ s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_2D);
+ else
+ s2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
+ s2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
+ S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
+ OUT_RING(s2);
+ OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
+ S4_CULLMODE_NONE | S4_VFMT_SPEC_FOG | S4_VFMT_COLOR | S4_VFMT_XYZW);
+ OUT_RING(0x00000000); /* S5 - enable bits */
+ OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
+ (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
+ (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE |
+ (2 << S6_TRISTRIP_PV_SHIFT));
+
+ OUT_RING(STATE3D_INDEPENDENT_ALPHA_BLEND |
+ IAB_MODIFY_ENABLE |
+ IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
+ IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) |
+ IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT));
+
+ OUT_RING(STATE3D_CONST_BLEND_COLOR);
+ OUT_RING(0x00000000);
+
+ OUT_RING(STATE3D_DEST_BUFFER_VARIABLES);
+ if (pI830->cpp == 2)
+ format = COLR_BUF_RGB565;
+ else
+ format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
+
+ OUT_RING(LOD_PRECLAMP_OGL |
+ DSTORG_HORIZ_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
+
+ OUT_RING(STATE3D_STIPPLE);
+ OUT_RING(0x00000000);
+
+ /* front buffer, pitch, offset */
+ OUT_RING(STATE3D_BUFFER_INFO);
+ OUT_RING(BUFFERID_COLOR_BACK | BUFFER_USE_FENCES |
+ (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+ OUT_RING(pI830->bufferOffset);
+ ADVANCE_LP_RING();
+
+ if (!planar) {
+ BEGIN_LP_RING(20);
+ /* fragment program - texture blend replace. */
+ OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | 8);
+ OUT_DCL(S, 0);
+ OUT_DCL(T, 0);
+ OUT_TEXLD(OC, 0, 0, T, 0);
+ /* End fragment program */
+
+ OUT_RING(STATE3D_SAMPLER_STATE | 3);
+ OUT_RING(0x00000001);
+ OUT_RING(SS2_COLORSPACE_CONVERSION |
+ (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+ (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+ OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+ (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
+ OUT_RING(0x00000000);
+
+ OUT_RING(STATE3D_MAP_STATE | 3);
+ OUT_RING(0x00000001); /* texture map #1 */
+ OUT_RING(pPriv->YBuf0offset);
+ ms3 = MAPSURF_422;
+ switch (id) {
+ case FOURCC_YUY2:
+ ms3 |= MT_422_YCRCB_NORMAL;
+ break;
+ case FOURCC_UYVY:
+ ms3 |= MT_422_YCRCB_SWAPY;
+ break;
+ }
+ ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
+ ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
+ if (!pI830->disableTiling)
+ ms3 |= MS3_USE_FENCE_REGS;
+ OUT_RING(ms3);
+ OUT_RING(((video_pitch / 4) - 1) << 21);
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(1 + 18 + (1 + 3*16) + 11 + 11);
+ OUT_RING(MI_NOOP);
+ /* For the planar formats, we set up three samplers -- one for each plane,
+ * in a Y8 format. Because I couldn't get the special PLANAR_TO_PACKED
+ * shader setup to work, I did the manual pixel shader:
+ *
+ * y' = y - .0625
+ * u' = u - .5
+ * v' = v - .5;
+ *
+ * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v'
+ * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
+ * b = 1.1643 * y' + 2.017 * u' + 0.0 * v'
+ *
+ * register assignment:
+ * r0 = (y',u',v',0)
+ * r1 = (y,y,y,y)
+ * r2 = (u,u,u,u)
+ * r3 = (v,v,v,v)
+ * OC = (r,g,b,1)
+ */
+ OUT_RING(STATE3D_PIXEL_SHADER_CONSTANTS | 16);
+ OUT_RING(0x000000f); /* constants 0-3 */
+ /* constant 0: normalization offsets */
+ OUT_RING_F(-0.0625);
+ OUT_RING_F(-0.5);
+ OUT_RING_F(-0.5);
+ OUT_RING_F(0.0);
+ /* constant 1: r coefficients*/
+ OUT_RING_F(1.1643);
+ OUT_RING_F(0.0);
+ OUT_RING_F(1.5958);
+ OUT_RING_F(0.0);
+ /* constant 2: g coefficients */
+ OUT_RING_F(1.1643);
+ OUT_RING_F(-0.39173);
+ OUT_RING_F(-0.81290);
+ OUT_RING_F(0.0);
+ /* constant 3: b coefficients */
+ OUT_RING_F(1.1643);
+ OUT_RING_F(2.017);
+ OUT_RING_F(0.0);
+ OUT_RING_F(0.0);
+
+ OUT_RING(STATE3D_PIXEL_SHADER_PROGRAM | (3 * 16 - 1));
+ /* Declare samplers */
+ OUT_DCL(S, 0);
+ OUT_DCL(S, 1);
+ OUT_DCL(S, 2);
+ OUT_DCL(T, 0);
+ OUT_DCL(T, 1);
+
+ /* Load samplers to temporaries. Y (sampler 0) gets the un-halved coords
+ * from t1.
+ */
+ OUT_TEXLD(R, 1, 0, T, 1);
+ OUT_TEXLD(R, 2, 1, T, 0);
+ OUT_TEXLD(R, 3, 2, T, 0);
+
+ /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
+ OUT_MOV_TO_CHANNEL(R, 0, R, 1, X);
+ OUT_MOV_TO_CHANNEL(R, 0, R, 2, Y);
+ OUT_MOV_TO_CHANNEL(R, 0, R, 3, Z);
+
+ /* Normalize the YUV data */
+ OUT_RING(A0_ADD | A0_DEST_CHANNEL_ALL |
+ (REG_TYPE_R << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) | \
+ (REG_TYPE_R << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+ OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) |
+ (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) |
+ (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) |
+ (SRC_W << A1_SRC0_CHANNEL_W_SHIFT) |
+ (REG_TYPE_CONST << A1_SRC1_TYPE_SHIFT) | (0 << A1_SRC1_NR_SHIFT) |
+ (SRC_X << A1_SRC1_CHANNEL_X_SHIFT) |
+ (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT));
+ OUT_RING((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) |
+ (SRC_W << A2_SRC1_CHANNEL_W_SHIFT));
+
+ /* dot-product the YUV data in R0 by the vectors of coefficients for
+ * calculating R, G, and B, storing the results in the R, G, or B channels
+ * of the output color.
+ */
+ OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 1, X);
+ OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 2, Y);
+ OUT_DP3_TO_CHANNEL(OC, 0, R, 0, CONST, 3, Z);
+
+ /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
+ * the source.
+ */
+ OUT_RING(A0_MOV | A0_DEST_CHANNEL_W |
+ (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | (0 << A0_DEST_NR_SHIFT) |
+ (REG_TYPE_OC << A0_SRC0_TYPE_SHIFT) | (0 << A0_SRC0_NR_SHIFT));
+ OUT_RING((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) |
+ (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) |
+ (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) |
+ (SRC_ONE << A1_SRC0_CHANNEL_W_SHIFT));
+ OUT_RING(0);
+ /* End fragment program */
+
+ OUT_RING(STATE3D_SAMPLER_STATE | 9);
+ OUT_RING(0x00000007);
+ /* sampler 0 */
+ OUT_RING(0x00000000);
+ OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+ (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+ OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+ (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
+ /* sampler 1 */
+ OUT_RING(0x00000000);
+ OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+ (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+ OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+ (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
+ /* sampler 2 */
+ OUT_RING(0x00000000);
+ OUT_RING((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
+ (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
+ OUT_RING((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) |
+ (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT));
+
+ OUT_RING(STATE3D_MAP_STATE | 9);
+ OUT_RING(0x00000007);
+
+ OUT_RING(pPriv->YBuf0offset);
+ ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+ ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
+ ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
+ OUT_RING(ms3);
+ OUT_RING(((video_pitch * 2 / 4) - 1) << 21);
+
+ OUT_RING(pPriv->UBuf0offset);
+ ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+ ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
+ ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
+ OUT_RING(ms3);
+ OUT_RING(((video_pitch / 4) - 1) << 21);
+
+ OUT_RING(pPriv->VBuf0offset);
+ ms3 = MAPSURF_8BIT | MT_8BIT_I8;
+ ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
+ ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
+ OUT_RING(ms3);
+ OUT_RING(((video_pitch / 4) - 1) << 21);
+ ADVANCE_LP_RING();
+ }
+
+ {
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(0x00000000);
+ ADVANCE_LP_RING();
+ }
+
+ dxo = dstRegion->extents.x1;
+ dyo = dstRegion->extents.y1;
+
+ pbox = REGION_RECTS(dstRegion);
+ nbox = REGION_NUM_RECTS(dstRegion);
+ while (nbox--)
+ {
+ int box_x1 = pbox->x1;
+ int box_y1 = pbox->y1;
+ int box_x2 = pbox->x2;
+ int box_y2 = pbox->y2;
+ int j;
+ float src_scale_x, src_scale_y;
+ CARD32 vb[40];
+ float verts[4][2], tex[4][2], tex2[4][2];
+ int vert_data_count;
+
+ pbox++;
+
+ src_scale_x = (float)src_w / (float)drw_w;
+ src_scale_y = (float)src_h / (float)drw_h;
+
+ if (!planar)
+ vert_data_count = 32;
+ else
+ vert_data_count = 40;
+
+ BEGIN_LP_RING(vert_data_count + 8);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_NOOP);
+
+ /* vertex data */
+ OUT_RING(PRIMITIVE3D | PRIM3D_INLINE | PRIM3D_TRIFAN |
+ (vert_data_count - 1));
+ verts[0][0] = box_x1; verts[0][1] = box_y1;
+ verts[1][0] = box_x2; verts[1][1] = box_y1;
+ verts[2][0] = box_x2; verts[2][1] = box_y2;
+ verts[3][0] = box_x1; verts[3][1] = box_y2;
+
+ if (!planar) {
+ tex[0][0] = (box_x1 - dxo) * src_scale_x;
+ tex[0][1] = (box_y1 - dyo) * src_scale_y;
+ tex[1][0] = (box_x2 - dxo) * src_scale_x;
+ tex[1][1] = (box_y1 - dyo) * src_scale_y;
+ tex[2][0] = (box_x2 - dxo) * src_scale_x;
+ tex[2][1] = (box_y2 - dyo) * src_scale_y;
+ tex[3][0] = (box_x1 - dxo) * src_scale_x;
+ tex[3][1] = (box_y2 - dyo) * src_scale_y;
+ /* emit vertex buffer */
+ draw_poly(vb, verts, tex, NULL);
+ for (j = 0; j < vert_data_count; j++)
+ OUT_RING(vb[j]);
+ } else {
+ tex[0][0] = (box_x1 - dxo) * src_scale_x / 2.0;
+ tex[0][1] = (box_y1 - dyo) * src_scale_y / 2.0;
+ tex[1][0] = (box_x2 - dxo) * src_scale_x / 2.0;
+ tex[1][1] = (box_y1 - dyo) * src_scale_y / 2.0;
+ tex[2][0] = (box_x2 - dxo) * src_scale_x / 2.0;
+ tex[2][1] = (box_y2 - dyo) * src_scale_y / 2.0;
+ tex[3][0] = (box_x1 - dxo) * src_scale_x / 2.0;
+ tex[3][1] = (box_y2 - dyo) * src_scale_y / 2.0;
+ tex2[0][0] = (box_x1 - dxo) * src_scale_x;
+ tex2[0][1] = (box_y1 - dyo) * src_scale_y;
+ tex2[1][0] = (box_x2 - dxo) * src_scale_x;
+ tex2[1][1] = (box_y1 - dyo) * src_scale_y;
+ tex2[2][0] = (box_x2 - dxo) * src_scale_x;
+ tex2[2][1] = (box_y2 - dyo) * src_scale_y;
+ tex2[3][0] = (box_x1 - dxo) * src_scale_x;
+ tex2[3][1] = (box_y2 - dyo) * src_scale_y;
+ /* emit vertex buffer */
+ draw_poly(vb, verts, tex, tex2);
+ for (j = 0; j < vert_data_count; j++)
+ OUT_RING(vb[j]);
+ }
+
+ ADVANCE_LP_RING();
+ }
+
+ if (pI830->AccelInfoRec)
+ pI830->AccelInfoRec->NeedToSync = TRUE;
+}
+
static FBLinearPtr
I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
{
@@ -1908,6 +2649,19 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
return new_linear;
}
+/*
+ * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
+ * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
+ * id is a fourcc code for the format of the video.
+ * buf is the pointer to the source data in system memory.
+ * width and height are the w/h of the source data.
+ * If "sync" is TRUE, then we must be finished with *buf at the point of return
+ * (which we always are).
+ * clipBoxes is the clipping region in screen space.
+ * data is a pointer to our port private.
+ * pDraw is a Drawable, which might not be the screen in the case of
+ * compositing. It's a new argument to the function in the 1.1 server.
+ */
static int
I830PutImage(ScrnInfoPtr pScrn,
short src_x, short src_y,
@@ -1925,9 +2679,10 @@ I830PutImage(ScrnInfoPtr pScrn,
I830OverlayRegPtr overlay =
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
INT32 x1, x2, y1, y2;
- int srcPitch, srcPitch2 = 0, dstPitch;
+ int srcPitch, srcPitch2 = 0, dstPitch, destId;
int top, left, npixels, nlines, size, loops;
BoxRec dstBox;
+ int pitchAlignMask;
DPRINTF(PFX, "I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
"width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
@@ -1971,50 +2726,59 @@ I830PutImage(ScrnInfoPtr pScrn,
width, height))
return Success;
+ destId = id;
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
srcPitch = (width + 3) & ~3;
srcPitch2 = ((width >> 1) + 3) & ~3;
-#if 1
- if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- dstPitch = ((height / 2) + 63) & ~63;
- size = dstPitch * width * 3;
- } else {
- dstPitch = ((width / 2) + 63) & ~63; /* of chroma */
- size = dstPitch * height * 3;
+ if (pPriv->textured) {
+ destId = FOURCC_YUY2;
}
-#else
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ srcPitch = width << 1;
+ break;
+ }
+
+ /* Only needs to be DWORD-aligned for textured on i915, but overlay has
+ * stricter requirements.
+ */
+ if (pPriv->textured) {
+ pitchAlignMask = 3;
+ } else {
+ if (IS_BROADWATER(pI830)) {
+ pitchAlignMask = 255;
+ else
+ pitchAlignMask = 63;
+ }
+
+ /* Determine the desired destination pitch (representing the chroma's pitch,
+ * in the planar case.
+ */
+ switch (destId) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- dstPitch = ((height / 2) + 255) & ~255;
+ dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * width * 3;
} else {
- dstPitch = ((width / 2) + 255) & ~255; /* of chroma */
+ dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * height * 3;
}
-#endif
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
- srcPitch = width << 1;
-#if 1
- if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- dstPitch = ((height << 1) + 63) & ~63;
- size = dstPitch * width;
- } else {
- dstPitch = ((width << 1) + 63) & ~63; /* of chroma */
- size = dstPitch * height;
- }
-#else
if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- dstPitch = ((height << 1) + 255) & ~255;
+ dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * width;
} else {
- dstPitch = ((width << 1) + 255) & ~255; /* of chroma */
+ dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * height;
}
-#endif
break;
}
ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
@@ -2052,7 +2816,9 @@ I830PutImage(ScrnInfoPtr pScrn,
/* Make sure this buffer isn't in use */
loops = 0;
- if (*pI830->overlayOn && pPriv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) {
+ if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer &&
+ (overlay->OCMD & OVERLAY_ENABLE))
+ {
while (loops < 1000000) {
#if USE_USLEEP_FOR_VIDEO
usleep(10);
@@ -2081,32 +2847,54 @@ I830PutImage(ScrnInfoPtr pScrn,
left = (x1 >> 16) & ~1;
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
+ if (pPriv->textured) {
+ /* For textured video, we don't double buffer, and instead just wait for
+ * acceleration to finish before writing the new video data into
+ * framebuffer.
+ */
+ if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+ (*pI830->AccelInfoRec->Sync)(pScrn);
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+ }
+ }
+
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
top &= ~1;
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
- I830CopyPlanarData(pScrn, buf, srcPitch, srcPitch2, dstPitch, height, top, left,
- nlines, npixels, id);
+ if (pPriv->textured) {
+ I830CopyPlanarToPackedData(pScrn, pPriv, buf, srcPitch, srcPitch2,
+ dstPitch, height, top, left, nlines,
+ npixels, id);
+ } else {
+ I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch,
+ height, top, left, nlines, npixels, id);
+ }
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
nlines = ((y2 + 0xffff) >> 16) - top;
- I830CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines,
- npixels);
+ I830CopyPackedData(pScrn, pPriv, buf, srcPitch, dstPitch, top, left,
+ nlines, npixels);
break;
}
- /* update cliplist */
- if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
- REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
- xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
- }
-
- I830DisplayVideo(pScrn, id, width, height, dstPitch,
- x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+ if (!pPriv->textured) {
+ /* update cliplist */
+ if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+ xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
+ }
+ I830DisplayVideo(pScrn, destId, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+ } else {
+ I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+ dstPitch, x1, y1, x2, y2,
+ src_w, src_h, drw_w, drw_h, pDraw);
+ }
pPriv->videoStatus = CLIENT_VIDEO_ON;
return Success;
@@ -2116,23 +2904,25 @@ static int
I830QueryImageAttributes(ScrnInfoPtr pScrn,
int id,
unsigned short *w, unsigned short *h,
- int *pitches, int *offsets)
+ int *pitches, int *offsets, Bool textured)
{
I830Ptr pI830 = I830PTR(pScrn);
int size, tmp;
ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
- if (IS_845G(pI830) || IS_I830(pI830)) {
- if (*w > IMAGE_MAX_WIDTH_LEGACY)
- *w = IMAGE_MAX_WIDTH_LEGACY;
- if (*h > IMAGE_MAX_HEIGHT_LEGACY)
- *h = IMAGE_MAX_HEIGHT_LEGACY;
- } else {
- if (*w > IMAGE_MAX_WIDTH)
- *w = IMAGE_MAX_WIDTH;
- if (*h > IMAGE_MAX_HEIGHT)
- *h = IMAGE_MAX_HEIGHT;
+ if (!textured) {
+ if (IS_845G(pI830) || IS_I830(pI830)) {
+ if (*w > IMAGE_MAX_WIDTH_LEGACY)
+ *w = IMAGE_MAX_WIDTH_LEGACY;
+ if (*h > IMAGE_MAX_HEIGHT_LEGACY)
+ *h = IMAGE_MAX_HEIGHT_LEGACY;
+ } else {
+ if (*w > IMAGE_MAX_WIDTH)
+ *w = IMAGE_MAX_WIDTH;
+ if (*h > IMAGE_MAX_HEIGHT)
+ *h = IMAGE_MAX_HEIGHT;
+ }
}
*w = (*w + 1) & ~1;
@@ -2185,6 +2975,24 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
return size;
}
+static int
+I830QueryImageAttributesOverlay(ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets)
+{
+ return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, FALSE);
+}
+
+static int
+I830QueryImageAttributesTextured(ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets)
+{
+ return I830QueryImageAttributes(pScrn, id, w, h, pitches, offsets, TRUE);
+}
+
static void
I830BlockHandler(int i,
pointer blockData, pointer pTimeout, pointer pReadmask)