summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWang Zhenyu <zhenyu.z.wang@intel.com>2006-08-24 10:23:22 +0800
committerWang Zhenyu <zhenyu.z.wang@intel.com>2006-08-24 10:23:22 +0800
commit078af29fa65653c5322b006404f7ad29aec24cce (patch)
tree1c05fbbbc4e07cb6f2e930bc6048f8fa288a38f1 /src
parent7458a6adb5ea62f56bb3d4ab19ad7d1aa6ad2d19 (diff)
parentea63e82ef417a9918e7d7105910a8ddeba2994f6 (diff)
Merge branch 'master' into exa
Conflicts: man/i810.man src/Makefile.am src/i830_accel.c src/i830_dga.c src/i830_driver.c
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/brw_defines.h847
-rw-r--r--src/brw_structs.h1340
-rw-r--r--src/common.h35
-rw-r--r--src/i810.h4
-rw-r--r--src/i810_dri.h4
-rw-r--r--src/i810_driver.c21
-rw-r--r--src/i810_reg.h323
-rw-r--r--src/i830.h67
-rw-r--r--src/i830_3d.c1
-rw-r--r--src/i830_accel.c14
-rw-r--r--src/i830_common.h8
-rw-r--r--src/i830_cursor.c218
-rw-r--r--src/i830_dga.c47
-rw-r--r--src/i830_dri.c118
-rw-r--r--src/i830_dri.h38
-rw-r--r--src/i830_driver.c2678
-rw-r--r--src/i830_memory.c111
-rw-r--r--src/i830_modes.c132
-rw-r--r--src/i830_rotate.c40
-rw-r--r--src/i830_video.c1528
-rw-r--r--src/i830_video.h76
-rw-r--r--src/i830_xaa.c76
-rw-r--r--src/i915_3d.c1
-rw-r--r--src/i915_video.c467
-rw-r--r--src/wm_prog.h166
26 files changed, 7861 insertions, 504 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c2e49ac3..e58350c9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,6 +31,9 @@ i810_drv_la_LDFLAGS = -module -avoid-version
i810_drv_ladir = @moduledir@/drivers
i810_drv_la_SOURCES = \
+ brw_defines.h \
+ brw_structs.h \
+ wm_prog.h \
common.h \
i810_accel.c \
i810_common.h \
@@ -53,6 +56,7 @@ i810_drv_la_SOURCES = \
i830_memory.c \
i830_modes.c \
i830_video.c \
+ i830_video.h \
i830_rotate.c \
i830_randr.c \
i830_3d.c \
@@ -60,6 +64,7 @@ i810_drv_la_SOURCES = \
i915_3d.c \
i915_3d.h \
i915_reg.h \
+ i915_video.c \
i830_exa.c \
i830_xaa.c \
i830_exa_render.c \
diff --git a/src/brw_defines.h b/src/brw_defines.h
new file mode 100644
index 00000000..93aed544
--- /dev/null
+++ b/src/brw_defines.h
@@ -0,0 +1,847 @@
+ /**************************************************************************
+ *
+ * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#ifndef BRW_DEFINES_H
+#define BRW_DEFINES_H
+
+/*
+ */
+#if 0
+#define MI_NOOP 0x00
+#define MI_USER_INTERRUPT 0x02
+#define MI_WAIT_FOR_EVENT 0x03
+#define MI_FLUSH 0x04
+#define MI_REPORT_HEAD 0x07
+#define MI_ARB_ON_OFF 0x08
+#define MI_BATCH_BUFFER_END 0x0A
+#define MI_OVERLAY_FLIP 0x11
+#define MI_LOAD_SCAN_LINES_INCL 0x12
+#define MI_LOAD_SCAN_LINES_EXCL 0x13
+#define MI_DISPLAY_BUFFER_INFO 0x14
+#define MI_SET_CONTEXT 0x18
+#define MI_STORE_DATA_IMM 0x20
+#define MI_STORE_DATA_INDEX 0x21
+#define MI_LOAD_REGISTER_IMM 0x22
+#define MI_STORE_REGISTER_MEM 0x24
+#define MI_BATCH_BUFFER_START 0x31
+
+#define MI_SYNCHRONOUS_FLIP 0x0
+#define MI_ASYNCHRONOUS_FLIP 0x1
+
+#define MI_BUFFER_SECURE 0x0
+#define MI_BUFFER_NONSECURE 0x1
+
+#define MI_ARBITRATE_AT_CHAIN_POINTS 0x0
+#define MI_ARBITRATE_BETWEEN_INSTS 0x1
+#define MI_NO_ARBITRATION 0x3
+
+#define MI_CONDITION_CODE_WAIT_DISABLED 0x0
+#define MI_CONDITION_CODE_WAIT_0 0x1
+#define MI_CONDITION_CODE_WAIT_1 0x2
+#define MI_CONDITION_CODE_WAIT_2 0x3
+#define MI_CONDITION_CODE_WAIT_3 0x4
+#define MI_CONDITION_CODE_WAIT_4 0x5
+
+#define MI_DISPLAY_PIPE_A 0x0
+#define MI_DISPLAY_PIPE_B 0x1
+
+#define MI_DISPLAY_PLANE_A 0x0
+#define MI_DISPLAY_PLANE_B 0x1
+#define MI_DISPLAY_PLANE_C 0x2
+
+#define MI_STANDARD_FLIP 0x0
+#define MI_ENQUEUE_FLIP_PERFORM_BASE_FRAME_NUMBER_LOAD 0x1
+#define MI_ENQUEUE_FLIP_TARGET_FRAME_NUMBER_RELATIVE 0x2
+#define MI_ENQUEUE_FLIP_ABSOLUTE_TARGET_FRAME_NUMBER 0x3
+
+#define MI_PHYSICAL_ADDRESS 0x0
+#define MI_VIRTUAL_ADDRESS 0x1
+
+#define MI_BUFFER_MEMORY_MAIN 0x0
+#define MI_BUFFER_MEMORY_GTT 0x2
+#define MI_BUFFER_MEMORY_PER_PROCESS_GTT 0x3
+
+#define MI_FLIP_CONTINUE 0x0
+#define MI_FLIP_ON 0x1
+#define MI_FLIP_OFF 0x2
+
+#define MI_UNTRUSTED_REGISTER_SPACE 0x0
+#define MI_TRUSTED_REGISTER_SPACE 0x1
+#endif
+
+/* 3D state:
+ */
+#define _3DOP_3DSTATE_PIPELINED 0x0
+#define _3DOP_3DSTATE_NONPIPELINED 0x1
+#define _3DOP_3DCONTROL 0x2
+#define _3DOP_3DPRIMITIVE 0x3
+
+#define _3DSTATE_PIPELINED_POINTERS 0x00
+#define _3DSTATE_BINDING_TABLE_POINTERS 0x01
+#define _3DSTATE_VERTEX_BUFFERS 0x08
+#define _3DSTATE_VERTEX_ELEMENTS 0x09
+#define _3DSTATE_INDEX_BUFFER 0x0A
+#define _3DSTATE_VF_STATISTICS 0x0B
+#define _3DSTATE_DRAWING_RECTANGLE 0x00
+#define _3DSTATE_CONSTANT_COLOR 0x01
+#define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02
+#define _3DSTATE_CHROMA_KEY 0x04
+#define _3DSTATE_DEPTH_BUFFER 0x05
+#define _3DSTATE_POLY_STIPPLE_OFFSET 0x06
+#define _3DSTATE_POLY_STIPPLE_PATTERN 0x07
+#define _3DSTATE_LINE_STIPPLE 0x08
+#define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09
+#define _3DCONTROL 0x00
+#define _3DPRIMITIVE 0x00
+
+#define PIPE_CONTROL_NOWRITE 0x00
+#define PIPE_CONTROL_WRITEIMMEDIATE 0x01
+#define PIPE_CONTROL_WRITEDEPTH 0x02
+#define PIPE_CONTROL_WRITETIMESTAMP 0x03
+
+#define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00
+#define PIPE_CONTROL_GTTWRITE_GLOBAL 0x01
+
+#define _3DPRIM_POINTLIST 0x01
+#define _3DPRIM_LINELIST 0x02
+#define _3DPRIM_LINESTRIP 0x03
+#define _3DPRIM_TRILIST 0x04
+#define _3DPRIM_TRISTRIP 0x05
+#define _3DPRIM_TRIFAN 0x06
+#define _3DPRIM_QUADLIST 0x07
+#define _3DPRIM_QUADSTRIP 0x08
+#define _3DPRIM_LINELIST_ADJ 0x09
+#define _3DPRIM_LINESTRIP_ADJ 0x0A
+#define _3DPRIM_TRILIST_ADJ 0x0B
+#define _3DPRIM_TRISTRIP_ADJ 0x0C
+#define _3DPRIM_TRISTRIP_REVERSE 0x0D
+#define _3DPRIM_POLYGON 0x0E
+#define _3DPRIM_RECTLIST 0x0F
+#define _3DPRIM_LINELOOP 0x10
+#define _3DPRIM_POINTLIST_BF 0x11
+#define _3DPRIM_LINESTRIP_CONT 0x12
+#define _3DPRIM_LINESTRIP_BF 0x13
+#define _3DPRIM_LINESTRIP_CONT_BF 0x14
+#define _3DPRIM_TRIFAN_NOSTIPPLE 0x15
+
+#define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0
+#define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1
+
+#define BRW_ANISORATIO_2 0
+#define BRW_ANISORATIO_4 1
+#define BRW_ANISORATIO_6 2
+#define BRW_ANISORATIO_8 3
+#define BRW_ANISORATIO_10 4
+#define BRW_ANISORATIO_12 5
+#define BRW_ANISORATIO_14 6
+#define BRW_ANISORATIO_16 7
+
+#define BRW_BLENDFACTOR_ONE 0x1
+#define BRW_BLENDFACTOR_SRC_COLOR 0x2
+#define BRW_BLENDFACTOR_SRC_ALPHA 0x3
+#define BRW_BLENDFACTOR_DST_ALPHA 0x4
+#define BRW_BLENDFACTOR_DST_COLOR 0x5
+#define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6
+#define BRW_BLENDFACTOR_CONST_COLOR 0x7
+#define BRW_BLENDFACTOR_CONST_ALPHA 0x8
+#define BRW_BLENDFACTOR_SRC1_COLOR 0x9
+#define BRW_BLENDFACTOR_SRC1_ALPHA 0x0A
+#define BRW_BLENDFACTOR_ZERO 0x11
+#define BRW_BLENDFACTOR_INV_SRC_COLOR 0x12
+#define BRW_BLENDFACTOR_INV_SRC_ALPHA 0x13
+#define BRW_BLENDFACTOR_INV_DST_ALPHA 0x14
+#define BRW_BLENDFACTOR_INV_DST_COLOR 0x15
+#define BRW_BLENDFACTOR_INV_CONST_COLOR 0x17
+#define BRW_BLENDFACTOR_INV_CONST_ALPHA 0x18
+#define BRW_BLENDFACTOR_INV_SRC1_COLOR 0x19
+#define BRW_BLENDFACTOR_INV_SRC1_ALPHA 0x1A
+
+#define BRW_BLENDFUNCTION_ADD 0
+#define BRW_BLENDFUNCTION_SUBTRACT 1
+#define BRW_BLENDFUNCTION_REVERSE_SUBTRACT 2
+#define BRW_BLENDFUNCTION_MIN 3
+#define BRW_BLENDFUNCTION_MAX 4
+
+#define BRW_ALPHATEST_FORMAT_UNORM8 0
+#define BRW_ALPHATEST_FORMAT_FLOAT32 1
+
+#define BRW_CHROMAKEY_KILL_ON_ANY_MATCH 0
+#define BRW_CHROMAKEY_REPLACE_BLACK 1
+
+#define BRW_CLIP_API_OGL 0
+#define BRW_CLIP_API_DX 1
+
+#define BRW_CLIPMODE_NORMAL 0
+#define BRW_CLIPMODE_CLIP_ALL 1
+#define BRW_CLIPMODE_CLIP_NON_REJECTED 2
+#define BRW_CLIPMODE_REJECT_ALL 3
+#define BRW_CLIPMODE_ACCEPT_ALL 4
+
+#define BRW_CLIP_NDCSPACE 0
+#define BRW_CLIP_SCREENSPACE 1
+
+#define BRW_COMPAREFUNCTION_ALWAYS 0
+#define BRW_COMPAREFUNCTION_NEVER 1
+#define BRW_COMPAREFUNCTION_LESS 2
+#define BRW_COMPAREFUNCTION_EQUAL 3
+#define BRW_COMPAREFUNCTION_LEQUAL 4
+#define BRW_COMPAREFUNCTION_GREATER 5
+#define BRW_COMPAREFUNCTION_NOTEQUAL 6
+#define BRW_COMPAREFUNCTION_GEQUAL 7
+
+#define BRW_COVERAGE_PIXELS_HALF 0
+#define BRW_COVERAGE_PIXELS_1 1
+#define BRW_COVERAGE_PIXELS_2 2
+#define BRW_COVERAGE_PIXELS_4 3
+
+#define BRW_CULLMODE_BOTH 0
+#define BRW_CULLMODE_NONE 1
+#define BRW_CULLMODE_FRONT 2
+#define BRW_CULLMODE_BACK 3
+
+#define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM 0
+#define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT 1
+
+#define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0
+#define BRW_DEPTHFORMAT_D32_FLOAT 1
+#define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT 2
+#define BRW_DEPTHFORMAT_D16_UNORM 5
+
+#define BRW_FLOATING_POINT_IEEE_754 0
+#define BRW_FLOATING_POINT_NON_IEEE_754 1
+
+#define BRW_FRONTWINDING_CW 0
+#define BRW_FRONTWINDING_CCW 1
+
+#define BRW_INDEX_BYTE 0
+#define BRW_INDEX_WORD 1
+#define BRW_INDEX_DWORD 2
+
+#define BRW_LOGICOPFUNCTION_CLEAR 0
+#define BRW_LOGICOPFUNCTION_NOR 1
+#define BRW_LOGICOPFUNCTION_AND_INVERTED 2
+#define BRW_LOGICOPFUNCTION_COPY_INVERTED 3
+#define BRW_LOGICOPFUNCTION_AND_REVERSE 4
+#define BRW_LOGICOPFUNCTION_INVERT 5
+#define BRW_LOGICOPFUNCTION_XOR 6
+#define BRW_LOGICOPFUNCTION_NAND 7
+#define BRW_LOGICOPFUNCTION_AND 8
+#define BRW_LOGICOPFUNCTION_EQUIV 9
+#define BRW_LOGICOPFUNCTION_NOOP 10
+#define BRW_LOGICOPFUNCTION_OR_INVERTED 11
+#define BRW_LOGICOPFUNCTION_COPY 12
+#define BRW_LOGICOPFUNCTION_OR_REVERSE 13
+#define BRW_LOGICOPFUNCTION_OR 14
+#define BRW_LOGICOPFUNCTION_SET 15
+
+#define BRW_MAPFILTER_NEAREST 0x0
+#define BRW_MAPFILTER_LINEAR 0x1
+#define BRW_MAPFILTER_ANISOTROPIC 0x2
+
+#define BRW_MIPFILTER_NONE 0
+#define BRW_MIPFILTER_NEAREST 1
+#define BRW_MIPFILTER_LINEAR 3
+
+#define BRW_POLYGON_FRONT_FACING 0
+#define BRW_POLYGON_BACK_FACING 1
+
+#define BRW_PREFILTER_ALWAYS 0x0
+#define BRW_PREFILTER_NEVER 0x1
+#define BRW_PREFILTER_LESS 0x2
+#define BRW_PREFILTER_EQUAL 0x3
+#define BRW_PREFILTER_LEQUAL 0x4
+#define BRW_PREFILTER_GREATER 0x5
+#define BRW_PREFILTER_NOTEQUAL 0x6
+#define BRW_PREFILTER_GEQUAL 0x7
+
+#define BRW_PROVOKING_VERTEX_0 0
+#define BRW_PROVOKING_VERTEX_1 1
+#define BRW_PROVOKING_VERTEX_2 2
+
+#define BRW_RASTRULE_UPPER_LEFT 0
+#define BRW_RASTRULE_UPPER_RIGHT 1
+
+#define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0
+#define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1
+#define BRW_RENDERTARGET_CLAMPRANGE_FORMAT 2
+
+#define BRW_STENCILOP_KEEP 0
+#define BRW_STENCILOP_ZERO 1
+#define BRW_STENCILOP_REPLACE 2
+#define BRW_STENCILOP_INCRSAT 3
+#define BRW_STENCILOP_DECRSAT 4
+#define BRW_STENCILOP_INCR 5
+#define BRW_STENCILOP_DECR 6
+#define BRW_STENCILOP_INVERT 7
+
+#define BRW_SURFACE_MIPMAPLAYOUT_BELOW 0
+#define BRW_SURFACE_MIPMAPLAYOUT_RIGHT 1
+
+#define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000
+#define BRW_SURFACEFORMAT_R32G32B32A32_SINT 0x001
+#define BRW_SURFACEFORMAT_R32G32B32A32_UINT 0x002
+#define BRW_SURFACEFORMAT_R32G32B32A32_UNORM 0x003
+#define BRW_SURFACEFORMAT_R32G32B32A32_SNORM 0x004
+#define BRW_SURFACEFORMAT_R64G64_FLOAT 0x005
+#define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006
+#define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007
+#define BRW_SURFACEFORMAT_R32G32B32A32_USCALED 0x008
+#define BRW_SURFACEFORMAT_R32G32B32_FLOAT 0x040
+#define BRW_SURFACEFORMAT_R32G32B32_SINT 0x041
+#define BRW_SURFACEFORMAT_R32G32B32_UINT 0x042
+#define BRW_SURFACEFORMAT_R32G32B32_UNORM 0x043
+#define BRW_SURFACEFORMAT_R32G32B32_SNORM 0x044
+#define BRW_SURFACEFORMAT_R32G32B32_SSCALED 0x045
+#define BRW_SURFACEFORMAT_R32G32B32_USCALED 0x046
+#define BRW_SURFACEFORMAT_R16G16B16A16_UNORM 0x080
+#define BRW_SURFACEFORMAT_R16G16B16A16_SNORM 0x081
+#define BRW_SURFACEFORMAT_R16G16B16A16_SINT 0x082
+#define BRW_SURFACEFORMAT_R16G16B16A16_UINT 0x083
+#define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084
+#define BRW_SURFACEFORMAT_R32G32_FLOAT 0x085
+#define BRW_SURFACEFORMAT_R32G32_SINT 0x086
+#define BRW_SURFACEFORMAT_R32G32_UINT 0x087
+#define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088
+#define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089
+#define BRW_SURFACEFORMAT_L32A32_FLOAT 0x08A
+#define BRW_SURFACEFORMAT_R32G32_UNORM 0x08B
+#define BRW_SURFACEFORMAT_R32G32_SNORM 0x08C
+#define BRW_SURFACEFORMAT_R64_FLOAT 0x08D
+#define BRW_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E
+#define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F
+#define BRW_SURFACEFORMAT_A32X32_FLOAT 0x090
+#define BRW_SURFACEFORMAT_L32X32_FLOAT 0x091
+#define BRW_SURFACEFORMAT_I32X32_FLOAT 0x092
+#define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093
+#define BRW_SURFACEFORMAT_R16G16B16A16_USCALED 0x094
+#define BRW_SURFACEFORMAT_R32G32_SSCALED 0x095
+#define BRW_SURFACEFORMAT_R32G32_USCALED 0x096
+#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0
+#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1
+#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2
+#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3
+#define BRW_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4
+#define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5
+#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7
+#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8
+#define BRW_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9
+#define BRW_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA
+#define BRW_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB
+#define BRW_SURFACEFORMAT_R16G16_UNORM 0x0CC
+#define BRW_SURFACEFORMAT_R16G16_SNORM 0x0CD
+#define BRW_SURFACEFORMAT_R16G16_SINT 0x0CE
+#define BRW_SURFACEFORMAT_R16G16_UINT 0x0CF
+#define BRW_SURFACEFORMAT_R16G16_FLOAT 0x0D0
+#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1
+#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2
+#define BRW_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3
+#define BRW_SURFACEFORMAT_R32_SINT 0x0D6
+#define BRW_SURFACEFORMAT_R32_UINT 0x0D7
+#define BRW_SURFACEFORMAT_R32_FLOAT 0x0D8
+#define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9
+#define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA
+#define BRW_SURFACEFORMAT_L16A16_UNORM 0x0DF
+#define BRW_SURFACEFORMAT_I24X8_UNORM 0x0E0
+#define BRW_SURFACEFORMAT_L24X8_UNORM 0x0E1
+#define BRW_SURFACEFORMAT_A24X8_UNORM 0x0E2
+#define BRW_SURFACEFORMAT_I32_FLOAT 0x0E3
+#define BRW_SURFACEFORMAT_L32_FLOAT 0x0E4
+#define BRW_SURFACEFORMAT_A32_FLOAT 0x0E5
+#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9
+#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA
+#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB
+#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC
+#define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED
+#define BRW_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE
+#define BRW_SURFACEFORMAT_L16A16_FLOAT 0x0F0
+#define BRW_SURFACEFORMAT_R32_UNORM 0x0F1
+#define BRW_SURFACEFORMAT_R32_SNORM 0x0F2
+#define BRW_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3
+#define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4
+#define BRW_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5
+#define BRW_SURFACEFORMAT_R16G16_SSCALED 0x0F6
+#define BRW_SURFACEFORMAT_R16G16_USCALED 0x0F7
+#define BRW_SURFACEFORMAT_R32_SSCALED 0x0F8
+#define BRW_SURFACEFORMAT_R32_USCALED 0x0F9
+#define BRW_SURFACEFORMAT_B5G6R5_UNORM 0x100
+#define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101
+#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM 0x102
+#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103
+#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM 0x104
+#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105
+#define BRW_SURFACEFORMAT_R8G8_UNORM 0x106
+#define BRW_SURFACEFORMAT_R8G8_SNORM 0x107
+#define BRW_SURFACEFORMAT_R8G8_SINT 0x108
+#define BRW_SURFACEFORMAT_R8G8_UINT 0x109
+#define BRW_SURFACEFORMAT_R16_UNORM 0x10A
+#define BRW_SURFACEFORMAT_R16_SNORM 0x10B
+#define BRW_SURFACEFORMAT_R16_SINT 0x10C
+#define BRW_SURFACEFORMAT_R16_UINT 0x10D
+#define BRW_SURFACEFORMAT_R16_FLOAT 0x10E
+#define BRW_SURFACEFORMAT_I16_UNORM 0x111
+#define BRW_SURFACEFORMAT_L16_UNORM 0x112
+#define BRW_SURFACEFORMAT_A16_UNORM 0x113
+#define BRW_SURFACEFORMAT_L8A8_UNORM 0x114
+#define BRW_SURFACEFORMAT_I16_FLOAT 0x115
+#define BRW_SURFACEFORMAT_L16_FLOAT 0x116
+#define BRW_SURFACEFORMAT_A16_FLOAT 0x117
+#define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119
+#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A
+#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B
+#define BRW_SURFACEFORMAT_R8G8_SSCALED 0x11C
+#define BRW_SURFACEFORMAT_R8G8_USCALED 0x11D
+#define BRW_SURFACEFORMAT_R16_SSCALED 0x11E
+#define BRW_SURFACEFORMAT_R16_USCALED 0x11F
+#define BRW_SURFACEFORMAT_R8_UNORM 0x140
+#define BRW_SURFACEFORMAT_R8_SNORM 0x141
+#define BRW_SURFACEFORMAT_R8_SINT 0x142
+#define BRW_SURFACEFORMAT_R8_UINT 0x143
+#define BRW_SURFACEFORMAT_A8_UNORM 0x144
+#define BRW_SURFACEFORMAT_I8_UNORM 0x145
+#define BRW_SURFACEFORMAT_L8_UNORM 0x146
+#define BRW_SURFACEFORMAT_P4A4_UNORM 0x147
+#define BRW_SURFACEFORMAT_A4P4_UNORM 0x148
+#define BRW_SURFACEFORMAT_R8_SSCALED 0x149
+#define BRW_SURFACEFORMAT_R8_USCALED 0x14A
+#define BRW_SURFACEFORMAT_R1_UINT 0x181
+#define BRW_SURFACEFORMAT_YCRCB_NORMAL 0x182
+#define BRW_SURFACEFORMAT_YCRCB_SWAPUVY 0x183
+#define BRW_SURFACEFORMAT_BC1_UNORM 0x186
+#define BRW_SURFACEFORMAT_BC2_UNORM 0x187
+#define BRW_SURFACEFORMAT_BC3_UNORM 0x188
+#define BRW_SURFACEFORMAT_BC4_UNORM 0x189
+#define BRW_SURFACEFORMAT_BC5_UNORM 0x18A
+#define BRW_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B
+#define BRW_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C
+#define BRW_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D
+#define BRW_SURFACEFORMAT_MONO8 0x18E
+#define BRW_SURFACEFORMAT_YCRCB_SWAPUV 0x18F
+#define BRW_SURFACEFORMAT_YCRCB_SWAPY 0x190
+#define BRW_SURFACEFORMAT_DXT1_RGB 0x191
+#define BRW_SURFACEFORMAT_FXT1 0x192
+#define BRW_SURFACEFORMAT_R8G8B8_UNORM 0x193
+#define BRW_SURFACEFORMAT_R8G8B8_SNORM 0x194
+#define BRW_SURFACEFORMAT_R8G8B8_SSCALED 0x195
+#define BRW_SURFACEFORMAT_R8G8B8_USCALED 0x196
+#define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197
+#define BRW_SURFACEFORMAT_R64G64B64_FLOAT 0x198
+#define BRW_SURFACEFORMAT_BC4_SNORM 0x199
+#define BRW_SURFACEFORMAT_BC5_SNORM 0x19A
+#define BRW_SURFACEFORMAT_R16G16B16_UNORM 0x19C
+#define BRW_SURFACEFORMAT_R16G16B16_SNORM 0x19D
+#define BRW_SURFACEFORMAT_R16G16B16_SSCALED 0x19E
+#define BRW_SURFACEFORMAT_R16G16B16_USCALED 0x19F
+
+#define BRW_SURFACERETURNFORMAT_FLOAT32 0
+#define BRW_SURFACERETURNFORMAT_S1 1
+
+#define BRW_SURFACE_1D 0
+#define BRW_SURFACE_2D 1
+#define BRW_SURFACE_3D 2
+#define BRW_SURFACE_CUBE 3
+#define BRW_SURFACE_BUFFER 4
+#define BRW_SURFACE_NULL 7
+
+#define BRW_TEXCOORDMODE_WRAP 0
+#define BRW_TEXCOORDMODE_MIRROR 1
+#define BRW_TEXCOORDMODE_CLAMP 2
+#define BRW_TEXCOORDMODE_CUBE 3
+#define BRW_TEXCOORDMODE_CLAMP_BORDER 4
+#define BRW_TEXCOORDMODE_MIRROR_ONCE 5
+
+#define BRW_THREAD_PRIORITY_NORMAL 0
+#define BRW_THREAD_PRIORITY_HIGH 1
+
+#define BRW_TILEWALK_XMAJOR 0
+#define BRW_TILEWALK_YMAJOR 1
+
+#define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS 0
+#define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS 1
+
+#define BRW_VERTEXBUFFER_ACCESS_VERTEXDATA 0
+#define BRW_VERTEXBUFFER_ACCESS_INSTANCEDATA 1
+
+#define BRW_VFCOMPONENT_NOSTORE 0
+#define BRW_VFCOMPONENT_STORE_SRC 1
+#define BRW_VFCOMPONENT_STORE_0 2
+#define BRW_VFCOMPONENT_STORE_1_FLT 3
+#define BRW_VFCOMPONENT_STORE_1_INT 4
+#define BRW_VFCOMPONENT_STORE_VID 5
+#define BRW_VFCOMPONENT_STORE_IID 6
+#define BRW_VFCOMPONENT_STORE_PID 7
+
+
+
+/* Execution Unit (EU) defines
+ */
+
+#define BRW_ALIGN_1 0
+#define BRW_ALIGN_16 1
+
+#define BRW_ADDRESS_DIRECT 0
+#define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1
+
+#define BRW_CHANNEL_X 0
+#define BRW_CHANNEL_Y 1
+#define BRW_CHANNEL_Z 2
+#define BRW_CHANNEL_W 3
+
+#define BRW_COMPRESSION_NONE 0
+#define BRW_COMPRESSION_2NDHALF 1
+#define BRW_COMPRESSION_COMPRESSED 2
+
+#define BRW_CONDITIONAL_NONE 0
+#define BRW_CONDITIONAL_Z 1
+#define BRW_CONDITIONAL_NZ 2
+#define BRW_CONDITIONAL_EQ 1 /* Z */
+#define BRW_CONDITIONAL_NEQ 2 /* NZ */
+#define BRW_CONDITIONAL_G 3
+#define BRW_CONDITIONAL_GE 4
+#define BRW_CONDITIONAL_L 5
+#define BRW_CONDITIONAL_LE 6
+#define BRW_CONDITIONAL_C 7
+#define BRW_CONDITIONAL_O 8
+
+#define BRW_DEBUG_NONE 0
+#define BRW_DEBUG_BREAKPOINT 1
+
+#define BRW_DEPENDENCY_NORMAL 0
+#define BRW_DEPENDENCY_NOTCLEARED 1
+#define BRW_DEPENDENCY_NOTCHECKED 2
+#define BRW_DEPENDENCY_DISABLE 3
+
+#define BRW_EXECUTE_1 0
+#define BRW_EXECUTE_2 1
+#define BRW_EXECUTE_4 2
+#define BRW_EXECUTE_8 3
+#define BRW_EXECUTE_16 4
+#define BRW_EXECUTE_32 5
+
+#define BRW_HORIZONTAL_STRIDE_0 0
+#define BRW_HORIZONTAL_STRIDE_1 1
+#define BRW_HORIZONTAL_STRIDE_2 2
+#define BRW_HORIZONTAL_STRIDE_4 3
+
+#define BRW_INSTRUCTION_NORMAL 0
+#define BRW_INSTRUCTION_SATURATE 1
+
+#define BRW_MASK_ENABLE 0
+#define BRW_MASK_DISABLE 1
+
+#define BRW_OPCODE_MOV 1
+#define BRW_OPCODE_SEL 2
+#define BRW_OPCODE_NOT 4
+#define BRW_OPCODE_AND 5
+#define BRW_OPCODE_OR 6
+#define BRW_OPCODE_XOR 7
+#define BRW_OPCODE_SHR 8
+#define BRW_OPCODE_SHL 9
+#define BRW_OPCODE_RSR 10
+#define BRW_OPCODE_RSL 11
+#define BRW_OPCODE_ASR 12
+#define BRW_OPCODE_CMP 16
+#define BRW_OPCODE_JMPI 32
+#define BRW_OPCODE_IF 34
+#define BRW_OPCODE_IFF 35
+#define BRW_OPCODE_ELSE 36
+#define BRW_OPCODE_ENDIF 37
+#define BRW_OPCODE_DO 38
+#define BRW_OPCODE_WHILE 39
+#define BRW_OPCODE_BREAK 40
+#define BRW_OPCODE_CONTINUE 41
+#define BRW_OPCODE_HALT 42
+#define BRW_OPCODE_MSAVE 44
+#define BRW_OPCODE_MRESTORE 45
+#define BRW_OPCODE_PUSH 46
+#define BRW_OPCODE_POP 47
+#define BRW_OPCODE_WAIT 48
+#define BRW_OPCODE_SEND 49
+#define BRW_OPCODE_ADD 64
+#define BRW_OPCODE_MUL 65
+#define BRW_OPCODE_AVG 66
+#define BRW_OPCODE_FRC 67
+#define BRW_OPCODE_RNDU 68
+#define BRW_OPCODE_RNDD 69
+#define BRW_OPCODE_RNDE 70
+#define BRW_OPCODE_RNDZ 71
+#define BRW_OPCODE_MAC 72
+#define BRW_OPCODE_MACH 73
+#define BRW_OPCODE_LZD 74
+#define BRW_OPCODE_SAD2 80
+#define BRW_OPCODE_SADA2 81
+#define BRW_OPCODE_DP4 84
+#define BRW_OPCODE_DPH 85
+#define BRW_OPCODE_DP3 86
+#define BRW_OPCODE_DP2 87
+#define BRW_OPCODE_DPA2 88
+#define BRW_OPCODE_LINE 89
+#define BRW_OPCODE_NOP 126
+
+#define BRW_PREDICATE_NONE 0
+#define BRW_PREDICATE_NORMAL 1
+#define BRW_PREDICATE_ALIGN1_ANYV 2
+#define BRW_PREDICATE_ALIGN1_ALLV 3
+#define BRW_PREDICATE_ALIGN1_ANY2H 4
+#define BRW_PREDICATE_ALIGN1_ALL2H 5
+#define BRW_PREDICATE_ALIGN1_ANY4H 6
+#define BRW_PREDICATE_ALIGN1_ALL4H 7
+#define BRW_PREDICATE_ALIGN1_ANY8H 8
+#define BRW_PREDICATE_ALIGN1_ALL8H 9
+#define BRW_PREDICATE_ALIGN1_ANY16H 10
+#define BRW_PREDICATE_ALIGN1_ALL16H 11
+#define BRW_PREDICATE_ALIGN16_REPLICATE_X 2
+#define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3
+#define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4
+#define BRW_PREDICATE_ALIGN16_REPLICATE_W 5
+#define BRW_PREDICATE_ALIGN16_ANY4H 6
+#define BRW_PREDICATE_ALIGN16_ALL4H 7
+
+#define BRW_ARCHITECTURE_REGISTER_FILE 0
+#define BRW_GENERAL_REGISTER_FILE 1
+#define BRW_MESSAGE_REGISTER_FILE 2
+#define BRW_IMMEDIATE_VALUE 3
+
+#define BRW_REGISTER_TYPE_UD 0
+#define BRW_REGISTER_TYPE_D 1
+#define BRW_REGISTER_TYPE_UW 2
+#define BRW_REGISTER_TYPE_W 3
+#define BRW_REGISTER_TYPE_UB 4
+#define BRW_REGISTER_TYPE_B 5
+#define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */
+#define BRW_REGISTER_TYPE_HF 6
+#define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */
+#define BRW_REGISTER_TYPE_F 7
+
+#define BRW_ARF_NULL 0x00
+#define BRW_ARF_ADDRESS 0x10
+#define BRW_ARF_ACCUMULATOR 0x20
+#define BRW_ARF_FLAG 0x30
+#define BRW_ARF_MASK 0x40
+#define BRW_ARF_MASK_STACK 0x50
+#define BRW_ARF_MASK_STACK_DEPTH 0x60
+#define BRW_ARF_STATE 0x70
+#define BRW_ARF_CONTROL 0x80
+#define BRW_ARF_NOTIFICATION_COUNT 0x90
+#define BRW_ARF_IP 0xA0
+
+#define BRW_AMASK 0
+#define BRW_IMASK 1
+#define BRW_LMASK 2
+#define BRW_CMASK 3
+
+
+
+#define BRW_THREAD_NORMAL 0
+#define BRW_THREAD_ATOMIC 1
+#define BRW_THREAD_SWITCH 2
+
+#define BRW_VERTICAL_STRIDE_0 0
+#define BRW_VERTICAL_STRIDE_1 1
+#define BRW_VERTICAL_STRIDE_2 2
+#define BRW_VERTICAL_STRIDE_4 3
+#define BRW_VERTICAL_STRIDE_8 4
+#define BRW_VERTICAL_STRIDE_16 5
+#define BRW_VERTICAL_STRIDE_32 6
+#define BRW_VERTICAL_STRIDE_64 7
+#define BRW_VERTICAL_STRIDE_128 8
+#define BRW_VERTICAL_STRIDE_256 9
+#define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF
+
+#define BRW_WIDTH_1 0
+#define BRW_WIDTH_2 1
+#define BRW_WIDTH_4 2
+#define BRW_WIDTH_8 3
+#define BRW_WIDTH_16 4
+
+#define BRW_STATELESS_BUFFER_BOUNDARY_1K 0
+#define BRW_STATELESS_BUFFER_BOUNDARY_2K 1
+#define BRW_STATELESS_BUFFER_BOUNDARY_4K 2
+#define BRW_STATELESS_BUFFER_BOUNDARY_8K 3
+#define BRW_STATELESS_BUFFER_BOUNDARY_16K 4
+#define BRW_STATELESS_BUFFER_BOUNDARY_32K 5
+#define BRW_STATELESS_BUFFER_BOUNDARY_64K 6
+#define BRW_STATELESS_BUFFER_BOUNDARY_128K 7
+#define BRW_STATELESS_BUFFER_BOUNDARY_256K 8
+#define BRW_STATELESS_BUFFER_BOUNDARY_512K 9
+#define BRW_STATELESS_BUFFER_BOUNDARY_1M 10
+#define BRW_STATELESS_BUFFER_BOUNDARY_2M 11
+
+#define BRW_POLYGON_FACING_FRONT 0
+#define BRW_POLYGON_FACING_BACK 1
+
+#define BRW_MESSAGE_TARGET_NULL 0
+#define BRW_MESSAGE_TARGET_MATH 1
+#define BRW_MESSAGE_TARGET_SAMPLER 2
+#define BRW_MESSAGE_TARGET_GATEWAY 3
+#define BRW_MESSAGE_TARGET_DATAPORT_READ 4
+#define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5
+#define BRW_MESSAGE_TARGET_URB 6
+#define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7
+
+#define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0
+#define BRW_SAMPLER_RETURN_FORMAT_UINT32 2
+#define BRW_SAMPLER_RETURN_FORMAT_SINT32 3
+
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0
+#define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2
+#define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO 2
+#define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3
+#define BRW_SAMPLER_MESSAGE_SIMD8_LD 3
+#define BRW_SAMPLER_MESSAGE_SIMD16_LD 3
+
+#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0
+#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1
+#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2
+#define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3
+#define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4
+
+#define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0
+#define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2
+
+#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2
+#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3
+
+#define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0
+#define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1
+#define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2
+#define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3
+
+#define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0
+#define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1
+#define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2
+
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4
+
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3
+#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4
+#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5
+#define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7
+
+#define BRW_MATH_FUNCTION_INV 1
+#define BRW_MATH_FUNCTION_LOG 2
+#define BRW_MATH_FUNCTION_EXP 3
+#define BRW_MATH_FUNCTION_SQRT 4
+#define BRW_MATH_FUNCTION_RSQ 5
+#define BRW_MATH_FUNCTION_SIN 6 /* was 7 */
+#define BRW_MATH_FUNCTION_COS 7 /* was 8 */
+#define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */
+#define BRW_MATH_FUNCTION_TAN 9
+#define BRW_MATH_FUNCTION_POW 10
+#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11
+#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12
+#define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13
+
+#define BRW_MATH_INTEGER_UNSIGNED 0
+#define BRW_MATH_INTEGER_SIGNED 1
+
+#define BRW_MATH_PRECISION_FULL 0
+#define BRW_MATH_PRECISION_PARTIAL 1
+
+#define BRW_MATH_SATURATE_NONE 0
+#define BRW_MATH_SATURATE_SATURATE 1
+
+#define BRW_MATH_DATA_VECTOR 0
+#define BRW_MATH_DATA_SCALAR 1
+
+#define BRW_URB_OPCODE_WRITE 0
+
+#define BRW_URB_SWIZZLE_NONE 0
+#define BRW_URB_SWIZZLE_INTERLEAVE 1
+#define BRW_URB_SWIZZLE_TRANSPOSE 2
+
+#define BRW_SCRATCH_SPACE_SIZE_1K 0
+#define BRW_SCRATCH_SPACE_SIZE_2K 1
+#define BRW_SCRATCH_SPACE_SIZE_4K 2
+#define BRW_SCRATCH_SPACE_SIZE_8K 3
+#define BRW_SCRATCH_SPACE_SIZE_16K 4
+#define BRW_SCRATCH_SPACE_SIZE_32K 5
+#define BRW_SCRATCH_SPACE_SIZE_64K 6
+#define BRW_SCRATCH_SPACE_SIZE_128K 7
+#define BRW_SCRATCH_SPACE_SIZE_256K 8
+#define BRW_SCRATCH_SPACE_SIZE_512K 9
+#define BRW_SCRATCH_SPACE_SIZE_1M 10
+#define BRW_SCRATCH_SPACE_SIZE_2M 11
+
+
+
+
+#define CMD_URB_FENCE 0x6000
+#define CMD_CONST_BUFFER_STATE 0x6001
+#define CMD_CONST_BUFFER 0x6002
+
+#define CMD_STATE_BASE_ADDRESS 0x6101
+#define CMD_STATE_INSN_POINTER 0x6102
+#define CMD_PIPELINE_SELECT 0x6104
+
+#define CMD_PIPELINED_STATE_POINTERS 0x7800
+#define CMD_BINDING_TABLE_PTRS 0x7801
+#define CMD_VERTEX_BUFFER 0x7808
+#define CMD_VERTEX_ELEMENT 0x7809
+#define CMD_INDEX_BUFFER 0x780a
+#define CMD_VF_STATISTICS 0x780b
+
+#define CMD_DRAW_RECT 0x7900
+#define CMD_BLEND_CONSTANT_COLOR 0x7901
+#define CMD_CHROMA_KEY 0x7904
+#define CMD_DEPTH_BUFFER 0x7905
+#define CMD_POLY_STIPPLE_OFFSET 0x7906
+#define CMD_POLY_STIPPLE_PATTERN 0x7907
+#define CMD_LINE_STIPPLE_PATTERN 0x7908
+#define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7908
+
+#define CMD_PIPE_CONTROL 0x7a00
+
+#define CMD_3D_PRIM 0x7b00
+
+#define CMD_MI_FLUSH 0x0200
+
+
+/* Various values from the R0 vertex header:
+ */
+#define R02_PRIM_END 0x1
+#define R02_PRIM_START 0x2
+
+
+
+#endif
diff --git a/src/brw_structs.h b/src/brw_structs.h
new file mode 100644
index 00000000..d2f9be0f
--- /dev/null
+++ b/src/brw_structs.h
@@ -0,0 +1,1340 @@
+ /**************************************************************************
+ *
+ * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#ifndef BRW_STRUCTS_H
+#define BRW_STRUCTS_H
+
+/* Command packets:
+ */
+struct header
+{
+ unsigned int length:16;
+ unsigned int opcode:16;
+} bits;
+
+
+union header_union
+{
+ struct header bits;
+ unsigned int dword;
+};
+
+struct brw_3d_control
+{
+ struct
+ {
+ unsigned int length:8;
+ unsigned int notify_enable:1;
+ unsigned int pad:3;
+ unsigned int wc_flush_enable:1;
+ unsigned int depth_stall_enable:1;
+ unsigned int operation:2;
+ unsigned int opcode:16;
+ } header;
+
+ struct
+ {
+ unsigned int pad:2;
+ unsigned int dest_addr_type:1;
+ unsigned int dest_addr:29;
+ } dest;
+
+ unsigned int dword2;
+ unsigned int dword3;
+};
+
+
+struct brw_3d_primitive
+{
+ struct
+ {
+ unsigned int length:8;
+ unsigned int pad:2;
+ unsigned int topology:5;
+ unsigned int indexed:1;
+ unsigned int opcode:16;
+ } header;
+
+ unsigned int verts_per_instance;
+ unsigned int start_vert_location;
+ unsigned int instance_count;
+ unsigned int start_instance_location;
+ unsigned int base_vert_location;
+};
+
+/* These seem to be passed around as function args, so it works out
+ * better to keep them as #defines:
+ */
+#define BRW_FLUSH_READ_CACHE 0x1
+#define BRW_FLUSH_STATE_CACHE 0x2
+#define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4
+#define BRW_FLUSH_SNAPSHOT_COUNTERS 0x8
+
+struct brw_mi_flush
+{
+ unsigned int flags:4;
+ unsigned int pad:12;
+ unsigned int opcode:16;
+};
+
+struct brw_vf_statistics
+{
+ unsigned int statistics_enable:1;
+ unsigned int pad:15;
+ unsigned int opcode:16;
+};
+
+
+
+struct brw_binding_table_pointers
+{
+ struct header header;
+ unsigned int vs;
+ unsigned int gs;
+ unsigned int clp;
+ unsigned int sf;
+ unsigned int wm;
+};
+
+
+struct brw_blend_constant_color
+{
+ struct header header;
+ float blend_constant_color[4];
+};
+
+
+struct brw_depthbuffer
+{
+ union header_union header;
+
+ union {
+ struct {
+ unsigned int pitch:18;
+ unsigned int format:3;
+ unsigned int pad:4;
+ unsigned int depth_offset_disable:1;
+ unsigned int tile_walk:1;
+ unsigned int tiled_surface:1;
+ unsigned int pad2:1;
+ unsigned int surface_type:3;
+ } bits;
+ unsigned int dword;
+ } dword1;
+
+ unsigned int dword2_base_addr;
+
+ union {
+ struct {
+ unsigned int pad:1;
+ unsigned int mipmap_layout:1;
+ unsigned int lod:4;
+ unsigned int width:13;
+ unsigned int height:13;
+ } bits;
+ unsigned int dword;
+ } dword3;
+
+ union {
+ struct {
+ unsigned int pad:12;
+ unsigned int min_array_element:9;
+ unsigned int depth:11;
+ } bits;
+ unsigned int dword;
+ } dword4;
+};
+
+struct brw_drawrect
+{
+ struct header header;
+ unsigned int xmin:16;
+ unsigned int ymin:16;
+ unsigned int xmax:16;
+ unsigned int ymax:16;
+ unsigned int xorg:16;
+ unsigned int yorg:16;
+};
+
+
+
+
+struct brw_global_depth_offset_clamp
+{
+ struct header header;
+ float depth_offset_clamp;
+};
+
+struct brw_indexbuffer
+{
+ union {
+ struct
+ {
+ unsigned int length:8;
+ unsigned int index_format:2;
+ unsigned int cut_index_enable:1;
+ unsigned int pad:5;
+ unsigned int opcode:16;
+ } bits;
+ unsigned int dword;
+
+ } header;
+
+ unsigned int buffer_start;
+ unsigned int buffer_end;
+};
+
+
+struct brw_line_stipple
+{
+ struct header header;
+
+ struct
+ {
+ unsigned int pattern:16;
+ unsigned int pad:16;
+ } bits0;
+
+ struct
+ {
+ unsigned int repeat_count:9;
+ unsigned int pad:7;
+ unsigned int inverse_repeat_count:16;
+ } bits1;
+};
+
+
+struct brw_pipelined_state_pointers
+{
+ struct header header;
+
+ struct {
+ unsigned int pad:5;
+ unsigned int offset:27;
+ } vs;
+
+ struct
+ {
+ unsigned int enable:1;
+ unsigned int pad:4;
+ unsigned int offset:27;
+ } gs;
+
+ struct
+ {
+ unsigned int enable:1;
+ unsigned int pad:4;
+ unsigned int offset:27;
+ } clp;
+
+ struct
+ {
+ unsigned int pad:5;
+ unsigned int offset:27;
+ } sf;
+
+ struct
+ {
+ unsigned int pad:5;
+ unsigned int offset:27;
+ } wm;
+
+ struct
+ {
+ unsigned int pad:5;
+ unsigned int offset:27; /* KW: check me! */
+ } cc;
+};
+
+
+struct brw_polygon_stipple_offset
+{
+ struct header header;
+
+ struct {
+ unsigned int y_offset:5;
+ unsigned int pad:3;
+ unsigned int x_offset:5;
+ unsigned int pad0:19;
+ } bits0;
+};
+
+
+
+struct brw_polygon_stipple
+{
+ struct header header;
+ unsigned int stipple[32];
+};
+
+
+
+struct brw_pipeline_select
+{
+ struct
+ {
+ unsigned int pipeline_select:1;
+ unsigned int pad:15;
+ unsigned int opcode:16;
+ } header;
+};
+
+
+struct brw_pipe_control
+{
+ struct
+ {
+ unsigned int length:8;
+ unsigned int notify_enable:1;
+ unsigned int pad:2;
+ unsigned int instruction_state_cache_flush_enable:1;
+ unsigned int write_cache_flush_enable:1;
+ unsigned int depth_stall_enable:1;
+ unsigned int post_sync_operation:2;
+
+ unsigned int opcode:16;
+ } header;
+
+ struct
+ {
+ unsigned int pad:2;
+ unsigned int dest_addr_type:1;
+ unsigned int dest_addr:29;
+ } bits1;
+
+ unsigned int data0;
+ unsigned int data1;
+};
+
+
+struct brw_urb_fence
+{
+ struct
+ {
+ unsigned int length:8;
+ unsigned int vs_realloc:1;
+ unsigned int gs_realloc:1;
+ unsigned int clp_realloc:1;
+ unsigned int sf_realloc:1;
+ unsigned int vfe_realloc:1;
+ unsigned int cs_realloc:1;
+ unsigned int pad:2;
+ unsigned int opcode:16;
+ } header;
+
+ struct
+ {
+ unsigned int vs_fence:10;
+ unsigned int gs_fence:10;
+ unsigned int clp_fence:10;
+ unsigned int pad:2;
+ } bits0;
+
+ struct
+ {
+ unsigned int sf_fence:10;
+ unsigned int vf_fence:10;
+ unsigned int cs_fence:10;
+ unsigned int pad:2;
+ } bits1;
+};
+
+struct brw_constant_buffer_state /* previously brw_command_streamer */
+{
+ struct header header;
+
+ struct
+ {
+ unsigned int nr_urb_entries:3;
+ unsigned int pad:1;
+ unsigned int urb_entry_size:5;
+ unsigned int pad0:23;
+ } bits0;
+};
+
+struct brw_constant_buffer
+{
+ struct
+ {
+ unsigned int length:8;
+ unsigned int valid:1;
+ unsigned int pad:7;
+ unsigned int opcode:16;
+ } header;
+
+ struct
+ {
+ unsigned int buffer_length:6;
+ unsigned int buffer_address:26;
+ } bits0;
+};
+
+struct brw_state_base_address
+{
+ struct header header;
+
+ struct
+ {
+ unsigned int modify_enable:1;
+ unsigned int pad:4;
+ unsigned int general_state_address:27;
+ } bits0;
+
+ struct
+ {
+ unsigned int modify_enable:1;
+ unsigned int pad:4;
+ unsigned int surface_state_address:27;
+ } bits1;
+
+ struct
+ {
+ unsigned int modify_enable:1;
+ unsigned int pad:4;
+ unsigned int indirect_object_state_address:27;
+ } bits2;
+
+ struct
+ {
+ unsigned int modify_enable:1;
+ unsigned int pad:11;
+ unsigned int general_state_upper_bound:20;
+ } bits3;
+
+ struct
+ {
+ unsigned int modify_enable:1;
+ unsigned int pad:11;
+ unsigned int indirect_object_state_upper_bound:20;
+ } bits4;
+};
+
+struct brw_state_prefetch
+{
+ struct header header;
+
+ struct
+ {
+ unsigned int prefetch_count:3;
+ unsigned int pad:3;
+ unsigned int prefetch_pointer:26;
+ } bits0;
+};
+
+struct brw_system_instruction_pointer
+{
+ struct header header;
+
+ struct
+ {
+ unsigned int pad:4;
+ unsigned int system_instruction_pointer:28;
+ } bits0;
+};
+
+
+
+
+/* State structs for the various fixed function units:
+ */
+
+
+struct thread0
+{
+ unsigned int pad0:1;
+ unsigned int grf_reg_count:3;
+ unsigned int pad1:2;
+ unsigned int kernel_start_pointer:26;
+};
+
+struct thread1
+{
+ unsigned int ext_halt_exception_enable:1;
+ unsigned int sw_exception_enable:1;
+ unsigned int mask_stack_exception_enable:1;
+ unsigned int timeout_exception_enable:1;
+ unsigned int illegal_op_exception_enable:1;
+ unsigned int pad0:3;
+ unsigned int depth_coef_urb_read_offset:6; /* WM only */
+ unsigned int pad1:2;
+ unsigned int floating_point_mode:1;
+ unsigned int thread_priority:1;
+ unsigned int binding_table_entry_count:8;
+ unsigned int pad3:5;
+ unsigned int single_program_flow:1;
+};
+
+struct thread2
+{
+ unsigned int per_thread_scratch_space:4;
+ unsigned int pad0:6;
+ unsigned int scratch_space_base_pointer:22;
+};
+
+
+struct thread3
+{
+ unsigned int dispatch_grf_start_reg:4;
+ unsigned int urb_entry_read_offset:6;
+ unsigned int pad0:1;
+ unsigned int urb_entry_read_length:6;
+ unsigned int pad1:1;
+ unsigned int const_urb_entry_read_offset:6;
+ unsigned int pad2:1;
+ unsigned int const_urb_entry_read_length:6;
+ unsigned int pad3:1;
+};
+
+
+
+struct brw_clip_unit_state
+{
+ struct thread0 thread0;
+ struct thread1 thread1;
+ struct thread2 thread2;
+ struct thread3 thread3;
+
+ struct
+ {
+ unsigned int pad0:9;
+ unsigned int gs_output_stats:1; /* not always */
+ unsigned int stats_enable:1;
+ unsigned int nr_urb_entries:7;
+ unsigned int pad1:1;
+ unsigned int urb_entry_allocation_size:5;
+ unsigned int pad2:1;
+ unsigned int max_threads:6; /* may be less */
+ unsigned int pad3:1;
+ } thread4;
+
+ struct
+ {
+ unsigned int pad0:13;
+ unsigned int clip_mode:3;
+ unsigned int userclip_enable_flags:8;
+ unsigned int userclip_must_clip:1;
+ unsigned int pad1:1;
+ unsigned int guard_band_enable:1;
+ unsigned int viewport_z_clip_enable:1;
+ unsigned int viewport_xy_clip_enable:1;
+ unsigned int vertex_position_space:1;
+ unsigned int api_mode:1;
+ unsigned int pad2:1;
+ } clip5;
+
+ struct
+ {
+ unsigned int pad0:5;
+ unsigned int clipper_viewport_state_ptr:27;
+ } clip6;
+
+
+ float viewport_xmin;
+ float viewport_xmax;
+ float viewport_ymin;
+ float viewport_ymax;
+};
+
+
+
+struct brw_cc_unit_state
+{
+ struct
+ {
+ unsigned int pad0:3;
+ unsigned int bf_stencil_pass_depth_pass_op:3;
+ unsigned int bf_stencil_pass_depth_fail_op:3;
+ unsigned int bf_stencil_fail_op:3;
+ unsigned int bf_stencil_func:3;
+ unsigned int bf_stencil_enable:1;
+ unsigned int pad1:2;
+ unsigned int stencil_write_enable:1;
+ unsigned int stencil_pass_depth_pass_op:3;
+ unsigned int stencil_pass_depth_fail_op:3;
+ unsigned int stencil_fail_op:3;
+ unsigned int stencil_func:3;
+ unsigned int stencil_enable:1;
+ } cc0;
+
+
+ struct
+ {
+ unsigned int bf_stencil_ref:8;
+ unsigned int stencil_write_mask:8;
+ unsigned int stencil_test_mask:8;
+ unsigned int stencil_ref:8;
+ } cc1;
+
+
+ struct
+ {
+ unsigned int logicop_enable:1;
+ unsigned int pad0:10;
+ unsigned int depth_write_enable:1;
+ unsigned int depth_test_function:3;
+ unsigned int depth_test:1;
+ unsigned int bf_stencil_write_mask:8;
+ unsigned int bf_stencil_test_mask:8;
+ } cc2;
+
+
+ struct
+ {
+ unsigned int pad0:8;
+ unsigned int alpha_test_func:3;
+ unsigned int alpha_test:1;
+ unsigned int blend_enable:1;
+ unsigned int ia_blend_enable:1;
+ unsigned int pad1:1;
+ unsigned int alpha_test_format:1;
+ unsigned int pad2:16;
+ } cc3;
+
+ struct
+ {
+ unsigned int pad0:5;
+ unsigned int cc_viewport_state_offset:27;
+ } cc4;
+
+ struct
+ {
+ unsigned int pad0:2;
+ unsigned int ia_dest_blend_factor:5;
+ unsigned int ia_src_blend_factor:5;
+ unsigned int ia_blend_function:3;
+ unsigned int statistics_enable:1;
+ unsigned int logicop_func:4;
+ unsigned int pad1:11;
+ unsigned int dither_enable:1;
+ } cc5;
+
+ struct
+ {
+ unsigned int clamp_post_alpha_blend:1;
+ unsigned int clamp_pre_alpha_blend:1;
+ unsigned int clamp_range:2;
+ unsigned int pad0:11;
+ unsigned int y_dither_offset:2;
+ unsigned int x_dither_offset:2;
+ unsigned int dest_blend_factor:5;
+ unsigned int src_blend_factor:5;
+ unsigned int blend_function:3;
+ } cc6;
+
+ struct {
+ union {
+ float f;
+ unsigned char ub[4];
+ } alpha_ref;
+ } cc7;
+};
+
+
+
+struct brw_sf_unit_state
+{
+ struct thread0 thread0;
+ struct {
+ unsigned int pad0:7;
+ unsigned int sw_exception_enable:1;
+ unsigned int pad1:3;
+ unsigned int mask_stack_exception_enable:1;
+ unsigned int pad2:1;
+ unsigned int illegal_op_exception_enable:1;
+ unsigned int pad3:2;
+ unsigned int floating_point_mode:1;
+ unsigned int thread_priority:1;
+ unsigned int binding_table_entry_count:8;
+ unsigned int pad4:5;
+ unsigned int single_program_flow:1;
+ } sf1;
+
+ struct thread2 thread2;
+ struct thread3 thread3;
+
+ struct
+ {
+ unsigned int pad0:10;
+ unsigned int stats_enable:1;
+ unsigned int nr_urb_entries:7;
+ unsigned int pad1:1;
+ unsigned int urb_entry_allocation_size:5;
+ unsigned int pad2:1;
+ unsigned int max_threads:6;
+ unsigned int pad3:1;
+ } thread4;
+
+ struct
+ {
+ unsigned int front_winding:1;
+ unsigned int viewport_transform:1;
+ unsigned int pad0:3;
+ unsigned int sf_viewport_state_offset:27;
+ } sf5;
+
+ struct
+ {
+ unsigned int pad0:9;
+ unsigned int dest_org_vbias:4;
+ unsigned int dest_org_hbias:4;
+ unsigned int scissor:1;
+ unsigned int disable_2x2_trifilter:1;
+ unsigned int disable_zero_pix_trifilter:1;
+ unsigned int point_rast_rule:2;
+ unsigned int line_endcap_aa_region_width:2;
+ unsigned int line_width:4;
+ unsigned int fast_scissor_disable:1;
+ unsigned int cull_mode:2;
+ unsigned int aa_enable:1;
+ } sf6;
+
+ struct
+ {
+ unsigned int point_size:11;
+ unsigned int use_point_size_state:1;
+ unsigned int subpixel_precision:1;
+ unsigned int sprite_point:1;
+ unsigned int pad0:11;
+ unsigned int trifan_pv:2;
+ unsigned int linestrip_pv:2;
+ unsigned int tristrip_pv:2;
+ unsigned int line_last_pixel_enable:1;
+ } sf7;
+
+};
+
+
+struct brw_gs_unit_state
+{
+ struct thread0 thread0;
+ struct thread1 thread1;
+ struct thread2 thread2;
+ struct thread3 thread3;
+
+ struct
+ {
+ unsigned int pad0:10;
+ unsigned int stats_enable:1;
+ unsigned int nr_urb_entries:7;
+ unsigned int pad1:1;
+ unsigned int urb_entry_allocation_size:5;
+ unsigned int pad2:1;
+ unsigned int max_threads:1;
+ unsigned int pad3:6;
+ } thread4;
+
+ struct
+ {
+ unsigned int sampler_count:3;
+ unsigned int pad0:2;
+ unsigned int sampler_state_pointer:27;
+ } gs5;
+
+
+ struct
+ {
+ unsigned int max_vp_index:4;
+ unsigned int pad0:26;
+ unsigned int reorder_enable:1;
+ unsigned int pad1:1;
+ } gs6;
+};
+
+
+struct brw_vs_unit_state
+{
+ struct thread0 thread0;
+ struct thread1 thread1;
+ struct thread2 thread2;
+ struct thread3 thread3;
+
+ struct
+ {
+ unsigned int pad0:10;
+ unsigned int stats_enable:1;
+ unsigned int nr_urb_entries:7;
+ unsigned int pad1:1;
+ unsigned int urb_entry_allocation_size:5;
+ unsigned int pad2:1;
+ unsigned int max_threads:4;
+ unsigned int pad3:3;
+ } thread4;
+
+ struct
+ {
+ unsigned int sampler_count:3;
+ unsigned int pad0:2;
+ unsigned int sampler_state_pointer:27;
+ } vs5;
+
+ struct
+ {
+ unsigned int vs_enable:1;
+ unsigned int vert_cache_disable:1;
+ unsigned int pad0:30;
+ } vs6;
+};
+
+
+struct brw_wm_unit_state
+{
+ struct thread0 thread0;
+ struct thread1 thread1;
+ struct thread2 thread2;
+ struct thread3 thread3;
+
+ struct {
+ unsigned int stats_enable:1;
+ unsigned int pad0:1;
+ unsigned int sampler_count:3;
+ unsigned int sampler_state_pointer:27;
+ } wm4;
+
+ struct
+ {
+ unsigned int enable_8_pix:1;
+ unsigned int enable_16_pix:1;
+ unsigned int enable_32_pix:1;
+ unsigned int pad0:7;
+ unsigned int legacy_global_depth_bias:1;
+ unsigned int line_stipple:1;
+ unsigned int depth_offset:1;
+ unsigned int polygon_stipple:1;
+ unsigned int line_aa_region_width:2;
+ unsigned int line_endcap_aa_region_width:2;
+ unsigned int early_depth_test:1;
+ unsigned int thread_dispatch_enable:1;
+ unsigned int program_uses_depth:1;
+ unsigned int program_computes_depth:1;
+ unsigned int program_uses_killpixel:1;
+ unsigned int legacy_line_rast: 1;
+ unsigned int pad1:1;
+ unsigned int max_threads:6;
+ unsigned int pad2:1;
+ } wm5;
+
+ float global_depth_offset_constant;
+ float global_depth_offset_scale;
+};
+
+struct brw_sampler_default_color {
+ float color[4];
+};
+
+struct brw_sampler_state
+{
+
+ struct
+ {
+ unsigned int shadow_function:3;
+ unsigned int lod_bias:11;
+ unsigned int min_filter:3;
+ unsigned int mag_filter:3;
+ unsigned int mip_filter:2;
+ unsigned int base_level:5;
+ unsigned int pad:1;
+ unsigned int lod_preclamp:1;
+ unsigned int default_color_mode:1;
+ unsigned int pad0:1;
+ unsigned int disable:1;
+ } ss0;
+
+ struct
+ {
+ unsigned int r_wrap_mode:3;
+ unsigned int t_wrap_mode:3;
+ unsigned int s_wrap_mode:3;
+ unsigned int pad:3;
+ unsigned int max_lod:10;
+ unsigned int min_lod:10;
+ } ss1;
+
+
+ struct
+ {
+ unsigned int pad:5;
+ unsigned int default_color_pointer:27;
+ } ss2;
+
+ struct
+ {
+ unsigned int pad:19;
+ unsigned int max_aniso:3;
+ unsigned int chroma_key_mode:1;
+ unsigned int chroma_key_index:2;
+ unsigned int chroma_key_enable:1;
+ unsigned int monochrome_filter_width:3;
+ unsigned int monochrome_filter_height:3;
+ } ss3;
+};
+
+
+struct brw_clipper_viewport
+{
+ float xmin;
+ float xmax;
+ float ymin;
+ float ymax;
+};
+
+struct brw_cc_viewport
+{
+ float min_depth;
+ float max_depth;
+};
+
+struct brw_sf_viewport
+{
+ struct {
+ float m00;
+ float m11;
+ float m22;
+ float m30;
+ float m31;
+ float m32;
+ } viewport;
+
+ struct {
+ short xmin;
+ short ymin;
+ short xmax;
+ short ymax;
+ } scissor;
+};
+
+/* Documented in the subsystem/shared-functions/sampler chapter...
+ */
+struct brw_surface_state
+{
+ struct {
+ unsigned int cube_pos_z:1;
+ unsigned int cube_neg_z:1;
+ unsigned int cube_pos_y:1;
+ unsigned int cube_neg_y:1;
+ unsigned int cube_pos_x:1;
+ unsigned int cube_neg_x:1;
+ unsigned int pad:3;
+ unsigned int render_cache_read_mode:1;
+ unsigned int mipmap_layout_mode:1;
+ unsigned int vert_line_stride_ofs:1;
+ unsigned int vert_line_stride:1;
+ unsigned int color_blend:1;
+ unsigned int writedisable_blue:1;
+ unsigned int writedisable_green:1;
+ unsigned int writedisable_red:1;
+ unsigned int writedisable_alpha:1;
+ unsigned int surface_format:9;
+ unsigned int data_return_format:1;
+ unsigned int pad0:1;
+ unsigned int surface_type:3;
+ } ss0;
+
+ struct {
+ unsigned int base_addr;
+ } ss1;
+
+ struct {
+ unsigned int render_target_rotation:2;
+ unsigned int mip_count:4;
+ unsigned int width:13;
+ unsigned int height:13;
+ } ss2;
+
+ struct {
+ unsigned int tile_walk:1;
+ unsigned int tiled_surface:1;
+ unsigned int pad:1;
+ unsigned int pitch:18;
+ unsigned int depth:11;
+ } ss3;
+
+ struct {
+ unsigned int pad:19;
+ unsigned int min_array_elt:9;
+ unsigned int min_lod:4;
+ } ss4;
+};
+
+
+
+struct brw_vertex_buffer_state
+{
+ struct {
+ unsigned int pitch:11;
+ unsigned int pad:15;
+ unsigned int access_type:1;
+ unsigned int vb_index:5;
+ } vb0;
+
+ unsigned int start_addr;
+ unsigned int max_index;
+#if 1
+ unsigned int instance_data_step_rate; /* not included for sequential/random vertices? */
+#endif
+};
+
+#define BRW_VBP_MAX 17
+
+struct brw_vb_array_state {
+ struct header header;
+ struct brw_vertex_buffer_state vb[BRW_VBP_MAX];
+};
+
+
+struct brw_vertex_element_state
+{
+ struct
+ {
+ unsigned int src_offset:11;
+ unsigned int pad:5;
+ unsigned int src_format:9;
+ unsigned int pad0:1;
+ unsigned int valid:1;
+ unsigned int vertex_buffer_index:5;
+ } ve0;
+
+ struct
+ {
+ unsigned int dst_offset:8;
+ unsigned int pad:8;
+ unsigned int vfcomponent3:4;
+ unsigned int vfcomponent2:4;
+ unsigned int vfcomponent1:4;
+ unsigned int vfcomponent0:4;
+ } ve1;
+};
+
+#define BRW_VEP_MAX 18
+
+struct brw_vertex_element_packet {
+ struct header header;
+ struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */
+};
+
+
+struct brw_urb_immediate {
+ unsigned int opcode:4;
+ unsigned int offset:6;
+ unsigned int swizzle_control:2;
+ unsigned int pad:1;
+ unsigned int allocate:1;
+ unsigned int used:1;
+ unsigned int complete:1;
+ unsigned int response_length:4;
+ unsigned int msg_length:4;
+ unsigned int msg_target:4;
+ unsigned int pad1:3;
+ unsigned int end_of_thread:1;
+};
+
+/* Instruction format for the execution units:
+ */
+
+struct brw_instruction
+{
+ struct
+ {
+ unsigned int opcode:7;
+ unsigned int pad:1;
+ unsigned int access_mode:1;
+ unsigned int mask_control:1;
+ unsigned int dependency_control:2;
+ unsigned int compression_control:2;
+ unsigned int thread_control:2;
+ unsigned int predicate_control:4;
+ unsigned int predicate_inverse:1;
+ unsigned int execution_size:3;
+ unsigned int destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */
+ unsigned int pad0:2;
+ unsigned int debug_control:1;
+ unsigned int saturate:1;
+ } header;
+
+ union {
+ struct
+ {
+ unsigned int dest_reg_file:2;
+ unsigned int dest_reg_type:3;
+ unsigned int src0_reg_file:2;
+ unsigned int src0_reg_type:3;
+ unsigned int src1_reg_file:2;
+ unsigned int src1_reg_type:3;
+ unsigned int pad:1;
+ unsigned int dest_subreg_nr:5;
+ unsigned int dest_reg_nr:8;
+ unsigned int dest_horiz_stride:2;
+ unsigned int dest_address_mode:1;
+ } da1;
+
+ struct
+ {
+ unsigned int dest_reg_file:2;
+ unsigned int dest_reg_type:3;
+ unsigned int src0_reg_file:2;
+ unsigned int src0_reg_type:3;
+ unsigned int pad:6;
+ int dest_indirect_offset:10; /* offset against the deref'd address reg */
+ unsigned int dest_subreg_nr:3; /* subnr for the address reg a0.x */
+ unsigned int dest_horiz_stride:2;
+ unsigned int dest_address_mode:1;
+ } ia1;
+
+ struct
+ {
+ unsigned int dest_reg_file:2;
+ unsigned int dest_reg_type:3;
+ unsigned int src0_reg_file:2;
+ unsigned int src0_reg_type:3;
+ unsigned int src1_reg_file:2;
+ unsigned int src1_reg_type:3;
+ unsigned int pad0:1;
+ unsigned int dest_writemask:4;
+ unsigned int dest_subreg_nr:1;
+ unsigned int dest_reg_nr:8;
+ unsigned int pad1:2;
+ unsigned int dest_address_mode:1;
+ } da16;
+
+ struct
+ {
+ unsigned int dest_reg_file:2;
+ unsigned int dest_reg_type:3;
+ unsigned int src0_reg_file:2;
+ unsigned int src0_reg_type:3;
+ unsigned int pad0:6;
+ unsigned int dest_writemask:4;
+ int dest_indirect_offset:6;
+ unsigned int dest_subreg_nr:3;
+ unsigned int pad1:2;
+ unsigned int dest_address_mode:1;
+ } ia16;
+ } bits1;
+
+
+ union {
+ struct
+ {
+ unsigned int src0_subreg_nr:5;
+ unsigned int src0_reg_nr:8;
+ unsigned int src0_abs:1;
+ unsigned int src0_negate:1;
+ unsigned int src0_address_mode:1;
+ unsigned int src0_horiz_stride:2;
+ unsigned int src0_width:3;
+ unsigned int src0_vert_stride:4;
+ unsigned int flag_reg_nr:1;
+ unsigned int pad:6;
+ } da1;
+
+ struct
+ {
+ int src0_indirect_offset:10;
+ unsigned int src0_subreg_nr:3;
+ unsigned int src0_abs:1;
+ unsigned int src0_negate:1;
+ unsigned int src0_address_mode:1;
+ unsigned int src0_horiz_stride:2;
+ unsigned int src0_width:3;
+ unsigned int src0_vert_stride:4;
+ unsigned int flag_reg_nr:1;
+ unsigned int pad:6;
+ } ia1;
+
+ struct
+ {
+ unsigned int src0_swz_x:2;
+ unsigned int src0_swz_y:2;
+ unsigned int src0_subreg_nr:1;
+ unsigned int src0_reg_nr:8;
+ unsigned int src0_abs:1;
+ unsigned int src0_negate:1;
+ unsigned int src0_address_mode:1;
+ unsigned int src0_swz_z:2;
+ unsigned int src0_swz_w:2;
+ unsigned int pad0:1;
+ unsigned int src0_vert_stride:4;
+ unsigned int flag_reg_nr:1;
+ unsigned int pad1:6;
+ } da16;
+
+ struct
+ {
+ unsigned int src0_swz_x:2;
+ unsigned int src0_swz_y:2;
+ int src0_indirect_offset:6;
+ unsigned int src0_subreg_nr:3;
+ unsigned int src0_abs:1;
+ unsigned int src0_negate:1;
+ unsigned int src0_address_mode:1;
+ unsigned int src0_swz_z:2;
+ unsigned int src0_swz_w:2;
+ unsigned int pad0:1;
+ unsigned int src0_vert_stride:4;
+ unsigned int flag_reg_nr:1;
+ unsigned int pad1:6;
+ } ia16;
+
+ } bits2;
+
+ union
+ {
+ struct
+ {
+ unsigned int src1_subreg_nr:5;
+ unsigned int src1_reg_nr:8;
+ unsigned int src1_abs:1;
+ unsigned int src1_negate:1;
+ unsigned int pad:1;
+ unsigned int src1_horiz_stride:2;
+ unsigned int src1_width:3;
+ unsigned int src1_vert_stride:4;
+ unsigned int pad0:7;
+ } da1;
+
+ struct
+ {
+ unsigned int src1_swz_x:2;
+ unsigned int src1_swz_y:2;
+ unsigned int src1_subreg_nr:1;
+ unsigned int src1_reg_nr:8;
+ unsigned int src1_abs:1;
+ unsigned int src1_negate:1;
+ unsigned int pad0:1;
+ unsigned int src1_swz_z:2;
+ unsigned int src1_swz_w:2;
+ unsigned int pad1:1;
+ unsigned int src1_vert_stride:4;
+ unsigned int pad2:7;
+ } da16;
+
+ struct
+ {
+ int src1_indirect_offset:10;
+ unsigned int src1_subreg_nr:3;
+ unsigned int src1_abs:1;
+ unsigned int src1_negate:1;
+ unsigned int pad0:1;
+ unsigned int src1_horiz_stride:2;
+ unsigned int src1_width:3;
+ unsigned int src1_vert_stride:4;
+ unsigned int flag_reg_nr:1;
+ unsigned int pad1:6;
+ } ia1;
+
+ struct
+ {
+ unsigned int src1_swz_x:2;
+ unsigned int src1_swz_y:2;
+ int src1_indirect_offset:6;
+ unsigned int src1_subreg_nr:3;
+ unsigned int src1_abs:1;
+ unsigned int src1_negate:1;
+ unsigned int pad0:1;
+ unsigned int src1_swz_z:2;
+ unsigned int src1_swz_w:2;
+ unsigned int pad1:1;
+ unsigned int src1_vert_stride:4;
+ unsigned int flag_reg_nr:1;
+ unsigned int pad2:6;
+ } ia16;
+
+
+ struct
+ {
+ int jump_count:16; /* note: signed */
+ unsigned int pop_count:4;
+ unsigned int pad0:12;
+ } if_else;
+
+ struct {
+ unsigned int function:4;
+ unsigned int int_type:1;
+ unsigned int precision:1;
+ unsigned int saturate:1;
+ unsigned int data_type:1;
+ unsigned int pad0:8;
+ unsigned int response_length:4;
+ unsigned int msg_length:4;
+ unsigned int msg_target:4;
+ unsigned int pad1:3;
+ unsigned int end_of_thread:1;
+ } math;
+
+ struct {
+ unsigned int binding_table_index:8;
+ unsigned int sampler:4;
+ unsigned int return_format:2;
+ unsigned int msg_type:2;
+ unsigned int response_length:4;
+ unsigned int msg_length:4;
+ unsigned int msg_target:4;
+ unsigned int pad1:3;
+ unsigned int end_of_thread:1;
+ } sampler;
+
+ struct brw_urb_immediate urb;
+
+ struct {
+ unsigned int binding_table_index:8;
+ unsigned int msg_control:4;
+ unsigned int msg_type:2;
+ unsigned int target_cache:2;
+ unsigned int response_length:4;
+ unsigned int msg_length:4;
+ unsigned int msg_target:4;
+ unsigned int pad1:3;
+ unsigned int end_of_thread:1;
+ } dp_read;
+
+ struct {
+ unsigned int binding_table_index:8;
+ unsigned int msg_control:3;
+ unsigned int pixel_scoreboard_clear:1;
+ unsigned int msg_type:3;
+ unsigned int send_commit_msg:1;
+ unsigned int response_length:4;
+ unsigned int msg_length:4;
+ unsigned int msg_target:4;
+ unsigned int pad1:3;
+ unsigned int end_of_thread:1;
+ } dp_write;
+
+ struct {
+ unsigned int pad:16;
+ unsigned int response_length:4;
+ unsigned int msg_length:4;
+ unsigned int msg_target:4;
+ unsigned int pad1:3;
+ unsigned int end_of_thread:1;
+ } generic;
+
+ unsigned int ud;
+ } bits3;
+};
+
+
+#endif
diff --git a/src/common.h b/src/common.h
index 31e67b90..ad5ee1de 100644
--- a/src/common.h
+++ b/src/common.h
@@ -130,13 +130,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)
@@ -277,6 +281,26 @@ extern int I810_DEBUG;
#define PCI_CHIP_I945_GM_BRIDGE 0x27A0
#endif
+#ifndef PCI_CHIP_I965_G_1
+#define PCI_CHIP_I965_G_1 0x2982
+#define PCI_CHIP_I965_G_1_BRIDGE 0x2980
+#endif
+
+#ifndef PCI_CHIP_I965_Q
+#define PCI_CHIP_I965_Q 0x2992
+#define PCI_CHIP_I965_Q_BRIDGE 0x2990
+#endif
+
+#ifndef PCI_CHIP_I965_G
+#define PCI_CHIP_I965_G 0x29A2
+#define PCI_CHIP_I965_G_BRIDGE 0x29A0
+#endif
+
+#ifndef PCI_CHIP_I946_GZ
+#define PCI_CHIP_I946_GZ 0x2972
+#define PCI_CHIP_I946_GZ_BRIDGE 0x2970
+#endif
+
#define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 || \
pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -292,7 +316,8 @@ extern int I810_DEBUG;
#define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
#define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
#define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM)
-#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810))
+#define IS_I965G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I965_G || pI810->PciInfo->chipType == PCI_CHIP_I965_G_1 || pI810->PciInfo->chipType == PCI_CHIP_I965_Q || pI810->PciInfo->chipType == PCI_CHIP_I946_GZ)
+#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810))
#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810))
diff --git a/src/i810.h b/src/i810.h
index 044eb60f..852a64a9 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -64,10 +64,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I810_VERSION 4000
#define I810_NAME "I810"
#define I810_DRIVER_NAME "i810"
-#define I810_MAJOR_VERSION 1
-#define I810_MINOR_VERSION 6
-#define I810_PATCHLEVEL 0
-
/* HWMC Surfaces */
#define I810_MAX_SURFACES 7
diff --git a/src/i810_dri.h b/src/i810_dri.h
index 408a4ebb..027a47a9 100644
--- a/src/i810_dri.h
+++ b/src/i810_dri.h
@@ -8,6 +8,10 @@
#define I810_MAX_DRAWABLES 256
+#define I810_MAJOR_VERSION 1
+#define I810_MINOR_VERSION 6
+#define I810_PATCHLEVEL 3
+
typedef struct {
drm_handle_t regs;
drmSize regsSize;
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 7d854df2..22635c86 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -140,6 +140,10 @@ static SymTabRec I810Chipsets[] = {
{PCI_CHIP_I915_GM, "915GM"},
{PCI_CHIP_I945_G, "945G"},
{PCI_CHIP_I945_GM, "945GM"},
+ {PCI_CHIP_I965_G, "965G"},
+ {PCI_CHIP_I965_G_1, "965G"},
+ {PCI_CHIP_I965_Q, "965Q"},
+ {PCI_CHIP_I946_GZ, "946GZ"},
{-1, NULL}
};
@@ -159,6 +163,10 @@ static PciChipsets I810PciChipsets[] = {
{PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
{PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
{PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA},
+ {PCI_CHIP_I965_G, PCI_CHIP_I965_G, RES_SHARED_VGA},
+ {PCI_CHIP_I965_G_1, PCI_CHIP_I965_G_1, RES_SHARED_VGA},
+ {PCI_CHIP_I965_Q, PCI_CHIP_I965_Q, RES_SHARED_VGA},
+ {PCI_CHIP_I946_GZ, PCI_CHIP_I946_GZ, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED }
};
@@ -324,14 +332,13 @@ const char *I810driSymbols[] = {
"DRICreatePCIBusID",
NULL
};
-#endif
+
+#endif /* I830_ONLY */
const char *I810shadowSymbols[] = {
"shadowInit",
"shadowSetup",
"shadowAdd",
- "shadowRemove",
- "shadowUpdateRotatePacked",
NULL
};
@@ -372,7 +379,7 @@ static XF86ModuleVersionInfo i810VersRec = {
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
- I810_MAJOR_VERSION, I810_MINOR_VERSION, I810_PATCHLEVEL,
+ INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_VIDEODRV,
@@ -401,9 +408,9 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin)
#ifdef XF86DRI
I810drmSymbols,
I810driSymbols,
+#endif
I810shadowSymbols,
I810shadowFBSymbols,
-#endif
I810vbeSymbols, vbeOptionalSymbols,
I810ddcSymbols, I810int10Symbols, NULL);
@@ -578,6 +585,10 @@ I810Probe(DriverPtr drv, int flags)
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I965_G:
+ case PCI_CHIP_I965_G_1:
+ case PCI_CHIP_I965_Q:
+ case PCI_CHIP_I946_GZ:
xf86SetEntitySharable(usedChips[i]);
/* Allocate an entity private if necessary */
diff --git a/src/i810_reg.h b/src/i810_reg.h
index e52375f8..05710c48 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -293,8 +293,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define STATE_VAR_UPDATE_DISABLE 0x02
#define PAL_STIP_DISABLE 0x01
-#define INST_DONE 0x2090
-#define INST_PS 0x20c4
#define MEMMODE 0x20dc
@@ -303,6 +301,66 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define IPEIR 0x2088
#define IPEHR 0x208C
+#define INST_DONE 0x2090
+#define INST_PS 0x20c4
+#define IPEIR_I965 0x2064 /* i965 */
+#define IPEHR_I965 0x2068 /* i965 */
+#define INST_DONE_I965 0x206c
+#define INST_PS_I965 0x2070
+#define ACTHD 0x2074
+#define DMA_FADD_P 0x2078
+#define INST_DONE_1 0x207c
+
+#define CACHE_MODE_0 0x2120
+#define CACHE_MODE_1 0x2124
+#define MI_ARB_STATE 0x20e4
+
+#define WIZ_CTL 0x7c00
+#define WIZ_CTL_SINGLE_SUBSPAN (1<<6)
+#define WIZ_CTL_IGNORE_STALLS (1<<5)
+
+#define SVG_WORK_CTL 0x7408
+
+#define TS_CTL 0x7e00
+#define TS_MUX_ERR_CODE (0<<8)
+#define TS_MUX_URB_0 (1<<8)
+#define TS_MUX_DISPATCH_ID_0 (10<<8)
+#define TS_MUX_ERR_CODE_VALID (15<<8)
+#define TS_MUX_TID_0 (16<<8)
+#define TS_MUX_EUID_0 (18<<8)
+#define TS_MUX_FFID_0 (22<<8)
+#define TS_MUX_EOT (26<<8)
+#define TS_MUX_SIDEBAND_0 (27<<8)
+#define TS_SNAP_ALL_CHILD (1<<2)
+#define TS_SNAP_ALL_ROOT (1<<1)
+#define TS_SNAP_ENABLE (1<<0)
+
+#define TS_DEBUG_DATA 0x7e0c
+
+#define TD_CTL 0x8000
+#define TD_CTL2 0x8004
+
+
+#define ECOSKPD 0x21d0
+#define EXCC 0x2028
+
+/* I965 debug regs:
+ */
+#define IA_VERTICES_COUNT_QW 0x2310
+#define IA_PRIMITIVES_COUNT_QW 0x2318
+#define VS_INVOCATION_COUNT_QW 0x2320
+#define GS_INVOCATION_COUNT_QW 0x2328
+#define GS_PRIMITIVES_COUNT_QW 0x2330
+#define CL_INVOCATION_COUNT_QW 0x2338
+#define CL_PRIMITIVES_COUNT_QW 0x2340
+#define PS_INVOCATION_COUNT_QW 0x2348
+#define PS_DEPTH_COUNT_QW 0x2350
+#define TIMESTAMP_QW 0x2358
+#define CLKCMP_QW 0x2360
+
+
+
+
/* General error reporting regs, p296
@@ -366,6 +424,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define FENCE 0x2000
#define FENCE_NR 8
+#define FENCE_NEW 0x3000
+#define FENCE_NEW_NR 16
+
+#define FENCE_LINEAR 0
+#define FENCE_XMAJOR 1
+#define FENCE_YMAJOR 2
+
#define I915G_FENCE_START_MASK 0x0ff00000
#define I830_FENCE_START_MASK 0x07f80000
@@ -772,6 +837,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPBPOS 0x7118C
#define DSPBSIZE 0x71190
+#define DSPASURF 0x7019C
+#define DSPATILEOFF 0x701A4
+
+#define DSPBSURF 0x7119C
+#define DSPBTILEOFF 0x711A4
+
/* Various masks for reserved bits, etc. */
#define I830_FWATER1_MASK (~((1<<11)|(1<<10)|(1<<9)| \
(1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)| \
@@ -866,15 +937,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21)
#define XY_MONO_SRC_BLT_WRITE_RGB (1<<20)
-/* 3d state */
#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 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)
@@ -907,7 +975,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MI_WRITE_DIRTY_STATE (1<<4)
#define MI_END_SCENE (1<<3)
#define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2)
+#define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1)
#define MI_INVALIDATE_MAP_CACHE (1<<0)
+/* broadwater flush bits */
+#define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3)
/* Noop */
#define MI_NOOP 0x00
@@ -921,6 +992,244 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ENABLE_FOG_CONST (1<<24)
#define ENABLE_FOG_DENSITY (1<<23)
+/*
+ * New regs for broadwater -- we need to split this file up sensibly somehow.
+ */
+#define BRW_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \
+ ((Pipeline) << 27) | \
+ ((Opcode) << 24) | \
+ ((Subopcode) << 16))
+
+#define BRW_URB_FENCE BRW_3D(0, 0, 0)
+#define BRW_CS_URB_STATE BRW_3D(0, 0, 1)
+#define BRW_CONSTANT_BUFFER BRW_3D(0, 0, 2)
+#define BRW_STATE_PREFETCH BRW_3D(0, 0, 3)
+
+#define BRW_STATE_BASE_ADDRESS BRW_3D(0, 1, 1)
+#define BRW_STATE_SIP BRW_3D(0, 1, 2)
+#define BRW_PIPELINE_SELECT BRW_3D(0, 1, 4)
+
+#define BRW_MEDIA_STATE_POINTERS BRW_3D(2, 0, 0)
+#define BRW_MEDIA_OBJECT BRW_3D(2, 1, 0)
+
+#define BRW_3DSTATE_PIPELINED_POINTERS BRW_3D(3, 0, 0)
+#define BRW_3DSTATE_BINDING_TABLE_POINTERS BRW_3D(3, 0, 1)
+#define BRW_3DSTATE_VERTEX_BUFFERS BRW_3D(3, 0, 8)
+#define BRW_3DSTATE_VERTEX_ELEMENTS BRW_3D(3, 0, 9)
+#define BRW_3DSTATE_INDEX_BUFFER BRW_3D(3, 0, 0xa)
+#define BRW_3DSTATE_VF_STATISTICS BRW_3D(3, 0, 0xb)
+
+#define BRW_3DSTATE_DRAWING_RECTANGLE BRW_3D(3, 1, 0)
+#define BRW_3DSTATE_CONSTANT_COLOR BRW_3D(3, 1, 1)
+#define BRW_3DSTATE_SAMPLER_PALETTE_LOAD BRW_3D(3, 1, 2)
+#define BRW_3DSTATE_CHROMA_KEY BRW_3D(3, 1, 4)
+#define BRW_3DSTATE_DEPTH_BUFFER BRW_3D(3, 1, 5)
+#define BRW_3DSTATE_POLY_STIPPLE_OFFSET BRW_3D(3, 1, 6)
+#define BRW_3DSTATE_POLY_STIPPLE_PATTERN BRW_3D(3, 1, 7)
+#define BRW_3DSTATE_LINE_STIPPLE BRW_3D(3, 1, 8)
+#define BRW_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP BRW_3D(3, 1, 9)
+/* These two are BLC and CTG only, not BW or CL */
+#define BRW_3DSTATE_AA_LINE_PARAMS BRW_3D(3, 1, 0xa)
+#define BRW_3DSTATE_GS_SVB_INDEX BRW_3D(3, 1, 0xb)
+
+#define BRW_PIPE_CONTROL BRW_3D(3, 2, 0)
+
+#define BRW_3DPRIMITIVE BRW_3D(3, 3, 0)
+
+#define PIPELINE_SELECT_3D 0
+#define PIPELINE_SELECT_MEDIA 1
+
+#define UF0_CS_REALLOC (1 << 13)
+#define UF0_VFE_REALLOC (1 << 12)
+#define UF0_SF_REALLOC (1 << 11)
+#define UF0_CLIP_REALLOC (1 << 10)
+#define UF0_GS_REALLOC (1 << 9)
+#define UF0_VS_REALLOC (1 << 8)
+#define UF1_CLIP_FENCE_SHIFT 20
+#define UF1_GS_FENCE_SHIFT 10
+#define UF1_VS_FENCE_SHIFT 0
+#define UF2_CS_FENCE_SHIFT 20
+#define UF2_VFE_FENCE_SHIFT 10
+#define UF2_SF_FENCE_SHIFT 0
+
+/* for BRW_STATE_BASE_ADDRESS */
+#define BASE_ADDRESS_MODIFY (1 << 0)
+
+/* for BRW_3DSTATE_PIPELINED_POINTERS */
+#define BRW_GS_DISABLE 0
+#define BRW_GS_ENABLE 1
+#define BRW_CLIP_DISABLE 0
+#define BRW_CLIP_ENABLE 1
+
+/* for BRW_PIPE_CONTROL */
+#define BRW_PIPE_CONTROL_NOWRITE (0 << 14)
+#define BRW_PIPE_CONTROL_WRITE_QWORD (1 << 14)
+#define BRW_PIPE_CONTROL_WRITE_DEPTH (2 << 14)
+#define BRW_PIPE_CONTROL_WRITE_TIME (3 << 14)
+#define BRW_PIPE_CONTROL_DEPTH_STALL (1 << 13)
+#define BRW_PIPE_CONTROL_WC_FLUSH (1 << 12)
+#define BRW_PIPE_CONTROL_IS_FLUSH (1 << 11)
+#define BRW_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8)
+#define BRW_PIPE_CONTROL_GLOBAL_GTT (1 << 2)
+#define BRW_PIPE_CONTROL_LOCAL_PGTT (0 << 2)
+
+/* VERTEX_BUFFER_STATE Structure */
+#define VB0_BUFFER_INDEX_SHIFT 27
+#define VB0_VERTEXDATA (0 << 26)
+#define VB0_INSTANCEDATA (1 << 26)
+#define VB0_BUFFER_PITCH_SHIFT 0
+
+/* VERTEX_ELEMENT_STATE Structure */
+#define VE0_VERTEX_BUFFER_INDEX_SHIFT 27
+#define VE0_VALID (1 << 26)
+#define VE0_FORMAT_SHIFT 16
+#define VE0_OFFSET_SHIFT 0
+#define VE1_VFCOMPONENT_0_SHIFT 28
+#define VE1_VFCOMPONENT_1_SHIFT 24
+#define VE1_VFCOMPONENT_2_SHIFT 20
+#define VE1_VFCOMPONENT_3_SHIFT 16
+#define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0
+
+/* 3DPRIMITIVE bits */
+#define BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15)
+#define BRW_3DPRIMITIVE_VERTEX_RANDOM (1 << 15)
+/* Primitive types are in brw_defines.h */
+#define BRW_3DPRIMITIVE_TOPOLOGY_SHIFT 10
+
+#define BRW_SVG_CTL 0x7400
+
+#define BRW_SVG_CTL_GS_BA (0 << 8)
+#define BRW_SVG_CTL_SS_BA (1 << 8)
+#define BRW_SVG_CTL_IO_BA (2 << 8)
+#define BRW_SVG_CTL_GS_AUB (3 << 8)
+#define BRW_SVG_CTL_IO_AUB (4 << 8)
+#define BRW_SVG_CTL_SIP (5 << 8)
+
+#define BRW_SVG_RDATA 0x7404
+#define BRW_SVG_WORK_CTL 0x7408
+
+#define BRW_VF_CTL 0x7500
+
+#define BRW_VF_CTL_SNAPSHOT_COMPLETE (1 << 31)
+#define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8)
+#define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8)
+#define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4)
+#define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4)
+#define BRW_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3)
+#define BRW_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2)
+#define BRW_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1)
+#define BRW_VF_CTL_SNAPSHOT_ENABLE (1 << 0)
+
+#define BRW_VF_STRG_VAL 0x7504
+#define BRW_VF_STR_VL_OVR 0x7508
+#define BRW_VF_VC_OVR 0x750c
+#define BRW_VF_STR_PSKIP 0x7510
+#define BRW_VF_MAX_PRIM 0x7514
+#define BRW_VF_RDATA 0x7518
+
+#define BRW_VS_CTL 0x7600
+#define BRW_VS_CTL_SNAPSHOT_COMPLETE (1 << 31)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8)
+#define BRW_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8)
+#define BRW_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2)
+#define BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1)
+#define BRW_VS_CTL_SNAPSHOT_ENABLE (1 << 0)
+
+#define BRW_VS_STRG_VAL 0x7604
+#define BRW_VS_RDATA 0x7608
+
+#define BRW_SF_CTL 0x7b00
+#define BRW_SF_CTL_SNAPSHOT_COMPLETE (1 << 31)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8)
+#define BRW_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8)
+#define BRW_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4)
+#define BRW_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3)
+#define BRW_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2)
+#define BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1)
+#define BRW_SF_CTL_SNAPSHOT_ENABLE (1 << 0)
+
+#define BRW_SF_STRG_VAL 0x7b04
+#define BRW_SF_RDATA 0x7b18
+
+#define BRW_WIZ_CTL 0x7c00
+#define BRW_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31)
+#define BRW_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16
+#define BRW_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8)
+#define BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8)
+#define BRW_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8)
+#define BRW_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6)
+#define BRW_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5)
+#define BRW_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4)
+#define BRW_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3)
+#define BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2)
+#define BRW_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1)
+#define BRW_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0)
+
+#define BRW_WIZ_STRG_VAL 0x7c04
+#define BRW_WIZ_RDATA 0x7c18
+
+#define BRW_TS_CTL 0x7e00
+#define BRW_TS_CTL_SNAPSHOT_COMPLETE (1 << 31)
+#define BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8)
+#define BRW_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8)
+#define BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2)
+#define BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1)
+#define BRW_TS_CTL_SNAPSHOT_ENABLE (1 << 0)
+
+#define BRW_TS_STRG_VAL 0x7e04
+#define BRW_TS_RDATA 0x7e08
+
+#define BRW_TD_CTL 0x8000
+#define BRW_TD_CTL_MUX_SHIFT 8
+#define BRW_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7)
+#define BRW_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6)
+#define BRW_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5)
+#define BRW_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4)
+#define BRW_TD_CTL_BREAKPOINT_ENABLE (1 << 2)
+#define BRW_TD_CTL2 0x8004
+#define BRW_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28)
+#define BRW_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26)
+#define BRW_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25)
+#define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16
+#define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8)
+#define BRW_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7)
+#define BRW_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6)
+#define BRW_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5)
+#define BRW_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4)
+#define BRW_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3)
+#define BRW_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0)
+#define BRW_TD_VF_VS_EMSK 0x8008
+#define BRW_TD_GS_EMSK 0x800c
+#define BRW_TD_CLIP_EMSK 0x8010
+#define BRW_TD_SF_EMSK 0x8014
+#define BRW_TD_WIZ_EMSK 0x8018
+#define BRW_TD_0_6_EHTRG_VAL 0x801c
+#define BRW_TD_0_7_EHTRG_VAL 0x8020
+#define BRW_TD_0_6_EHTRG_MSK 0x8024
+#define BRW_TD_0_7_EHTRG_MSK 0x8028
+#define BRW_TD_RDATA 0x802c
+#define BRW_TD_TS_EMSK 0x8030
+
+#define BRW_EU_CTL 0x8800
+#define BRW_EU_CTL_SELECT_SHIFT 16
+#define BRW_EU_CTL_DATA_MUX_SHIFT 8
+#define BRW_EU_ATT_0 0x8810
+#define BRW_EU_ATT_1 0x8814
+#define BRW_EU_ATT_DATA_0 0x8820
+#define BRW_EU_ATT_DATA_1 0x8824
+#define BRW_EU_ATT_CLR_0 0x8830
+#define BRW_EU_ATT_CLR_1 0x8834
+#define BRW_EU_RDATA 0x8840
+
+/* End regs for broadwater */
#define MAX_DISPLAY_PIPES 2
diff --git a/src/i830.h b/src/i830.h
index 777ffd3c..df1c171a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -47,6 +47,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _I830_H_
#define _I830_H_
+#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
@@ -56,6 +57,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86xv.h"
#include "xf86int10.h"
#include "vbe.h"
+#include "vbeModes.h"
#include "vgaHW.h"
#include "randrstr.h"
@@ -79,6 +81,11 @@ Bool I830XAAInit(ScreenPtr pScreen);
#include "common.h"
+#define NEED_REPLIES /* ? */
+#define EXTENSION_PROC_ARGS void *
+#include "extnsionst.h" /* required */
+#include <X11/extensions/panoramiXproto.h> /* required */
+
/* I830 Video BIOS support */
/*
@@ -102,7 +109,6 @@ typedef struct _VESARec {
int statePage, stateSize, stateMode, stateRefresh;
CARD32 *savedPal;
int savedScanlinePitch;
- xf86MonPtr monitor;
/* Don't try to set the refresh rate for any modes. */
Bool useDefaultRefresh;
/* display start */
@@ -150,7 +156,7 @@ typedef struct {
} I830RingBuffer;
typedef struct {
- unsigned int Fence[8];
+ unsigned int Fence[FENCE_NEW_NR * 2];
} I830RegRec, *I830RegPtr;
typedef struct {
@@ -164,6 +170,29 @@ typedef struct {
#endif
} I830EntRec, *I830EntPtr;
+typedef struct _MergedDisplayModeRec {
+ DisplayModePtr First;
+ DisplayModePtr Second;
+ int SecondPosition;
+} I830MergedDisplayModeRec, *I830MergedDisplayModePtr;
+
+typedef struct _I830XineramaData {
+ int x;
+ int y;
+ int width;
+ int height;
+} I830XineramaData;
+
+typedef struct _ModePrivateRec {
+ I830MergedDisplayModeRec merged;
+ VbeModeInfoData vbeData;
+} I830ModePrivateRec, *I830ModePrivatePtr;
+
+typedef struct _region {
+ int x0,x1,y0,y1;
+} region;
+
+
typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
@@ -229,7 +258,25 @@ typedef struct _I830Rec {
I830MemRange *OverlayMem;
I830MemRange LinearMem;
#endif
- unsigned int LinearAlloc;
+ int LinearAlloc;
+
+ Bool MergedFB;
+ ScrnInfoPtr pScrn_2;
+ char *SecondHSync;
+ char *SecondVRefresh;
+ char *MetaModes;
+ int SecondPosition;
+ int FirstXOffs, FirstYOffs, SecondXOffs, SecondYOffs;
+ int FirstframeX0, FirstframeX1, FirstframeY0, FirstframeY1;
+ int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
+ Bool NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
+ int maxFirst_X1, maxFirst_X2, maxFirst_Y1, maxFirst_Y2;
+ int maxSecond_X1, maxSecond_X2, maxSecond_Y1, maxSecond_Y2;
+ region NonRectDead, OffDead1, OffDead2;
+ Bool IntelXinerama;
+ Bool SecondIsScrn0;
+ ExtensionEntry *XineramaExtEntry;
+ int I830XineramaVX, I830XineramaVY;
XF86ModReqInfo shadowReq; /* to test for later libshadow */
I830MemRange RotatedMem;
@@ -249,6 +296,12 @@ typedef struct _I830Rec {
int TexGranularity;
int drmMinor;
Bool have3DWindows;
+
+ unsigned int front_tiled;
+ unsigned int back_tiled;
+ unsigned int depth_tiled;
+ unsigned int rotated_tiled;
+ unsigned int rotated2_tiled;
#endif
Bool NeedRingBufferLow;
@@ -397,6 +450,9 @@ typedef struct _I830Rec {
Bool devicePresence;
OsTimerPtr devicesTimer;
+
+ CARD32 savedAsurf;
+ CARD32 savedBsurf;
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@@ -411,6 +467,7 @@ extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis);
extern void I830SetPIOAccess(I830Ptr pI830);
extern void I830SetMMIOAccess(I830Ptr pI830);
extern void I830PrintErrorState(ScrnInfoPtr pScrn);
+extern void I965PrintErrorState(ScrnInfoPtr pScrn);
extern void I830Sync(ScrnInfoPtr pScrn);
extern void I830InitHWCursor(ScrnInfoPtr pScrn);
extern Bool I830CursorInit(ScreenPtr pScreen);
@@ -471,8 +528,8 @@ extern long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn);
extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags);
extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool);
extern Bool I830FixupOffsets(ScrnInfoPtr pScrn);
-extern Bool I830BindGARTMemory(ScrnInfoPtr pScrn);
-extern Bool I830UnbindGARTMemory(ScrnInfoPtr pScrn);
+extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
+extern Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result,
I830MemPool *pool, long size,
unsigned long alignment, int flags);
diff --git a/src/i830_3d.c b/src/i830_3d.c
index 214beb60..563dcef7 100644
--- a/src/i830_3d.c
+++ b/src/i830_3d.c
@@ -29,6 +29,7 @@
#include "config.h"
#endif
+#include "xf86.h"
#include "i830.h"
#include "i830_reg.h"
diff --git a/src/i830_accel.c b/src/i830_accel.c
index 6b338879..6ad62d1f 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -134,6 +134,7 @@ void
I830Sync(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
ErrorF("I830Sync\n");
@@ -148,13 +149,17 @@ I830Sync(ScrnInfoPtr pScrn)
if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning) return;
+ if (IS_I965G(pI830))
+ flags = 0;
+
/* Send a flush instruction and then wait till the ring is empty.
* This is stronger than waiting for the blitter to finish as it also
* flushes the internal graphics caches.
*/
+
{
BEGIN_LP_RING(2);
- OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(MI_FLUSH | flags);
OUT_RING(MI_NOOP); /* pad to quadword */
ADVANCE_LP_RING();
}
@@ -169,9 +174,13 @@ void
I830EmitFlush(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
+
+ if (IS_I965G(pI830))
+ flags = 0;
BEGIN_LP_RING(2);
- OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
+ OUT_RING(MI_FLUSH | flags);
OUT_RING(MI_NOOP); /* pad to quadword */
ADVANCE_LP_RING();
}
@@ -233,4 +242,3 @@ I830AccelInit(ScreenPtr pScreen)
#endif
return FALSE;
}
-
diff --git a/src/i830_common.h b/src/i830_common.h
index a27bc011..c3ef4cde 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -84,7 +84,7 @@ typedef struct {
drmTextureRegion texList[I830_NR_TEX_REGIONS+1];
int last_upload; /* last time texture was uploaded */
int last_enqueue; /* last time a buffer was enqueued */
- int last_dispatch; /* age of the most recently dispatched buffer */
+ volatile int last_dispatch; /* age of the most recently dispatched buffer */
int ctxOwner; /* last context to upload state */
int texAge;
int pf_enabled; /* is pageflipping allowed? */
@@ -115,6 +115,12 @@ typedef struct {
int rotated_size;
int rotated_pitch;
int virtualX, virtualY;
+
+ unsigned int front_tiled;
+ unsigned int back_tiled;
+ unsigned int depth_tiled;
+ unsigned int rotated_tiled;
+ unsigned int rotated2_tiled;
} drmI830Sarea;
/* Flags for perf_boxes
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index e465b98c..c9e04e97 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -93,30 +93,47 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
MCURSOR_PIPE_SELECT);
temp |= CURSOR_MODE_DISABLE;
temp |= (pI830->pipe << 28);
- if(pI830->CursorIsARGB)
- temp |= MCURSOR_GAMMA_ENABLE;
- /* Need to set control, then address. */
- OUTREG(CURSOR_A_CONTROL, temp);
if (pI830->CursorIsARGB)
- OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
else
- OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
- if (pI830->Clone) {
+ temp |= CURSOR_MODE_64_4C_AX;
+ /* Need to set control, then address. */
+ OUTREG(CURSOR_A_CONTROL, temp);
+ if (pI830->CursorNeedsPhysical) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ } else {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+ }
+ if (pI830->Clone || pI830->MergedFB) {
temp &= ~MCURSOR_PIPE_SELECT;
temp |= (!pI830->pipe << 28);
OUTREG(CURSOR_B_CONTROL, temp);
- if (pI830->CursorIsARGB)
- OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
- else
- OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ if (pI830->CursorNeedsPhysical) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ } else {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+ }
}
} else {
temp = INREG(CURSOR_CONTROL);
temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
CURSOR_ENABLE | CURSOR_STRIDE_MASK);
- temp |= (CURSOR_FORMAT_3C);
if (pI830->CursorIsARGB)
- temp |= CURSOR_GAMMA_ENABLE;
+ temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+ else
+ temp |= CURSOR_FORMAT_3C;
/* This initialises the format and leave the cursor disabled. */
OUTREG(CURSOR_CONTROL, temp);
/* Need to set address and size after disabling. */
@@ -357,6 +374,102 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
}
#endif
+#define CDMPTR ((I830ModePrivatePtr)pI830->currentMode->Private)->merged
+
+static void
+I830SetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ ScrnInfoPtr pScrn2 = pI830->pScrn_2;
+ DisplayModePtr mode1 = CDMPTR.First;
+ Bool hide = FALSE, show = FALSE;
+ DisplayModePtr mode2 = CDMPTR.Second;
+ int x1, y1, x2, y2;
+ int total_y1 = pScrn->frameY1 - pScrn->frameY0;
+ int total_y2 = pScrn2->frameY1 - pScrn2->frameY0;
+ CARD32 temp = 0, temp2 = 0;
+
+ x += pScrn->frameX0;
+ y += pScrn->frameY0;
+
+ x1 = x - pI830->FirstframeX0;
+ y1 = y - pI830->FirstframeY0;
+
+ x2 = x - pScrn2->frameX0;
+ y2 = y - pScrn2->frameY0;
+
+ if (y1 > total_y1)
+ y1 = total_y1;
+ if (y2 > total_y2)
+ y2 = total_y2;
+
+ /* move cursor offscreen */
+ if (y1 >= 0 && y2 >= mode2->VDisplay) {
+ y2 = -I810_CURSOR_Y;
+ } else if (y2 >= 0 && y1 >= mode1->VDisplay) {
+ y1 = -I810_CURSOR_Y;
+ }
+ if (x1 >= 0 && x2 >= mode2->HDisplay) {
+ x2 = -I810_CURSOR_X;
+ } else if (x2 >= 0 && x1 >= mode1->HDisplay) {
+ x1 = -I810_CURSOR_X;
+ }
+
+ /* Clamp the cursor position to the visible screen area */
+ if (x1 >= mode1->HDisplay) x1 = mode1->HDisplay - 1;
+ if (y1 >= mode1->VDisplay) y1 = mode1->VDisplay - 1;
+ if (x1 <= -I810_CURSOR_X) x1 = -I810_CURSOR_X + 1;
+ if (y1 <= -I810_CURSOR_Y) y1 = -I810_CURSOR_Y + 1;
+ if (x2 >= mode2->HDisplay) x2 = mode2->HDisplay - 1;
+ if (y2 >= mode2->VDisplay) y2 = mode2->VDisplay - 1;
+ if (x2 <= -I810_CURSOR_X) x2 = -I810_CURSOR_X + 1;
+ if (y2 <= -I810_CURSOR_Y) y2 = -I810_CURSOR_Y + 1;
+
+ if (x1 < 0) {
+ temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+ x1 = -x1;
+ }
+ if (y1 < 0) {
+ temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+ y1 = -y1;
+ }
+ if (x2 < 0) {
+ temp2 |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+ x2 = -x2;
+ }
+ if (y2 < 0) {
+ temp2 |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+ y2 = -y2;
+ }
+
+ temp |= ((x1 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+ temp |= ((y1 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+ temp2 |= ((x2 & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+ temp2 |= ((y2 & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+
+ OUTREG(CURSOR_A_POSITION, temp);
+ OUTREG(CURSOR_B_POSITION, temp2);
+
+ if (pI830->cursorOn) {
+ if (hide)
+ pI830->CursorInfoRec->HideCursor(pScrn);
+ else if (show)
+ pI830->CursorInfoRec->ShowCursor(pScrn);
+ pI830->cursorOn = TRUE;
+ }
+
+ /* have to upload the base for the new position */
+ if (IS_I9XX(pI830)) {
+ if (pI830->CursorIsARGB) {
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ } else {
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ }
+ }
+}
+
static void
I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
@@ -369,6 +482,11 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
static Bool outsideViewport = FALSE;
#endif
+ if (pI830->MergedFB) {
+ I830SetCursorPositionMerged(pScrn, x, y);
+ return;
+ }
+
oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
oldy += pScrn->frameY0;
@@ -451,15 +569,29 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
/* have to upload the base for the new position */
if (IS_I9XX(pI830)) {
- if (pI830->CursorIsARGB)
- OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
- else
- OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
- if (pI830->Clone) {
+ if (pI830->CursorNeedsPhysical) {
if (pI830->CursorIsARGB)
- OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
else
- OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ } else {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+ }
+ if (pI830->Clone) {
+ if (pI830->CursorNeedsPhysical) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ } else {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+ }
}
}
}
@@ -483,7 +615,7 @@ I830ShowCursor(ScrnInfoPtr pScrn)
pI830->cursorOn = TRUE;
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
- temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+ temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT | MCURSOR_GAMMA_ENABLE);
if (pI830->CursorIsARGB)
temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
else
@@ -491,25 +623,39 @@ I830ShowCursor(ScrnInfoPtr pScrn)
temp |= (pI830->pipe << 28); /* Connect to correct pipe */
/* Need to set mode, then address. */
OUTREG(CURSOR_A_CONTROL, temp);
- if (pI830->CursorIsARGB)
- OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
- else
- OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
- if (pI830->Clone) {
+ if (pI830->CursorNeedsPhysical) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ } else {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Start);
+ }
+ if (pI830->Clone || pI830->MergedFB) {
temp &= ~MCURSOR_PIPE_SELECT;
temp |= (!pI830->pipe << 28);
OUTREG(CURSOR_B_CONTROL, temp);
- if (pI830->CursorIsARGB)
- OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
- else
- OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ if (pI830->CursorNeedsPhysical) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ } else {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Start);
+ }
}
} else {
temp = INREG(CURSOR_CONTROL);
- temp &= ~(CURSOR_FORMAT_MASK);
+ temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE);
temp |= CURSOR_ENABLE;
if (pI830->CursorIsARGB)
- temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+ temp |= CURSOR_FORMAT_ARGB;
else
temp |= CURSOR_FORMAT_3C;
OUTREG(CURSOR_CONTROL, temp);
@@ -531,7 +677,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
pI830->cursorOn = FALSE;
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
- temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
+ temp &= ~CURSOR_MODE;
temp |= CURSOR_MODE_DISABLE;
OUTREG(CURSOR_A_CONTROL, temp);
/* This is needed to flush the above change. */
@@ -539,7 +685,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
else
OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
- if (pI830->Clone) {
+ if (pI830->Clone || pI830->MergedFB) {
OUTREG(CURSOR_B_CONTROL, temp);
if (pI830->CursorIsARGB)
OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
@@ -548,7 +694,7 @@ I830HideCursor(ScrnInfoPtr pScrn)
}
} else {
temp = INREG(CURSOR_CONTROL);
- temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
+ temp &= ~CURSOR_ENABLE;
OUTREG(CURSOR_CONTROL, temp);
}
}
@@ -570,7 +716,7 @@ I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
- if (pI830->Clone) {
+ if (pI830->Clone || pI830->MergedFB) {
OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff);
OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff);
OUTREG(CURSOR_B_PALETTE2, fg & 0x00ffffff);
diff --git a/src/i830_dga.c b/src/i830_dga.c
index 08207d39..c78063e1 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -99,6 +99,31 @@ I830DGAInit(ScreenPtr pScreen)
while (pMode) {
+ if(pI830->MergedFB) {
+ Bool nogood = FALSE;
+ /* Filter out all meta modes that would require driver-side panning */
+ switch(((I830ModePrivatePtr)pMode->Private)->merged.SecondPosition) {
+ case PosRightOf:
+ case PosLeftOf:
+ if( (((I830ModePrivatePtr)pMode->Private)->merged.First->VDisplay !=
+ ((I830ModePrivatePtr)pMode->Private)->merged.Second->VDisplay) ||
+ (((I830ModePrivatePtr)pMode->Private)->merged.First->VDisplay != pMode->VDisplay) )
+ nogood = TRUE;
+ break;
+ default:
+ if( (((I830ModePrivatePtr)pMode->Private)->merged.First->HDisplay !=
+ ((I830ModePrivatePtr)pMode->Private)->merged.Second->HDisplay) ||
+ (((I830ModePrivatePtr)pMode->Private)->merged.First->HDisplay != pMode->HDisplay) )
+ nogood = TRUE;
+ }
+ if(nogood) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DGA: MetaMode %dx%d not suitable for DGA, skipping\n",
+ pMode->HDisplay, pMode->VDisplay);
+ goto mode_nogood;
+ }
+ }
+
newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
if (!newmodes) {
@@ -155,6 +180,7 @@ I830DGAInit(ScreenPtr pScreen)
currentMode->maxViewportY = currentMode->imageHeight -
currentMode->viewportHeight;
+mode_nogood:
pMode = pMode->next;
if (pMode == firstMode)
break;
@@ -254,15 +280,26 @@ I830_FillRect(ScrnInfoPtr pScrn,
static void
I830_Sync(ScrnInfoPtr pScrn)
{
-#ifdef I830_USE_XAA
I830Ptr pI830 = I830PTR(pScrn);
+ int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
MARKER();
- if (pI830->AccelInfoRec) {
- (*pI830->AccelInfoRec->Sync) (pScrn);
- }
-#endif
+ if (pI830->noAccel)
+ return;
+
+ if (IS_I965G(pI830))
+ flags = 0;
+
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_FLUSH | flags);
+ OUT_RING(MI_NOOP); /* pad to quadword */
+ ADVANCE_LP_RING();
+
+ I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0);
+
+ pI830->LpRing->space = pI830->LpRing->mem.Size - 8;
+ pI830->nextColorExpandBuf = 0;
}
static void
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 56534342..8a52750f 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -81,8 +81,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830.h"
#include "i830_dri.h"
+#include "dristruct.h"
+
static char I830KernelDriverName[] = "i915";
static char I830ClientDriverName[] = "i915";
+static char I965ClientDriverName[] = "i965";
static Bool I830InitVisualConfigs(ScreenPtr pScreen);
static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual,
@@ -424,11 +427,13 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
* for known symbols in each module. */
if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs"))
return FALSE;
+ if (!xf86LoaderCheckSymbol("DRIScreenInit"))
+ return FALSE;
if (!xf86LoaderCheckSymbol("drmAvailable"))
return FALSE;
if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[dri] %s failed (libdri.a too old)\n", "I830DRIScreenInit");
+ "[dri] %s failed (libdri.a too old)\n", "I830CheckDRIAvailable");
return FALSE;
}
@@ -440,10 +445,10 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed because of a version mismatch.\n"
- "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n"
+ "[dri] libDRI version is %d.%d.%d but version %d.%d.x is needed.\n"
"[dri] Disabling DRI.\n",
- "I830DRIScreenInit", major, minor, patch,
- DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+ "I830CheckDRIAvailable", major, minor, patch,
+ DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
return FALSE;
}
}
@@ -475,7 +480,11 @@ I830DRIScreenInit(ScreenPtr pScreen)
pI830->LockHeld = 0;
pDRIInfo->drmDriverName = I830KernelDriverName;
- pDRIInfo->clientDriverName = I830ClientDriverName;
+ if (IS_I965G(pI830))
+ pDRIInfo->clientDriverName = I965ClientDriverName;
+ else
+ pDRIInfo->clientDriverName = I830ClientDriverName;
+
if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
pDRIInfo->busIdString = DRICreatePCIBusID(pI830->PciInfo);
} else {
@@ -488,13 +497,16 @@ I830DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
-#if 1 /* temporary until this gets removed from the libdri layer */
+#if 1 /* Remove this soon - see bug 5714 */
pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr +
pI830->FrontBuffer.Start;
pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
pScrn->virtualY * pI830->cpp);
- pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
+#else
+ /* For rotation we map a 0 length framebuffer as we remap ourselves later */
+ pDRIInfo->frameBufferSize = 0;
#endif
+ pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES;
if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES)
@@ -534,6 +546,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
+ /* do driver-independent DRI screen initialization here */
if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] DRIScreenInit failed. Disabling DRI.\n");
@@ -544,6 +557,27 @@ I830DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
+#if 0 /* disabled now, see frameBufferSize above being set to 0 */
+ /* for this driver, get rid of the front buffer mapping now */
+ if (xf86LoaderCheckSymbol("DRIGetScreenPrivate")) {
+ DRIScreenPrivPtr pDRIPriv
+ = (DRIScreenPrivPtr) DRIGetScreenPrivate(pScreen);
+
+ if (pDRIPriv && pDRIPriv->drmFD && pDRIPriv->hFrameBuffer) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[intel] removing original screen mapping\n");
+ drmRmMap(pDRIPriv->drmFD, pDRIPriv->hFrameBuffer);
+ pDRIPriv->hFrameBuffer = 0;
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[intel] done removing original screen mapping\n");
+ }
+ }
+ else {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[intel] DRIGetScreenPrivate not found!!!!\n");
+ }
+#endif
+
/* Check the i915 DRM versioning */
{
drmVersionPtr version;
@@ -589,11 +623,11 @@ I830DRIScreenInit(ScreenPtr pScreen)
/* Check the i915 DRM version */
version = drmGetVersion(pI830->drmSubFD);
if (version) {
- if (version->version_major != 1 || version->version_minor < 4) {
+ if (version->version_major != 1 || version->version_minor < 3) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] %s failed because of a version mismatch.\n"
- "[dri] i915 kernel module version is %d.%d.%d but version 1.4 or greater is needed.\n"
+ "[dri] i915 kernel module version is %d.%d.%d but version 1.3 or greater is needed.\n"
"[dri] Disabling DRI.\n",
"I830DRIScreenInit",
version->version_major,
@@ -623,21 +657,31 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
ScreenPtr pScreen = pScrn->pScreen;
I830Ptr pI830 = I830PTR(pScrn);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] Mapping front buffer\n");
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
- sarea->front_size,
- DRM_FRAME_BUFFER, /*DRM_AGP,*/
- 0,
- (drmAddress) &sarea->front_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
+#if 1 /* Remove this soon - see bug 5714 */
+ pI830->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
+ pScrn->virtualY * pI830->cpp);
+#endif
+
+ /* The I965G isn't ready for the front buffer mapping to be moved around,
+ * because of issues with rmmap, it seems.
+ */
+ if (!IS_I965G(pI830)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] Mapping front buffer\n");
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
+ sarea->front_size,
+ DRM_AGP,
+ 0,
+ (drmAddress) &sarea->front_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n",
+ (int)sarea->front_handle);
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n",
- (int)sarea->front_handle);
if (drmAddMap(pI830->drmSubFD,
(drm_handle_t)(sarea->back_offset + pI830->LinearAddr),
@@ -684,12 +728,10 @@ I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
{
I830Ptr pI830 = I830PTR(pScrn);
-#if 1
if (sarea->front_handle) {
drmRmMap(pI830->drmSubFD, sarea->front_handle);
sarea->front_handle = 0;
}
-#endif
if (sarea->back_handle) {
drmRmMap(pI830->drmSubFD, sarea->back_handle);
sarea->back_handle = 0;
@@ -785,7 +827,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
/* screen mappings probably failed */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAddMap(screen mappings) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
return FALSE;
}
@@ -824,9 +865,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
pI830DRI->mem = pScrn->videoRam * 1024;
pI830DRI->cpp = pI830->cpp;
- pI830DRI->fbOffset = pI830->FrontBuffer.Start;
- pI830DRI->fbStride = pI830->backPitch;
-
pI830DRI->bitsPerPixel = pScrn->bitsPerPixel;
pI830DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
@@ -1032,6 +1070,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
{
ScreenPtr pScreen = pParent->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
BoxPtr pboxTmp, pboxNext, pboxBase;
DDXPointPtr pptTmp, pptNew2;
int xdir, ydir;
@@ -1164,8 +1203,10 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
I830SelectBuffer(pScrn, I830_SELECT_BACK);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
- I830SelectBuffer(pScrn, I830_SELECT_DEPTH);
- I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ if (!IS_I965G(pI830)) {
+ I830SelectBuffer(pScrn, I830_SELECT_DEPTH);
+ I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ }
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
I830EmitFlush(pScrn);
@@ -1204,6 +1245,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
* might be faster, but seems like a lot more work...
*/
+
#if 0
/* This should be done *before* XAA syncs,
* Otherwise will have to sync again???
@@ -1213,7 +1255,7 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- RegionPtr damage = (RegionPtr) shadowDamage(pBuf);
+ RegionPtr damage = &pBuf->damage;
int i, num = REGION_NUM_RECTS(damage);
BoxPtr pbox = REGION_RECTS(damage);
drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
@@ -1343,6 +1385,7 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
}
pI830->have3DWindows = 0;
+
}
@@ -1359,6 +1402,14 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
I830DRIUnmapScreenRegions(pScrn, sarea);
+ sarea->front_tiled = pI830->front_tiled;
+ sarea->back_tiled = pI830->back_tiled;
+ sarea->depth_tiled = pI830->depth_tiled;
+ sarea->rotated_tiled = pI830->rotated_tiled;
+#if 0
+ sarea->rotated2_tiled = pI830->rotated2_tiled;
+#endif
+
if (pI830->rotation == RR_Rotate_0) {
sarea->front_offset = pI830->FrontBuffer.Start;
/* Don't use FrontBuffer.Size here as it includes the pixmap cache area
@@ -1418,7 +1469,8 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
success = I830DRIMapScreenRegions(pScrn, sarea);
- I830InitTextureHeap(pScrn, sarea);
+ if (success)
+ I830InitTextureHeap(pScrn, sarea);
return success;
}
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 4f356d1f..41f8a90a 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -10,7 +10,7 @@
#define I830_MAJOR_VERSION 1
#define I830_MINOR_VERSION 6
-#define I830_PATCHLEVEL 0
+#define I830_PATCHLEVEL 4
#define I830_REG_SIZE 0x80000
@@ -18,20 +18,20 @@ typedef struct _I830DRIRec {
drm_handle_t regs;
drmSize regsSize;
- drmSize backbufferSize;
- drm_handle_t backbuffer;
+ drmSize unused1; /* backbufferSize */
+ drm_handle_t unused2; /* backbuffer */
- drmSize depthbufferSize;
- drm_handle_t depthbuffer;
+ drmSize unused3; /* depthbufferSize */
+ drm_handle_t unused4; /* depthbuffer */
- drmSize rotatedSize;
- drm_handle_t rotatedbuffer;
+ drmSize unused5; /* rotatedSize /*/
+ drm_handle_t unused6; /* rotatedbuffer */
- drm_handle_t textures;
- int textureSize;
+ drm_handle_t unused7; /* textures */
+ int unused8; /* textureSize */
- drm_handle_t agp_buffers;
- drmSize agp_buf_size;
+ drm_handle_t unused9; /* agp_buffers */
+ drmSize unused10; /* agp_buf_size */
int deviceID;
int width;
@@ -40,20 +40,10 @@ typedef struct _I830DRIRec {
int cpp;
int bitsPerPixel;
- int fbOffset;
- int fbStride;
+ int unused11[8]; /* was front/back/depth/rotated offset/pitch */
- int backOffset;
- int backPitch;
-
- int depthOffset;
- int depthPitch;
-
- int rotatedOffset;
- int rotatedPitch;
-
- int logTextureGranularity;
- int textureOffset;
+ int unused12; /* logTextureGranularity */
+ int unused13; /* textureOffset */
int irq;
int sarea_priv_offset;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index ed855855..10a329c9 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -150,6 +150,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* 09/2005 Alan Hourihane
* - Add Intel(R) 945GM support.
*
+ * 10/2005 Alan Hourihane, Keith Whitwell, Brian Paul
+ * - Added Rotation support
+ *
+ * 12/2005 Alan Hourihane, Keith Whitwell
+ * - Add Intel(R) 965G support.
*/
#ifdef HAVE_CONFIG_H
@@ -161,6 +166,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#include <string.h>
+#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@@ -178,13 +184,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <X11/extensions/randr.h>
#include "fb.h"
#include "miscstruct.h"
+#include "dixstruct.h"
#include "xf86xv.h"
#include <X11/extensions/Xv.h>
#include "vbe.h"
-#include "vbeModes.h"
#include "shadow.h"
#include "i830.h"
+#ifdef HAS_MTRR_SUPPORT
+#include <asm/mtrr.h>
+#endif
+
#ifdef XF86DRI
#include "dri.h"
#endif
@@ -216,6 +226,10 @@ static SymTabRec I830BIOSChipsets[] = {
{PCI_CHIP_I915_GM, "915GM"},
{PCI_CHIP_I945_G, "945G"},
{PCI_CHIP_I945_GM, "945GM"},
+ {PCI_CHIP_I965_G, "965G"},
+ {PCI_CHIP_I965_G_1, "965G"},
+ {PCI_CHIP_I965_Q, "965Q"},
+ {PCI_CHIP_I946_GZ, "946GZ"},
{-1, NULL}
};
@@ -229,6 +243,10 @@ static PciChipsets I830BIOSPciChipsets[] = {
{PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
{PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
{PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA},
+ {PCI_CHIP_I965_G, PCI_CHIP_I965_G, RES_SHARED_VGA},
+ {PCI_CHIP_I965_G_1, PCI_CHIP_I965_G_1, RES_SHARED_VGA},
+ {PCI_CHIP_I965_Q, PCI_CHIP_I965_Q, RES_SHARED_VGA},
+ {PCI_CHIP_I946_GZ, PCI_CHIP_I946_GZ, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
@@ -259,7 +277,13 @@ typedef enum {
OPTION_CHECKDEVICES,
OPTION_FIXEDPIPE,
OPTION_ROTATE,
- OPTION_LINEARALLOC
+ OPTION_LINEARALLOC,
+ OPTION_MERGEDFB,
+ OPTION_METAMODES,
+ OPTION_SECONDHSYNC,
+ OPTION_SECONDVREFRESH,
+ OPTION_SECONDPOSITION,
+ OPTION_INTELXINERAMA
} I830Opts;
static OptionInfoRec I830BIOSOptions[] = {
@@ -284,13 +308,19 @@ static OptionInfoRec I830BIOSOptions[] = {
{OPTION_FIXEDPIPE, "FixedPipe", OPTV_ANYSTR, {0}, FALSE},
{OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE},
{OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_METAMODES, "MetaModes", OPTV_STRING, {0}, FALSE},
+ {OPTION_SECONDHSYNC, "SecondMonitorHorizSync",OPTV_STRING, {0}, FALSE },
+ {OPTION_SECONDVREFRESH,"SecondMonitorVertRefresh",OPTV_STRING,{0}, FALSE },
+ {OPTION_SECONDPOSITION,"SecondPosition",OPTV_STRING, {0}, FALSE },
+ {OPTION_INTELXINERAMA,"MergedXinerama",OPTV_BOOLEAN, {0}, TRUE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,
int PowerManagementMode, int flags);
-static void I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags);
+static void I830AdjustFrame(int scrnIndex, int x, int y, int flags);
static Bool I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack);
static Bool I830BIOSEnterVT(int scrnIndex, int flags);
@@ -301,9 +331,24 @@ static Bool SetPipeAccess(ScrnInfoPtr pScrn);
extern int I830EntityIndex;
+static Bool I830noPanoramiXExtension = TRUE;
+static int I830XineramaNumScreens = 0;
+static I830XineramaData *I830XineramadataPtr = NULL;
+static int I830XineramaGeneration;
+
+static int I830ProcXineramaQueryVersion(ClientPtr client);
+static int I830ProcXineramaGetState(ClientPtr client);
+static int I830ProcXineramaGetScreenCount(ClientPtr client);
+static int I830ProcXineramaGetScreenSize(ClientPtr client);
+static int I830ProcXineramaIsActive(ClientPtr client);
+static int I830ProcXineramaQueryScreens(ClientPtr client);
+static int I830SProcXineramaDispatch(ClientPtr client);
+
/* temporary */
extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
+static const char *SecondMonitorName = "MergedFBMonitor";
+
#ifdef I830DEBUG
void
@@ -372,11 +417,9 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
if (mode) {
do {
if (mode->Private) {
- VbeModeInfoData *data = (VbeModeInfoData *) mode->Private;
+ I830ModePrivatePtr mp = (I830ModePrivatePtr) mode->Private;
- if (data->block)
- xfree(data->block);
- xfree(data);
+ xfree(mp);
mode->Private = NULL;
}
mode = mode->next;
@@ -391,8 +434,6 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
}
pVesa = pI830->vesa;
- if (pVesa->monitor)
- xfree(pVesa->monitor);
if (pVesa->savedPal)
xfree(pVesa->savedPal);
xfree(pVesa);
@@ -401,6 +442,1601 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn)
pScrn->driverPrivate = NULL;
}
+static Bool
+InRegion(int x, int y, region r)
+{
+ return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
+}
+
+static int
+I830StrToRanges(range *r, char *s, int max)
+{
+ float num = 0.0;
+ int rangenum = 0;
+ Bool gotdash = FALSE;
+ Bool nextdash = FALSE;
+ char *strnum = NULL;
+ do {
+ switch(*s) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ if(strnum == NULL) {
+ strnum = s;
+ gotdash = nextdash;
+ nextdash = FALSE;
+ }
+ break;
+ case '-':
+ case ' ':
+ case 0:
+ if(strnum == NULL) break;
+ sscanf(strnum, "%f", &num);
+ strnum = NULL;
+ if(gotdash) {
+ r[rangenum - 1].hi = num;
+ } else {
+ r[rangenum].lo = num;
+ r[rangenum].hi = num;
+ rangenum++;
+ }
+ if(*s == '-') nextdash = (rangenum != 0);
+ else if(rangenum >= max) return rangenum;
+ break;
+ default:
+ return 0;
+ }
+
+ } while(*(s++) != 0);
+
+ return rangenum;
+}
+
+/* Calculate the vertical refresh rate from a mode */
+static float
+I830CalcVRate(DisplayModePtr mode)
+{
+ float hsync, refresh = 0;
+
+ if(mode->HSync > 0.0)
+ hsync = mode->HSync;
+ else if(mode->HTotal > 0)
+ hsync = (float)mode->Clock / (float)mode->HTotal;
+ else
+ hsync = 0.0;
+
+ if(mode->VTotal > 0)
+ refresh = hsync * 1000.0 / mode->VTotal;
+
+ if(mode->Flags & V_INTERLACE)
+ refresh *= 2.0;
+
+ if(mode->Flags & V_DBLSCAN)
+ refresh /= 2.0;
+
+ if(mode->VScan > 1)
+ refresh /= mode->VScan;
+
+ if(mode->VRefresh > 0.0)
+ refresh = mode->VRefresh;
+
+ if(hsync == 0.0 || refresh == 0.0) return 0.0;
+
+ return refresh;
+}
+
+/* Copy and link two modes (i, j) for mergedfb mode
+ * (Code base taken from mga driver)
+ *
+ * - Copy mode i, merge j to copy of i, link the result to dest
+ * - Link i and j in private record.
+ * - If dest is NULL, return value is copy of i linked to itself.
+ * - For mergedfb auto-config, we only check the dimension
+ * against virtualX/Y, if they were user-provided.
+ * - No special treatment required for CRTxxOffs.
+ * - Provide fake dotclock in order to distinguish between similar
+ * looking MetaModes (for RandR and VidMode extensions)
+ * - Set unique VRefresh of dest mode for RandR
+ */
+static DisplayModePtr
+I830CopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
+ DisplayModePtr i, DisplayModePtr j,
+ int pos)
+{
+ DisplayModePtr mode;
+ int dx = 0,dy = 0;
+
+ if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;
+ memcpy(mode, i, sizeof(DisplayModeRec));
+ if(!((mode->Private = xalloc(sizeof(I830ModePrivateRec))))) {
+ xfree(mode);
+ return dest;
+ }
+ ((I830ModePrivatePtr)mode->Private)->merged.First = i;
+ ((I830ModePrivatePtr)mode->Private)->merged.Second = j;
+ ((I830ModePrivatePtr)mode->Private)->merged.SecondPosition = pos;
+ if (((I830ModePrivatePtr)i->Private)->vbeData.mode > 0x30) {
+ ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)i->Private)->vbeData.mode;
+ ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)i->Private)->vbeData.data;
+ } else {
+ ((I830ModePrivatePtr)mode->Private)->vbeData.mode = ((I830ModePrivatePtr)j->Private)->vbeData.mode;
+ ((I830ModePrivatePtr)mode->Private)->vbeData.data = ((I830ModePrivatePtr)j->Private)->vbeData.data;
+ }
+ mode->PrivSize = sizeof(I830ModePrivateRec);
+
+ switch(pos) {
+ case PosLeftOf:
+ case PosRightOf:
+ if(!(pScrn->display->virtualX)) {
+ dx = i->HDisplay + j->HDisplay;
+ } else {
+ dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
+ }
+ dx -= mode->HDisplay;
+ if(!(pScrn->display->virtualY)) {
+ dy = max(i->VDisplay, j->VDisplay);
+ } else {
+ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+ }
+ dy -= mode->VDisplay;
+ break;
+ case PosAbove:
+ case PosBelow:
+ if(!(pScrn->display->virtualY)) {
+ dy = i->VDisplay + j->VDisplay;
+ } else {
+ dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
+ }
+ dy -= mode->VDisplay;
+ if(!(pScrn->display->virtualX)) {
+ dx = max(i->HDisplay, j->HDisplay);
+ } else {
+ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+ }
+ dx -= mode->HDisplay;
+ break;
+ }
+ mode->HDisplay += dx;
+ mode->HSyncStart += dx;
+ mode->HSyncEnd += dx;
+ mode->HTotal += dx;
+ mode->VDisplay += dy;
+ mode->VSyncStart += dy;
+ mode->VSyncEnd += dy;
+ mode->VTotal += dy;
+
+ mode->type = M_T_DEFAULT;
+
+ /* Set up as user defined (ie fake that the mode has been named in the
+ * Modes-list in the screen section; corrects cycling with CTRL-ALT-[-+]
+ * when source mode has not been listed there.)
+ */
+ mode->type |= M_T_USERDEF;
+
+ /* Set the VRefresh field (in order to make RandR use it for the rates). We
+ * simply set this to the refresh rate for the First mode (since Second will
+ * mostly be LCD or TV anyway).
+ */
+ mode->VRefresh = I830CalcVRate(i);
+
+ if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > (pScrn->videoRam * 1024)) ||
+ (mode->HDisplay > 4088) ||
+ (mode->VDisplay > 4096) ) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n",
+ mode->name, mode->HDisplay, mode->VDisplay);
+ xfree(mode->Private);
+ xfree(mode);
+
+ return dest;
+ }
+
+ /* Now see if the resulting mode would be discarded as a "size" by the
+ * RandR extension, and increase its clock by 1000 in case it does.
+ */
+ if(dest) {
+ DisplayModePtr t = dest;
+ do {
+ if((t->HDisplay == mode->HDisplay) &&
+ (t->VDisplay == mode->VDisplay) &&
+ ((int)(t->VRefresh + .5) == (int)(mode->VRefresh + .5))) {
+ mode->VRefresh += 1000.0;
+ }
+ t = t->next;
+ } while((t) && (t != dest));
+ }
+
+ /* Provide a fake but unique DotClock in order to trick the vidmode
+ * extension to allow selecting among a number of modes whose merged result
+ * looks identical but consists of different modes for First and Second
+ */
+ mode->Clock = (int)(mode->VRefresh * 1000.0);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d (%d)\n",
+ i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay,
+ mode->HDisplay, mode->VDisplay, (int)mode->VRefresh);
+
+ mode->next = mode;
+ mode->prev = mode;
+
+ if(dest) {
+ mode->next = dest->next; /* Insert node after "dest" */
+ dest->next->prev = mode;
+ mode->prev = dest;
+ dest->next = mode;
+ }
+
+ return mode;
+}
+
+/* Helper function to find a mode from a given name
+ * (Code base taken from mga driver)
+ */
+static DisplayModePtr
+I830GetModeFromName(char* str, DisplayModePtr i)
+{
+ DisplayModePtr c = i;
+ if(!i) return NULL;
+ do {
+ if(strcmp(str, c->name) == 0) return c;
+ c = c->next;
+ } while(c != i);
+ return NULL;
+}
+
+static DisplayModePtr
+I830FindWidestTallestMode(DisplayModePtr i, Bool tallest)
+{
+ DisplayModePtr c = i, d = NULL;
+ int max = 0;
+ if(!i) return NULL;
+ do {
+ if(tallest) {
+ if(c->VDisplay > max) {
+ max = c->VDisplay;
+ d = c;
+ }
+ } else {
+ if(c->HDisplay > max) {
+ max = c->HDisplay;
+ d = c;
+ }
+ }
+ c = c->next;
+ } while(c != i);
+ return d;
+}
+
+static void
+I830FindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,
+ DisplayModePtr *a, DisplayModePtr *b)
+{
+ DisplayModePtr c = i, d;
+ int max = 0;
+ Bool foundone;
+
+ (*a) = (*b) = NULL;
+
+ if(!i || !j) return;
+
+ do {
+ d = j;
+ foundone = FALSE;
+ do {
+ if( (c->HDisplay == d->HDisplay) &&
+ (c->VDisplay == d->VDisplay) ) {
+ foundone = TRUE;
+ break;
+ }
+ d = d->next;
+ } while(d != j);
+ if(foundone) {
+ if(tallest) {
+ if(c->VDisplay > max) {
+ max = c->VDisplay;
+ (*a) = c;
+ (*b) = d;
+ }
+ } else {
+ if(c->HDisplay > max) {
+ max = c->HDisplay;
+ (*a) = c;
+ (*b) = d;
+ }
+ }
+ }
+ c = c->next;
+ } while(c != i);
+}
+
+static DisplayModePtr
+I830GenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
+ DisplayModePtr i, DisplayModePtr j,
+ int pos)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr mode1 = NULL;
+ DisplayModePtr mode2 = NULL;
+ DisplayModePtr mode3 = NULL;
+ DisplayModePtr mode4 = NULL;
+ DisplayModePtr result = NULL;
+
+ /* Now build a default list of MetaModes.
+ * - Non-clone: If the user enabled NonRectangular, we use the
+ * largest mode for each First and Second. If not, we use the largest
+ * common mode for First and Second (if available). Additionally, and
+ * regardless if the above, we produce a clone mode consisting of
+ * the largest common mode (if available) in order to use DGA.
+ */
+
+ switch(pos) {
+ case PosLeftOf:
+ case PosRightOf:
+ mode1 = I830FindWidestTallestMode(i, FALSE);
+ mode2 = I830FindWidestTallestMode(j, FALSE);
+ I830FindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
+ break;
+ case PosAbove:
+ case PosBelow:
+ mode1 = I830FindWidestTallestMode(i, TRUE);
+ mode2 = I830FindWidestTallestMode(j, TRUE);
+ I830FindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);
+ break;
+ }
+
+ if(mode3 && mode4 && !pI830->NonRect) {
+ mode1 = mode3;
+ mode2 = mode2;
+ }
+
+ if(mode1 && mode2) {
+ result = I830CopyModeNLink(pScrn, result, mode1, mode2, pos);
+ }
+
+ return result;
+}
+
+/* Generate the merged-fb mode modelist
+ * (Taken from mga driver)
+ */
+static DisplayModePtr
+I830GenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str,
+ DisplayModePtr i, DisplayModePtr j,
+ int pos)
+{
+ char* strmode = str;
+ char modename[256];
+ Bool gotdash = FALSE;
+ char gotsep = 0;
+ int p;
+ DisplayModePtr mode1 = NULL;
+ DisplayModePtr mode2 = NULL;
+ DisplayModePtr result = NULL;
+ int myslen;
+
+ do {
+ switch(*str) {
+ case 0:
+ case '-':
+ case '+':
+ case ' ':
+ case ',':
+ case ';':
+ if(strmode != str) {
+
+ myslen = str - strmode;
+ if(myslen > 255) myslen = 255;
+ strncpy(modename, strmode, myslen);
+ modename[myslen] = 0;
+
+ if(gotdash) {
+ if(mode1 == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Error parsing MetaModes parameter\n");
+ return NULL;
+ }
+ mode2 = I830GetModeFromName(modename, j);
+ if(!mode2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for Second\n", modename);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename);
+ mode1 = NULL;
+ gotsep = 0;
+ }
+ } else {
+ mode1 = I830GetModeFromName(modename, i);
+ if(!mode1) {
+ char* tmps = str;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for First\n", modename);
+ while(*tmps == ' ' || *tmps == ';') tmps++;
+ /* skip the next mode */
+ if(*tmps == '-' || *tmps == '+' || *tmps == ',') {
+ tmps++;
+ /* skip spaces */
+ while(*tmps == ' ' || *tmps == ';') tmps++;
+ /* skip modename */
+ while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++;
+ myslen = tmps - strmode;
+ if(myslen > 255) myslen = 255;
+ strncpy(modename,strmode,myslen);
+ modename[myslen] = 0;
+ str = tmps - 1;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\t(Skipping metamode \"%s\")\n", modename);
+ mode1 = NULL;
+ gotsep = 0;
+ }
+ }
+ gotdash = FALSE;
+ }
+ strmode = str + 1;
+ gotdash |= (*str == '-' || *str == '+' || *str == ',');
+ if (*str == '-' || *str == '+' || *str == ',')
+ gotsep = *str;
+
+ if(*str != 0) break;
+ /* Fall through otherwise */
+
+ default:
+ if(!gotdash && mode1) {
+ p = pos ;
+ if(!mode2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for Second\n", mode1->name);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\t(Skipping metamode \"%s\")\n", modename);
+ mode1 = NULL;
+ } else {
+ result = I830CopyModeNLink(pScrn, result, mode1, mode2, p);
+ mode1 = NULL;
+ mode2 = NULL;
+ }
+ gotsep = 0;
+ }
+ break;
+
+ }
+
+ } while(*(str++) != 0);
+
+ return result;
+}
+
+static DisplayModePtr
+I830GenerateModeList(ScrnInfoPtr pScrn, char* str,
+ DisplayModePtr i, DisplayModePtr j,
+ int pos)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if(str != NULL) {
+ return(I830GenerateModeListFromMetaModes(pScrn, str, i, j, pos));
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No MetaModes given, linking %s modes by default\n",
+ (pI830->NonRect ?
+ (((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest" : "tallest")
+ :
+ (((pos == PosLeftOf) || (pos == PosRightOf)) ? "widest common" : "tallest common")) );
+ return(I830GenerateModeListFromLargestModes(pScrn, i, j, pos));
+ }
+}
+
+static void
+I830RecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr mode, bmode;
+ int maxh, maxv;
+ static const char *str = "MergedFB: Virtual %s %d\n";
+ static const char *errstr = "Virtual %s to small for given SecondPosition offset\n";
+
+ mode = bmode = pScrn->modes;
+ maxh = maxv = 0;
+ do {
+ if(mode->HDisplay > maxh) maxh = mode->HDisplay;
+ if(mode->VDisplay > maxv) maxv = mode->VDisplay;
+ mode = mode->next;
+ } while(mode != bmode);
+
+ maxh += pI830->FirstXOffs + pI830->SecondXOffs;
+ maxv += pI830->FirstYOffs + pI830->SecondYOffs;
+
+ if(!(pScrn->display->virtualX)) {
+ if(maxh > 4088) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Virtual width with SecondPosition offset beyond hardware specs\n");
+ pI830->FirstXOffs = pI830->SecondXOffs = 0;
+ maxh -= (pI830->FirstXOffs + pI830->SecondXOffs);
+ }
+ pScrn->virtualX = maxh;
+ pScrn->displayWidth = maxh;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
+ } else {
+ if(maxh < pScrn->display->virtualX) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width");
+ pI830->FirstXOffs = pI830->SecondXOffs = 0;
+ }
+ }
+
+ if(!(pScrn->display->virtualY)) {
+ pScrn->virtualY = maxv;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
+ } else {
+ if(maxv < pScrn->display->virtualY) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height");
+ pI830->FirstYOffs = pI830->SecondYOffs = 0;
+ }
+ }
+}
+
+#define SDMPTR(x) ((I830ModePrivatePtr)x->currentMode->Private)->merged
+#define CDMPTR ((I830ModePrivatePtr)pI830->currentMode->Private)->merged
+
+#define BOUND(test,low,hi) \
+ { \
+ if((test) < (low)) (test) = (low); \
+ if((test) > (hi)) (test) = (hi); \
+ }
+
+#define REBOUND(low,hi,test) \
+ { \
+ if((test) < (low)) { \
+ (hi) += (test)-(low); \
+ (low) = (test); \
+ } \
+ if((test) > (hi)) { \
+ (low) += (test)-(hi); \
+ (hi) = (test); \
+ } \
+ }
+
+
+static void
+I830MergedPointerMoved(int scrnIndex, int x, int y)
+{
+ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+ I830Ptr pI830 = I830PTR(pScrn1);
+ ScrnInfoPtr pScrn2 = pI830->pScrn_2;
+ region out, in1, in2, f2, f1;
+ int deltax, deltay;
+ int temp1, temp2;
+ int old1x0, old1y0, old2x0, old2y0;
+ int FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0;
+ int HVirt = pScrn1->virtualX;
+ int VVirt = pScrn1->virtualY;
+ int sigstate;
+ Bool doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE;
+ int pos = ((I830MergedDisplayModePtr)pI830->currentMode->Private)->SecondPosition;
+
+ if(pI830->DGAactive) {
+ return;
+ /* DGA: There is no cursor and no panning while DGA is active. */
+ } else {
+ FirstXOffs = pI830->FirstXOffs;
+ FirstYOffs = pI830->FirstYOffs;
+ SecondXOffs = pI830->SecondXOffs;
+ SecondYOffs = pI830->SecondYOffs;
+ HaveNonRect = pI830->HaveNonRect;
+ HaveOffsRegions = pI830->HaveOffsRegions;
+ }
+
+ /* Check if the pointer is inside our dead areas */
+ if((pI830->MouseRestrictions) && !I830noPanoramiXExtension) {
+ if(HaveNonRect) {
+ if(InRegion(x, y, pI830->NonRectDead)) {
+ switch(pos) {
+ case PosLeftOf:
+ case PosRightOf: y = pI830->NonRectDead.y0 - 1;
+ doit = TRUE;
+ break;
+ case PosAbove:
+ case PosBelow: x = pI830->NonRectDead.x0 - 1;
+ doit = TRUE;
+ default: break;
+ }
+ }
+ }
+ if(HaveOffsRegions) {
+ if(InRegion(x, y, pI830->OffDead1)) {
+ switch(pos) {
+ case PosLeftOf:
+ case PosRightOf: y = pI830->OffDead1.y1;
+ doit = TRUE;
+ break;
+ case PosAbove:
+ case PosBelow: x = pI830->OffDead1.x1;
+ doit = TRUE;
+ default: break;
+ }
+ } else if(InRegion(x, y, pI830->OffDead2)) {
+ switch(pos) {
+ case PosLeftOf:
+ case PosRightOf: y = pI830->OffDead2.y0 - 1;
+ doit = TRUE;
+ break;
+ case PosAbove:
+ case PosBelow: x = pI830->OffDead2.x0 - 1;
+ doit = TRUE;
+ default: break;
+ }
+ }
+ }
+ if(doit) {
+ UpdateCurrentTime();
+ sigstate = xf86BlockSIGIO();
+ miPointerAbsoluteCursor(x, y, currentTime.milliseconds);
+ xf86UnblockSIGIO(sigstate);
+ return;
+ }
+ }
+
+ f1.x0 = old1x0 = pI830->FirstframeX0;
+ f1.x1 = pI830->FirstframeX1;
+ f1.y0 = old1y0 = pI830->FirstframeY0;
+ f1.y1 = pI830->FirstframeY1;
+ f2.x0 = old2x0 = pScrn2->frameX0;
+ f2.x1 = pScrn2->frameX1;
+ f2.y0 = old2y0 = pScrn2->frameY0;
+ f2.y1 = pScrn2->frameY1;
+
+ /* Define the outer region. Crossing this causes all frames to move */
+ out.x0 = pScrn1->frameX0;
+ out.x1 = pScrn1->frameX1;
+ out.y0 = pScrn1->frameY0;
+ out.y1 = pScrn1->frameY1;
+
+ /*
+ * Define the inner sliding window. Being outsize both frames but
+ * inside the outer clipping window will slide corresponding frame
+ */
+ in1 = out;
+ in2 = out;
+ switch(pos) {
+ case PosLeftOf:
+ in1.x0 = f1.x0;
+ in2.x1 = f2.x1;
+ break;
+ case PosRightOf:
+ in1.x1 = f1.x1;
+ in2.x0 = f2.x0;
+ break;
+ case PosBelow:
+ in1.y1 = f1.y1;
+ in2.y0 = f2.y0;
+ break;
+ case PosAbove:
+ in1.y0 = f1.y0;
+ in2.y1 = f2.y1;
+ break;
+ }
+
+ deltay = 0;
+ deltax = 0;
+
+ if(InRegion(x, y, out)) { /* inside outer region */
+
+ if(InRegion(x, y, in1) && !InRegion(x, y, f1)) {
+ REBOUND(f1.x0, f1.x1, x);
+ REBOUND(f1.y0, f1.y1, y);
+ deltax = 1;
+ }
+ if(InRegion(x, y, in2) && !InRegion(x, y, f2)) {
+ REBOUND(f2.x0, f2.x1, x);
+ REBOUND(f2.y0, f2.y1, y);
+ deltax = 1;
+ }
+
+ } else { /* outside outer region */
+
+ if(out.x0 > x) {
+ deltax = x - out.x0;
+ }
+ if(out.x1 < x) {
+ deltax = x - out.x1;
+ }
+ if(deltax) {
+ pScrn1->frameX0 += deltax;
+ pScrn1->frameX1 += deltax;
+ f1.x0 += deltax;
+ f1.x1 += deltax;
+ f2.x0 += deltax;
+ f2.x1 += deltax;
+ }
+
+ if(out.y0 > y) {
+ deltay = y - out.y0;
+ }
+ if(out.y1 < y) {
+ deltay = y - out.y1;
+ }
+ if(deltay) {
+ pScrn1->frameY0 += deltay;
+ pScrn1->frameY1 += deltay;
+ f1.y0 += deltay;
+ f1.y1 += deltay;
+ f2.y0 += deltay;
+ f2.y1 += deltay;
+ }
+
+ switch(pos) {
+ case PosLeftOf:
+ if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
+ if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
+ break;
+ case PosRightOf:
+ if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); }
+ if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); }
+ break;
+ case PosBelow:
+ if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); }
+ if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); }
+ break;
+ case PosAbove:
+ if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); }
+ if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); }
+ break;
+ }
+
+ }
+
+ if(deltax || deltay) {
+ pI830->FirstframeX0 = f1.x0;
+ pI830->FirstframeY0 = f1.y0;
+ pScrn2->frameX0 = f2.x0;
+ pScrn2->frameY0 = f2.y0;
+
+ switch(pos) {
+ case PosLeftOf:
+ case PosRightOf:
+ if(FirstYOffs || SecondYOffs || HaveNonRect) {
+ if(pI830->FirstframeY0 != old1y0) {
+ if(pI830->FirstframeY0 < FirstYOffs)
+ pI830->FirstframeY0 = FirstYOffs;
+
+ temp1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay;
+ temp2 = min((VVirt - SecondYOffs), (FirstYOffs + pI830->MBXNR1YMAX));
+ if(temp1 > temp2)
+ pI830->FirstframeY0 -= (temp1 - temp2);
+ }
+ if(pScrn2->frameY0 != old2y0) {
+ if(pScrn2->frameY0 < SecondYOffs)
+ pScrn2->frameY0 = SecondYOffs;
+
+ temp1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay;
+ temp2 = min((VVirt - FirstYOffs), (SecondYOffs + pI830->MBXNR2YMAX));
+ if(temp1 > temp2)
+ pScrn2->frameY0 -= (temp1 - temp2);
+ }
+ }
+ break;
+ case PosBelow:
+ case PosAbove:
+ if(FirstXOffs || SecondXOffs || HaveNonRect) {
+ if(pI830->FirstframeX0 != old1x0) {
+ if(pI830->FirstframeX0 < FirstXOffs)
+ pI830->FirstframeX0 = FirstXOffs;
+
+ temp1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay;
+ temp2 = min((HVirt - SecondXOffs), (FirstXOffs + pI830->MBXNR1XMAX));
+ if(temp1 > temp2)
+ pI830->FirstframeX0 -= (temp1 - temp2);
+ }
+ if(pScrn2->frameX0 != old2x0) {
+ if(pScrn2->frameX0 < SecondXOffs)
+ pScrn2->frameX0 = SecondXOffs;
+
+ temp1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay;
+ temp2 = min((HVirt - FirstXOffs), (SecondXOffs + pI830->MBXNR2XMAX));
+ if(temp1 > temp2)
+ pScrn2->frameX0 -= (temp1 - temp2);
+ }
+ }
+ break;
+ }
+
+ pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1;
+ pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1;
+ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay - 1;
+ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay - 1;
+
+ /* No need to update pScrn1->frame?1, done above */
+ if (pI830->pipe == 0) {
+ OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+ OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
+ } else {
+ OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn1->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+ OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pScrn2->frameY0 * pScrn1->displayWidth + pScrn2->frameX0) * pI830->cpp));
+ }
+ }
+}
+
+static void
+I830AdjustFrameMerged(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+ I830Ptr pI830 = I830PTR(pScrn1);
+ ScrnInfoPtr pScrn2 = pI830->pScrn_2;
+ int HTotal = pI830->currentMode->HDisplay;
+ int VTotal = pI830->currentMode->VDisplay;
+ int HMax = HTotal;
+ int VMax = VTotal;
+ int HVirt = pScrn1->virtualX;
+ int VVirt = pScrn1->virtualY;
+ int x1 = x, x2 = x;
+ int y1 = y, y2 = y;
+ int FirstXOffs = 0, FirstYOffs = 0, SecondXOffs = 0, SecondYOffs = 0;
+ int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536;
+
+ if(pI830->DGAactive) {
+ HVirt = pScrn1->displayWidth;
+ VVirt = pScrn1->virtualY;
+ } else {
+ FirstXOffs = pI830->FirstXOffs;
+ FirstYOffs = pI830->FirstYOffs;
+ SecondXOffs = pI830->SecondXOffs;
+ SecondYOffs = pI830->SecondYOffs;
+ MBXNR1XMAX = pI830->MBXNR1XMAX;
+ MBXNR1YMAX = pI830->MBXNR1YMAX;
+ MBXNR2XMAX = pI830->MBXNR2XMAX;
+ MBXNR2YMAX = pI830->MBXNR2YMAX;
+ }
+
+ BOUND(x, 0, HVirt - HTotal);
+ BOUND(y, 0, VVirt - VTotal);
+ BOUND(x1, FirstXOffs, min(HVirt, MBXNR1XMAX + FirstXOffs) - min(HTotal, MBXNR1XMAX) - SecondXOffs);
+ BOUND(y1, FirstYOffs, min(VVirt, MBXNR1YMAX + FirstYOffs) - min(VTotal, MBXNR1YMAX) - SecondYOffs);
+ BOUND(x2, SecondXOffs, min(HVirt, MBXNR2XMAX + SecondXOffs) - min(HTotal, MBXNR2XMAX) - FirstXOffs);
+ BOUND(y2, SecondYOffs, min(VVirt, MBXNR2YMAX + SecondYOffs) - min(VTotal, MBXNR2YMAX) - FirstYOffs);
+
+ switch(SDMPTR(pScrn1).SecondPosition) {
+ case PosLeftOf:
+ pScrn2->frameX0 = x2;
+ BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay);
+ pI830->FirstframeX0 = x1 + CDMPTR.Second->HDisplay;
+ BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay);
+ break;
+ case PosRightOf:
+ pI830->FirstframeX0 = x1;
+ BOUND(pI830->FirstframeY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR.First->VDisplay);
+ pScrn2->frameX0 = x2 + CDMPTR.First->HDisplay;
+ BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR.Second->VDisplay);
+ break;
+ case PosAbove:
+ BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay);
+ pScrn2->frameY0 = y2;
+ BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay);
+ pI830->FirstframeY0 = y1 + CDMPTR.Second->VDisplay;
+ break;
+ case PosBelow:
+ BOUND(pI830->FirstframeX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR.First->HDisplay);
+ pI830->FirstframeY0 = y1;
+ BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR.Second->HDisplay);
+ pScrn2->frameY0 = y2 + CDMPTR.First->VDisplay;
+ break;
+ }
+
+ BOUND(pI830->FirstframeX0, 0, HVirt - CDMPTR.First->HDisplay);
+ BOUND(pI830->FirstframeY0, 0, VVirt - CDMPTR.First->VDisplay);
+ BOUND(pScrn2->frameX0, 0, HVirt - CDMPTR.Second->HDisplay);
+ BOUND(pScrn2->frameY0, 0, VVirt - CDMPTR.Second->VDisplay);
+
+ pScrn1->frameX0 = x;
+ pScrn1->frameY0 = y;
+
+ pI830->FirstframeX1 = pI830->FirstframeX0 + CDMPTR.First->HDisplay - 1;
+ pI830->FirstframeY1 = pI830->FirstframeY0 + CDMPTR.First->VDisplay - 1;
+ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR.Second->HDisplay - 1;
+ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR.Second->VDisplay - 1;
+
+ pScrn1->frameX1 = pScrn1->frameX0 + pI830->currentMode->HDisplay - 1;
+ pScrn1->frameY1 = pScrn1->frameY0 + pI830->currentMode->VDisplay - 1;
+ pScrn1->frameX1 += FirstXOffs + SecondXOffs;
+ pScrn1->frameY1 += FirstYOffs + SecondYOffs;
+}
+
+/* Pseudo-Xinerama extension for MergedFB mode */
+static void
+I830UpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
+{
+ I830Ptr pI830 = I830PTR(pScrn1);
+ int scrnnum1 = 0, scrnnum2 = 1;
+ int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
+ int realvirtX, realvirtY;
+ DisplayModePtr currentMode, firstMode;
+ Bool infochanged = FALSE;
+ Bool usenonrect = pI830->NonRect;
+ const char *rectxine = "\t... setting up rectangular Xinerama layout\n";
+
+ pI830->MBXNR1XMAX = pI830->MBXNR1YMAX = pI830->MBXNR2XMAX = pI830->MBXNR2YMAX = 65536;
+ pI830->HaveNonRect = pI830->HaveOffsRegions = FALSE;
+
+ if(!pI830->MergedFB) return;
+
+ if(I830noPanoramiXExtension) return;
+
+ if(!I830XineramadataPtr) return;
+
+ if(pI830->SecondIsScrn0) {
+ scrnnum1 = 1;
+ scrnnum2 = 0;
+ }
+
+ /* Attention: Usage of RandR may lead to virtual X and Y dimensions
+ * actually smaller than our MetaModes. To avoid this, we calculate
+ * the max* fields here (and not somewhere else, like in CopyNLink)
+ *
+ * *** Note: RandR is disabled if one of CRTxxOffs is non-zero.
+ */
+
+ /* "Real" virtual: Virtual without the Offset */
+ realvirtX = pScrn1->virtualX - pI830->FirstXOffs - pI830->SecondXOffs;
+ realvirtY = pScrn1->virtualY - pI830->FirstYOffs - pI830->SecondYOffs;
+
+ if((pI830->I830XineramaVX != pScrn1->virtualX) || (pI830->I830XineramaVY != pScrn1->virtualY)) {
+
+ if(!(pScrn1->modes)) return;
+
+ pI830->maxFirst_X1 = pI830->maxFirst_X2 = 0;
+ pI830->maxFirst_Y1 = pI830->maxFirst_Y2 = 0;
+ pI830->maxSecond_X1 = pI830->maxSecond_X2 = 0;
+ pI830->maxSecond_Y1 = pI830->maxSecond_Y2 = 0;
+
+ currentMode = firstMode = pScrn1->modes;
+
+ do {
+
+ DisplayModePtr p = currentMode->next;
+ DisplayModePtr i = ((I830ModePrivatePtr)currentMode->Private)->merged.First;
+ DisplayModePtr j = ((I830ModePrivatePtr)currentMode->Private)->merged.Second;
+
+ if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
+ (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
+ (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) {
+
+ if(pI830->maxFirst_X1 == i->HDisplay) {
+ if(pI830->maxFirst_X2 < j->HDisplay) {
+ pI830->maxFirst_X2 = j->HDisplay; /* Widest Second mode displayed with widest CRT1 mode */
+ }
+ } else if(pI830->maxFirst_X1 < i->HDisplay) {
+ pI830->maxFirst_X1 = i->HDisplay; /* Widest CRT1 mode */
+ pI830->maxFirst_X2 = j->HDisplay;
+ }
+ if(pI830->maxSecond_X2 == j->HDisplay) {
+ if(pI830->maxSecond_X1 < i->HDisplay) {
+ pI830->maxSecond_X1 = i->HDisplay; /* Widest First mode displayed with widest Second mode */
+ }
+ } else if(pI830->maxSecond_X2 < j->HDisplay) {
+ pI830->maxSecond_X2 = j->HDisplay; /* Widest Second mode */
+ pI830->maxSecond_X1 = i->HDisplay;
+ }
+ if(pI830->maxFirst_Y1 == i->VDisplay) { /* Same as above, but tallest instead of widest */
+ if(pI830->maxFirst_Y2 < j->VDisplay) {
+ pI830->maxFirst_Y2 = j->VDisplay;
+ }
+ } else if(pI830->maxFirst_Y1 < i->VDisplay) {
+ pI830->maxFirst_Y1 = i->VDisplay;
+ pI830->maxFirst_Y2 = j->VDisplay;
+ }
+ if(pI830->maxSecond_Y2 == j->VDisplay) {
+ if(pI830->maxSecond_Y1 < i->VDisplay) {
+ pI830->maxSecond_Y1 = i->VDisplay;
+ }
+ } else if(pI830->maxSecond_Y2 < j->VDisplay) {
+ pI830->maxSecond_Y2 = j->VDisplay;
+ pI830->maxSecond_Y1 = i->VDisplay;
+ }
+ }
+ currentMode = p;
+
+ } while((currentMode) && (currentMode != firstMode));
+
+ pI830->I830XineramaVX = pScrn1->virtualX;
+ pI830->I830XineramaVY = pScrn1->virtualY;
+ infochanged = TRUE;
+
+ }
+
+ if((usenonrect) && pI830->maxFirst_X1) {
+ switch(pI830->SecondPosition) {
+ case PosLeftOf:
+ case PosRightOf:
+ if((pI830->maxFirst_Y1 != realvirtY) && (pI830->maxSecond_Y2 != realvirtY)) {
+ usenonrect = FALSE;
+ }
+ break;
+ case PosAbove:
+ case PosBelow:
+ if((pI830->maxFirst_X1 != realvirtX) && (pI830->maxSecond_X2 != realvirtX)) {
+ usenonrect = FALSE;
+ }
+ break;
+ }
+ if(infochanged && !usenonrect) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Virtual screen size does not match maximum display modes...\n");
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
+
+ }
+ } else if(infochanged && usenonrect) {
+ usenonrect = FALSE;
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Only clone modes available for this virtual screen size...\n");
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
+ }
+
+ if(pI830->maxFirst_X1) { /* Means we have at least one non-clone mode */
+ switch(pI830->SecondPosition) {
+ case PosLeftOf:
+ x1 = min(pI830->maxFirst_X2, pScrn1->virtualX - pI830->maxFirst_X1);
+ if(x1 < 0) x1 = 0;
+ y1 = pI830->FirstYOffs;
+ w1 = pScrn1->virtualX - x1;
+ h1 = realvirtY;
+ if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) {
+ h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1;
+ pI830->NonRectDead.x0 = x1;
+ pI830->NonRectDead.x1 = x1 + w1 - 1;
+ pI830->NonRectDead.y0 = y1 + h1;
+ pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ x2 = 0;
+ y2 = pI830->SecondYOffs;
+ w2 = max(pI830->maxSecond_X2, pScrn1->virtualX - pI830->maxSecond_X1);
+ if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
+ h2 = realvirtY;
+ if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) {
+ h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2;
+ pI830->NonRectDead.x0 = x2;
+ pI830->NonRectDead.x1 = x2 + w2 - 1;
+ pI830->NonRectDead.y0 = y2 + h2;
+ pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ break;
+ case PosRightOf:
+ x1 = 0;
+ y1 = pI830->FirstYOffs;
+ w1 = max(pI830->maxFirst_X1, pScrn1->virtualX - pI830->maxFirst_X2);
+ if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
+ h1 = realvirtY;
+ if((usenonrect) && (pI830->maxFirst_Y1 != realvirtY)) {
+ h1 = pI830->MBXNR1YMAX = pI830->maxFirst_Y1;
+ pI830->NonRectDead.x0 = x1;
+ pI830->NonRectDead.x1 = x1 + w1 - 1;
+ pI830->NonRectDead.y0 = y1 + h1;
+ pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ x2 = min(pI830->maxSecond_X1, pScrn1->virtualX - pI830->maxSecond_X2);
+ if(x2 < 0) x2 = 0;
+ y2 = pI830->SecondYOffs;
+ w2 = pScrn1->virtualX - x2;
+ h2 = realvirtY;
+ if((usenonrect) && (pI830->maxSecond_Y2 != realvirtY)) {
+ h2 = pI830->MBXNR2YMAX = pI830->maxSecond_Y2;
+ pI830->NonRectDead.x0 = x2;
+ pI830->NonRectDead.x1 = x2 + w2 - 1;
+ pI830->NonRectDead.y0 = y2 + h2;
+ pI830->NonRectDead.y1 = pScrn1->virtualY - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ break;
+ case PosAbove:
+ x1 = pI830->FirstXOffs;
+ y1 = min(pI830->maxFirst_Y2, pScrn1->virtualY - pI830->maxFirst_Y1);
+ if(y1 < 0) y1 = 0;
+ w1 = realvirtX;
+ h1 = pScrn1->virtualY - y1;
+ if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) {
+ w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1;
+ pI830->NonRectDead.x0 = x1 + w1;
+ pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+ pI830->NonRectDead.y0 = y1;
+ pI830->NonRectDead.y1 = y1 + h1 - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ x2 = pI830->SecondXOffs;
+ y2 = 0;
+ w2 = realvirtX;
+ h2 = max(pI830->maxSecond_Y2, pScrn1->virtualY - pI830->maxSecond_Y1);
+ if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
+ if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) {
+ w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2;
+ pI830->NonRectDead.x0 = x2 + w2;
+ pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+ pI830->NonRectDead.y0 = y2;
+ pI830->NonRectDead.y1 = y2 + h2 - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ break;
+ case PosBelow:
+ x1 = pI830->FirstXOffs;
+ y1 = 0;
+ w1 = realvirtX;
+ h1 = max(pI830->maxFirst_Y1, pScrn1->virtualY - pI830->maxFirst_Y2);
+ if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
+ if((usenonrect) && (pI830->maxFirst_X1 != realvirtX)) {
+ w1 = pI830->MBXNR1XMAX = pI830->maxFirst_X1;
+ pI830->NonRectDead.x0 = x1 + w1;
+ pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+ pI830->NonRectDead.y0 = y1;
+ pI830->NonRectDead.y1 = y1 + h1 - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ x2 = pI830->SecondXOffs;
+ y2 = min(pI830->maxSecond_Y1, pScrn1->virtualY - pI830->maxSecond_Y2);
+ if(y2 < 0) y2 = 0;
+ w2 = realvirtX;
+ h2 = pScrn1->virtualY - y2;
+ if((usenonrect) && (pI830->maxSecond_X2 != realvirtX)) {
+ w2 = pI830->MBXNR2XMAX = pI830->maxSecond_X2;
+ pI830->NonRectDead.x0 = x2 + w2;
+ pI830->NonRectDead.x1 = pScrn1->virtualX - 1;
+ pI830->NonRectDead.y0 = y2;
+ pI830->NonRectDead.y1 = y2 + h2 - 1;
+ pI830->HaveNonRect = TRUE;
+ }
+ default:
+ break;
+ }
+
+ switch(pI830->SecondPosition) {
+ case PosLeftOf:
+ case PosRightOf:
+ if(pI830->FirstYOffs) {
+ pI830->OffDead1.x0 = x1;
+ pI830->OffDead1.x1 = x1 + w1 - 1;
+ pI830->OffDead1.y0 = 0;
+ pI830->OffDead1.y1 = y1 - 1;
+ pI830->OffDead2.x0 = x2;
+ pI830->OffDead2.x1 = x2 + w2 - 1;
+ pI830->OffDead2.y0 = y2 + h2;
+ pI830->OffDead2.y1 = pScrn1->virtualY - 1;
+ pI830->HaveOffsRegions = TRUE;
+ } else if(pI830->SecondYOffs) {
+ pI830->OffDead1.x0 = x2;
+ pI830->OffDead1.x1 = x2 + w2 - 1;
+ pI830->OffDead1.y0 = 0;
+ pI830->OffDead1.y1 = y2 - 1;
+ pI830->OffDead2.x0 = x1;
+ pI830->OffDead2.x1 = x1 + w1 - 1;
+ pI830->OffDead2.y0 = y1 + h1;
+ pI830->OffDead2.y1 = pScrn1->virtualY - 1;
+ pI830->HaveOffsRegions = TRUE;
+ }
+ break;
+ case PosAbove:
+ case PosBelow:
+ if(pI830->FirstXOffs) {
+ pI830->OffDead1.x0 = x2 + w2;
+ pI830->OffDead1.x1 = pScrn1->virtualX - 1;
+ pI830->OffDead1.y0 = y2;
+ pI830->OffDead1.y1 = y2 + h2 - 1;
+ pI830->OffDead2.x0 = 0;
+ pI830->OffDead2.x1 = x1 - 1;
+ pI830->OffDead2.y0 = y1;
+ pI830->OffDead2.y1 = y1 + h1 - 1;
+ pI830->HaveOffsRegions = TRUE;
+ } else if(pI830->SecondXOffs) {
+ pI830->OffDead1.x0 = x1 + w1;
+ pI830->OffDead1.x1 = pScrn1->virtualX - 1;
+ pI830->OffDead1.y0 = y1;
+ pI830->OffDead1.y1 = y1 + h1 - 1;
+ pI830->OffDead2.x0 = 0;
+ pI830->OffDead2.x1 = x2 - 1;
+ pI830->OffDead2.y0 = y2;
+ pI830->OffDead2.y1 = y2 + h2 - 1;
+ pI830->HaveOffsRegions = TRUE;
+ }
+ default:
+ break;
+ }
+
+ }
+
+ I830XineramadataPtr[scrnnum1].x = x1;
+ I830XineramadataPtr[scrnnum1].y = y1;
+ I830XineramadataPtr[scrnnum1].width = w1;
+ I830XineramadataPtr[scrnnum1].height = h1;
+ I830XineramadataPtr[scrnnum2].x = x2;
+ I830XineramadataPtr[scrnnum2].y = y2;
+ I830XineramadataPtr[scrnnum2].width = w2;
+ I830XineramadataPtr[scrnnum2].height = h2;
+
+ if(infochanged) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: First (Screen %d) (%d,%d)-(%d,%d)\n",
+ scrnnum1, x1, y1, w1+x1-1, h1+y1-1);
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Second (Screen %d) (%d,%d)-(%d,%d)\n",
+ scrnnum2, x2, y2, w2+x2-1, h2+y2-1);
+ if(pI830->HaveNonRect) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n",
+ pI830->NonRectDead.x0, pI830->NonRectDead.y0,
+ pI830->NonRectDead.x1, pI830->NonRectDead.y1);
+ }
+ if(pI830->HaveOffsRegions) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
+ pI830->OffDead1.x0, pI830->OffDead1.y0,
+ pI830->OffDead1.x1, pI830->OffDead1.y1);
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
+ pI830->OffDead2.x0, pI830->OffDead2.y0,
+ pI830->OffDead2.x1, pI830->OffDead2.y1);
+ }
+ if(pI830->HaveNonRect || pI830->HaveOffsRegions) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Mouse restriction for inaccessible areas is %s\n",
+ pI830->MouseRestrictions ? "enabled" : "disabled");
+ }
+ }
+}
+
+/* Proc */
+
+int
+I830ProcXineramaQueryVersion(ClientPtr client)
+{
+ xPanoramiXQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = 1;
+ rep.minorVersion = 0;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+int
+I830ProcXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ pWin = LookupWindow(stuff->window, client);
+ if(!pWin) return BadWindow;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !I830noPanoramiXExtension;
+ if(client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.state, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+I830ProcXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ pWin = LookupWindow(stuff->window, client);
+ if(!pWin) return BadWindow;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.ScreenCount = I830XineramaNumScreens;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.ScreenCount, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+I830ProcXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenSizeReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ pWin = LookupWindow (stuff->window, client);
+ if(!pWin) return BadWindow;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.width = I830XineramadataPtr[stuff->screen].width;
+ rep.height = I830XineramadataPtr[stuff->screen].height;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.width, n);
+ swaps(&rep.height, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+I830ProcXineramaIsActive(ClientPtr client)
+{
+ xXineramaIsActiveReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !I830noPanoramiXExtension;
+ if(client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.state, n);
+ }
+ WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
+ return client->noClientException;
+}
+
+int
+I830ProcXineramaQueryScreens(ClientPtr client)
+{
+ xXineramaQueryScreensReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.number = (I830noPanoramiXExtension) ? 0 : I830XineramaNumScreens;
+ rep.length = rep.number * sz_XineramaScreenInfo >> 2;
+ if(client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.number, n);
+ }
+ WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
+
+ if(!I830noPanoramiXExtension) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < I830XineramaNumScreens; i++) {
+ scratch.x_org = I830XineramadataPtr[i].x;
+ scratch.y_org = I830XineramadataPtr[i].y;
+ scratch.width = I830XineramadataPtr[i].width;
+ scratch.height = I830XineramadataPtr[i].height;
+ if(client->swapped) {
+ register int n;
+ swaps(&scratch.x_org, n);
+ swaps(&scratch.y_org, n);
+ swaps(&scratch.width, n);
+ swaps(&scratch.height, n);
+ }
+ WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
+ }
+ }
+
+ return client->noClientException;
+}
+
+static int
+I830ProcXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return I830ProcXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return I830ProcXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return I830ProcXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return I830ProcXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return I830ProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return I830ProcXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+/* SProc */
+
+static int
+I830SProcXineramaQueryVersion (ClientPtr client)
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+ register int n;
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ return I830ProcXineramaQueryVersion(client);
+}
+
+static int
+I830SProcXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ return I830ProcXineramaGetState(client);
+}
+
+static int
+I830SProcXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ return I830ProcXineramaGetScreenCount(client);
+}
+
+static int
+I830SProcXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ return I830ProcXineramaGetScreenSize(client);
+}
+
+static int
+I830SProcXineramaIsActive(ClientPtr client)
+{
+ REQUEST(xXineramaIsActiveReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+ return I830ProcXineramaIsActive(client);
+}
+
+static int
+I830SProcXineramaQueryScreens(ClientPtr client)
+{
+ REQUEST(xXineramaQueryScreensReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+ return I830ProcXineramaQueryScreens(client);
+}
+
+int
+I830SProcXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return I830SProcXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return I830SProcXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return I830SProcXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return I830SProcXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return I830SProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return I830SProcXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+static void
+I830XineramaResetProc(ExtensionEntry* extEntry)
+{
+ /* Called by CloseDownExtensions() */
+ if(I830XineramadataPtr) {
+ Xfree(I830XineramadataPtr);
+ I830XineramadataPtr = NULL;
+ }
+}
+
+static void
+I830XineramaExtensionInit(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool success = FALSE;
+
+ if(!(I830XineramadataPtr)) {
+
+ if(!pI830->MergedFB) {
+ I830noPanoramiXExtension = TRUE;
+ pI830->MouseRestrictions = FALSE;
+ return;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xinerama active, not initializing Intel Pseudo-Xinerama\n");
+ I830noPanoramiXExtension = TRUE;
+ pI830->MouseRestrictions = FALSE;
+ return;
+ }
+#endif
+
+ if(I830noPanoramiXExtension) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Intel Pseudo-Xinerama disabled\n");
+ pI830->MouseRestrictions = FALSE;
+ return;
+ }
+
+ I830XineramaNumScreens = 2;
+
+ while(I830XineramaGeneration != serverGeneration) {
+
+ pI830->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
+ I830ProcXineramaDispatch,
+ I830SProcXineramaDispatch,
+ I830XineramaResetProc,
+ StandardMinorOpcode);
+
+ if(!pI830->XineramaExtEntry) break;
+
+ if(!(I830XineramadataPtr = (I830XineramaData *)
+ xcalloc(I830XineramaNumScreens, sizeof(I830XineramaData)))) break;
+
+ I830XineramaGeneration = serverGeneration;
+ success = TRUE;
+ }
+
+ if(!success) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to initialize Intel Pseudo-Xinerama extension\n");
+ I830noPanoramiXExtension = TRUE;
+ pI830->MouseRestrictions = FALSE;
+ return;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Intel Pseudo-Xinerama extension initialized\n");
+
+ pI830->I830XineramaVX = 0;
+ pI830->I830XineramaVY = 0;
+
+ }
+
+ I830UpdateXineramaScreenInfo(pScrn);
+
+}
+
static void
I830BIOSProbeDDC(ScrnInfoPtr pScrn, int index)
{
@@ -489,7 +2125,7 @@ GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle)
CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",
- i, (unsigned long) VODA);
+ i, VODA);
/* Check if it's a custom Video Output Device Attribute */
if (!(VODA & 0x80000000))
@@ -546,8 +2182,7 @@ GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn)
for (i=0; i<(pVbe->pInt10->cx & 0xff); i++)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Attachable device 0x%lx.\n",
- (unsigned long) ((CARD32*)pVbe->memory)[i]);
+ "Attachable device 0x%lx.\n", ((CARD32*)pVbe->memory)[i]);
return pVbe->pInt10->cx & 0xffff;
}
@@ -944,7 +2579,7 @@ SetPipeAccess(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
/* Don't try messing with the pipe, unless we're dual head */
- if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->origPipe != pI830->pipe) {
+ if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->MergedFB || pI830->origPipe != pI830->pipe) {
if (!SetBIOSPipe(pScrn, pI830->pipe))
return FALSE;
}
@@ -969,10 +2604,12 @@ I830Set640x480(ScrnInfoPtr pScrn)
m = 0x50;
break;
}
+
m |= (1 << 15) | (1 << 14);
if (VBESetVBEMode(pI830->pVbe, m, NULL))
return TRUE;
+
/* if the first failed, let's try the next - usually 800x600 */
m = 0x32;
switch (pScrn->depth) {
@@ -985,6 +2622,7 @@ I830Set640x480(ScrnInfoPtr pScrn)
break;
}
m |= (1 << 15) | (1 << 14);
+
if (VBESetVBEMode(pI830->pVbe, m, NULL))
return TRUE;
@@ -1089,7 +2727,7 @@ SetDisplayDevices(ScrnInfoPtr pScrn, int devices)
}
/* LVDS doesn't exist on these */
- if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))
+ if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I945G(pI830) || IS_I965G(pI830))
singlepipe &= ~(PIPE_LFP | (PIPE_LFP<<8));
if (pI830->availablePipes == 1)
@@ -1280,7 +2918,7 @@ static const char *displayDevices[] = {
"TV",
"DFP (digital flat panel)",
"LFP (local flat panel)",
- "CRT2 (second CRT)",
+ "Second (second CRT)",
"TV2 (second TV)",
"DFP2 (second digital flat panel)",
"LFP2 (second local flat panel)",
@@ -1459,8 +3097,11 @@ I830DetectMemory(ScrnInfoPtr pScrn)
gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
/* We need to reduce the stolen size, by the GTT and the popup.
- * The GTT varying according the the FbMapSize and the popup is 4KB */
- range = (pI830->FbMapSize / (1024*1024)) + 4;
+ * The GTT varying according the the FbMapSize and the popup is 4KB. */
+ if (IS_I965G(pI830))
+ range = 512 + 4; /* Fixed 512KB size for i965 */
+ else
+ range = (pI830->FbMapSize / MB(1)) + 4;
if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@ -1506,6 +3147,12 @@ I830DetectMemory(ScrnInfoPtr pScrn)
break;
}
}
+
+#if 0
+ /* And 64KB page aligned */
+ memsize &= ~0xFFFF;
+#endif
+
if (memsize > 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"detected %d kB stolen memory.\n", memsize / 1024);
@@ -1877,19 +3524,94 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
unsigned char r, g, b;
CARD32 val, temp;
int palreg;
- int dspreg, dspbase;
+ int dspreg, dspbase, dspsurf;
DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
pI830 = I830PTR(pScrn);
+ if (pI830->Clone || pI830->MergedFB) {
+ if (!pI830->pipe == 0) {
+ palreg = PALETTE_A;
+ dspreg = DSPACNTR;
+ dspbase = DSPABASE;
+ } else {
+ palreg = PALETTE_B;
+ dspreg = DSPBCNTR;
+ dspbase = DSPBBASE;
+ }
+
+ /* To ensure gamma is enabled we need to turn off and on the plane */
+ temp = INREG(dspreg);
+ OUTREG(dspreg, temp & ~(1<<31));
+ OUTREG(dspbase, INREG(dspbase));
+ OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
+ OUTREG(dspbase, INREG(dspbase));
+
+ /* It seems that an initial read is needed. */
+ temp = INREG(palreg);
+
+ switch(pScrn->depth) {
+ case 15:
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ r = colors[index].red;
+ g = colors[index].green;
+ b = colors[index].blue;
+ val = (r << 16) | (g << 8) | b;
+ for (j = 0; j < 8; j++) {
+ OUTREG(palreg + index * 32 + (j * 4), val);
+ }
+ }
+ break;
+ case 16:
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ r = colors[index / 2].red;
+ g = colors[index].green;
+ b = colors[index / 2].blue;
+
+ val = (r << 16) | (g << 8) | b;
+ OUTREG(palreg + index * 16, val);
+ OUTREG(palreg + index * 16 + 4, val);
+ OUTREG(palreg + index * 16 + 8, val);
+ OUTREG(palreg + index * 16 + 12, val);
+
+ if (index <= 31) {
+ r = colors[index].red;
+ g = colors[(index * 2) + 1].green;
+ b = colors[index].blue;
+
+ val = (r << 16) | (g << 8) | b;
+ OUTREG(palreg + index * 32, val);
+ OUTREG(palreg + index * 32 + 4, val);
+ OUTREG(palreg + index * 32 + 8, val);
+ OUTREG(palreg + index * 32 + 12, val);
+ }
+ }
+ break;
+ default:
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ r = colors[index].red;
+ g = colors[index].green;
+ b = colors[index].blue;
+ val = (r << 16) | (g << 8) | b;
+ OUTREG(palreg + index * 4, val);
+ }
+ break;
+ }
+ }
+
if (pI830->pipe == 0) {
palreg = PALETTE_A;
dspreg = DSPACNTR;
dspbase = DSPABASE;
+ dspsurf = DSPASURF;
} else {
palreg = PALETTE_B;
dspreg = DSPBCNTR;
dspbase = DSPBBASE;
+ dspsurf = DSPBSURF;
}
/* To ensure gamma is enabled we need to turn off and on the plane */
@@ -1898,6 +3620,8 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
OUTREG(dspbase, INREG(dspbase));
OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
OUTREG(dspbase, INREG(dspbase));
+ if (IS_I965G(pI830))
+ OUTREG(dspsurf, INREG(dspsurf));
/* It seems that an initial read is needed. */
temp = INREG(palreg);
@@ -2109,9 +3833,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
int flags24;
int defmon = 0;
int i, n;
- int DDCclock = 0;
+ int DDCclock = 0, DDCclock2 = 0;
char *s;
DisplayModePtr p, pMon;
+ xf86MonPtr monitor = NULL;
pointer pDDCModule = NULL, pVBEModule = NULL;
Bool enable;
const char *chipname;
@@ -2305,6 +4030,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_I945_GM:
chipname = "945GM";
break;
+ case PCI_CHIP_I965_G:
+ case PCI_CHIP_I965_G_1:
+ chipname = "965G";
+ break;
+ case PCI_CHIP_I965_Q:
+ chipname = "965Q";
+ break;
+ case PCI_CHIP_I946_GZ:
+ chipname = "946GZ";
+ break;
default:
chipname = "unknown chipset";
break;
@@ -2545,8 +4280,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->LinearAlloc = 0;
if (xf86GetOptValInteger(pI830->Options, OPTION_LINEARALLOC,
&(pI830->LinearAlloc))) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n",
+ if (pI830->LinearAlloc > 0)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n",
pI830->LinearAlloc);
+ else
+ pI830->LinearAlloc = 0;
}
pI830->fixedPipe = -1;
@@ -2559,6 +4297,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->fixedPipe = 1;
}
+ pI830->MergedFB =
+ xf86ReturnOptValBool(pI830->Options, OPTION_MERGEDFB, FALSE);
+
+ pI830->IntelXinerama =
+ xf86ReturnOptValBool(pI830->Options, OPTION_INTELXINERAMA, TRUE);
+
pI830->MonType1 = PIPE_NONE;
pI830->MonType2 = PIPE_NONE;
pI830->specifiedMonitor = FALSE;
@@ -2585,7 +4329,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->MonType1 |= PIPE_DFP;
else if (strcmp(sub, "LFP") == 0)
pI830->MonType1 |= PIPE_LFP;
- else if (strcmp(sub, "CRT2") == 0)
+ else if (strcmp(sub, "Second") == 0)
pI830->MonType1 |= PIPE_CRT2;
else if (strcmp(sub, "TV2") == 0)
pI830->MonType1 |= PIPE_TV2;
@@ -2614,7 +4358,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->MonType2 |= PIPE_DFP;
else if (strcmp(sub, "LFP") == 0)
pI830->MonType2 |= PIPE_LFP;
- else if (strcmp(sub, "CRT2") == 0)
+ else if (strcmp(sub, "Second") == 0)
pI830->MonType2 |= PIPE_CRT2;
else if (strcmp(sub, "TV2") == 0)
pI830->MonType2 |= PIPE_TV2;
@@ -2645,7 +4389,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->specifiedMonitor = TRUE;
}
- if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
+ if (!pI830->MergedFB &&
+ xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
if (pI830->availablePipes == 1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Can't enable Clone Mode because this is a single pipe device\n");
@@ -2676,17 +4421,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone) {
+ if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone ||
+ pI830->MergedFB) {
if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout "
- "defined for use in a DualHead or Clone setup.\n");
+ "defined for use in a DualHead, Clone or MergedFB setup.\n");
PreInitCleanup(pScrn);
return FALSE;
}
if (pI830->MonType1 == PIPE_NONE || pI830->MonType2 == PIPE_NONE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Monitor 1 or Monitor 2 "
- "cannot be type NONE in Dual or Clone setup.\n");
+ "cannot be type NONE in DualHead, Clone or MergedFB setup.\n");
PreInitCleanup(pScrn);
return FALSE;
}
@@ -2706,7 +4452,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
/*
* Let's setup the mobile systems to check the lid status
*/
- if (IS_MOBILE(pI830)) {
+ if (IS_MOBILE(pI830) && !pI830->MergedFB) {
pI830->checkDevices = TRUE;
if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
@@ -2914,6 +4660,80 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ if (pI830->MergedFB) {
+ pI830->pScrn_2 = xalloc(sizeof(ScrnInfoRec));
+
+ if(!pI830->pScrn_2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate memory for MergedFB mode. Disabling.\n");
+ pI830->MergedFB = FALSE;
+ } else {
+ memcpy(pI830->pScrn_2, pScrn, sizeof(ScrnInfoRec));
+ }
+ if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDPOSITION))) {
+ int result;
+ int ival;
+ Bool valid = FALSE;
+ char *tempstr = xalloc(strlen(s) + 1);
+ result = sscanf(s, "%s %d", tempstr, &ival);
+ if(result >= 1) {
+ if(!xf86NameCmp(tempstr,"LeftOf")) {
+ pI830->SecondPosition = PosLeftOf;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) pI830->FirstYOffs = -ival;
+ else pI830->SecondYOffs = ival;
+ }
+ pI830->SecondIsScrn0 = TRUE;
+ } else if(!xf86NameCmp(tempstr,"RightOf")) {
+ pI830->SecondPosition = PosRightOf;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) pI830->FirstYOffs = -ival;
+ else pI830->SecondYOffs = ival;
+ }
+ pI830->SecondIsScrn0 = FALSE;
+ } else if(!xf86NameCmp(tempstr,"Above")) {
+ pI830->SecondPosition = PosAbove;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) pI830->FirstXOffs = -ival;
+ else pI830->SecondXOffs = ival;
+ }
+ pI830->SecondIsScrn0 = FALSE;
+ } else if(!xf86NameCmp(tempstr,"Below")) {
+ pI830->SecondPosition = PosBelow;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) pI830->FirstXOffs = -ival;
+ else pI830->SecondXOffs = ival;
+ }
+ pI830->SecondIsScrn0 = TRUE;
+ }
+ }
+ if(!valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid parameters are: \"RightOf\", \"LeftOf\", \"Above\" or \"Below\"\n");
+ }
+ xfree(tempstr);
+ }
+ if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_METAMODES))) {
+ pI830->MetaModes = xalloc(strlen(s) + 1);
+ if(pI830->MetaModes)
+ memcpy(pI830->MetaModes, s, strlen(s) + 1);
+ }
+ if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDHSYNC))) {
+ pI830->SecondHSync = xalloc(strlen(s) + 1);
+ if(pI830->SecondHSync)
+ memcpy(pI830->SecondHSync, s, strlen(s) + 1);
+ }
+ if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_SECONDVREFRESH))) {
+ pI830->SecondVRefresh = xalloc(strlen(s) + 1);
+ if(pI830->SecondVRefresh)
+ memcpy(pI830->SecondVRefresh, s, strlen(s) + 1);
+ }
+ }
+
+
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
*/
@@ -2962,7 +4782,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* or, at least it's meant to..... alas it doesn't seem to always work.
*/
if (pI830->devicePresence) {
- int req=0, att=0, enc=0;
+ int req, att, enc;
GetDevicePresence(pScrn, &req, &att, &enc);
for (i = 0; i < NumDisplayTypes; i++) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -2981,7 +4801,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
/* Override */
if (pI830->fixedPipe != -1) {
- if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
+ if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone ||
+ pI830->MergedFB) {
pI830->pipe = pI830->fixedPipe;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Fixed Pipe setting primary to pipe %s.\n",
@@ -3003,9 +4824,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
- if (!xf86IsEntityShared(pScrn->entityList[0]) && !pI830->Clone) {
- /* If we're not dual head or clone, turn off the second head,
- * if monitorlayout is also specified. */
+ if (!xf86IsEntityShared(pScrn->entityList[0]) && !pI830->Clone &&
+ !pI830->MergedFB) {
+ /* If we're not dual head, clone or mergedfb, turn off the
+ * second head if monitorlayout is also specified.
+ */
if (pI830->pipe == 0)
pI830->operatingDevices = pI830->MonType1;
@@ -3108,6 +4931,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
else
pI830->CursorNeedsPhysical = FALSE;
+ if (IS_I965G(pI830))
+ pI830->CursorNeedsPhysical = FALSE;
+
/* Force ring buffer to be in low memory for all chipsets */
pI830->NeedRingBufferLow = TRUE;
@@ -3157,12 +4983,74 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pDDCModule = xf86LoadSubModule(pScrn, "ddc");
- pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
-
- if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL) {
- xf86PrintEDID(pI830->vesa->monitor);
- xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
+ monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+
+ if ((pScrn->monitor->DDC = monitor) != NULL) {
+ xf86PrintEDID(monitor);
+ xf86SetDDCproperties(pScrn, monitor);
+ }
+
+ if(pI830->MergedFB) {
+ pI830->pScrn_2->monitor = xalloc(sizeof(MonRec));
+ if(pI830->pScrn_2->monitor) {
+ DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
+ memcpy(pI830->pScrn_2->monitor, pScrn->monitor, sizeof(MonRec));
+ pI830->pScrn_2->monitor->DDC = NULL;
+ pI830->pScrn_2->monitor->Modes = NULL;
+ pI830->pScrn_2->monitor->id = (char *)SecondMonitorName;
+ tempm = pScrn->monitor->Modes;
+ while(tempm) {
+ if(!(newm = xalloc(sizeof(DisplayModeRec)))) break;
+ memcpy(newm, tempm, sizeof(DisplayModeRec));
+ if(!(newm->name = xalloc(strlen(tempm->name) + 1))) {
+ xfree(newm);
+ break;
+ }
+ strcpy(newm->name, tempm->name);
+ if(!pI830->pScrn_2->monitor->Modes)
+ pI830->pScrn_2->monitor->Modes = newm;
+ if(currentm) {
+ currentm->next = newm;
+ newm->prev = currentm;
+ }
+ currentm = newm;
+ tempm = tempm->next;
+ }
+ if(pI830->SecondHSync) {
+ pI830->pScrn_2->monitor->nHsync =
+ I830StrToRanges(pI830->pScrn_2->monitor->hsync, pI830->SecondHSync, MAX_HSYNC);
+ }
+ if(pI830->SecondVRefresh) {
+ pI830->pScrn_2->monitor->nVrefresh =
+ I830StrToRanges(pI830->pScrn_2->monitor->vrefresh, pI830->SecondVRefresh, MAX_VREFRESH);
+ }
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ pI830->pVbe->ddc = DDC_UNCHECKED;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Probing DDC data for second head\n");
+ if((monitor = vbeDoEDID(pI830->pVbe, pDDCModule))) {
+ xf86PrintEDID(monitor);
+ xf86SetDDCproperties(pI830->pScrn_2, monitor);
+ pI830->pScrn_2->monitor->DDC = monitor;
+ /* use DDC data if no ranges in config file */
+ if(!pI830->SecondHSync) {
+ pI830->pScrn_2->monitor->nHsync = 0;
+ }
+ if(!pI830->SecondVRefresh) {
+ pI830->pScrn_2->monitor->nVrefresh = 0;
+ }
+ }
+ SetPipeAccess(pScrn);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate memory for second monitor.\n");
+ if(pI830->pScrn_2)
+ xfree(pI830->pScrn_2);
+ pI830->pScrn_2 = NULL;
+ pI830->MergedFB = FALSE;
+ }
}
+
xf86UnloadSubModule(pDDCModule);
/* XXX Move this to a header. */
@@ -3189,7 +5077,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->useExtendedRefresh = FALSE;
- if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
+ if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone ||
+ pI830->MergedFB) {
int pipe =
(pI830->operatingDevices >> PIPE_SHIFT(pI830->pipe)) & PIPE_ACTIVE_MASK;
if (pipe & ~PIPE_CRT_ACTIVE) {
@@ -3268,6 +5157,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
DDCclock = I830UseDDC(pScrn);
+ if (pI830->MergedFB)
+ DDCclock2 = I830UseDDC(pI830->pScrn_2);
+
/*
* Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
* functions.
@@ -3281,6 +5173,21 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
+ if (pI830->MergedFB) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Retrieving mode pool for second head.\n");
+ pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo);
+
+ if (!pI830->pScrn_2->modePool) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No Video BIOS modes for chosen depth.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ SetPipeAccess(pScrn);
+ }
+
/* This may look a little weird, but to notify that we're using the
* default hsync/vrefresh we need to unset what we just set .....
*/
@@ -3298,6 +5205,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
SetPipeAccess(pScrn);
VBESetModeNames(pScrn->modePool);
+ if (pI830->MergedFB)
+ VBESetModeNames(pI830->pScrn_2->modePool);
+
/*
* XXX DDC information: There's code in xf86ValidateModes
@@ -3321,6 +5231,20 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
+ if (pI830->MergedFB) {
+ n = VBEValidateModes(pI830->pScrn_2, NULL, pI830->pScrn_2->display->modes, NULL,
+ NULL, 0, MAX_DISPLAY_PITCH, 1,
+ 0, MAX_DISPLAY_HEIGHT,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ memsize, LOOKUP_BEST_REFRESH);
+ if (n <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ }
+
/* Only use this if we've got DDC available */
if (DDCclock > 0) {
p = pScrn->modes;
@@ -3352,6 +5276,37 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
} while (p != NULL && p != pScrn->modes);
}
+ /* Only use this if we've got DDC available */
+ if (DDCclock2 > 0) {
+ p = pI830->pScrn_2->modes;
+ if (p == NULL)
+ return FALSE;
+ do {
+ int Clock = 100000000; /* incredible value */
+
+ if (p->status == MODE_OK) {
+ for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) {
+ if ((pMon->HDisplay != p->HDisplay) ||
+ (pMon->VDisplay != p->VDisplay) ||
+ (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+ continue;
+
+ /* Find lowest supported Clock for this resolution */
+ if (Clock > pMon->Clock)
+ Clock = pMon->Clock;
+ }
+
+ if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) {
+ ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
+ p->name, pI830->pScrn_2->monitor->id,
+ Clock/1000.0, DDCclock2);
+ p->status = MODE_BAD;
+ }
+ }
+ p = p->next;
+ } while (p != NULL && p != pI830->pScrn_2->modes);
+ }
+
xf86PruneDriverModes(pScrn);
if (pScrn->modes == NULL) {
@@ -3360,14 +5315,42 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
+ if (pI830->MergedFB) {
+ DisplayModePtr old_modes, cur_mode;
+
+ xf86PruneDriverModes(pI830->pScrn_2);
+
+ if (pI830->pScrn_2->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+
+ old_modes = pScrn->modes;
+ cur_mode = pScrn->currentMode;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n");
+
+ pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes,
+ old_modes, pI830->pScrn_2->modes,
+ pI830->SecondPosition);
+
+ if(!pScrn->modes) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n");
+ pScrn->modes = old_modes;
+ pScrn->currentMode = cur_mode;
+ pI830->MergedFB = FALSE;
+ }
+ }
+
/* Now we check the VESA BIOS's displayWidth and reset if necessary */
p = pScrn->modes;
do {
- VbeModeInfoData *data = (VbeModeInfoData *) p->Private;
+ I830ModePrivatePtr mp = (I830ModePrivatePtr) p->Private;
VbeModeInfoBlock *modeInfo;
/* Get BytesPerScanline so we can reset displayWidth */
- if ((modeInfo = VBEGetModeInfo(pI830->pVbe, data->mode))) {
+ if ((modeInfo = VBEGetModeInfo(pI830->pVbe, mp->vbeData.mode))) {
if (pScrn->displayWidth < modeInfo->BytesPerScanline / pI830->cpp) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Correcting stride (%d -> %d)\n", pScrn->displayWidth, modeInfo->BytesPerScanline);
pScrn->displayWidth = modeInfo->BytesPerScanline / pI830->cpp;
@@ -3378,6 +5361,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->currentMode = pScrn->modes;
+ if (pI830->MergedFB) {
+ /* If no virtual dimension was given by the user,
+ * calculate a sane one now. Adapts pScrn->virtualX,
+ * pScrn->virtualY and pScrn->displayWidth.
+ */
+ I830RecalcDefaultVirtualSize(pScrn);
+
+ pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
+ pScrn->currentMode = pScrn->modes;
+ pI830->currentMode = pScrn->currentMode;
+ }
+
#ifndef USE_PITCHES
#define USE_PITCHES 1
#endif
@@ -3681,8 +5676,12 @@ CheckInheritedState(ScrnInfoPtr pScrn)
}
#if 0
- if (errors)
- I830PrintErrorState(pScrn);
+ if (errors) {
+ if (IS_I965G(pI830))
+ I965PrintErrorState(pScrn);
+ else
+ I830PrintErrorState(pScrn);
+ }
#endif
if (fatal)
@@ -3712,8 +5711,15 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
pI830->entityPrivate->RingRunning = 0;
/* Reset the fence registers to 0 */
- for (i = 0; i < 8; i++)
- OUTREG(FENCE + i * 4, 0);
+ if (IS_I965G(pI830)) {
+ for (i = 0; i < FENCE_NEW_NR; i++) {
+ OUTREG(FENCE_NEW + i * 8, 0);
+ OUTREG(FENCE_NEW + 4 + i * 8, 0);
+ }
+ } else {
+ for (i = 0; i < FENCE_NR; i++)
+ OUTREG(FENCE + i * 4, 0);
+ }
/* Flush the ring buffer (if enabled), then disable it. */
/* God this is ugly */
#define flush_ring() do { \
@@ -3752,10 +5758,21 @@ SetFenceRegs(ScrnInfoPtr pScrn)
if (!I830IsPrimary(pScrn)) return;
- for (i = 0; i < 8; i++) {
- OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
- if (I810_DEBUG & DEBUG_VERBOSE_VGA)
- ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+ if (IS_I965G(pI830)) {
+ for (i = 0; i < FENCE_NEW_NR; i++) {
+ OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
+ OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+ if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
+ ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]);
+ ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+ }
+ }
+ } else {
+ for (i = 0; i < FENCE_NR; i++) {
+ OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
+ if (I810_DEBUG & DEBUG_VERBOSE_VGA)
+ ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+ }
}
}
@@ -3856,6 +5873,12 @@ SaveHWState(ScrnInfoPtr pScrn)
vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
pVesa = pI830->vesa;
+
+ if (IS_I965G(pI830)) {
+ pI830->savedAsurf = INREG(DSPASURF);
+ pI830->savedBsurf = INREG(DSPBSURF);
+ }
+
/*
* This save/restore method doesn't work for 845G BIOS, or for some
* other platforms. Enable it in all cases.
@@ -3908,9 +5931,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
DPRINTF(PFX, "RestoreHWState\n");
-#ifdef XF86DRI
- I830DRISetVBlankInterrupt (pScrn, FALSE);
-#endif
if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
SetBIOSPipe(pScrn, pI830->origPipe);
else
@@ -3969,6 +5989,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
VBESetDisplayStart(pVbe, pVesa->x, pVesa->y, TRUE);
+ if (IS_I965G(pI830)) {
+ OUTREG(DSPASURF, pI830->savedAsurf);
+ OUTREG(DSPBSURF, pI830->savedBsurf);
+ }
+
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
@@ -4035,7 +6060,8 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
pScrn->virtualY * pI830->displayWidth * pI830->cpp);
#endif
- if (pI830->Clone && pI830->CloneHDisplay && pI830->CloneVDisplay &&
+ if (pI830->Clone &&
+ pI830->CloneHDisplay && pI830->CloneVDisplay &&
!pI830->preinit && !pI830->closing) {
VbeCRTCInfoBlock newblock;
int newmode = mode;
@@ -4112,12 +6138,18 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
else
Mon = pI830->MonType2;
+
/* Now recheck refresh operations we can use */
pI830->useExtendedRefresh = FALSE;
pI830->vesa->useDefaultRefresh = FALSE;
- if (Mon != PIPE_CRT)
+ if (Mon != PIPE_CRT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "A non-CRT device is attached to pipe %c.\n"
+ "\tNo refresh rate overrides will be attempted.\n",
+ PIPE_NAME(pI830->pipe));
pI830->vesa->useDefaultRefresh = TRUE;
+ }
mode |= 1 << 11;
if (pI830->vesa->useDefaultRefresh)
@@ -4169,7 +6201,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
{
I830Ptr pI830 = I830PTR(pScrn);
vbeInfoPtr pVbe = pI830->pVbe;
- VbeModeInfoData *data = (VbeModeInfoData *) pMode->Private;
+ I830ModePrivatePtr mp = (I830ModePrivatePtr) pMode->Private;
int mode, i;
CARD32 planeA, planeB, temp;
int refresh = 60;
@@ -4180,7 +6212,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
DPRINTF(PFX, "I830VESASetMode\n");
/* Always Enable Linear Addressing */
- mode = data->mode | (1 << 15) | (1 << 14);
+ mode = mp->vbeData.mode | (1 << 15) | (1 << 14);
#ifdef XF86DRI
didLock = I830DRILock(pScrn);
@@ -4200,18 +6232,63 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
SetPipeAccess(pScrn);
- if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
- return FALSE;
+ if (!pI830->MergedFB) {
+ if (I830VESASetVBEMode(pScrn, mode, mp->vbeData.block) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
+ return FALSE;
+ }
+ }else {
+ I830ModePrivatePtr s = (I830ModePrivatePtr)mp->merged.Second->Private;
+ I830ModePrivatePtr f = (I830ModePrivatePtr)mp->merged.First->Private;
+ int pipe = pI830->pipe; /* save current pipe */
+
+ SetBIOSPipe(pScrn, !pI830->pipe);
+
+ pI830->pipe = !pI830->pipe;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
+
+ if (I830VESASetVBEMode(pScrn, (s->vbeData.mode | 1<<15 | 1<<14), s->vbeData.block) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
+ return FALSE;
+ }
+
+ pI830->pipe = pipe; /* restore current pipe */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode on Pipe %s.\n", pI830->pipe ? "B" : "A");
+
+ SetPipeAccess(pScrn);
+
+ if (I830VESASetVBEMode(pScrn, (f->vbeData.mode | 1<<15 | 1<<14), f->vbeData.block) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
+ return FALSE;
+ }
}
+#if 0
+ { /* I965G ENABLE TILING */
+ planeA = INREG(DSPACNTR) | 1<<10;
+ OUTREG(DSPACNTR, planeA);
+ /* flush the change. */
+ temp = INREG(DSPABASE);
+ OUTREG(DSPABASE, temp);
+ }
+#else
+ { /* I965G DISABLE TILING */
+ planeA = INREG(DSPACNTR) & ~1<<10;
+ OUTREG(DSPACNTR, planeA);
+ /* flush the change. */
+ temp = INREG(DSPABASE);
+ OUTREG(DSPABASE, temp);
+ OUTREG(DSPASURF, INREG(DSPASURF));
+ }
+#endif
+
/*
* The BIOS may not set a scanline pitch that would require more video
* memory than it's aware of. We check for this later, and set it
* explicitly if necessary.
*/
- if (data->data->XResolution != pI830->displayWidth) {
- if (pI830->Clone) {
+ if (mp->vbeData.data->XResolution != pI830->displayWidth) {
+ if (pI830->Clone || pI830->MergedFB) {
SetBIOSPipe(pScrn, !pI830->pipe);
VBESetLogicalScanline(pVbe, pI830->displayWidth);
}
@@ -4220,7 +6297,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
}
if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) {
- if (pI830->Clone) {
+ if (pI830->Clone || pI830->MergedFB) {
SetBIOSPipe(pScrn, !pI830->pipe);
VBESetGetDACPaletteFormat(pVbe, 8);
}
@@ -4264,6 +6341,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* flush the change. */
temp = INREG(DSPABASE);
OUTREG(DSPABASE, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(DSPASURF);
+ OUTREG(DSPASURF, temp);
+ }
}
if (pI830->planeEnabled[1]) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n");
@@ -4274,6 +6355,10 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* flush the change. */
temp = INREG(DSPBADDR);
OUTREG(DSPBADDR, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(DSPBSURF);
+ OUTREG(DSPBSURF, temp);
+ }
}
planeA = INREG(DSPACNTR);
@@ -4306,6 +6391,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+ CARD32 surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
temp = INREG(stridereg);
@@ -4319,12 +6405,17 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* Trigger update */
temp = INREG(basereg);
OUTREG(basereg, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(surfreg);
+ OUTREG(surfreg, temp);
+ }
if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
basereg = pI830->pipe ? DSPABASE : DSPBBASE;
sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+ surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
temp = INREG(stridereg);
if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) {
@@ -4337,11 +6428,16 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* Trigger update */
temp = INREG(basereg);
OUTREG(basereg, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(surfreg);
+ OUTREG(surfreg, temp);
+ }
}
} else {
CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE;
CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+ CARD32 surfreg = pI830->pipe ? DSPASURF : DSPBSURF;
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
@@ -4356,10 +6452,15 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* Trigger update */
temp = INREG(basereg);
OUTREG(basereg, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(surfreg);
+ OUTREG(surfreg, temp);
+ }
stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+ surfreg = !pI830->pipe ? DSPASURF : DSPBSURF;
temp = INREG(stridereg);
if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) {
@@ -4372,12 +6473,17 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* Trigger update */
temp = INREG(basereg);
OUTREG(basereg, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(surfreg);
+ OUTREG(surfreg, temp);
+ }
}
} else {
for (i = 0; i < pI830->availablePipes; i++) {
CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE;
CARD32 basereg = i ? DSPBBASE : DSPABASE;
CARD32 sizereg = i ? DSPBSIZE : DSPASIZE;
+ CARD32 surfreg = i ? DSPBSURF : DSPASURF;
if (!pI830->planeEnabled[i])
continue;
@@ -4389,10 +6495,29 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
(int)(temp / pI830->cpp), pI830->displayWidth);
OUTREG(stridereg, pI830->displayWidth * pI830->cpp);
}
- OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
+
+ if (pI830->MergedFB) {
+ switch (pI830->SecondPosition) {
+ case PosRightOf:
+ case PosBelow:
+ OUTREG(DSPABASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
+ OUTREG(DSPBBASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
+ break;
+ case PosLeftOf:
+ case PosAbove:
+ OUTREG(DSPABASE, (CDMPTR.Second->HDisplay - 1) | ((CDMPTR.Second->VDisplay - 1) << 16));
+ OUTREG(DSPBBASE, (CDMPTR.First->HDisplay - 1) | ((CDMPTR.First->VDisplay - 1) << 16));
+ break;
+ }
+ } else
+ OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
/* Trigger update */
temp = INREG(basereg);
OUTREG(basereg, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(surfreg);
+ OUTREG(surfreg, temp);
+ }
}
}
@@ -4495,9 +6620,13 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
SetHWOperatingState(pScrn);
#endif
-#ifdef XF86DRI
- I830DRISetVBlankInterrupt (pScrn, TRUE);
+#if 0
+ if (IS_I965G(pI830))
+ I965PrintErrorState(pScrn);
+ else
+ I830PrintErrorState(pScrn);
#endif
+
#ifdef XF86DRI
if (didLock)
I830DRIUnlock(pScrn);
@@ -4551,6 +6680,72 @@ I830PrintErrorState(ScrnInfoPtr pScrn)
INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
}
+void
+I965PrintErrorState(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
+ INREG(PGETBL_CTL), INREG(PGE_ERR));
+
+ ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965));
+
+ ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
+ INREG(LP_RING + RING_TAIL),
+ INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
+ INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
+
+ ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
+ (int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR));
+
+ ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965),
+ (int)INREG(INST_DONE_1));
+ ErrorF("instpm: %x\n", (int)INREG(INST_PM));
+
+ ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
+
+ ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n",
+ (int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR),
+ (int)INREG(IIR));
+
+ ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
+ ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
+
+ ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0),
+ (int)INREG(CACHE_MODE_1));
+ ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE));
+
+ ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", (int)INREG(IA_VERTICES_COUNT_QW),
+ (int)INREG(IA_VERTICES_COUNT_QW+4));
+ ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(IA_PRIMITIVES_COUNT_QW),
+ (int)INREG(IA_PRIMITIVES_COUNT_QW+4));
+
+ ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(VS_INVOCATION_COUNT_QW),
+ (int)INREG(VS_INVOCATION_COUNT_QW+4));
+
+ ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(GS_INVOCATION_COUNT_QW),
+ (int)INREG(GS_INVOCATION_COUNT_QW+4));
+ ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(GS_PRIMITIVES_COUNT_QW),
+ (int)INREG(GS_PRIMITIVES_COUNT_QW+4));
+
+ ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(CL_INVOCATION_COUNT_QW),
+ (int)INREG(CL_INVOCATION_COUNT_QW+4));
+ ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(CL_PRIMITIVES_COUNT_QW),
+ (int)INREG(CL_PRIMITIVES_COUNT_QW+4));
+
+ ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(PS_INVOCATION_COUNT_QW),
+ (int)INREG(PS_INVOCATION_COUNT_QW+4));
+ ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", (int)INREG(PS_DEPTH_COUNT_QW),
+ (int)INREG(PS_DEPTH_COUNT_QW+4));
+
+ ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL));
+ ErrorF("TS_CTL %x TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL),
+ (int)INREG(TS_DEBUG_DATA));
+ ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2));
+
+
+}
+
#ifdef I830DEBUG
static void
dump_DSPACNTR(ScrnInfoPtr pScrn)
@@ -4777,7 +6972,8 @@ I830CreateScreenResources (ScreenPtr pScreen)
if (!(*pScreen->CreateScreenResources)(pScreen))
return FALSE;
- if (pI830->rotation != RR_Rotate_0) {
+ if (xf86LoaderCheckSymbol("I830RandRSetConfig") && pI830->rotation != RR_Rotate_0) {
+ Rotation (*I830RandRSetConfig)(ScreenPtr pScreen, Rotation rr, int rate, RRScreenSizePtr pSize) = NULL;
RRScreenSize p;
Rotation requestedRotation = pI830->rotation;
@@ -4789,9 +6985,12 @@ I830CreateScreenResources (ScreenPtr pScreen)
p.mmWidth = pScreen->mmWidth;
p.mmHeight = pScreen->mmHeight;
- pI830->starting = TRUE; /* abuse this for dual head & rotation */
- I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
- pI830->starting = FALSE;
+ I830RandRSetConfig = LoaderSymbol("I830RandRSetConfig");
+ if (I830RandRSetConfig) {
+ pI830->starting = TRUE; /* abuse this for dual head & rotation */
+ (*I830RandRSetConfig) (pScreen, requestedRotation, 0, &p);
+ pI830->starting = FALSE;
+ }
}
return TRUE;
@@ -4844,6 +7043,9 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
CARD32 ctx_addr;
+ if (pI830->noAccel)
+ return;
+
ctx_addr = pI830->ContextMem.Start;
/* Align to a 2k boundry */
ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
@@ -4857,10 +7059,13 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn)
ADVANCE_LP_RING();
}
- if (IS_I9XX(pI830))
- I915EmitInvarientState(pScrn);
- else
- I830EmitInvarientState(pScrn);
+ if (!IS_I965G(pI830))
+ {
+ if (IS_I9XX(pI830))
+ I915EmitInvarientState(pScrn);
+ else
+ I830EmitInvarientState(pScrn);
+ }
}
static Bool
@@ -4890,6 +7095,47 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->RotatedMem2.Key = -1;
}
+#ifdef HAS_MTRR_SUPPORT
+ {
+ int fd;
+ struct mtrr_gentry gentry;
+ struct mtrr_sentry sentry;
+
+ if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) {
+ for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
+ ++gentry.regnum) {
+
+ if (gentry.size < 1) {
+ /* DISABLED */
+ continue;
+ }
+
+ /* Check the MTRR range is one we like and if not - remove it.
+ * The Xserver common layer will then setup the right range
+ * for us.
+ */
+ if (gentry.base == pI830->LinearAddr &&
+ gentry.size < pI830->FbMapSize) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Removing bad MTRR range (base 0x%lx, size 0x%x)\n",
+ gentry.base, gentry.size);
+
+ sentry.base = gentry.base;
+ sentry.size = gentry.size;
+ sentry.type = gentry.type;
+
+ if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to remove bad MTRR range\n");
+ }
+ }
+ }
+ close(fd);
+ }
+ }
+#endif
+
if (xf86IsEntityShared(pScrn->entityList[0])) {
/* PreInit failed on the second head, so make sure we turn it off */
if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
@@ -5242,13 +7488,33 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = I830BIOSCloseScreen;
- if (pI830->shadowReq.minorversion >= 1) {
+ if (pI830->MergedFB) {
+ pI830->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = I830MergedPointerMoved;
+
+ if(pI830->IntelXinerama) {
+ I830noPanoramiXExtension = FALSE;
+ I830XineramaExtensionInit(pScrn);
+ if(!I830noPanoramiXExtension) {
+ if(pI830->HaveNonRect) {
+ /* Reset the viewport (now eventually non-recangular) */
+ I830AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ }
+ }
+ } else {
+ pI830->MouseRestrictions = FALSE;
+ }
+ } else if (pI830->shadowReq.minorversion >= 1) {
/* Rotation */
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
xf86DisableRandR(); /* Disable built-in RandR extension */
shadowSetup(pScreen);
/* support all rotations */
- I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+ if (IS_I965G(pI830)) {
+ I830RandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
+ } else {
+ I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+ }
pI830->PointerMoved = pScrn->PointerMoved;
pScrn->PointerMoved = I830PointerMoved;
pI830->CreateScreenResources = pScreen->CreateScreenResources;
@@ -5265,6 +7531,20 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
I830_dump_registers(pScrn);
#endif
+ if (IS_I965G(pI830)) {
+ /* turn off clock gating */
+#if 0
+ OUTREG(0x6204, 0x70804000);
+ OUTREG(0x6208, 0x00000001);
+#else
+ OUTREG(0x6204, 0x70000000);
+#endif
+ /* Enable DAP stateless accesses.
+ * Required for all i965 steppings.
+ */
+ OUTREG(SVG_WORK_CTL, 0x00000010);
+ }
+
pI830->starting = FALSE;
pI830->closing = FALSE;
pI830->suspended = FALSE;
@@ -5296,7 +7576,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
static void
-I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
+I830AdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn;
I830Ptr pI830;
@@ -5307,12 +7587,26 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
pI830 = I830PTR(pScrn);
pVbe = pI830->pVbe;
- DPRINTF(PFX, "I830BIOSAdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
+ DPRINTF(PFX, "I830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
x, pI830->xoffset, y, pI830->yoffset);
/* Sync the engine before adjust frame */
i830WaitSync(pScrn);
+ if (pI830->MergedFB) {
+ I830AdjustFrameMerged(scrnIndex, x, y, flags);
+
+ if (pI830->pipe == 0) {
+ OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+ OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp));
+ } else {
+ OUTREG(DSPBBASE, pI830->FrontBuffer.Start + ((pI830->FirstframeY0 * pScrn->displayWidth + pI830->FirstframeX0) * pI830->cpp));
+ OUTREG(DSPABASE, pI830->FrontBuffer.Start + ((pI830->pScrn_2->frameY0 * pScrn->displayWidth + pI830->pScrn_2->frameX0) * pI830->cpp));
+ }
+
+ return;
+ }
+
if (I830IsPrimary(pScrn))
Start = pI830->FrontBuffer.Start;
else {
@@ -5327,16 +7621,36 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
if (pI830->Clone) {
if (!pI830->pipe == 0) {
- OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ if (!IS_I965G(pI830)) {
+ OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ } else {
+ OUTREG(DSPABASE, 0);
+ OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ }
} else {
- OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ if (!IS_I965G(pI830)) {
+ OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ } else {
+ OUTREG(DSPBBASE, 0);
+ OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ }
}
}
if (pI830->pipe == 0) {
- OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ if (!IS_I965G(pI830)) {
+ OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ } else {
+ OUTREG(DSPABASE, 0);
+ OUTREG(DSPASURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ }
} else {
- OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ if (!IS_I965G(pI830)) {
+ OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ } else {
+ OUTREG(DSPBBASE, 0);
+ OUTREG(DSPBSURF, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ }
}
}
@@ -5395,7 +7709,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
I830VideoSwitchModeBefore(pScrn, NULL);
#endif
- if (pI830->Clone) {
+ if (pI830->Clone || pI830->MergedFB) {
/* Ensure we don't try and setup modes on a clone head */
pI830->CloneHDisplay = 0;
pI830->CloneVDisplay = 0;
@@ -5411,6 +7725,8 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
#ifdef XF86DRI
if (pI830->directRenderingOpen) {
DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
+
+ I830DRISetVBlankInterrupt (pScrn, FALSE);
drmCtlUninstHandler(pI830->drmSubFD);
}
@@ -5467,10 +7783,11 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
pointer pDDCModule = NULL;
DisplayModePtr p, pMon;
int memsize;
- int DDCclock = 0;
+ int DDCclock = 0, DDCclock2 = 0;
int displayWidth = pScrn->displayWidth;
int curHDisplay = pScrn->currentMode->HDisplay;
int curVDisplay = pScrn->currentMode->VDisplay;
+ xf86MonPtr monitor = NULL;
DPRINTF(PFX, "Detect Monitor Change\n");
@@ -5478,19 +7795,31 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
/* Re-read EDID */
pDDCModule = xf86LoadSubModule(pScrn, "ddc");
- if (pI830->vesa->monitor)
- xfree(pI830->vesa->monitor);
- pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+
+ if (pI830->MergedFB) {
+ pI830->pVbe->ddc = DDC_UNCHECKED;
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
+ if ((pI830->pScrn_2->monitor->DDC = monitor) != NULL) {
+ xf86PrintEDID(monitor);
+ xf86SetDDCproperties(pScrn, monitor);
+ }
+ SetPipeAccess(pScrn);
+ }
+
+ pI830->pVbe->ddc = DDC_UNCHECKED;
+ monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
xf86UnloadSubModule(pDDCModule);
- if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL) {
- xf86PrintEDID(pI830->vesa->monitor);
- xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
- } else
- /* No DDC, so get out of here, and continue to use the current settings */
- return FALSE;
+ if ((pScrn->monitor->DDC = monitor) != NULL) {
+ xf86PrintEDID(monitor);
+ xf86SetDDCproperties(pScrn, monitor);
+ }
- if (!(DDCclock = I830UseDDC(pScrn)))
- return FALSE;
+ DDCclock = I830UseDDC(pScrn);
+
+ /* Check if DDC exists on the second head, if not don't abort. */
+ if (pI830->MergedFB)
+ DDCclock2 = I830UseDDC(pI830->pScrn_2);
/* Revalidate the modes */
@@ -5498,6 +7827,8 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
* Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
* functions.
*/
+ SetPipeAccess(pScrn);
+
pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo);
if (!pScrn->modePool) {
@@ -5508,8 +7839,24 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
return FALSE;
}
- SetPipeAccess(pScrn);
+ if (pI830->MergedFB) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Retrieving mode pool for second head.\n");
+ pI830->pScrn_2->modePool = I830GetModePool(pI830->pScrn_2, pI830->pVbe, pI830->vbeInfo);
+
+ if (!pI830->pScrn_2->modePool) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No Video BIOS modes for chosen depth.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ SetPipeAccess(pScrn);
+ }
+
VBESetModeNames(pScrn->modePool);
+ if (pI830->MergedFB)
+ VBESetModeNames(pI830->pScrn_2->modePool);
if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
memsize = pI830->vbeInfo->TotalMemory * 64;
@@ -5523,6 +7870,16 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
pScrn->display->virtualY,
memsize, LOOKUP_BEST_REFRESH);
+ if (pI830->MergedFB) {
+ VBEValidateModes(pI830->pScrn_2, pI830->pScrn_2->monitor->Modes,
+ pI830->pScrn_2->display->modes, NULL,
+ NULL, 0, MAX_DISPLAY_PITCH, 1,
+ 0, MAX_DISPLAY_HEIGHT,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ memsize, LOOKUP_BEST_REFRESH);
+ }
+
if (DDCclock > 0) {
p = pScrn->modes;
if (p == NULL)
@@ -5553,10 +7910,61 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
} while (p != NULL && p != pScrn->modes);
}
- pScrn->displayWidth = displayWidth; /* restore old displayWidth */
+ /* Only use this if we've got DDC available */
+ if (pI830->MergedFB && DDCclock2 > 0) {
+ p = pI830->pScrn_2->modes;
+ if (p == NULL)
+ return FALSE;
+ do {
+ int Clock = 100000000; /* incredible value */
+
+ if (p->status == MODE_OK) {
+ for (pMon = pI830->pScrn_2->monitor->Modes; pMon != NULL; pMon = pMon->next) {
+ if ((pMon->HDisplay != p->HDisplay) ||
+ (pMon->VDisplay != p->VDisplay) ||
+ (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+ continue;
+
+ /* Find lowest supported Clock for this resolution */
+ if (Clock > pMon->Clock)
+ Clock = pMon->Clock;
+ }
+
+ if (Clock != 100000000 && DDCclock2 < 2550 && Clock / 1000.0 > DDCclock2) {
+ ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
+ p->name, pI830->pScrn_2->monitor->id,
+ Clock/1000.0, DDCclock2);
+ p->status = MODE_BAD;
+ }
+ }
+ p = p->next;
+ } while (p != NULL && p != pI830->pScrn_2->modes);
+ }
xf86PruneDriverModes(pScrn);
- I830PrintModes(pScrn);
+
+ if (pI830->MergedFB)
+ xf86PruneDriverModes(pI830->pScrn_2);
+
+ if (pI830->MergedFB) {
+ DisplayModePtr old_modes, cur_mode;
+
+ old_modes = pScrn->modes;
+ cur_mode = pScrn->currentMode;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MergedFB: Generating mode list\n");
+
+ pScrn->modes = I830GenerateModeList(pScrn, pI830->MetaModes,
+ old_modes, pI830->pScrn_2->modes,
+ pI830->SecondPosition);
+
+ if(!pScrn->modes) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes. Disabling MergedFB.\n");
+ pScrn->modes = old_modes;
+ pScrn->currentMode = cur_mode;
+ pI830->MergedFB = FALSE;
+ }
+ }
if (!pI830->vesa->useDefaultRefresh)
I830SetModeParameters(pScrn, pI830->pVbe);
@@ -5566,6 +7974,21 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
* and reconnecting monitors */
pScrn->currentMode = pScrn->modes;
+
+ if (pI830->MergedFB) {
+ /* If no virtual dimension was given by the user,
+ * calculate a sane one now. Adapts pScrn->virtualX,
+ * pScrn->virtualY and pScrn->displayWidth.
+ */
+ I830RecalcDefaultVirtualSize(pScrn);
+
+ pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
+ pScrn->currentMode = pScrn->modes;
+ pI830->currentMode = pScrn->currentMode;
+ }
+
+ pScrn->displayWidth = displayWidth; /* restore old displayWidth */
+
p = pScrn->modes;
if (p == NULL)
return FALSE;
@@ -5578,6 +8001,8 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
p = p->next;
} while (p != NULL && p != pScrn->modes);
+ I830PrintModes(pScrn);
+
/* Now readjust for panning if necessary */
{
pScrn->frameX0 = (pScrn->frameX0 + pScrn->frameX1 + 1 - pScrn->currentMode->HDisplay) / 2;
@@ -5603,6 +8028,9 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn)
}
}
+ if (pI830->MergedFB)
+ I830AdjustFrameMerged(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
return TRUE;
}
@@ -5712,7 +8140,6 @@ I830BIOSEnterVT(int scrnIndex, int flags)
ResetState(pScrn, FALSE);
SetHWOperatingState(pScrn);
- /* Detect monitor change and switch to suitable mode */
if (!pI830->starting)
I830DetectMonitorChange(pScrn);
@@ -5735,12 +8162,21 @@ I830BIOSEnterVT(int scrnIndex, int flags)
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
if (!pI830->starting) {
+ ScreenPtr pScreen = pScrn->pScreen;
+ drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+ int i;
+
I830DRIResume(screenInfo.screens[scrnIndex]);
+ I830DRISetVBlankInterrupt (pScrn, TRUE);
I830RefreshRing(pScrn);
I830Sync(pScrn);
DO_RING_IDLE();
+ sarea->texAge++;
+ for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++)
+ sarea->texList[i].age = sarea->texAge;
+
DPRINTF(PFX, "calling dri unlock\n");
DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
}
@@ -5797,7 +8233,8 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
* The extra WindowTable check detects a rotation at startup.
*/
if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) &&
- !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) ) {
+ !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) &&
+ !IS_I965G(pI830)) {
if (!I830Rotate(pScrn, mode))
ret = FALSE;
}
@@ -5824,6 +8261,13 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
#endif
}
+ /* Since RandR (indirectly) uses SwitchMode(), we need to
+ * update our Xinerama info here, too, in case of resizing
+ */
+ if(pI830->MergedFB) {
+ I830UpdateXineramaScreenInfo(pScrn);
+ }
+
return ret;
}
@@ -5833,7 +8277,7 @@ I830BIOSSaveScreen(ScreenPtr pScreen, int mode)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
Bool on = xf86IsUnblank(mode);
- CARD32 temp, ctrl, base;
+ CARD32 temp, ctrl, base, surf;
DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
@@ -5841,9 +8285,11 @@ I830BIOSSaveScreen(ScreenPtr pScreen, int mode)
if (pI830->pipe == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
+ surf = DSPASURF;
} else {
ctrl = DSPBCNTR;
base = DSPBADDR;
+ surf = DSPBSURF;
}
if (pI830->planeEnabled[pI830->pipe]) {
temp = INREG(ctrl);
@@ -5855,6 +8301,10 @@ I830BIOSSaveScreen(ScreenPtr pScreen, int mode)
/* Flush changes */
temp = INREG(base);
OUTREG(base, temp);
+ if (IS_I965G(pI830)) {
+ temp = INREG(surf);
+ OUTREG(surf, temp);
+ }
}
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
@@ -5876,7 +8326,7 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
I830Ptr pI830 = I830PTR(pScrn);
vbeInfoPtr pVbe = pI830->pVbe;
- if (pI830->Clone) {
+ if (pI830->Clone || pI830->MergedFB) {
SetBIOSPipe(pScrn, !pI830->pipe);
if (xf86LoaderCheckSymbol("VBEDPMSSet")) {
VBEDPMSSet(pVbe, PowerManagementMode);
@@ -5998,9 +8448,7 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
pI830->used3D = NULL;
}
- if (pI830->shadowReq.minorversion >= 1)
- pScrn->PointerMoved = pI830->PointerMoved;
-
+ pScrn->PointerMoved = pI830->PointerMoved;
pScrn->vtSema = FALSE;
pI830->closing = FALSE;
pScreen->CloseScreen = pI830->CloseScreen;
@@ -6323,16 +8771,23 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
}
- if (pI830->pipe == 0)
- adjust = INREG(DSPABASE);
- else
- adjust = INREG(DSPBBASE);
+ if (IS_I965G(pI830)) {
+ if (pI830->pipe == 0)
+ adjust = INREG(DSPASURF);
+ else
+ adjust = INREG(DSPBSURF);
+ } else {
+ if (pI830->pipe == 0)
+ adjust = INREG(DSPABASE);
+ else
+ adjust = INREG(DSPBBASE);
+ }
if (adjust != offset) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Fixing display offsets.\n");
- I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+ I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
}
}
@@ -6340,7 +8795,6 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
ScreenPtr pCursorScreen;
int x = 0, y = 0;
-
pCursorScreen = miPointerCurrentScreen();
if (pScrn->pScreen == pCursorScreen)
miPointerPosition(&x, &y);
@@ -6357,7 +8811,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
pI830->currentMode = NULL;
I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
- I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+ I830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
if (xf86IsEntityShared(pScrn->entityList[0])) {
ScrnInfoPtr pScrn2;
@@ -6376,7 +8830,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
pI8302->currentMode = NULL;
I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
- I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
+ I830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
(*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
(*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
@@ -6462,7 +8916,7 @@ I830InitpScrn(ScrnInfoPtr pScrn)
pScrn->PreInit = I830BIOSPreInit;
pScrn->ScreenInit = I830BIOSScreenInit;
pScrn->SwitchMode = I830BIOSSwitchMode;
- pScrn->AdjustFrame = I830BIOSAdjustFrame;
+ pScrn->AdjustFrame = I830AdjustFrame;
pScrn->EnterVT = I830BIOSEnterVT;
pScrn->LeaveVT = I830BIOSLeaveVT;
pScrn->FreeScreen = I830BIOSFreeScreen;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index c1c7cb73..88dc5acb 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -209,12 +209,12 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size,
if (newApStart > newApEnd)
return 0;
- if (flags & NEED_PHYSICAL_ADDR) {
+ if (flags & NEED_PHYSICAL_ADDR)
result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
&(result->Physical));
- } else {
+ else
result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
- }
+
if (result->Key == -1)
return 0;
}
@@ -498,7 +498,7 @@ I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, int flags)
alloced = 0;
if (tileable) {
align = GetBestTileAlignment(size);
- for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+ for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem),
&(pI830->StolenPool), size, align,
flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -563,7 +563,7 @@ I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, int flags)
alloced = 0;
if (tileable) {
align = GetBestTileAlignment(size);
- for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+ for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2),
&(pI830->StolenPool), size, align,
flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -673,6 +673,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
memset(&(pI830->FrontBuffer2), 0, sizeof(pI830->FrontBuffer2));
pI830->FrontBuffer2.Key = -1;
+#if 1 /* ROTATION */
pI830->FbMemBox2.x1 = 0;
pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
pI830->FbMemBox2.y1 = 0;
@@ -680,6 +681,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX;
else
pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
+#else
+ pI830->FbMemBox2.x1 = 0;
+ pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
+ pI830->FbMemBox2.y1 = 0;
+ pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
+#endif
/*
* Calculate how much framebuffer memory to allocate. For the
@@ -731,19 +738,26 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip &&
IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
if (tileable) {
- align = KB(512);
+ if (IS_I9XX(pI830))
+ align = MB(1);
+ else
+ align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
+#if 1 /* ROTATION */
if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines);
else
size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
-
+#else
+ size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
+ size = ROUND_TO_PAGE(size);
+#endif
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sSecondary framebuffer allocation size: %ld kByte\n", s,
size / 1024);
@@ -765,6 +779,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
pI830->FrontBuffer.Key = -1;
+#if 1 /* ROTATION */
pI830->FbMemBox.x1 = 0;
pI830->FbMemBox.x2 = pScrn->displayWidth;
pI830->FbMemBox.y1 = 0;
@@ -772,6 +787,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->FbMemBox.y2 = pScrn->virtualX;
else
pI830->FbMemBox.y2 = pScrn->virtualY;
+#else
+ pI830->FbMemBox.x1 = 0;
+ pI830->FbMemBox.x2 = pScrn->displayWidth;
+ pI830->FbMemBox.y1 = 0;
+ pI830->FbMemBox.y2 = pScrn->virtualY;
+#endif
/*
* Calculate how much framebuffer memory to allocate. For the
@@ -823,19 +844,26 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn->displayWidth * pI830->cpp);
if (tileable) {
- align = KB(512);
+ if (IS_I9XX(pI830))
+ align = MB(1);
+ else
+ align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
+#if 1 /* ROTATION */
if (pScrn->virtualX > pScrn->virtualY)
size = lineSize * (pScrn->virtualX + cacheLines);
else
size = lineSize * (pScrn->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
-
+#else
+ size = lineSize * (pScrn->virtualY + cacheLines);
+ size = ROUND_TO_PAGE(size);
+#endif
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sInitial framebuffer allocation size: %ld kByte\n", s,
size / 1024);
@@ -937,7 +965,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn->displayWidth * pI830->cpp);
if (tileable) {
- align = KB(512);
+ if (IS_I9XX(pI830))
+ align = MB(1);
+ else
+ align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
@@ -1175,7 +1206,7 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags)
alloced = 0;
if (tileable) {
align = GetBestTileAlignment(size);
- for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+ for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
&(pI830->StolenPool), size, align,
flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -1238,7 +1269,7 @@ I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags)
alloced = 0;
if (tileable) {
align = GetBestTileAlignment(size);
- for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
+ for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
&(pI830->StolenPool), size, align,
flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
@@ -1672,7 +1703,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
}
static Bool
-MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem)
+MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence)
{
I830Ptr pI830 = I830PTR(pScrn);
int pitch, ntiles, i;
@@ -1690,6 +1721,31 @@ MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem)
}
pitch = pScrn->displayWidth * pI830->cpp;
+
+ if (IS_I965G(pI830)) {
+ I830RegPtr i830Reg = &pI830->ModeReg;
+
+ switch (fence) {
+ case FENCE_XMAJOR:
+ i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
+ break;
+ case FENCE_YMAJOR:
+ /* YMajor can be 128B aligned but the current code dictates
+ * otherwise. This isn't a problem apart from memory waste.
+ * FIXME */
+ i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
+ i830Reg->Fence[nextTile] |= (1<<1);
+ break;
+ default:
+ case FENCE_LINEAR:
+ break;
+ }
+
+ i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End;
+ nextTile++;
+ return TRUE;
+ }
+
/*
* Simply try to break the region up into at most four pieces of size
* equal to the alignment.
@@ -1731,20 +1787,27 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
return;
}
+ pI830->front_tiled = FENCE_LINEAR;
+ pI830->back_tiled = FENCE_LINEAR;
+ pI830->depth_tiled = FENCE_LINEAR;
+ pI830->rotated_tiled = FENCE_LINEAR;
+ pI830->rotated2_tiled = FENCE_LINEAR;
+
if (pI830->allowPageFlip) {
if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->FrontBuffer))) {
+ if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Activating tiled memory for the FRONT buffer\n");
+ "Activating tiled memory for the front buffer\n");
+ pI830->front_tiled = FENCE_XMAJOR;
} else {
pI830->allowPageFlip = FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MakeTiles failed for the FRONT buffer\n");
+ "MakeTiles failed for the front buffer\n");
}
} else {
pI830->allowPageFlip = FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Alignment bad for the FRONT buffer\n");
+ "Alignment bad for the front buffer\n");
}
}
@@ -1755,9 +1818,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
* value.
*/
if (pI830->BackBuffer.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->BackBuffer))) {
+ if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Activating tiled memory for the back buffer.\n");
+ pI830->back_tiled = FENCE_XMAJOR;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the back buffer.\n");
@@ -1766,9 +1830,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
}
if (pI830->DepthBuffer.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->DepthBuffer))) {
+ if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Activating tiled memory for the depth buffer.\n");
+ "Activating tiled memory for the depth buffer.\n");
+ pI830->depth_tiled = FENCE_YMAJOR;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the depth buffer.\n");
@@ -1776,9 +1841,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
}
if (pI830->RotatedMem.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->RotatedMem))) {
+ if (MakeTiles(pScrn, &(pI830->RotatedMem), FENCE_XMAJOR)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Activating tiled memory for the rotated buffer.\n");
+ pI830->rotated_tiled = FENCE_XMAJOR;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the rotated buffer.\n");
@@ -1787,9 +1853,10 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
#if 0
if (pI830->RotatedMem2.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->RotatedMem2))) {
+ if (MakeTiles(pScrn, &(pI830->RotatedMem2), FENCE_XMAJOR)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Activating tiled memory for the rotated2 buffer.\n");
+ pI830->rotated2_tiled = FENCE_XMAJOR;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MakeTiles failed for the rotated buffer.\n");
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 97e40e0a..7d145198 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -42,8 +42,6 @@
#include <string.h>
#include "xf86.h"
-#include "vbe.h"
-#include "vbeModes.h"
#include "i830.h"
#include <math.h>
@@ -363,7 +361,11 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
CARD16 major, minor;
VbeModeInfoBlock *mode;
DisplayModePtr p = NULL, pMode = NULL;
+#if 0
VbeModeInfoData *data;
+#else
+ I830ModePrivatePtr data;
+#endif
Bool modeOK = FALSE;
ModeStatus status = MODE_OK;
@@ -602,12 +604,21 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
pMode->HDisplay = mode->XResolution;
pMode->VDisplay = mode->YResolution;
+#if 0
data = xnfcalloc(sizeof(VbeModeInfoData), 1);
data->mode = id;
data->data = mode;
pMode->PrivSize = sizeof(VbeModeInfoData);
pMode->Private = (INT32*)data;
+#else
+ data = xnfcalloc(sizeof(I830ModePrivateRec), 1);
+ data->vbeData.mode = id;
+ data->vbeData.data = mode;
+ pMode->PrivSize = sizeof(I830ModePrivateRec);
+ pMode->Private = (INT32*)data;
+#endif
pMode->next = NULL;
+
return pMode;
}
@@ -663,54 +674,113 @@ I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
void
I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
{
- DisplayModePtr pMode;
- VbeModeInfoData *data;
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr pMode = pScrn->modes;
+ DisplayModePtr ppMode = pScrn->modes;
+ I830ModePrivatePtr mp = NULL;
- pMode = pScrn->modes;
do {
int clock;
+
+ mp = (I830ModePrivatePtr) pMode->Private;
- data = (VbeModeInfoData*)pMode->Private;
- data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
- data->block->HorizontalTotal = pMode->HTotal;
- data->block->HorizontalSyncStart = pMode->HSyncStart;
- data->block->HorizontalSyncEnd = pMode->HSyncEnd;
- data->block->VerticalTotal = pMode->VTotal;
- data->block->VerticalSyncStart = pMode->VSyncStart;
- data->block->VerticalSyncEnd = pMode->VSyncEnd;
- data->block->Flags = ((pMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
- ((pMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
- data->block->PixelClock = pMode->Clock * 1000;
+ if (pI830->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s\n", pScrn->monitor->id);
+ ppMode = (DisplayModePtr) mp->merged.First;
+ mp = (I830ModePrivatePtr) mp->merged.First->Private;
+ }
+ mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
+ mp->vbeData.block->HorizontalTotal = ppMode->HTotal;
+ mp->vbeData.block->HorizontalSyncStart = ppMode->HSyncStart;
+ mp->vbeData.block->HorizontalSyncEnd = ppMode->HSyncEnd;
+ mp->vbeData.block->VerticalTotal = ppMode->VTotal;
+ mp->vbeData.block->VerticalSyncStart = ppMode->VSyncStart;
+ mp->vbeData.block->VerticalSyncEnd = ppMode->VSyncEnd;
+ mp->vbeData.block->Flags = ((ppMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+ ((ppMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+ mp->vbeData.block->PixelClock = ppMode->Clock * 1000;
/* XXX May not have this. */
- clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
+ clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
if (clock)
- data->block->PixelClock = clock;
+ mp->vbeData.block->PixelClock = clock;
#ifdef DEBUG
ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
- (double)data->block->PixelClock / 1000000.0,
+ (double)mp->vbeData.block->PixelClock / 1000000.0,
(double)clock / 1000000.0);
#endif
- data->mode |= (1 << 11);
- if (pMode->VRefresh != 0) {
- data->block->RefreshRate = pMode->VRefresh * 100;
+ mp->vbeData.mode |= (1 << 11);
+ if (ppMode->VRefresh != 0) {
+ mp->vbeData.block->RefreshRate = ppMode->VRefresh * 100;
} else {
- data->block->RefreshRate = (int)(((double)(data->block->PixelClock)/
- (double)(pMode->HTotal * pMode->VTotal)) * 100);
+ mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
+ (double)(ppMode->HTotal * ppMode->VTotal)) * 100);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
- (float)(((double)(data->block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, data->mode);
+ (float)(((double)(mp->vbeData.block->PixelClock) / (double)(ppMode->HTotal * ppMode->VTotal))), ppMode->name, mp->vbeData.mode);
#ifdef DEBUG
ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
" %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
- data->mode, pMode->name, pMode->HDisplay, pMode->HSyncStart,
- pMode->HSyncEnd, pMode->HTotal, pMode->VDisplay,
- pMode->VSyncStart,pMode->VSyncEnd,pMode->VTotal,
- (double)data->block->PixelClock/1000000.0,
- (double)data->block->RefreshRate/100);
+ mp->vbeData.mode, ppMode->name, ppMode->HDisplay, ppMode->HSyncStart,
+ ppMode->HSyncEnd, ppMode->HTotal, ppMode->VDisplay,
+ ppMode->VSyncStart,ppMode->VSyncEnd,ppMode->VTotal,
+ (double)mp->vbeData.block->PixelClock/1000000.0,
+ (double)mp->vbeData.block->RefreshRate/100);
#endif
- pMode = pMode->next;
+ pMode = ppMode = pMode->next;
} while (pMode != pScrn->modes);
+
+ if (pI830->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s\n", pI830->pScrn_2->monitor->id);
+ pMode = pScrn->modes;
+ do {
+ int clock;
+
+ mp = (I830ModePrivatePtr) pMode->Private;
+ ppMode = (DisplayModePtr) mp->merged.Second;
+ mp = (I830ModePrivatePtr) mp->merged.Second->Private;
+
+ mp->vbeData.block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
+ mp->vbeData.block->HorizontalTotal = ppMode->HTotal;
+ mp->vbeData.block->HorizontalSyncStart = ppMode->HSyncStart;
+ mp->vbeData.block->HorizontalSyncEnd = ppMode->HSyncEnd;
+ mp->vbeData.block->VerticalTotal = ppMode->VTotal;
+ mp->vbeData.block->VerticalSyncStart = ppMode->VSyncStart;
+ mp->vbeData.block->VerticalSyncEnd = ppMode->VSyncEnd;
+ mp->vbeData.block->Flags = ((ppMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+ ((ppMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+ mp->vbeData.block->PixelClock = ppMode->Clock * 1000;
+ /* XXX May not have this. */
+ clock = VBEGetPixelClock(pVbe, mp->vbeData.mode, mp->vbeData.block->PixelClock);
+ if (clock)
+ mp->vbeData.block->PixelClock = clock;
+#ifdef DEBUG
+ ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
+ (double)mp->vbeData.block->PixelClock / 1000000.0,
+ (double)clock / 1000000.0);
+#endif
+ mp->vbeData.mode |= (1 << 11);
+ if (ppMode->VRefresh != 0) {
+ mp->vbeData.block->RefreshRate = ppMode->VRefresh * 100;
+ } else {
+ mp->vbeData.block->RefreshRate = (int)(((double)(mp->vbeData.block->PixelClock)/
+ (double)(ppMode->HTotal * ppMode->VTotal)) * 100);
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
+ (float)(((double)(mp->vbeData.block->PixelClock) / (double)(ppMode->HTotal * ppMode->VTotal))), ppMode->name, mp->vbeData.mode);
+#ifdef DEBUG
+ ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
+ " %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
+ mp->vbeData.mode, ppMode->name, ppMode->HDisplay, ppMode->HSyncStart,
+ ppMode->HSyncEnd, ppMode->HTotal, ppMode->VDisplay,
+ ppMode->VSyncStart,ppMode->VSyncEnd,ppMode->VTotal,
+ (double)mp->vbeData.block->PixelClock/1000000.0,
+ (double)mp->vbeData.block->RefreshRate/100);
+#endif
+ pMode = ppMode = pMode->next;
+ } while (pMode != pScrn->modes);
+ }
}
void
diff --git a/src/i830_rotate.c b/src/i830_rotate.c
index e57a0878..76effa29 100644
--- a/src/i830_rotate.c
+++ b/src/i830_rotate.c
@@ -404,7 +404,7 @@ 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 |= MAPSURF_8BIT;
@@ -575,15 +575,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(_3DSTATE_DRAW_RECT_CMD);
+ 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(_3DSTATE_BUF_INFO_CMD);
OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2));
if (I830IsPrimary(pScrn))
OUT_RING(pI830->FrontBuffer.Start);
@@ -736,12 +736,12 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
};
if (pI830->noAccel)
- func = LoaderSymbol("shadowUpdateRotatePacked");
+ func = LoaderSymbol("shadowUpdateRotatePacked");
else
- if (IS_I9XX(pI830))
- func = I915UpdateRotate;
- else
- func = I830UpdateRotate;
+ if (IS_I9XX(pI830))
+ func = I915UpdateRotate;
+ else
+ func = I830UpdateRotate;
if (I830IsPrimary(pScrn)) {
pI8301 = pI830;
@@ -771,6 +771,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
* We grab the DRI lock when reallocating buffers to avoid DRI clients
* getting bogus information.
*/
+
#ifdef XF86DRI
if (pI8301->directRenderingEnabled && reAllocate) {
didLock = I830DRILock(pScrn1);
@@ -789,6 +790,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
}
+
if (pI8301->TexMem.Key != -1)
xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key);
I830FreeVidMem(pScrn1, &(pI8301->TexMem));
@@ -891,7 +893,7 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
if (pI8301->rotation != RR_Rotate_0) {
if (!I830AllocateRotatedBuffer(pScrn1,
- (pI8301->disableTiling ? ALLOC_NO_TILING : 0)))
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
goto BAIL1;
I830FixOffset(pScrn1, &(pI8301->RotatedMem));
@@ -903,8 +905,8 @@ I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
shadowRemove (pScrn->pScreen, NULL);
if (pI830->rotation != RR_Rotate_0)
shadowAdd (pScrn->pScreen,
- (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
- func, I830WindowLinear, pI830->rotation, 0);
+ (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+ func, I830WindowLinear, pI830->rotation, 0);
if (I830IsPrimary(pScrn)) {
if (pI830->rotation != RR_Rotate_0)
@@ -1105,7 +1107,7 @@ BAIL0:
if (pI8301->rotation != RR_Rotate_0) {
if (!I830AllocateRotatedBuffer(pScrn1,
- (pI8301->disableTiling ? ALLOC_NO_TILING : 0)))
+ pI8301->disableTiling ? ALLOC_NO_TILING : 0))
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Oh dear, the rotated buffer failed - badness\n");
@@ -1117,8 +1119,8 @@ BAIL0:
shadowRemove (pScrn->pScreen, NULL);
if (pI830->rotation != RR_Rotate_0)
shadowAdd (pScrn->pScreen,
- (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
- func, I830WindowLinear, pI830->rotation, 0);
+ (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
+ func, I830WindowLinear, pI830->rotation, 0);
if (I830IsPrimary(pScrn)) {
if (pI830->rotation != RR_Rotate_0)
diff --git a/src/i830_video.c b/src/i830_video.c
index 41ab055f..1c5bf4eb 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -66,6 +66,7 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <math.h>
#include <string.h>
+#include <assert.h>
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -77,12 +78,15 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "regionstr.h"
#include "randrstr.h"
#include "i830.h"
+#include "i830_video.h"
#include "xf86xv.h"
#include <X11/extensions/Xv.h>
#include "xaa.h"
#include "xaalocal.h"
#include "dixstruct.h"
#include "fourcc.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
#ifndef USE_USLEEP_FOR_VIDEO
#define USE_USLEEP_FOR_VIDEO 0
@@ -99,7 +103,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,20 +114,30 @@ 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);
+static FBLinearPtr
+I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size);
+
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
static Atom xvBrightness, xvContrast, xvColorKey, xvPipe, xvDoubleBuffer;
static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
#define IMAGE_MAX_WIDTH 1920
-#define IMAGE_MAX_HEIGHT 1088
+#define IMAGE_MAX_HEIGHT 1080
#define IMAGE_MAX_WIDTH_LEGACY 1024
-#define IMAGE_MAX_HEIGHT_LEGACY 1088
+#define IMAGE_MAX_HEIGHT_LEGACY 1080
+
+/*
+ * Broadwater requires a bit of extra video memory for state information
+ */
+#define BRW_LINEAR_EXTRA (32*1024)
#if !VIDEO_DEBUG
#define ErrorF Edummy
@@ -157,7 +172,10 @@ Edummy(const char *dummy, ...)
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \
} \
- OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
+ if (IS_I965G(pI830)) \
+ OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \
+ else \
+ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
ADVANCE_LP_RING(); \
ErrorF("OVERLAY_UPDATE\n"); \
} while(0)
@@ -172,11 +190,17 @@ Edummy(const char *dummy, ...)
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \
- OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
+ if (IS_I965G(pI830)) \
+ OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \
+ else \
+ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \
- OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
+ if (IS_I965G(pI830)) \
+ OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \
+ else \
+ OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
@@ -286,6 +310,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"},
@@ -334,18 +364,18 @@ typedef struct {
CARD32 OCONFIG;
CARD32 OCMD;
CARD32 RESERVED1; /* 0x6C */
- CARD32 AWINPOS;
- CARD32 AWINSZ;
- CARD32 RESERVED2; /* 0x78 */
- CARD32 RESERVED3; /* 0x7C */
- CARD32 RESERVED4; /* 0x80 */
- CARD32 RESERVED5; /* 0x84 */
- CARD32 RESERVED6; /* 0x88 */
- CARD32 RESERVED7; /* 0x8C */
- CARD32 RESERVED8; /* 0x90 */
- CARD32 RESERVED9; /* 0x94 */
- CARD32 RESERVEDA; /* 0x98 */
- CARD32 RESERVEDB; /* 0x9C */
+ CARD32 OSTART_0Y; /* for i965 */
+ CARD32 OSTART_1Y; /* for i965 */
+ CARD32 OSTART_0U;
+ CARD32 OSTART_0V;
+ CARD32 OSTART_1U;
+ CARD32 OSTART_1V;
+ CARD32 OTILEOFF_0Y;
+ CARD32 OTILEOFF_1Y;
+ CARD32 OTILEOFF_0U;
+ CARD32 OTILEOFF_0V;
+ CARD32 OTILEOFF_1U;
+ CARD32 OTILEOFF_1V;
CARD32 FASTHSCALE; /* 0xA0 */
CARD32 UVSCALEV; /* 0xA4 */
@@ -360,45 +390,6 @@ typedef struct {
CARD16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
} I830OverlayRegRec, *I830OverlayRegPtr;
-typedef struct {
- CARD32 YBuf0offset;
- CARD32 UBuf0offset;
- CARD32 VBuf0offset;
-
- CARD32 YBuf1offset;
- CARD32 UBuf1offset;
- CARD32 VBuf1offset;
-
- unsigned char currentBuf;
-
- int brightness;
- int contrast;
- int pipe;
- int doubleBuffer;
-
- RegionRec clip;
- CARD32 colorKey;
-
- CARD32 gamma0;
- CARD32 gamma1;
- CARD32 gamma2;
- CARD32 gamma3;
- CARD32 gamma4;
- CARD32 gamma5;
-
- CARD32 videoStatus;
- Time offTime;
- Time freeTime;
- FBLinearPtr linear;
-
- Bool overlayOK;
- int oneLineMode;
- int scaleRatio;
-} I830PortPrivRec, *I830PortPrivPtr;
-
-#define GET_PORT_PRIVATE(pScrn) \
- (I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
-
#if VIDEO_DEBUG
static void
CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
@@ -424,8 +415,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 +436,54 @@ I830InitVideo(ScreenPtr pScreen)
}
#endif
- if (pScrn->bitsPerPixel != 8) {
- newAdaptor = I830SetupImageVideo(pScreen);
+ 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 (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8) {
+ 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) || IS_I965G(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
@@ -501,8 +512,10 @@ I830ResetVideo(ScrnInfoPtr pScrn)
overlay->SHEIGHT = 0;
overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
overlay->OCLRC1 = 0x00000080; /* saturation: bypass */
+#if 0
overlay->AWINPOS = 0;
overlay->AWINSZ = 0;
+#endif
overlay->FASTHSCALE = 0;
/*
@@ -642,7 +655,7 @@ I830UpdateGamma(ScrnInfoPtr pScrn)
}
static XF86VideoAdaptorPtr
-I830SetupImageVideo(ScreenPtr pScreen)
+I830SetupImageVideoOverlay(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
@@ -650,7 +663,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))))
@@ -703,8 +716,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;
@@ -742,8 +756,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 */
@@ -766,6 +778,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)
{
@@ -803,6 +895,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);
@@ -842,6 +937,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;
@@ -994,13 +1097,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;
@@ -1088,13 +1190,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;
@@ -1400,6 +1561,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
unsigned int swidth;
unsigned int mask, shift, offsety, offsetu;
int tmp;
+ BoxRec dstBox2;
ErrorF("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
dstPitch);
@@ -1411,21 +1573,24 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
#endif
- /* When in dual head with different bpp setups we need to refresh the
- * color key, so let's reset the video parameters and refresh here */
- if (pI830->entityPrivate)
- I830ResetVideo(pScrn);
-
- /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
- if (!*pI830->overlayOn)
- OVERLAY_UPDATE;
-
switch (pI830->rotation) {
case RR_Rotate_0:
- dstBox->x1 -= pScrn->frameX0;
- dstBox->x2 -= pScrn->frameX0;
- dstBox->y1 -= pScrn->frameY0;
- dstBox->y2 -= pScrn->frameY0;
+ if (pI830->MergedFB) {
+ memcpy(&dstBox2, dstBox, sizeof(BoxRec));
+ dstBox->x1 -= pI830->FirstframeX0;
+ dstBox->x2 -= pI830->FirstframeX0;
+ dstBox->y1 -= pI830->FirstframeY0;
+ dstBox->y2 -= pI830->FirstframeY0;
+ dstBox2.x1 -= pI830->pScrn_2->frameX0;
+ dstBox2.x2 -= pI830->pScrn_2->frameX0;
+ dstBox2.y1 -= pI830->pScrn_2->frameY0;
+ dstBox2.y2 -= pI830->pScrn_2->frameY0;
+ } else {
+ dstBox->x1 -= pScrn->frameX0;
+ dstBox->x2 -= pScrn->frameX0;
+ dstBox->y1 -= pScrn->frameY0;
+ dstBox->y2 -= pScrn->frameY0;
+ }
break;
case RR_Rotate_90:
tmp = dstBox->x1;
@@ -1459,6 +1624,72 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
break;
}
+ if (pI830->MergedFB) {
+ I830ModePrivatePtr mp = (I830ModePrivatePtr)pScrn->currentMode->Private;
+ int w1, h1, w2, h2;
+
+ /* Clip the video to the independent modes of the merged screens */
+ if (dstBox->x1 > mp->merged.First->HDisplay) dstBox->x1 = mp->merged.First->HDisplay - 1;
+ if (dstBox->x2 > mp->merged.First->HDisplay) dstBox->x2 = mp->merged.First->HDisplay - 1;
+ if (dstBox2.x1 > mp->merged.Second->HDisplay) dstBox2.x1 = mp->merged.Second->HDisplay - 1;
+ if (dstBox2.x2 > mp->merged.Second->HDisplay) dstBox2.x2 = mp->merged.Second->HDisplay - 1;
+ if (dstBox->y1 > mp->merged.First->VDisplay) dstBox->y1 = mp->merged.First->VDisplay - 1;
+ if (dstBox->y2 > mp->merged.First->VDisplay) dstBox->y2 = mp->merged.First->VDisplay - 1;
+ if (dstBox2.y1 > mp->merged.Second->VDisplay) dstBox2.y1 = mp->merged.Second->VDisplay - 1;
+ if (dstBox2.y2 > mp->merged.Second->VDisplay) dstBox2.y2 = mp->merged.Second->VDisplay - 1;
+ if (dstBox->y1 < 0) dstBox->y1 = 0;
+ if (dstBox->y2 < 0) dstBox->y2 = 0;
+ if (dstBox->x1 < 0) dstBox->x1 = 0;
+ if (dstBox->x2 < 0) dstBox->x2 = 0;
+ if (dstBox2.y1 < 0) dstBox2.y1 = 0;
+ if (dstBox2.y2 < 0) dstBox2.y2 = 0;
+ if (dstBox2.x1 < 0) dstBox2.x1 = 0;
+ if (dstBox2.x2 < 0) dstBox2.x2 = 0;
+
+ w1 = dstBox->x2 - dstBox->x1;
+ w2 = dstBox2.x2 - dstBox2.x1;
+ h1 = dstBox->y2 - dstBox->y1;
+ h2 = dstBox2.y2 - dstBox2.y1;
+
+ switch (pI830->SecondPosition) {
+ case PosRightOf:
+ case PosBelow:
+ if ((w2 > 0 && w1 == 0) ||
+ (h2 > 0 && h1 == 0)) {
+ pPriv->pipe = !pI830->pipe;
+ dstBox->x1 = dstBox2.x1;
+ dstBox->y1 = dstBox2.y1;
+ dstBox->x2 = dstBox2.x2;
+ dstBox->y2 = dstBox2.y2;
+ } else
+ pPriv->pipe = pI830->pipe;
+ break;
+ case PosLeftOf:
+ case PosAbove:
+ if ((w1 > 0 && w2 == 0) ||
+ (h1 > 0 && h2 == 0)) {
+ pPriv->pipe = pI830->pipe;
+ } else {
+ pPriv->pipe = !pI830->pipe;
+ dstBox->x1 = dstBox2.x1;
+ dstBox->y1 = dstBox2.y1;
+ dstBox->x2 = dstBox2.x2;
+ dstBox->y2 = dstBox2.y2;
+ }
+ break;
+ }
+ }
+
+ /* When in dual head with different bpp setups we need to refresh the
+ * color key, so let's reset the video parameters and refresh here.
+ * In MergedFB mode, we may need to flip pipes too. */
+ if (pI830->entityPrivate || pI830->MergedFB)
+ I830ResetVideo(pScrn);
+
+ /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */
+ if (!*pI830->overlayOn)
+ OVERLAY_UPDATE;
+
/* Fix up the dstBox if outside the visible screen */
{
int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0;
@@ -1522,7 +1753,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
/* Keep the engine happy and clip to the real vertical size just
* in case an LFP is in use and it's not at it's native resolution.
*/
- int vactive = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+ int vactive = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
vactive += 1;
@@ -1647,14 +1878,31 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
dstBox->x2, dstBox->y2);
/* buffer locations */
- overlay->OBUF_0Y = pPriv->YBuf0offset;
- overlay->OBUF_0U = pPriv->UBuf0offset;
- overlay->OBUF_0V = pPriv->VBuf0offset;
-
- if(pPriv->doubleBuffer) {
- overlay->OBUF_1Y = pPriv->YBuf1offset;
- overlay->OBUF_1U = pPriv->UBuf1offset;
- overlay->OBUF_1V = pPriv->VBuf1offset;
+ if (IS_I965G(pI830))
+ {
+ overlay->OBUF_0Y = 0;
+ overlay->OBUF_0U = 0;
+ overlay->OBUF_0V = 0;
+ overlay->OSTART_0Y = pPriv->YBuf0offset;
+ overlay->OSTART_0U = pPriv->UBuf0offset;
+ overlay->OSTART_0V = pPriv->VBuf0offset;
+ if(pPriv->doubleBuffer) {
+ overlay->OBUF_1Y = 0;
+ overlay->OBUF_1U = 0;
+ overlay->OBUF_1V = 0;
+ overlay->OSTART_1Y = pPriv->YBuf1offset;
+ overlay->OSTART_1U = pPriv->UBuf1offset;
+ overlay->OSTART_1V = pPriv->VBuf1offset;
+ }
+ } else {
+ overlay->OBUF_0Y = pPriv->YBuf0offset;
+ overlay->OBUF_0U = pPriv->UBuf0offset;
+ overlay->OBUF_0V = pPriv->VBuf0offset;
+ if(pPriv->doubleBuffer) {
+ overlay->OBUF_1Y = pPriv->YBuf1offset;
+ overlay->OBUF_1U = pPriv->UBuf1offset;
+ overlay->OBUF_1V = pPriv->VBuf1offset;
+ }
}
ErrorF("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n", overlay->OBUF_0Y,
@@ -1847,6 +2095,827 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
OVERLAY_UPDATE;
}
+static const CARD32 sip_kernel_static[][4] = {
+/* wait (1) a0<1>UW a145<0,1,0>UW { align1 + } */
+ { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+
+/*
+ * this program computes dA/dx and dA/dy for the texture coordinates along
+ * with the base texture coordinate. It was extracted from the Mesa driver.
+ * It uses about 10 GRF registers.
+ */
+
+#define SF_KERNEL_NUM_GRF 16
+#define SF_MAX_THREADS 1
+
+static const CARD32 sf_kernel_static[][4] = {
+/* send 0 (1) g6<1>F g1.12<0,1,0>F math mlen 1 rlen 1 { align1 + } */
+ { 0x00000031, 0x20c01fbd, 0x0000002c, 0x01110081 },
+/* send 0 (1) g6.4<1>F g1.20<0,1,0>F math mlen 1 rlen 1 { align1 + } */
+ { 0x00000031, 0x20c41fbd, 0x00000034, 0x01110081 },
+/* add (8) g7<1>F g4<8,8,1>F g3<8,8,1>F { align1 + } */
+ { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
+/* mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 + } */
+ { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
+/* mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 + } */
+ { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
+/* mov (8) m1<1>F g7<0,1,0>F { align1 + } */
+ { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
+/* mov (8) m2<1>F g7.4<0,1,0>F { align1 + } */
+ { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
+/* mov (8) m3<1>F g3<8,8,1>F { align1 + } */
+ { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
+/* send 0 (8) a0<1>F g0<8,8,1>F urb mlen 4 rlen 0 write +0 transpose used complete EOT{ align1 + } */
+ { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+};
+
+/*
+ * Ok, this kernel picks up the required data flow values in g0 and g1
+ * and passes those along in m0 and m1. In m2-m9, it sticks constant
+ * values (bright pink).
+ */
+
+/* Our PS kernel uses less than 32 GRF registers (about 20) */
+#define PS_KERNEL_NUM_GRF 32
+#define PS_MAX_THREADS 32
+
+#define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1)
+
+static const CARD32 ps_kernel_static[][4] = {
+#include "wm_prog.h"
+};
+
+#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+#define WM_BINDING_TABLE_ENTRIES 2
+
+static CARD32 float_to_uint (float f) {
+ union {CARD32 i; float f;} x;
+ x.f = f;
+ return x.i;
+}
+
+#if 0
+static struct {
+ CARD32 svg_ctl;
+ char *name;
+} svg_ctl_bits[] = {
+ { BRW_SVG_CTL_GS_BA, "General State Base Address" },
+ { BRW_SVG_CTL_SS_BA, "Surface State Base Address" },
+ { BRW_SVG_CTL_IO_BA, "Indirect Object Base Address" },
+ { BRW_SVG_CTL_GS_AUB, "Generate State Access Upper Bound" },
+ { BRW_SVG_CTL_IO_AUB, "Indirect Object Access Upper Bound" },
+ { BRW_SVG_CTL_SIP, "System Instruction Pointer" },
+ { 0, 0 },
+};
+
+static void
+brw_debug (ScrnInfoPtr pScrn, char *when)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i;
+ CARD32 v;
+
+ I830Sync (pScrn);
+ ErrorF("brw_debug: %s\n", when);
+ for (i = 0; svg_ctl_bits[i].name; i++) {
+ OUTREG(BRW_SVG_CTL, svg_ctl_bits[i].svg_ctl);
+ v = INREG(BRW_SVG_RDATA);
+ ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v);
+ }
+}
+#endif
+
+#define WATCH_SF 0
+#define WATCH_WIZ 0
+#define WATCH_STATS 0
+
+static void
+BroadwaterDisplayVideoTextured(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);
+ BoxPtr pbox;
+ int nbox, dxo, dyo;
+ int urb_vs_start, urb_vs_size;
+ int urb_gs_start, urb_gs_size;
+ int urb_clip_start, urb_clip_size;
+ int urb_sf_start, urb_sf_size;
+ int urb_cs_start, urb_cs_size;
+ struct brw_surface_state *dest_surf_state;
+ struct brw_surface_state *src_surf_state;
+ struct brw_sampler_state *src_sampler_state;
+ struct brw_vs_unit_state *vs_state;
+ struct brw_sf_unit_state *sf_state;
+ struct brw_wm_unit_state *wm_state;
+ struct brw_cc_unit_state *cc_state;
+ struct brw_cc_viewport *cc_viewport;
+ struct brw_instruction *sf_kernel;
+ struct brw_instruction *ps_kernel;
+ struct brw_instruction *sip_kernel;
+ float *vb;
+ CARD32 *binding_table;
+ Bool first_output = TRUE;
+ int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
+ int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
+ int wm_scratch_offset;
+ int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
+ int binding_table_offset;
+ int next_offset, total_state_size;
+ int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
+ char *state_base;
+ int state_base_offset;
+
+#if 0
+ ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
+ video_pitch);
+#endif
+
+ /* enable debug */
+ OUTREG (INST_PM,
+ (1 << (16 + 4)) |
+ (1 << 4));
+#if 0
+ ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM));
+#endif
+
+ assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
+
+ /* 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;
+
+#ifdef XF86DRI
+ /* Tell the DRI that we're smashing its state. */
+ if (pI830->directRenderingEnabled) {
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+
+ pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
+ }
+#endif /* XF86DRI */
+
+ next_offset = 0;
+
+ /* Set up our layout of state in framebuffer. First the general state: */
+ vs_offset = ALIGN(next_offset, 64);
+ next_offset = vs_offset + sizeof(*vs_state);
+ sf_offset = ALIGN(next_offset, 32);
+ next_offset = sf_offset + sizeof(*sf_state);
+ wm_offset = ALIGN(next_offset, 32);
+ next_offset = wm_offset + sizeof(*wm_state);
+ wm_scratch_offset = ALIGN(next_offset, 1024);
+ next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
+ cc_offset = ALIGN(next_offset, 32);
+ next_offset = cc_offset + sizeof(*cc_state);
+
+ sf_kernel_offset = ALIGN(next_offset, 64);
+ next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
+ ps_kernel_offset = ALIGN(next_offset, 64);
+ next_offset = ps_kernel_offset + sizeof (ps_kernel_static);
+ sip_kernel_offset = ALIGN(next_offset, 64);
+ next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
+ cc_viewport_offset = ALIGN(next_offset, 32);
+ next_offset = cc_viewport_offset + sizeof(*cc_viewport);
+
+ src_sampler_offset = ALIGN(next_offset, 32);
+ next_offset = src_sampler_offset + sizeof(*src_sampler_state);
+
+ /* Align VB to native size of elements, for safety */
+ vb_offset = ALIGN(next_offset, 8);
+ next_offset = vb_offset + vb_size;
+
+ /* And then the general state: */
+ dest_surf_offset = ALIGN(next_offset, 32);
+ next_offset = dest_surf_offset + sizeof(*dest_surf_state);
+ src_surf_offset = ALIGN(next_offset, 32);
+ next_offset = src_surf_offset + sizeof(*src_surf_state);
+ binding_table_offset = ALIGN(next_offset, 32);
+ next_offset = binding_table_offset + (WM_BINDING_TABLE_ENTRIES * 4);
+
+ /* Allocate an area in framebuffer for our state layout we just set up */
+ total_state_size = next_offset;
+ assert (total_state_size < BRW_LINEAR_EXTRA);
+
+ /*
+ * Use the extra space allocated at the end of the Xv buffer
+ */
+ state_base_offset = (pPriv->YBuf0offset +
+ pPriv->linear->size * pI830->cpp -
+ BRW_LINEAR_EXTRA);
+ state_base_offset = ALIGN(state_base_offset, 64);
+
+ state_base = (char *)(pI830->FbBase + state_base_offset);
+ /* Set up our pointers to state structures in framebuffer. It would probably
+ * be a good idea to fill these structures out in system memory and then dump
+ * them there, instead.
+ */
+ vs_state = (void *)(state_base + vs_offset);
+ sf_state = (void *)(state_base + sf_offset);
+ wm_state = (void *)(state_base + wm_offset);
+ cc_state = (void *)(state_base + cc_offset);
+ sf_kernel = (void *)(state_base + sf_kernel_offset);
+ ps_kernel = (void *)(state_base + ps_kernel_offset);
+ sip_kernel = (void *)(state_base + sip_kernel_offset);
+
+ cc_viewport = (void *)(state_base + cc_viewport_offset);
+ dest_surf_state = (void *)(state_base + dest_surf_offset);
+ src_surf_state = (void *)(state_base + src_surf_offset);
+ src_sampler_state = (void *)(state_base + src_sampler_offset);
+ binding_table = (void *)(state_base + binding_table_offset);
+ vb = (void *)(state_base + vb_offset);
+
+ /* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it.
+ * A VUE consists of a 256-bit vertex header followed by the vertex data,
+ * which in our case is 4 floats (128 bits), thus a single 512-bit URB
+ * entry.
+ */
+#define URB_VS_ENTRIES 8
+#define URB_VS_ENTRY_SIZE 1
+
+#define URB_GS_ENTRIES 0
+#define URB_GS_ENTRY_SIZE 0
+
+#define URB_CLIP_ENTRIES 0
+#define URB_CLIP_ENTRY_SIZE 0
+
+ /* The SF kernel we use outputs only 4 256-bit registers, leading to an
+ * entry size of 2 512-bit URBs. We don't need to have many entries to
+ * output as we're generally working on large rectangles and don't care
+ * about having WM threads running on different rectangles simultaneously.
+ */
+#define URB_SF_ENTRIES 1
+#define URB_SF_ENTRY_SIZE 2
+
+#define URB_CS_ENTRIES 0
+#define URB_CS_ENTRY_SIZE 0
+
+ urb_vs_start = 0;
+ urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
+ urb_gs_start = urb_vs_start + urb_vs_size;
+ urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
+ urb_clip_start = urb_gs_start + urb_gs_size;
+ urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
+ urb_sf_start = urb_clip_start + urb_clip_size;
+ urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
+ urb_cs_start = urb_sf_start + urb_sf_size;
+ urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
+
+ /* We'll be poking the state buffers that could be in use by the 3d hardware
+ * here, but we should have synced the 3D engine already in I830PutImage.
+ */
+
+ memset (cc_viewport, 0, sizeof (*cc_viewport));
+ cc_viewport->min_depth = -1.e35;
+ cc_viewport->max_depth = 1.e35;
+
+ /* Color calculator state */
+ memset(cc_state, 0, sizeof(*cc_state));
+ cc_state->cc0.stencil_enable = 0; /* disable stencil */
+ cc_state->cc2.depth_test = 0; /* disable depth test */
+ cc_state->cc2.logicop_enable = 1; /* enable logic op */
+ cc_state->cc3.ia_blend_enable = 1; /* blend alpha just like colors */
+ cc_state->cc3.blend_enable = 0; /* disable color blend */
+ cc_state->cc3.alpha_test = 0; /* disable alpha test */
+ cc_state->cc4.cc_viewport_state_offset = (state_base_offset + cc_viewport_offset) >> 5;
+ cc_state->cc5.dither_enable = 0; /* disable dither */
+ cc_state->cc5.logicop_func = 0xc; /* WHITE */
+ cc_state->cc5.statistics_enable = 1;
+ cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
+ cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
+ cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
+
+ /* Upload system kernel */
+ memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
+
+ /* Set up the state buffer for the destination surface */
+ memset(dest_surf_state, 0, sizeof(*dest_surf_state));
+ dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+ dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
+ if (pI830->cpp == 2) {
+ dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+ } else {
+ dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+ }
+ dest_surf_state->ss0.writedisable_alpha = 0;
+ dest_surf_state->ss0.writedisable_red = 0;
+ dest_surf_state->ss0.writedisable_green = 0;
+ dest_surf_state->ss0.writedisable_blue = 0;
+ dest_surf_state->ss0.color_blend = 1;
+ dest_surf_state->ss0.vert_line_stride = 0;
+ dest_surf_state->ss0.vert_line_stride_ofs = 0;
+ dest_surf_state->ss0.mipmap_layout_mode = 0;
+ dest_surf_state->ss0.render_cache_read_mode = 0;
+
+ dest_surf_state->ss1.base_addr = pI830->FrontBuffer.Start;
+ dest_surf_state->ss2.height = pScrn->virtualY - 1;
+ dest_surf_state->ss2.width = pScrn->virtualX - 1;
+ dest_surf_state->ss2.mip_count = 0;
+ dest_surf_state->ss2.render_target_rotation = 0;
+ dest_surf_state->ss3.pitch = (pI830->displayWidth * pI830->cpp) - 1;
+
+ /* Set up the source surface state buffer */
+ memset(src_surf_state, 0, sizeof(*src_surf_state));
+ src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
+/* src_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; */
+ switch (id) {
+ case FOURCC_YUY2:
+ src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL;
+ break;
+ case FOURCC_UYVY:
+ src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_SWAPY;
+ break;
+ }
+ src_surf_state->ss0.writedisable_alpha = 0;
+ src_surf_state->ss0.writedisable_red = 0;
+ src_surf_state->ss0.writedisable_green = 0;
+ src_surf_state->ss0.writedisable_blue = 0;
+ src_surf_state->ss0.color_blend = 1;
+ src_surf_state->ss0.vert_line_stride = 0;
+ src_surf_state->ss0.vert_line_stride_ofs = 0;
+ src_surf_state->ss0.mipmap_layout_mode = 0;
+ src_surf_state->ss0.render_cache_read_mode = 0;
+
+ src_surf_state->ss1.base_addr = pPriv->YBuf0offset;
+ src_surf_state->ss2.width = width - 1;
+ src_surf_state->ss2.height = height - 1;
+ src_surf_state->ss2.mip_count = 0;
+ src_surf_state->ss2.render_target_rotation = 0;
+ src_surf_state->ss3.pitch = video_pitch - 1;
+
+ /* Set up a binding table for our two surfaces. Only the PS will use it */
+ /* XXX: are these offset from the right place? */
+ binding_table[0] = state_base_offset + dest_surf_offset;
+ binding_table[1] = state_base_offset + src_surf_offset;
+
+ /* Set up the packed YUV source sampler. Doesn't do colorspace conversion.
+ */
+ memset(src_sampler_state, 0, sizeof(*src_sampler_state));
+ src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
+ src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
+ src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+
+ /* Set up the vertex shader to be disabled (passthrough) */
+ memset(vs_state, 0, sizeof(*vs_state));
+ vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
+ vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
+ vs_state->vs6.vs_enable = 0;
+ vs_state->vs6.vert_cache_disable = 1;
+
+ /* Set up the SF kernel to do coord interp: for each attribute,
+ * calculate dA/dx and dA/dy. Hand these interpolation coefficients
+ * back to SF which then hands pixels off to WM.
+ */
+
+ memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
+ memset(sf_state, 0, sizeof(*sf_state));
+#if 0
+ ErrorF ("sf kernel: 0x%08x\n", state_base_offset + sf_kernel_offset);
+#endif
+ sf_state->thread0.kernel_start_pointer =
+ (state_base_offset + sf_kernel_offset) >> 6;
+ sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
+ sf_state->sf1.single_program_flow = 1; /* XXX */
+ sf_state->sf1.binding_table_entry_count = 0;
+ sf_state->sf1.thread_priority = 0;
+ sf_state->sf1.floating_point_mode = 0; /* Mesa does this */
+ sf_state->sf1.illegal_op_exception_enable = 1;
+ sf_state->sf1.mask_stack_exception_enable = 1;
+ sf_state->sf1.sw_exception_enable = 1;
+ sf_state->thread2.per_thread_scratch_space = 0;
+ sf_state->thread2.scratch_space_base_pointer = 0; /* not used in our kernel */
+ sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
+ sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
+ sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
+ sf_state->thread3.urb_entry_read_offset = 0;
+ sf_state->thread3.dispatch_grf_start_reg = 3;
+ sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
+ sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
+ sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
+ sf_state->thread4.stats_enable = 1;
+ sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
+ sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
+ sf_state->sf6.scissor = 0;
+ sf_state->sf7.trifan_pv = 2;
+ sf_state->sf6.dest_org_vbias = 0x8;
+ sf_state->sf6.dest_org_hbias = 0x8;
+
+ memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
+#if 0
+ ErrorF ("ps kernel: 0x%08x\n", state_base_offset + ps_kernel_offset);
+#endif
+ memset (wm_state, 0, sizeof (*wm_state));
+ wm_state->thread0.kernel_start_pointer =
+ (state_base_offset + ps_kernel_offset) >> 6;
+ wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
+ wm_state->thread1.single_program_flow = 1; /* XXX */
+ wm_state->thread1.binding_table_entry_count = 2;
+ /* Though we never use the scratch space in our WM kernel, it has to be
+ * set, and the minimum allocation is 1024 bytes.
+ */
+ wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
+ wm_scratch_offset) >> 10;
+ wm_state->thread2.per_thread_scratch_space = 0; /* 1024 bytes */
+ wm_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
+ wm_state->thread3.const_urb_entry_read_length = 0;
+ wm_state->thread3.const_urb_entry_read_offset = 0;
+ wm_state->thread3.urb_entry_read_length = 1; /* XXX */
+ wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
+ wm_state->wm4.stats_enable = 1;
+ wm_state->wm4.sampler_state_pointer = (state_base_offset + src_sampler_offset) >> 5;
+ wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
+ wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
+ wm_state->wm5.thread_dispatch_enable = 1;
+ wm_state->wm5.enable_16_pix = 1;
+ wm_state->wm5.enable_8_pix = 0;
+ wm_state->wm5.early_depth_test = 1;
+
+ {
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_FLUSH |
+ MI_STATE_INSTRUCTION_CACHE_FLUSH |
+ BRW_MI_GLOBAL_SNAPSHOT_RESET);
+ OUT_RING(MI_NOOP);
+ ADVANCE_LP_RING();
+ }
+
+/* brw_debug (pScrn, "before base address modify"); */
+ { BEGIN_LP_RING(12);
+ /* Match Mesa driver setup */
+ OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
+
+ /* Mesa does this. Who knows... */
+ OUT_RING(BRW_CS_URB_STATE | 0);
+ OUT_RING((0 << 4) | /* URB Entry Allocation Size */
+ (0 << 0)); /* Number of URB Entries */
+
+ /* Zero out the two base address registers so all offsets are absolute */
+ OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
+ OUT_RING(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */
+ OUT_RING(0 | BASE_ADDRESS_MODIFY); /* Surface state base address */
+ OUT_RING(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */
+ OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY); /* general state max addr, disabled */
+ OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY); /* media object state max addr, disabled */
+
+ /* Set system instruction pointer */
+ OUT_RING(BRW_STATE_SIP | 0);
+ OUT_RING(state_base_offset + sip_kernel_offset); /* system instruction pointer */
+
+ OUT_RING(MI_NOOP);
+ ADVANCE_LP_RING(); }
+
+/* brw_debug (pScrn, "after base address modify"); */
+
+ { BEGIN_LP_RING(42);
+ /* Enable VF statistics */
+ OUT_RING(BRW_3DSTATE_VF_STATISTICS | 1);
+
+ /* Pipe control */
+ OUT_RING(BRW_PIPE_CONTROL |
+ BRW_PIPE_CONTROL_NOWRITE |
+ BRW_PIPE_CONTROL_IS_FLUSH |
+ 2);
+ OUT_RING(0); /* Destination address */
+ OUT_RING(0); /* Immediate data low DW */
+ OUT_RING(0); /* Immediate data high DW */
+
+ /* Binding table pointers */
+ OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
+ OUT_RING(0); /* vs */
+ OUT_RING(0); /* gs */
+ OUT_RING(0); /* clip */
+ OUT_RING(0); /* sf */
+ /* Only the PS uses the binding table */
+ OUT_RING(state_base_offset + binding_table_offset); /* ps */
+
+ /* Blend constant color (magenta is fun) */
+ OUT_RING(BRW_3DSTATE_CONSTANT_COLOR | 3);
+ OUT_RING(float_to_uint (1.0));
+ OUT_RING(float_to_uint (0.0));
+ OUT_RING(float_to_uint (1.0));
+ OUT_RING(float_to_uint (1.0));
+
+ /* The drawing rectangle clipping is always on. Set it to values that
+ * shouldn't do any clipping.
+ */
+ OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2); /* XXX 3 for BLC or CTG */
+ OUT_RING(0x00000000); /* ymin, xmin */
+ OUT_RING((pScrn->virtualX - 1) |
+ (pScrn->virtualY - 1) << 16); /* ymax, xmax */
+ OUT_RING(0x00000000); /* yorigin, xorigin */
+
+ /* skip the depth buffer */
+ /* skip the polygon stipple */
+ /* skip the polygon stipple offset */
+ /* skip the line stipple */
+
+ /* Set the pointers to the 3d pipeline state */
+ OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
+ OUT_RING(state_base_offset + vs_offset); /* 32 byte aligned */
+ OUT_RING(BRW_GS_DISABLE); /* disable GS, resulting in passthrough */
+ OUT_RING(BRW_CLIP_DISABLE); /* disable CLIP, resulting in passthrough */
+ OUT_RING(state_base_offset + sf_offset); /* 32 byte aligned */
+ OUT_RING(state_base_offset + wm_offset); /* 32 byte aligned */
+ OUT_RING(state_base_offset + cc_offset); /* 64 byte aligned */
+
+ /* URB fence */
+ OUT_RING(BRW_URB_FENCE |
+ UF0_CS_REALLOC |
+ UF0_SF_REALLOC |
+ UF0_CLIP_REALLOC |
+ UF0_GS_REALLOC |
+ UF0_VS_REALLOC |
+ 1);
+ OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
+ ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
+ ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
+ OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
+ ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
+
+ /* Constant buffer state */
+ OUT_RING(BRW_CS_URB_STATE | 0);
+ OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) | /* URB Entry Allocation Size */
+ (URB_CS_ENTRIES << 0)); /* Number of URB Entries */
+
+ /* Set up the pointer to our vertex buffer */
+ OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 2);
+ OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
+ VB0_VERTEXDATA |
+ ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); /* four 32-bit floats per vertex */
+ OUT_RING(state_base_offset + vb_offset);
+ OUT_RING(3); /* four corners to our rectangle */
+
+ /* Set up our vertex elements, sourced from the single vertex buffer. */
+ OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | 3);
+ /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
+ OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+ VE0_VALID |
+ (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+ (0 << VE0_OFFSET_SHIFT));
+ OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+ (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+ /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
+ OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+ VE0_VALID |
+ (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+ (8 << VE0_OFFSET_SHIFT));
+ OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+ (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+
+ OUT_RING(MI_NOOP); /* pad to quadword */
+ 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 i;
+ float src_scale_x, src_scale_y;
+
+ if (!first_output) {
+ /* Since we use the same little vertex buffer over and over, sync for
+ * subsequent rectangles.
+ */
+ if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
+ (*pI830->AccelInfoRec->Sync)(pScrn);
+ pI830->AccelInfoRec->NeedToSync = FALSE;
+ }
+ }
+
+ pbox++;
+
+ /* Use normalized texture coordinates */
+ src_scale_x = (float)1.0 / (float)drw_w;
+ src_scale_y = (float)1.0 / (float)drw_h;
+
+ i = 0;
+ vb[i++] = (box_x2 - dxo) * src_scale_x;
+ vb[i++] = (box_y2 - dyo) * src_scale_y;
+ vb[i++] = (float) box_x2;
+ vb[i++] = (float) box_y2;
+
+ vb[i++] = (box_x1 - dxo) * src_scale_x;
+ vb[i++] = (box_y2 - dyo) * src_scale_y;
+ vb[i++] = (float) box_x1;
+ vb[i++] = (float) box_y2;
+
+ vb[i++] = (box_x1 - dxo) * src_scale_x;
+ vb[i++] = (box_y1 - dyo) * src_scale_y;
+ vb[i++] = (float) box_x1;
+ vb[i++] = (float) box_y1;
+
+#if 0
+ ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
+ INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
+ INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
+
+ OUTREG(BRW_VF_CTL,
+ BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID |
+ BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX |
+ BRW_VF_CTL_SNAPSHOT_ENABLE);
+ OUTREG(BRW_VF_STRG_VAL, 0);
+#endif
+
+#if 0
+ OUTREG(BRW_VS_CTL,
+ BRW_VS_CTL_SNAPSHOT_ALL_THREADS |
+ BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT |
+ BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE);
+
+ OUTREG(BRW_VS_STRG_VAL, 0);
+#endif
+
+#if WATCH_SF
+ OUTREG(BRW_SF_CTL,
+ BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT |
+ BRW_SF_CTL_SNAPSHOT_ALL_THREADS |
+ BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE);
+ OUTREG(BRW_SF_STRG_VAL, 0);
+#endif
+
+#if WATCH_WIZ
+ OUTREG(BRW_WIZ_CTL,
+ BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE |
+ BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS |
+ BRW_WIZ_CTL_SNAPSHOT_ENABLE);
+ OUTREG(BRW_WIZ_STRG_VAL,
+ (box_x1) | (box_y1 << 16));
+#endif
+
+#if 0
+ OUTREG(BRW_TS_CTL,
+ BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR |
+ BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS |
+ BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS |
+ BRW_TS_CTL_SNAPSHOT_ENABLE);
+#endif
+
+ BEGIN_LP_RING(6);
+ OUT_RING(BRW_3DPRIMITIVE |
+ BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+ (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
+ (0 << 9) | /* CTG - indirect vertex count */
+ 4);
+ OUT_RING(3); /* vertex count per instance */
+ OUT_RING(0); /* start vertex offset */
+ OUT_RING(1); /* single instance */
+ OUT_RING(0); /* start instance location */
+ OUT_RING(0); /* index buffer offset, ignored */
+ ADVANCE_LP_RING();
+
+#if 0
+ for (j = 0; j < 100000; j++) {
+ ctl = INREG(BRW_VF_CTL);
+ if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE)
+ break;
+ }
+
+ rdata = INREG(BRW_VF_RDATA);
+ OUTREG(BRW_VF_CTL, 0);
+ ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
+#endif
+
+#if 0
+ for (j = 0; j < 1000000; j++) {
+ ctl = INREG(BRW_VS_CTL);
+ if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE)
+ break;
+ }
+
+ rdata = INREG(BRW_VS_RDATA);
+ for (k = 0; k <= 3; k++) {
+ OUTREG(BRW_VS_CTL,
+ BRW_VS_CTL_SNAPSHOT_COMPLETE |
+ (k << 8));
+ rdata = INREG(BRW_VS_RDATA);
+ ErrorF ("VS_CTL: 0x%08x VS_RDATA(%d): 0x%08x\n", ctl, k, rdata);
+ }
+
+ OUTREG(BRW_VS_CTL, 0);
+#endif
+
+#if WATCH_SF
+ for (j = 0; j < 1000000; j++) {
+ ctl = INREG(BRW_SF_CTL);
+ if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE)
+ break;
+ }
+
+ for (k = 0; k <= 7; k++) {
+ OUTREG(BRW_SF_CTL,
+ BRW_SF_CTL_SNAPSHOT_COMPLETE |
+ (k << 8));
+ rdata = INREG(BRW_SF_RDATA);
+ ErrorF ("SF_CTL: 0x%08x SF_RDATA(%d): 0x%08x\n", ctl, k, rdata);
+ }
+
+ OUTREG(BRW_SF_CTL, 0);
+#endif
+
+#if WATCH_WIZ
+ for (j = 0; j < 100000; j++) {
+ ctl = INREG(BRW_WIZ_CTL);
+ if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE)
+ break;
+ }
+
+ rdata = INREG(BRW_WIZ_RDATA);
+ OUTREG(BRW_WIZ_CTL, 0);
+ ErrorF ("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata);
+#endif
+
+#if 0
+ for (j = 0; j < 100000; j++) {
+ ctl = INREG(BRW_TS_CTL);
+ if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE)
+ break;
+ }
+
+ rdata = INREG(BRW_TS_RDATA);
+ OUTREG(BRW_TS_CTL, 0);
+ ErrorF ("TS_CTL: 0x%08x TS_RDATA: 0x%08x\n", ctl, rdata);
+
+ ErrorF ("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
+ INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
+ INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
+#endif
+
+#if 0
+ for (j = 0; j < 256; j++) {
+ OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT);
+ rdata = INREG(BRW_TD_RDATA);
+ ErrorF ("TD_RDATA(%d): 0x%08x\n", j, rdata);
+ }
+#endif
+ first_output = FALSE;
+ if (pI830->AccelInfoRec)
+ pI830->AccelInfoRec->NeedToSync = TRUE;
+ }
+
+ if (pI830->AccelInfoRec)
+ (*pI830->AccelInfoRec->Sync)(pScrn);
+#if WATCH_STATS
+ I830PrintErrorState (pScrn);
+#endif
+}
+
static FBLinearPtr
I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
{
@@ -1887,6 +2956,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,
@@ -1904,9 +2986,11 @@ 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;
+ int extraLinear;
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,
@@ -1950,63 +3034,85 @@ 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_I965G(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) + 511) & ~511;
+ dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * width * 3;
} else {
- dstPitch = ((width / 2) + 511) & ~511; /* 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;
+ dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * width;
} else {
- dstPitch = ((width << 1) + 63) & ~63; /* of chroma */
+ dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * height;
}
-#else
- if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- dstPitch = ((height << 1) + 511) & ~511;
- size = dstPitch * width;
- } else {
- dstPitch = ((width << 1) + 511) & ~511; /* of chroma */
- size = dstPitch * height;
- }
-#endif
break;
}
+#if 0
ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
+#endif
+
+ if (IS_I965G(pI830))
+ extraLinear = BRW_LINEAR_EXTRA;
+ else
+ extraLinear = 0;
/* size is multiplied by 2 because we have two buffers that are flipping */
pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
- (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp);
+ (extraLinear +
+ (pPriv->doubleBuffer ? size * 2 : size)) /
+ pI830->cpp);
if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY))
return BadAlloc;
/* fixup pointers */
+#if 0
+ pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear->offset * pI830->cpp;
+#else
pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp;
+#endif
if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
@@ -2027,7 +3133,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);
@@ -2056,32 +3164,58 @@ 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 if (IS_I965G(pI830)) {
+ BroadwaterDisplayVideoTextured (pScrn, pPriv, destId, clipBoxes, width, height,
+ dstPitch, x1, y1, x2, y2,
+ src_w, src_h, drw_w, drw_h, pDraw);
+ } 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;
@@ -2091,23 +3225,27 @@ 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;
+#if 0
ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h);
+#endif
- 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;
@@ -2160,6 +3298,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)
@@ -2178,7 +3334,11 @@ I830BlockHandler(int i,
pScreen->BlockHandler = I830BlockHandler;
if (pPriv->videoStatus & TIMER_MASK) {
+#if 1
Time now = currentTime.milliseconds;
+#else
+ UpdateCurrentTime();
+#endif
if (pPriv->videoStatus & OFF_TIMER) {
if (pPriv->offTime < now) {
/* Turn off the overlay */
@@ -2278,7 +3438,11 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
surface->offsets[0] = linear->offset * bpp;
surface->devPrivate.ptr = (pointer) pPriv;
+#if 0
+ memset(pI830->FbBase + pScrn->fbOffset + surface->offsets[0], 0, size);
+#else
memset(pI830->FbBase + pI830->FrontBuffer.Start + surface->offsets[0], 0, size);
+#endif
return Success;
}
@@ -2524,37 +3688,39 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
}
- if (pPriv->pipe == 0) {
- if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling XVideo output because Pipe A is in double-wide mode.\n");
- pPriv->overlayOK = FALSE;
- } else if (!pPriv->overlayOK) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
- pPriv->overlayOK = TRUE;
+ if (!IS_I965G(pI830)) {
+ if (pPriv->pipe == 0) {
+ if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling XVideo output because Pipe A is in double-wide mode.\n");
+ pPriv->overlayOK = FALSE;
+ } else if (!pPriv->overlayOK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
+ pPriv->overlayOK = TRUE;
+ }
}
- }
- if (pPriv->pipe == 1) {
- if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling XVideo output because Pipe B is in double-wide mode.\n");
- pPriv->overlayOK = FALSE;
- } else if (!pPriv->overlayOK) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
- pPriv->overlayOK = TRUE;
+ if (pPriv->pipe == 1) {
+ if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling XVideo output because Pipe B is in double-wide mode.\n");
+ pPriv->overlayOK = FALSE;
+ } else if (!pPriv->overlayOK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
+ pPriv->overlayOK = TRUE;
+ }
}
}
/* Check we have an LFP connected */
if ((pPriv->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
(pPriv->pipe == 0 && pI830->operatingDevices & PIPE_LFP) ) {
- size = pI830->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+ size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
hsize = (size >> 16) & 0x7FF;
vsize = size & 0x7FF;
- active = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
+ active = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
if (vsize < active && hsize > 1024)
I830SetOneLineModeRatio(pScrn);
diff --git a/src/i830_video.h b/src/i830_video.h
new file mode 100644
index 00000000..9e11641e
--- /dev/null
+++ b/src/i830_video.h
@@ -0,0 +1,76 @@
+/***************************************************************************
+
+Copyright 2000 Intel Corporation. All Rights Reserved.
+
+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, sub license, 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+typedef struct {
+ CARD32 YBuf0offset;
+ CARD32 UBuf0offset;
+ CARD32 VBuf0offset;
+
+ CARD32 YBuf1offset;
+ CARD32 UBuf1offset;
+ CARD32 VBuf1offset;
+
+ unsigned char currentBuf;
+
+ int brightness;
+ int contrast;
+ int pipe;
+ int doubleBuffer;
+
+ RegionRec clip;
+ CARD32 colorKey;
+
+ CARD32 gamma0;
+ CARD32 gamma1;
+ CARD32 gamma2;
+ CARD32 gamma3;
+ CARD32 gamma4;
+ CARD32 gamma5;
+
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+ FBLinearPtr linear;
+
+ Bool overlayOK;
+ int oneLineMode;
+ int scaleRatio;
+ Bool textured;
+} I830PortPrivRec, *I830PortPrivPtr;
+
+#define GET_PORT_PRIVATE(pScrn) \
+ (I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+
+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);
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 9f3a3910..6948be08 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -230,6 +230,32 @@ I830XAAInit(ScreenPtr pScreen)
return XAAInit(pScreen, infoPtr);
}
+#ifdef XF86DRI
+static unsigned int
+CheckTiling(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned int tiled = 0;
+
+ /* Check tiling */
+ if (IS_I965G(pI830)) {
+ if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ if (pI830->bufferOffset == pI830->RotatedMem.Start && pI830->rotated_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ /* not really supported as it's always YMajor tiled */
+ if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
+ tiled = 1;
+ }
+
+ return tiled;
+}
+#else
+#define CheckTiling(pScrn) 0
+#endif
+
void
I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask)
@@ -292,6 +318,9 @@ I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
ADVANCE_LP_RING();
}
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
}
void
@@ -334,6 +363,7 @@ I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
{
I830Ptr pI830 = I830PTR(pScrn);
int dst_x2, dst_y2;
+ unsigned int tiled = CheckTiling(pScrn);
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
@@ -342,14 +372,18 @@ I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
dst_x2 = dst_x1 + w;
dst_y2 = dst_y1 + h;
+ if (tiled)
+ pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
+ (pI830->BR[13] & 0xFFFF0000);
+
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ XY_SRC_COPY_BLT_WRITE_RGB | tiled << 15 | tiled << 11);
} else {
- OUT_RING(XY_SRC_COPY_BLT_CMD);
+ OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 15 | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
@@ -361,6 +395,9 @@ I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1,
ADVANCE_LP_RING();
}
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
}
static void
@@ -402,6 +439,7 @@ I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
{
I830Ptr pI830 = I830PTR(pScrn);
int x1, x2, y1, y2;
+ unsigned int tiled = CheckTiling(pScrn);
x1 = x;
x2 = x + w;
@@ -411,16 +449,20 @@ I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentMono8x8PatternFillRect\n");
+ if (tiled)
+ pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
+ (pI830->BR[13] & 0xFFFF0000);
+
{
BEGIN_LP_RING(10);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_MONO_PAT_BLT_CMD | XY_MONO_PAT_BLT_WRITE_ALPHA |
- XY_MONO_PAT_BLT_WRITE_RGB |
+ XY_MONO_PAT_BLT_WRITE_RGB | tiled << 11 |
((patty << 8) & XY_MONO_PAT_VERT_SEED) |
((pattx << 12) & XY_MONO_PAT_HORT_SEED));
} else {
- OUT_RING(XY_MONO_PAT_BLT_CMD |
+ OUT_RING(XY_MONO_PAT_BLT_CMD | tiled << 11 |
((patty << 8) & XY_MONO_PAT_VERT_SEED) |
((pattx << 12) & XY_MONO_PAT_HORT_SEED));
}
@@ -435,6 +477,9 @@ I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
OUT_RING(0);
ADVANCE_LP_RING();
}
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
}
static void
@@ -510,6 +555,7 @@ static void
I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
+ unsigned int tiled = CheckTiling(pScrn);
if (pI830->init == 0) {
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
@@ -527,14 +573,18 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
bufno, pI830->BR[12]);
+ if (tiled)
+ pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) |
+ (pI830->BR[13] & 0xFFFF0000);
+
{
BEGIN_LP_RING(8);
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_MONO_SRC_BLT_CMD | XY_MONO_SRC_BLT_WRITE_ALPHA |
- XY_MONO_SRC_BLT_WRITE_RGB);
+ tiled << 11 | XY_MONO_SRC_BLT_WRITE_RGB);
} else {
- OUT_RING(XY_MONO_SRC_BLT_CMD);
+ OUT_RING(XY_MONO_SRC_BLT_CMD | tiled << 11);
}
OUT_RING(pI830->BR[13]);
OUT_RING(0); /* x1 = 0, y1 = 0 */
@@ -551,6 +601,9 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
*/
pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
I830GetNextScanlineColorExpandBuffer(pScrn);
+
+ if (IS_I965G(pI830))
+ I830EmitFlush(pScrn);
}
#if DO_SCANLINE_IMAGE_WRITE
@@ -602,6 +655,7 @@ static void
I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
+ unsigned int tiled = CheckTiling(pScrn);
if (pI830->init == 0) {
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
@@ -624,15 +678,15 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
if (pScrn->bitsPerPixel == 32) {
OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ tiled << 11 | XY_SRC_COPY_BLT_WRITE_RGB);
} else {
- OUT_RING(XY_SRC_COPY_BLT_CMD);
+ OUT_RING(XY_SRC_COPY_BLT_CMD | tiled << 11);
}
OUT_RING(pI830->BR[13]);
- OUT_RING(0); /* x1 = 0, y1 = 0 */
+ OUT_RING(0); /* x1 = 0, y1 = 0 */
OUT_RING(pI830->BR[11]); /* x2 = w, y2 = 1 */
- OUT_RING(pI830->BR[9]); /* dst addr */
- OUT_RING(0); /* source origin (0,0) */
+ OUT_RING(pI830->BR[9]); /* dst addr */
+ OUT_RING(0); /* source origin (0,0) */
OUT_RING(pI830->BR[11] & 0xffff); /* source pitch */
OUT_RING(pI830->BR[12]); /* src addr */
diff --git a/src/i915_3d.c b/src/i915_3d.c
index 942dbd17..e70bb24a 100644
--- a/src/i915_3d.c
+++ b/src/i915_3d.c
@@ -29,6 +29,7 @@
#include "config.h"
#endif
+#include "xf86.h"
#include "i830.h"
#include "i915_reg.h"
diff --git a/src/i915_video.c b/src/i915_video.c
new file mode 100644
index 00000000..0833d508
--- /dev/null
+++ b/src/i915_video.c
@@ -0,0 +1,467 @@
+/*
+ * Copyright © 2006 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:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86xv.h"
+#include "fourcc.h"
+
+#include "i830.h"
+#include "i830_video.h"
+#include "i915_reg.h"
+#include "i915_3d.h"
+
+union intfloat {
+ CARD32 ui;
+ float f;
+};
+
+#define OUT_RING_F(x) do { \
+ union intfloat _tmp; \
+ _tmp.f = x; \
+ OUT_RING(_tmp.ui); \
+} while (0)
+
+
+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(_3DSTATE_AA_CMD |
+ AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 |
+ AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
+
+ OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_DFLT_Z_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_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(_3DSTATE_RASTER_RULES_CMD |
+ 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(_3DSTATE_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(_3DSTATE_DRAW_RECT_CMD);
+ 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(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
+ OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD);
+ 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(_3DSTATE_MODES_4_CMD |
+ 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(_3DSTATE_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_XY);
+ 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(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
+ 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(_3DSTATE_CONST_BLEND_COLOR_CMD);
+ OUT_RING(0x00000000);
+
+ OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
+ 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_HORT_BIAS(0x80) | DSTORG_VERT_BIAS(0x80) | format);
+
+ OUT_RING(_3DSTATE_STIPPLE);
+ OUT_RING(0x00000000);
+
+ /* front buffer, pitch, offset */
+ OUT_RING(_3DSTATE_BUF_INFO_CMD);
+ OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
+ (((pI830->displayWidth * pI830->cpp) / 4) << 2));
+ OUT_RING(pI830->bufferOffset);
+ ADVANCE_LP_RING();
+
+ if (!planar) {
+ FS_LOCALS(3);
+
+ BEGIN_LP_RING(10);
+ OUT_RING(_3DSTATE_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(_3DSTATE_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();
+
+ FS_BEGIN();
+ i915_fs_dcl(FS_S0);
+ i915_fs_dcl(FS_T0);
+ i915_fs_texld(FS_OC, FS_S0, FS_T0);
+ FS_END();
+ } else {
+ FS_LOCALS(16);
+
+ BEGIN_LP_RING(1 + 18 + 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(_3DSTATE_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(_3DSTATE_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(_3DSTATE_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();
+
+ FS_BEGIN();
+ /* Declare samplers */
+ i915_fs_dcl(FS_S0);
+ i915_fs_dcl(FS_S1);
+ i915_fs_dcl(FS_S2);
+ i915_fs_dcl(FS_T0);
+ i915_fs_dcl(FS_T1);
+
+ /* Load samplers to temporaries. Y (sampler 0) gets the un-halved coords-
+ * from t1.
+ */
+ i915_fs_texld(FS_R1, FS_S0, FS_T1);
+ i915_fs_texld(FS_R2, FS_S1, FS_T0);
+ i915_fs_texld(FS_R3, FS_S2, FS_T0);
+
+ /* Move the sampled YUV data in R[123] to the first 3 channels of R0. */
+ i915_fs_mov_masked(FS_R0, MASK_X, i915_fs_operand_reg(FS_R1));
+ i915_fs_mov_masked(FS_R0, MASK_Y, i915_fs_operand_reg(FS_R2));
+ i915_fs_mov_masked(FS_R0, MASK_Z, i915_fs_operand_reg(FS_R3));
+
+ /* Normalize the YUV data */
+ i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0),
+ i915_fs_operand_reg(FS_C0));
+ /* 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.
+ */
+ i915_fs_dp3_masked(FS_OC, MASK_X | MASK_SATURATE,
+ i915_fs_operand_reg(FS_R0),
+ i915_fs_operand_reg(FS_C1));
+ i915_fs_dp3_masked(FS_OC, MASK_Y | MASK_SATURATE,
+ i915_fs_operand_reg(FS_R0),
+ i915_fs_operand_reg(FS_C2));
+ i915_fs_dp3_masked(FS_OC, MASK_Z | MASK_SATURATE,
+ i915_fs_operand_reg(FS_R0),
+ i915_fs_operand_reg(FS_C3));
+ /* Set alpha of the output to 1.0, by wiring W to 1 and not actually using
+ * the source.
+ */
+ i915_fs_mov_masked(FS_OC, MASK_W, i915_fs_operand_one());
+ FS_END();
+ }
+
+ {
+ 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;
+ float src_scale_x, src_scale_y;
+ 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 = 12;
+ else
+ vert_data_count = 18;
+
+ 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 - rect list consists of bottom right, bottom left, and top
+ * left vertices.
+ */
+ OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST |
+ (vert_data_count - 1));
+
+ /* bottom right */
+ OUT_RING_F(box_x2);
+ OUT_RING_F(box_y2);
+ if (!planar) {
+ OUT_RING_F((box_x2 - dxo) * src_scale_x);
+ OUT_RING_F((box_y2 - dyo) * src_scale_y);
+ } else {
+ OUT_RING_F((box_x2 - dxo) * src_scale_x / 2.0);
+ OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
+ OUT_RING_F((box_x2 - dxo) * src_scale_x);
+ OUT_RING_F((box_y2 - dyo) * src_scale_y);
+ }
+
+ /* bottom left */
+ OUT_RING_F(box_x1);
+ OUT_RING_F(box_y2);
+ if (!planar) {
+ OUT_RING_F((box_x1 - dxo) * src_scale_x);
+ OUT_RING_F((box_y2 - dyo) * src_scale_y);
+ } else {
+ OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
+ OUT_RING_F((box_y2 - dyo) * src_scale_y / 2.0);
+ OUT_RING_F((box_x1 - dxo) * src_scale_x);
+ OUT_RING_F((box_y2 - dyo) * src_scale_y);
+ }
+
+ /* top left */
+ OUT_RING_F(box_x1);
+ OUT_RING_F(box_y1);
+ if (!planar) {
+ OUT_RING_F((box_x1 - dxo) * src_scale_x);
+ OUT_RING_F((box_y1 - dyo) * src_scale_y);
+ } else {
+ OUT_RING_F((box_x1 - dxo) * src_scale_x / 2.0);
+ OUT_RING_F((box_y1 - dyo) * src_scale_y / 2.0);
+ OUT_RING_F((box_x1 - dxo) * src_scale_x);
+ OUT_RING_F((box_y1 - dyo) * src_scale_y);
+ }
+
+ ADVANCE_LP_RING();
+ }
+
+ if (pI830->AccelInfoRec)
+ pI830->AccelInfoRec->NeedToSync = TRUE;
+}
+
diff --git a/src/wm_prog.h b/src/wm_prog.h
new file mode 100644
index 00000000..297ddcbf
--- /dev/null
+++ b/src/wm_prog.h
@@ -0,0 +1,166 @@
+/* wm_program */
+/* mov (1) g4<1>F g1.8<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x2080013d, 0x00000028, 0x00000000 },
+/* add (1) g4.4<1>F g1.8<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20840d3d, 0x00000028, 0x00000001 },
+/* mov (1) g4.8<1>F g1.8<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x2088013d, 0x00000028, 0x00000000 },
+/* add (1) g4.12<1>F g1.8<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x208c0d3d, 0x00000028, 0x00000001 },
+/* mov (1) g6<1>F g1.10<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20c0013d, 0x0000002a, 0x00000000 },
+/* mov (1) g6.4<1>F g1.10<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20c4013d, 0x0000002a, 0x00000000 },
+/* add (1) g6.8<1>F g1.10<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20c80d3d, 0x0000002a, 0x00000001 },
+/* add (1) g6.12<1>F g1.10<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20cc0d3d, 0x0000002a, 0x00000001 },
+/* mov (1) g4.16<1>F g1.12<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x2090013d, 0x0000002c, 0x00000000 },
+/* add (1) g4.20<1>F g1.12<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20940d3d, 0x0000002c, 0x00000001 },
+/* mov (1) g4.24<1>F g1.12<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x2098013d, 0x0000002c, 0x00000000 },
+/* add (1) g4.28<1>F g1.12<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x209c0d3d, 0x0000002c, 0x00000001 },
+/* mov (1) g6.16<1>F g1.14<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20d0013d, 0x0000002e, 0x00000000 },
+/* mov (1) g6.20<1>F g1.14<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20d4013d, 0x0000002e, 0x00000000 },
+/* add (1) g6.24<1>F g1.14<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20d80d3d, 0x0000002e, 0x00000001 },
+/* add (1) g6.28<1>F g1.14<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20dc0d3d, 0x0000002e, 0x00000001 },
+/* mov (1) g5<1>F g1.16<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20a0013d, 0x00000030, 0x00000000 },
+/* add (1) g5.4<1>F g1.16<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20a40d3d, 0x00000030, 0x00000001 },
+/* mov (1) g5.8<1>F g1.16<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20a8013d, 0x00000030, 0x00000000 },
+/* add (1) g5.12<1>F g1.16<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20ac0d3d, 0x00000030, 0x00000001 },
+/* mov (1) g7<1>F g1.18<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20e0013d, 0x00000032, 0x00000000 },
+/* mov (1) g7.4<1>F g1.18<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20e4013d, 0x00000032, 0x00000000 },
+/* add (1) g7.8<1>F g1.18<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20e80d3d, 0x00000032, 0x00000001 },
+/* add (1) g7.12<1>F g1.18<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20ec0d3d, 0x00000032, 0x00000001 },
+/* mov (1) g5.16<1>F g1.20<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20b0013d, 0x00000034, 0x00000000 },
+/* add (1) g5.20<1>F g1.20<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20b40d3d, 0x00000034, 0x00000001 },
+/* mov (1) g5.24<1>F g1.20<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20b8013d, 0x00000034, 0x00000000 },
+/* add (1) g5.28<1>F g1.20<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20bc0d3d, 0x00000034, 0x00000001 },
+/* mov (1) g7.16<1>F g1.22<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20f0013d, 0x00000036, 0x00000000 },
+/* mov (1) g7.20<1>F g1.22<0,1,0>UW { align1 + } */
+ { 0x00000001, 0x20f4013d, 0x00000036, 0x00000000 },
+/* add (1) g7.24<1>F g1.22<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20f80d3d, 0x00000036, 0x00000001 },
+/* add (1) g7.28<1>F g1.22<0,1,0>UW 1 { align1 + } */
+ { 0x00000040, 0x20fc0d3d, 0x00000036, 0x00000001 },
+/* add (8) g4<1>F g4<8,8,1>F g1<0,1,0>F { align1 + } */
+ { 0x00600040, 0x208077bd, 0x008d0080, 0x00004020 },
+/* add (8) g5<1>F g5<8,8,1>F g1<0,1,0>F { align1 + } */
+ { 0x00600040, 0x20a077bd, 0x008d00a0, 0x00004020 },
+/* mul (8) g4<1>F g4<8,8,1>F g3<0,1,0>F { align1 + } */
+ { 0x00600041, 0x208077bd, 0x008d0080, 0x00000060 },
+/* mul (8) g5<1>F g5<8,8,1>F g3<0,1,0>F { align1 + } */
+ { 0x00600041, 0x20a077bd, 0x008d00a0, 0x00000060 },
+/* add (8) g4<1>F g4<8,8,1>F g3.12<0,1,0>F { align1 + } */
+ { 0x00600040, 0x208077bd, 0x008d0080, 0x0000006c },
+/* add (8) g5<1>F g5<8,8,1>F g3.12<0,1,0>F { align1 + } */
+ { 0x00600040, 0x20a077bd, 0x008d00a0, 0x0000006c },
+/* add (8) g6<1>F g6<8,8,1>F g1.4<0,1,0>F { align1 + } */
+ { 0x00600040, 0x20c077bd, 0x008d00c0, 0x00004024 },
+/* add (8) g7<1>F g7<8,8,1>F g1.4<0,1,0>F { align1 + } */
+ { 0x00600040, 0x20e077bd, 0x008d00e0, 0x00004024 },
+/* mul (8) g6<1>F g6<8,8,1>F g3.20<0,1,0>F { align1 + } */
+ { 0x00600041, 0x20c077bd, 0x008d00c0, 0x00000074 },
+/* mul (8) g7<1>F g7<8,8,1>F g3.20<0,1,0>F { align1 + } */
+ { 0x00600041, 0x20e077bd, 0x008d00e0, 0x00000074 },
+/* add (8) g6<1>F g6<8,8,1>F g3.28<0,1,0>F { align1 + } */
+ { 0x00600040, 0x20c077bd, 0x008d00c0, 0x0000007c },
+/* add (8) g7<1>F g7<8,8,1>F g3.28<0,1,0>F { align1 + } */
+ { 0x00600040, 0x20e077bd, 0x008d00e0, 0x0000007c },
+/* mov (8) m1<1>F g4<8,8,1>F { align1 + } */
+ { 0x00600001, 0x202003be, 0x008d0080, 0x00000000 },
+/* mov (8) m2<1>F g5<8,8,1>F { align1 + } */
+ { 0x00600001, 0x204003be, 0x008d00a0, 0x00000000 },
+/* mov (8) m3<1>F g6<8,8,1>F { align1 + } */
+ { 0x00600001, 0x206003be, 0x008d00c0, 0x00000000 },
+/* mov (8) m4<1>F g7<8,8,1>F { align1 + } */
+ { 0x00600001, 0x208003be, 0x008d00e0, 0x00000000 },
+/* send 0 (16) g12<1>UW g0<8,8,1>UW sampler mlen 5 rlen 8 { align1 + } */
+ { 0x00800031, 0x21801d29, 0x008d0000, 0x02580001 },
+/* mov (8) g19<1>UW g19<8,8,1>UW { align1 + } */
+ { 0x00600001, 0x22600129, 0x008d0260, 0x00000000 },
+/* add (8) g14<1>F g14<8,8,1>F -0.0627451{ align1 + } */
+ { 0x00600040, 0x21c07fbd, 0x008d01c0, 0xbd808081 },
+/* add (8) g12<1>F g12<8,8,1>F -0.501961{ align1 + } */
+ { 0x00600040, 0x21807fbd, 0x008d0180, 0xbf008081 },
+/* add (8) g16<1>F g16<8,8,1>F -0.501961{ align1 + } */
+ { 0x00600040, 0x22007fbd, 0x008d0200, 0xbf008081 },
+/* mul (8) g14<1>F g14<8,8,1>F 1.164{ align1 + } */
+ { 0x00600041, 0x21c07fbd, 0x008d01c0, 0x3f94fdf4 },
+/* mul (8) a0<1>F g12<8,8,1>F 1.596{ align1 + } */
+ { 0x00600041, 0x20007fbc, 0x008d0180, 0x3fcc49ba },
+/* mac (8) m2<1>F g14<8,8,1>F 1{ align1 + Saturate } */
+ { 0x80600048, 0x20407fbe, 0x008d01c0, 0x3f800000 },
+/* mul (8) a0<1>F g12<8,8,1>F -0.813{ align1 + } */
+ { 0x00600041, 0x20007fbc, 0x008d0180, 0xbf5020c5 },
+/* mac (8) a0<1>F g16<8,8,1>F -0.392{ align1 + } */
+ { 0x00600048, 0x20007fbc, 0x008d0200, 0xbec8b439 },
+/* mac (8) m3<1>F g14<8,8,1>F 1{ align1 + Saturate } */
+ { 0x80600048, 0x20607fbe, 0x008d01c0, 0x3f800000 },
+/* mul (8) a0<1>F g16<8,8,1>F 2.017{ align1 + } */
+ { 0x00600041, 0x20007fbc, 0x008d0200, 0x40011687 },
+/* mac (8) m4<1>F g14<8,8,1>F 1{ align1 + Saturate } */
+ { 0x80600048, 0x20807fbe, 0x008d01c0, 0x3f800000 },
+/* add (8) g15<1>F g15<8,8,1>F -0.0627451{ align1 + } */
+ { 0x00600040, 0x21e07fbd, 0x008d01e0, 0xbd808081 },
+/* add (8) g13<1>F g13<8,8,1>F -0.501961{ align1 + } */
+ { 0x00600040, 0x21a07fbd, 0x008d01a0, 0xbf008081 },
+/* add (8) g17<1>F g17<8,8,1>F -0.501961{ align1 + } */
+ { 0x00600040, 0x22207fbd, 0x008d0220, 0xbf008081 },
+/* mul (8) g15<1>F g15<8,8,1>F 1.164{ align1 + } */
+ { 0x00600041, 0x21e07fbd, 0x008d01e0, 0x3f94fdf4 },
+/* mul (8) a0<1>F g13<8,8,1>F 1.596{ align1 + } */
+ { 0x00600041, 0x20007fbc, 0x008d01a0, 0x3fcc49ba },
+/* mac (8) m6<1>F g15<8,8,1>F 1{ align1 + Saturate } */
+ { 0x80600048, 0x20c07fbe, 0x008d01e0, 0x3f800000 },
+/* mul (8) a0<1>F g13<8,8,1>F -0.813{ align1 + } */
+ { 0x00600041, 0x20007fbc, 0x008d01a0, 0xbf5020c5 },
+/* mac (8) a0<1>F g17<8,8,1>F -0.392{ align1 + } */
+ { 0x00600048, 0x20007fbc, 0x008d0220, 0xbec8b439 },
+/* mac (8) m7<1>F g15<8,8,1>F 1{ align1 + Saturate } */
+ { 0x80600048, 0x20e07fbe, 0x008d01e0, 0x3f800000 },
+/* mul (8) a0<1>F g17<8,8,1>F 2.017{ align1 + } */
+ { 0x00600041, 0x20007fbc, 0x008d0220, 0x40011687 },
+/* mac (8) m8<1>F g15<8,8,1>F 1{ align1 + Saturate } */
+ { 0x80600048, 0x21007fbe, 0x008d01e0, 0x3f800000 },
+/* mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable + } */
+ { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+/* send 0 (16) a0<1>UW g0<8,8,1>UW write mlen 10 rlen 0 EOT{ align1 + } */
+ { 0x00800031, 0x20001d28, 0x008d0000, 0x85a04800 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+/* nop (4) g0<1>UD { align1 + } */
+ { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
+