summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjhartmann <jhartmann>2000-04-04 22:08:12 +0000
committerjhartmann <jhartmann>2000-04-04 22:08:12 +0000
commit4fe5b7fbada2f73c1533e30f8abc5cf71e7c61c4 (patch)
treed526515e629abcae4e03e1c5c02b60243dc35f72
parentd13b9c4ecba68ca9c63d94dbf48a395e3d39b847 (diff)
Merged mga branch with trunkmga-0-0-2-20000404-merge
-rw-r--r--xc/config/cf/host.def17
-rw-r--r--xc/extras/Mesa/src/dlist.c1
-rw-r--r--xc/extras/Mesa/src/fog.c1
-rw-r--r--xc/extras/Mesa/src/fog.h2
-rw-r--r--xc/extras/Mesa/src/mmath.h7
-rw-r--r--xc/extras/Mesa/src/types.h2
-rw-r--r--xc/extras/Mesa/src/varray.c1
-rw-r--r--xc/include/GL/glx.h2
-rw-r--r--xc/lib/GL/Imakefile100
-rw-r--r--xc/lib/GL/dri/XF86dri.c55
-rw-r--r--xc/lib/GL/dri/drm/Imakefile2
-rw-r--r--xc/lib/GL/dri/xf86dri.h11
-rw-r--r--xc/lib/GL/dri/xf86dristr.h13
-rw-r--r--xc/lib/GL/highpc.c75
-rw-r--r--xc/lib/GL/lowpc.c4
-rwxr-xr-xxc/lib/GL/makeprofile.sh13
-rw-r--r--xc/lib/GL/mesa/dri/dri_mesa.c16
-rw-r--r--xc/lib/GL/mesa/dri/dri_mesaint.h10
-rw-r--r--xc/lib/GL/mesa/src/drv/Imakefile9
-rw-r--r--xc/lib/GL/mesa/src/drv/common/Imakefile6
-rw-r--r--xc/lib/GL/mesa/src/drv/common/depthtmp.h133
-rw-r--r--xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c88
-rw-r--r--xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h76
-rw-r--r--xc/lib/GL/mesa/src/drv/common/spantmp.h271
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/Imakefile246
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h77
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_init.c99
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_init.h197
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_inithw.c99
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c613
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810buf.h90
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.c207
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810context.c126
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810context.h161
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.c96
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.h18
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810depth.c735
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810depth.h80
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.c363
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.h148
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dmainit.c389
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810fastpath.c12
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810glx.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ioctl.c436
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ioctl.h32
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810lib.h57
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.c16
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ring.c162
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.c269
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.c803
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810swap.c315
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.c648
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.h72
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.c189
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.h168
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tritmp.h130
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.c125
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.h19
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/Imakefile242
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c281
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h54
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgabuffers.c315
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgabuffers.h9
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c357
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadd.c8
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgadepth.c116
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafastpath.c10
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h2
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.c535
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.h21
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgalib.h131
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaspan.c132
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.c360
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.h7
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.c490
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.h11
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.c50
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.h20
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatritmp.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.c42
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.h4
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/Imakefile2
-rw-r--r--xc/programs/Xserver/GL/dri/dri.c168
-rw-r--r--xc/programs/Xserver/GL/dri/dri.h24
-rw-r--r--xc/programs/Xserver/GL/dri/dristruct.h2
-rw-r--r--xc/programs/Xserver/GL/dri/xf86dri.c39
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml118
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c6
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile5
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h8
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c6
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c95
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h42
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c41
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h6
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile22
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h92
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c2
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c102
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c72
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c785
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h120
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c638
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c100
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h31
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c372
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c6
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c198
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h6
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile5
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel18
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux44
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c15
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c7
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c10
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c21
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h77
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h127
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c376
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c205
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c1228
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h93
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c141
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h132
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c151
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c430
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c417
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c60
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c1522
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h112
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h (renamed from xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h)233
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c34
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h286
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c782
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h13
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h930
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c10
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c7
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c18
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c44
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c3
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c142
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c81
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c117
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h77
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h29
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h147
155 files changed, 12965 insertions, 9747 deletions
diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def
index ef72a80d4..67b924bbf 100644
--- a/xc/config/cf/host.def
+++ b/xc/config/cf/host.def
@@ -1,13 +1,26 @@
+#define ProjectRoot /mnt/src/XF40
#define DefaultGcc2i386Opt -O2
#define LibraryCDebugFlags -O2
#define BuildServersOnly YES
-#define XF86CardDrivers vga i810 tdfx
+#define XF86CardDrivers vga tdfx i810 mga
#define LinuxDistribution LinuxRedHat
-#define DefaultCCOptions -ansi GccWarningOptions -pipe
+#define GccWarningOptions -Wall -Wpointer-arith -Wstrict-prototypes \
+ -Wmissing-prototypes -Wmissing-declarations \
+ -Wnested-externs
+#define DefaultCCOptions -ansi GccWarningOptions -pipe -g
+#define NormalLibGlx NO
+
#define BuildXF86DRI YES
#define HasGlide3 YES
+
/* Optionally turn these on for debugging */
/* #define GlxBuiltInTdfx YES */
+/* #define GlxBuiltInI810 YES */
+/* #define GlxBuiltInMga YES */
/* #define DoLoadableServer NO */
#define SharedLibFont NO
+
+#define XnestServer NO
+#define XVirtualFramebufferServer NO
+#define XprtServer NO
diff --git a/xc/extras/Mesa/src/dlist.c b/xc/extras/Mesa/src/dlist.c
index cdb1a5ac3..b2cc13787 100644
--- a/xc/extras/Mesa/src/dlist.c
+++ b/xc/extras/Mesa/src/dlist.c
@@ -4808,6 +4808,7 @@ static void print_list( GLcontext *ctx, FILE *f, GLuint list )
case OPCODE_END_OF_LIST:
fprintf(f,"END-LIST %u\n", list);
done = GL_TRUE;
+ gl_print_cassette( (struct immediate *) n[1].data );
break;
default:
if (opcode < 0 || opcode > OPCODE_END_OF_LIST) {
diff --git a/xc/extras/Mesa/src/fog.c b/xc/extras/Mesa/src/fog.c
index bac41cb1d..e35906c8f 100644
--- a/xc/extras/Mesa/src/fog.c
+++ b/xc/extras/Mesa/src/fog.c
@@ -35,6 +35,7 @@
#include "types.h"
#include "xform.h"
#endif
+#include "xform.h"
diff --git a/xc/extras/Mesa/src/fog.h b/xc/extras/Mesa/src/fog.h
index 9a58f54a1..59d84517b 100644
--- a/xc/extras/Mesa/src/fog.h
+++ b/xc/extras/Mesa/src/fog.h
@@ -65,4 +65,6 @@ extern void
_mesa_init_fog( void );
+extern struct gl_pipeline_stage gl_fog_coord_stage;
+
#endif
diff --git a/xc/extras/Mesa/src/mmath.h b/xc/extras/Mesa/src/mmath.h
index 6048eb186..30a300cdb 100644
--- a/xc/extras/Mesa/src/mmath.h
+++ b/xc/extras/Mesa/src/mmath.h
@@ -22,7 +22,7 @@
* 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.
*/
-
+/* $XFree86: xc/extras/Mesa/src/mmath.h,v 1.4 2000/03/03 18:30:08 tsi Exp $ */
/*
* Faster arithmetic functions. If the FAST_MATH preprocessor symbol is
@@ -47,7 +47,10 @@
* In the worst case, we force the compiler to use a memory access to
* truncate the float, by specifying the 'volatile' keyword.
*/
-#if defined(__linux__) && defined(__i386__)
+#if defined(__linux__) && defined(__i386__) && !defined(IN_MODULE)
+/*
+ * A libc interface is needed for this...
+ */
#include <fpu_control.h>
#if !defined(_FPU_SETCW)
diff --git a/xc/extras/Mesa/src/types.h b/xc/extras/Mesa/src/types.h
index dc1b5e103..e96740e78 100644
--- a/xc/extras/Mesa/src/types.h
+++ b/xc/extras/Mesa/src/types.h
@@ -1345,8 +1345,6 @@ struct gl_extensions {
#define DD_STENCIL 0x1000000
#define DD_CLIP_FOG_COORD 0x2000000
-
-
#define DD_SW_SETUP (DD_TRI_CULL| \
DD_TRI_CULL_FRONT_BACK| \
DD_TRI_OFFSET| \
diff --git a/xc/extras/Mesa/src/varray.c b/xc/extras/Mesa/src/varray.c
index dc758594a..786793da7 100644
--- a/xc/extras/Mesa/src/varray.c
+++ b/xc/extras/Mesa/src/varray.c
@@ -682,6 +682,7 @@ _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
VB->Primitive[VB->CopyStart] = mode;
ctx->Array.Flag[count] |= VERT_END_VB;
+ ctx->Array.Flag[count] |= VERT_END_VB;
/* Transform and render.
*/
gl_run_pipeline( VB );
diff --git a/xc/include/GL/glx.h b/xc/include/GL/glx.h
index 367ce0a51..0254b6064 100644
--- a/xc/include/GL/glx.h
+++ b/xc/include/GL/glx.h
@@ -101,7 +101,7 @@ extern GLXDrawable glXGetCurrentDrawableEXT (void);
extern GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID);
extern void glXFreeContextEXT (Display *dpy, GLXContext ctx);
extern int glXQueryContextInfoEXT (Display *dpy, GLXContext ctx, int attribute, int *value);
-extern void (*glXGetProcAddressARB(const GLubyte *procName))();
+extern void (*glXGetProcAddressARB(const GLubyte *procName))( void );
diff --git a/xc/lib/GL/Imakefile b/xc/lib/GL/Imakefile
index a185089e4..c3dfb015d 100644
--- a/xc/lib/GL/Imakefile
+++ b/xc/lib/GL/Imakefile
@@ -27,6 +27,14 @@ DependSubdirs($(SUBDIRS))
LIBNAME = GL
SOREV = $(SOGLREV)
+#if 0
+ LOWSRC = lowpc.c
+ LOWOBJ = lowpc.o
+
+ HISRC = highpc.c
+ HIOBJ = highpc.o
+#endif
+
GLXOBJS = glx/?*.o
GLXUOBJS = glx/unshared/?*.o
GLXDOBJS = glx/debugger/?*.o
@@ -98,6 +106,87 @@ DRIMESADONES = mesa/dri/DONE
DRVDONES = $(TDFXDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES)
REQUIREDLIBS += -lglide3x
+
+#elif GlxBuiltInI810
+
+ DRMOBJS = dri/drm/?*.o
+ DRMUOBJS = dri/drm/unshared/?*.o
+ DRMDOBJS = dri/drm/debugger/?*.o
+ DRMPOBJS = dri/drm/profiled/?*.o
+ DRMDONES = dri/drm/DONE
+
+ I810OBJS = mesa/src/drv/i810/?*.o
+ I810UOBJS = mesa/src/drv/i810/unshared/?*.o
+ I810DOBJS = mesa/src/drv/i810/debugger/?*.o
+ I810POBJS = mesa/src/drv/i810/profiled/?*.o
+ I810DONES = mesa/src/drv/i810/DONE
+
+ COMMONOBJS = mesa/src/drv/common/?*.o
+ COMMONUOBJS = mesa/src/drv/common/unshared/?*.o
+ COMMONDOBJS = mesa/src/drv/common/debugger/?*.o
+ COMMONPOBJS = mesa/src/drv/common/profiled/?*.o
+ COMMONDONES = mesa/src/drv/common/DONE
+
+ MESAOBJS = mesa/src/?*.o mesa/src/X86/?*.o
+ MESAUOBJS = mesa/src/unshared/?*.o mesa/src/X86/unshared/?*.o
+ MESADOBJS = mesa/src/debugger/?*.o mesa/src/X86/debugger/?*.o
+ MESAPOBJS = mesa/src/profiled/?*.o mesa/src/X86/profiled/?*.o
+ MESADONES = mesa/src/DONE mesa/src/X86/DONE
+
+ DRIMESAOBJS = mesa/dri/?*.o
+DRIMESAUOBJS = mesa/dri/unshared/?*.o
+DRIMESADOBJS = mesa/dri/debugger/?*.o
+DRIMESAPOBJS = mesa/dri/profiled/?*.o
+DRIMESADONES = mesa/dri/DONE
+
+ DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS)
+ DRVUOBJS = $(I810UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS)
+ DRVDOBJS = $(I810DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS)
+ DRVPOBJS = $(I810POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS)
+ DRVDONES = $(I810DONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES)
+
+
+
+
+#elif GlxBuiltInMga
+
+ DRMOBJS = dri/drm/?*.o
+ DRMUOBJS = dri/drm/unshared/?*.o
+ DRMDOBJS = dri/drm/debugger/?*.o
+ DRMPOBJS = dri/drm/profiled/?*.o
+ DRMDONES = dri/drm/DONE
+
+ MGAOBJS = mesa/src/drv/mga/?*.o
+ MGAUOBJS = mesa/src/drv/mga/unshared/?*.o
+ MGADOBJS = mesa/src/drv/mga/debugger/?*.o
+ MGAPOBJS = mesa/src/drv/mga/profiled/?*.o
+ MGADONES = mesa/src/drv/mga/DONE
+
+ COMMONOBJS = mesa/src/drv/common/?*.o
+ COMMONUOBJS = mesa/src/drv/common/unshared/?*.o
+ COMMONDOBJS = mesa/src/drv/common/debugger/?*.o
+ COMMONPOBJS = mesa/src/drv/common/profiled/?*.o
+ COMMONDONES = mesa/src/drv/common/DONE
+
+ MESAOBJS = mesa/src/?*.o mesa/src/X86/?*.o
+ MESAUOBJS = mesa/src/unshared/?*.o mesa/src/X86/unshared/?*.o
+ MESADOBJS = mesa/src/debugger/?*.o mesa/src/X86/debugger/?*.o
+ MESAPOBJS = mesa/src/profiled/?*.o mesa/src/X86/profiled/?*.o
+ MESADONES = mesa/src/DONE mesa/src/X86/DONE
+
+ DRIMESAOBJS = mesa/dri/?*.o
+DRIMESAUOBJS = mesa/dri/unshared/?*.o
+DRIMESADOBJS = mesa/dri/debugger/?*.o
+DRIMESAPOBJS = mesa/dri/profiled/?*.o
+DRIMESADONES = mesa/dri/DONE
+
+ DRVOBJS = $(MGAOBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS)
+ DRVUOBJS = $(MGAUOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS)
+ DRVDOBJS = $(MGADOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS)
+ DRVPOBJS = $(MGAPOBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS)
+ DRVDONES = $(MGADONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES)
+
+
#elif GlxBuiltInMesa
#ifndef GlxDriverUsesMesa
DRVOBJS = mesa/src/?*.o mesa/src/X/?*.o
@@ -113,17 +202,26 @@ DRIMESADONES = mesa/dri/DONE
#ifdef OS2Architecture
OBJS = $(LIBNAME).a
#else
- OBJS = $(GLXOBJS) $(DRIOBJS) $(DRVOBJS)
+ OBJS = $(LOWOBJ) $(GLXOBJS) $(DRIOBJS) $(DRVOBJS) $(HIOBJ)
#endif
#if HasSharedLibraries
+#if 1
UOBJS = $(GLXUOBJS) $(DRIUOBJS) $(DRVUOBJS)
#else
UOBJS = $(OBJS)
#endif
+#else
+ UOBJS = $(OBJS)
+#endif
DOBJS = $(GLXDOBJS) $(DRIDOBJS) $(DRVDOBJS)
POBJS = $(GLXPOBJS) $(DRIPOBJS) $(DRVPOBJS)
DONES = $(GLXDONES) $(DRIDONES) $(DRVDONES)
+#if 0
+SubdirLibraryRule(highpc.o lowpc.o)
+NormalLintTarget(highpc.c lowpc.c)
+#endif
+
#if LocalThreads
THREADOBJS = $(THREADS_LIBS)
#endif
diff --git a/xc/lib/GL/dri/XF86dri.c b/xc/lib/GL/dri/XF86dri.c
index 77654ac76..cd485680b 100644
--- a/xc/lib/GL/dri/XF86dri.c
+++ b/xc/lib/GL/dri/XF86dri.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.2 1999/06/27 14:07:22 dawes Exp $ */
+/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.5 2000/02/23 04:46:33 martin Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Kevin E. Martin <kevin@precisioninsight.com>
* Jens Owen <jens@precisioninsight.com>
*
- * $PI: xc/lib/GL/dri/XF86dri.c,v 1.14 1999/06/16 20:08:33 faith Exp $
*/
/* THIS IS NOT AN X CONSORTIUM STANDARD */
@@ -385,7 +384,11 @@ Bool XF86DRIDestroyDrawable(dpy, screen, drawable)
}
Bool XF86DRIGetDrawableInfo(dpy, screen, drawable,
- index, stamp, X, Y, W, H, numClipRects, pClipRects)
+ index, stamp, X, Y, W, H,
+ numClipRects, pClipRects,
+ backX, backY,
+ numBackClipRects, pBackClipRects
+ )
Display* dpy;
int screen;
Drawable drawable;
@@ -397,10 +400,15 @@ Bool XF86DRIGetDrawableInfo(dpy, screen, drawable,
int* H;
int* numClipRects;
XF86DRIClipRectPtr* pClipRects;
+ int* backX;
+ int* backY;
+ int* numBackClipRects;
+ XF86DRIClipRectPtr* pBackClipRects;
{
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIGetDrawableInfoReply rep;
xXF86DRIGetDrawableInfoReq *req;
+ int total_rects;
XF86DRICheckExtension (dpy, info, False);
@@ -410,7 +418,9 @@ Bool XF86DRIGetDrawableInfo(dpy, screen, drawable,
req->driReqType = X_XF86DRIGetDrawableInfo;
req->screen = screen;
req->drawable = drawable;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+
+ if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
+ {
UnlockDisplay(dpy);
SyncHandle();
return False;
@@ -422,16 +432,41 @@ Bool XF86DRIGetDrawableInfo(dpy, screen, drawable,
*W = (int)rep.drawableWidth;
*H = (int)rep.drawableHeight;
*numClipRects = rep.numClipRects;
+ total_rects = *numClipRects;
+
+ *backX = rep.backX;
+ *backY = rep.backY;
+ *numBackClipRects = rep.numBackClipRects;
+ total_rects += *numBackClipRects;
+
+ if (rep.length != (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply) +
+ total_rects * sizeof(XF86DRIClipRectRec))) {
+ _XEatData(dpy, rep.length);
+ return False;
+ }
+
- if (rep.length) {
- if (!(*pClipRects = (XF86DRIClipRectPtr)Xcalloc(rep.length, 1))) {
- _XEatData(dpy, rep.length);
- return False;
- }
- _XRead32(dpy, *pClipRects, rep.length);
+ if (*numClipRects) {
+ int len = sizeof(XF86DRIClipRectRec) * (*numClipRects);
+
+ *pClipRects = (XF86DRIClipRectPtr)Xcalloc(len, 1);
+ if (*pClipRects)
+ _XRead32(dpy, *pClipRects, len);
} else {
*pClipRects = NULL;
}
+
+ if (*numBackClipRects) {
+ int len = sizeof(XF86DRIClipRectRec) * (*numBackClipRects);
+
+ *pBackClipRects = (XF86DRIClipRectPtr)Xcalloc(len, 1);
+ if (*pBackClipRects)
+ _XRead32(dpy, *pBackClipRects, len);
+ } else {
+ *pBackClipRects = NULL;
+ }
+
UnlockDisplay(dpy);
SyncHandle();
return True;
diff --git a/xc/lib/GL/dri/drm/Imakefile b/xc/lib/GL/dri/drm/Imakefile
index 18619461b..4fd493e1d 100644
--- a/xc/lib/GL/dri/drm/Imakefile
+++ b/xc/lib/GL/dri/drm/Imakefile
@@ -25,6 +25,8 @@ LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
LinkSourceFile(xf86drm.h,$(XF86OSSRC))
LinkSourceFile(drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
+LinkSourceFile(mga_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
+LinkSourceFile(i810_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
#include <Library.tmpl>
diff --git a/xc/lib/GL/dri/xf86dri.h b/xc/lib/GL/dri/xf86dri.h
index 8e234fcb2..8b7cd3aa2 100644
--- a/xc/lib/GL/dri/xf86dri.h
+++ b/xc/lib/GL/dri/xf86dri.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.2 1999/06/27 14:07:24 dawes Exp $ */
+/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.5 2000/02/23 04:46:34 martin Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -32,7 +32,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Jens Owen <jens@precisioninsight.com>
* Rickard E. Faith <faith@precisioninsight.com>
*
- * $PI: xc/lib/GL/dri/xf86dri.h,v 1.12 1999/06/16 20:08:34 faith Exp $
*/
#ifndef _XF86DRI_H_
@@ -60,6 +59,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XF86DRIOperationNotSupported 1
#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
+/* Warning : Do not change XF86DRIClipRect without changing the kernel
+ * structure! */
typedef struct _XF86DRIClipRect {
unsigned short x1; /* Upper left: inclusive */
unsigned short y1;
@@ -178,7 +179,11 @@ Bool XF86DRIGetDrawableInfo(
int* /* W */,
int* /* H */,
int* /* numClipRects */,
- XF86DRIClipRectPtr* /* pClipRects */
+ XF86DRIClipRectPtr*,/* pClipRects */
+ int* /* backX */,
+ int* /* backY */,
+ int* /* numBackClipRects */,
+ XF86DRIClipRectPtr* /* pBackClipRects */
#endif
);
diff --git a/xc/lib/GL/dri/xf86dristr.h b/xc/lib/GL/dri/xf86dristr.h
index 32969834c..dd246bac8 100644
--- a/xc/lib/GL/dri/xf86dristr.h
+++ b/xc/lib/GL/dri/xf86dristr.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.2 1999/06/27 14:07:24 dawes Exp $ */
+/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.5 2000/02/23 04:46:34 martin Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Kevin E. Martin <kevin@precisioninsight.com>
* Jens Owen <jens@precisioninsight.com>
*
- * $PI: xc/lib/GL/dri/xf86dristr.h,v 1.11 1999/06/22 03:09:44 jens Exp $
*/
#ifndef _XF86DRISTR_H_
@@ -41,7 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XF86DRINAME "XFree86-DRI"
-#define XF86DRI_MAJOR_VERSION 1 /* current version numbers */
+#define XF86DRI_MAJOR_VERSION 2 /* current version numbers */
#define XF86DRI_MINOR_VERSION 0
#define XF86DRI_PATCH_VERSION 0
@@ -239,9 +238,13 @@ typedef struct {
INT16 drawableWidth B16;
INT16 drawableHeight B16;
CARD32 numClipRects B32;
- CARD32 pad6 B32;
+ INT16 backX B16;
+ INT16 backY B16;
+ CARD32 numBackClipRects B32;
} xXF86DRIGetDrawableInfoReply;
-#define sz_xXF86DRIGetDrawableInfoReply 32
+
+#define sz_xXF86DRIGetDrawableInfoReply 36
+
typedef struct _XF86DRIGetDeviceInfo {
CARD8 reqType; /* always DRIReqCode */
diff --git a/xc/lib/GL/highpc.c b/xc/lib/GL/highpc.c
new file mode 100644
index 000000000..c9218d02a
--- /dev/null
+++ b/xc/lib/GL/highpc.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/* Mesa shared lib profiling code by Josh Vanderhoof. Adapted
+ * (trivially) to the DRI by Keith Whitwell.
+ */
+
+/*
+ * This is the highest address in libGL.so
+ */
+void glx_highpc(void) { }
+
+#if defined(__GNUC__) && defined(__linux__)
+
+void monstartup( char *lowpc, char *highpc );
+void _mcleanup( void );
+void glx_lowpc( void );
+
+static int profile = 0;
+
+
+/*
+ * Start profiling
+ */
+void __attribute__ ((constructor))
+glx_init_prof( void )
+{
+ FILE *fp;
+ char *s = getenv("GLX_SO_MON");
+
+ fprintf(stderr, "\n\n\nIn glx_init_prof\n\n\n");
+
+ if (!s) return;
+
+ profile = 1;
+ monstartup( (char *)glx_lowpc, (char *)glx_highpc );
+
+ fprintf(stderr, "Starting profiling, %x %x\n",
+ (unsigned int)glx_lowpc,
+ (unsigned int)glx_highpc);
+
+ if ((fp = fopen( "glx_lowpc", "w" )) != NULL) {
+ fprintf( fp, "0x%08x ", (unsigned int)glx_lowpc );
+ fclose( fp );
+ }
+}
+
+
+
+/*
+ * Finish profiling
+ */
+void __attribute__ ((destructor))
+glx_fini_prof( void )
+{
+ fprintf(stderr, "in glx_fini_prof\n");
+
+ if (profile) {
+ _mcleanup();
+ profile = 0;
+ fprintf(stderr, "Finished profiling\n");
+ }
+}
+
+
+
+
+#else
+
+void force_init_prof( void )
+{
+}
+
+#endif
diff --git a/xc/lib/GL/lowpc.c b/xc/lib/GL/lowpc.c
new file mode 100644
index 000000000..7c580a02c
--- /dev/null
+++ b/xc/lib/GL/lowpc.c
@@ -0,0 +1,4 @@
+/*
+ * This is the lowest address in Mesa
+ */
+void glx_lowpc(void) { }
diff --git a/xc/lib/GL/makeprofile.sh b/xc/lib/GL/makeprofile.sh
new file mode 100755
index 000000000..05d1b221a
--- /dev/null
+++ b/xc/lib/GL/makeprofile.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+RUNDIR=$1
+
+[ -f ${RUNDIR}/glx_lowpc ] || { echo "no file ${RUNDIR}/glx_lowpc" ; exit 1 }
+[ -f ${RUNDIR}/gmon.out ] || { echo "no file ${RUNDIR}/gmon.out" ; exit 1 }
+
+rm -f glx_lowpc gmon.out glxsyms profile
+ln -s ${RUNDIR}/glx_lowpc . || exit 1
+ln -s ${RUNDIR}/gmon.out . || exit 1
+
+ld -o glxsyms -noinhibit-exec --whole-archive -Ttext=`cat glx_lowpc` libGL.a 2> /dev/null && \
+gprof glxsyms < gmon.out > profile
diff --git a/xc/lib/GL/mesa/dri/dri_mesa.c b/xc/lib/GL/mesa/dri/dri_mesa.c
index 08f3dfcfd..b2ee7e3e0 100644
--- a/xc/lib/GL/mesa/dri/dri_mesa.c
+++ b/xc/lib/GL/mesa/dri/dri_mesa.c
@@ -307,14 +307,26 @@ void driMesaUpdateDrawableInfo(Display *dpy, int scrn,
Xfree(pdp->pClipRects);
}
+ if (pdp->pBackClipRects) {
+ Xfree(pdp->pBackClipRects);
+ }
+
+
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
if (!XF86DRIGetDrawableInfo(dpy, scrn, pdp->draw,
&pdp->index, &pdp->lastStamp,
&pdp->x, &pdp->y, &pdp->w, &pdp->h,
- &pdp->numClipRects, &pdp->pClipRects)) {
+ &pdp->numClipRects, &pdp->pClipRects,
+ &pdp->backX,
+ &pdp->backY,
+ &pdp->numBackClipRects,
+ &pdp->pBackClipRects
+ )) {
pdp->numClipRects = 0;
pdp->pClipRects = NULL;
+ pdp->numBackClipRects = 0;
+ pdp->pBackClipRects = 0;
/* ERROR!!! */
}
@@ -354,7 +366,9 @@ static void *driMesaCreateDrawable(Display *dpy, int scrn, GLXDrawable draw,
pdp->w = 0;
pdp->h = 0;
pdp->numClipRects = 0;
+ pdp->numBackClipRects = 0;
pdp->pClipRects = NULL;
+ pdp->pBackClipRects = NULL;
pDRIScreen = __glXFindDRIScreen(dpy, scrn);
pdp->driScreenPriv = psp = (__DRIscreenPrivate *)pDRIScreen->private;
diff --git a/xc/lib/GL/mesa/dri/dri_mesaint.h b/xc/lib/GL/mesa/dri/dri_mesaint.h
index 6b64114d0..16c483f01 100644
--- a/xc/lib/GL/mesa/dri/dri_mesaint.h
+++ b/xc/lib/GL/mesa/dri/dri_mesaint.h
@@ -104,6 +104,16 @@ struct __DRIdrawablePrivateRec {
XF86DRIClipRectPtr pClipRects;
/*
+ ** Information about the back and depthbuffer where different
+ ** from above.
+ */
+ int backX;
+ int backY;
+ int backClipRectType;
+ int numBackClipRects;
+ XF86DRIClipRectPtr pBackClipRects;
+
+ /*
** Pointer to context to which this drawable is currently bound.
*/
__DRIcontextPrivate *driContextPriv;
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile
index fadb29bb2..306bf16dc 100644
--- a/xc/lib/GL/mesa/src/drv/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/Imakefile
@@ -16,6 +16,12 @@ DRIVER += gamma
#if GlxBuiltInTdfx
DRIVER += tdfx
#endif
+#if GlxBuiltInMga
+DRIVER += common mga
+#endif
+#if GlxBuiltInI810
+DRIVER += common i810
+#endif
SUBDIRS = $(DRIVER)
#else
@@ -23,6 +29,9 @@ SUBDIRS += gamma
#if HasGlide3
SUBDIRS += tdfx
#endif
+SUBDIRS += common
+SUBDIRS += mga
+SUBDIRS += i810
#endif
MakeSubdirs($(SUBDIRS))
diff --git a/xc/lib/GL/mesa/src/drv/common/Imakefile b/xc/lib/GL/mesa/src/drv/common/Imakefile
index 5c3d40dd7..e96291842 100644
--- a/xc/lib/GL/mesa/src/drv/common/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/common/Imakefile
@@ -22,8 +22,7 @@ MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
DRISRCS = hwlog.c mm.c
DRIOBJS = hwlog.o mm.o
@@ -44,7 +43,8 @@ LibraryObjectRule()
SubdirLibraryRule($(OBJS))
NormalLintTarget($(SRCS))
-#if !GlxUseBuiltInDRIDriver
+XCOMM #if !GlxUseBuiltInDRIDriver
+#if 0
LIBNAME = i810_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
diff --git a/xc/lib/GL/mesa/src/drv/common/depthtmp.h b/xc/lib/GL/mesa/src/drv/common/depthtmp.h
new file mode 100644
index 000000000..3aa307904
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/depthtmp.h
@@ -0,0 +1,133 @@
+#ifndef DBG
+#define DBG 0
+#endif
+
+
+
+static void TAG(WriteDepthSpan)( GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ const GLdepth *depth,
+ const GLubyte mask[] )
+{
+ HW_LOCK()
+ {
+ GLint x1;
+ GLint n1;
+ LOCAL_DEPTH_VARS;
+
+ y = Y_FLIP(y);
+
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+
+ if (DBG) fprintf(stderr, "WriteDepthSpan %d..%d (x1 %d)\n",
+ (int)i, (int)n1, (int)x1);
+
+ if (mask)
+ {
+ for (;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_DEPTH( x1, y, depth[i] );
+ }
+ else
+ {
+ for (;i<n1;i++,x1++)
+ WRITE_DEPTH( x1, y, depth[i] );
+ }
+ }
+ HW_ENDCLIPLOOP();
+ }
+ HW_UNLOCK();
+}
+
+
+static void TAG(WriteDepthPixels)( GLcontext *ctx,
+ GLuint n,
+ const GLint x[],
+ const GLint y[],
+ const GLdepth depth[],
+ const GLubyte mask[] )
+{
+ HW_LOCK()
+ {
+ GLint i;
+ LOCAL_DEPTH_VARS;
+
+ if (DBG) fprintf(stderr, "WriteDepthPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ {
+ if (mask[i]) {
+ const int fy = Y_FLIP(y[i]);
+ if (CLIPPIXEL(x[i],fy))
+ WRITE_DEPTH( x[i], fy, depth[i] );
+ }
+ }
+ }
+ HW_ENDCLIPLOOP();
+ }
+ HW_UNLOCK();
+}
+
+
+
+
+/* Read depth spans and pixels
+ */
+static void TAG(ReadDepthSpan)( GLcontext *ctx,
+ GLuint n, GLint x, GLint y,
+ GLdepth depth[])
+{
+ HW_LOCK()
+ {
+ GLint x1,n1;
+ LOCAL_DEPTH_VARS;
+
+ y = Y_FLIP(y);
+
+ if (DBG) fprintf(stderr, "ReadDepthSpan\n");
+
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+ for (;i<n1;i++)
+ READ_DEPTH( depth[i], (x1+i), y );
+ }
+ HW_ENDCLIPLOOP();
+ }
+ HW_UNLOCK();
+}
+
+static void TAG(ReadDepthPixels)( GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ GLdepth depth[] )
+{
+ HW_LOCK()
+ {
+ GLint i;
+ LOCAL_DEPTH_VARS;
+
+ if (DBG) fprintf(stderr, "ReadDepthPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++) {
+ int fy = Y_FLIP( y[i] );
+ if (CLIPPIXEL( x[i], fy ))
+ READ_DEPTH( depth[i], x[i], fy );
+ }
+ }
+ HW_ENDCLIPLOOP();
+ }
+ HW_UNLOCK();
+}
+
+
+#undef WRITE_DEPTH
+#undef READ_DEPTH
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c
new file mode 100644
index 000000000..2fd80eb3e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include "shared_texture_lru.h"
+
+/* (Re)initialize the global circular LRU list. The last element
+ * in the array (heap->nrRegions) is the sentinal. Keeping it
+ * at the end of the array allows the other elements of the array
+ * to be addressed rationally when looking up objects at a
+ * particular location in texture memory.
+ */
+static void resetGlobalLRU( driHeapPtr heap )
+{
+ driTexRegion *list = heap->shared->list;
+ int sz = 1 << heap->logGranularity;
+ int i;
+
+ heap->localAge = ++heap->shared->texAge;
+
+ for (i = 0 ; (i+1) * sz <= heap->size ; i++) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = heap->shared->texAge;
+ }
+
+ i--;
+ list[0].prev = heap->nrRegions;
+ list[i].prev = i-1;
+ list[i].next = heap->nrRegions;
+ list[heap->nrRegions].prev = i;
+ list[heap->nrRegions].next = 0;
+}
+
+/* Called by the client whenever it touches a local texture.
+ */
+void driUpdateHeap( driHeapPtr heap, int start, int end )
+{
+ driTexRegion *list = heap->shared->list;
+ int i;
+
+ heap->localAge = ++heap->shared->globalAge;
+
+ for (i = start ; i <= end ; i++)
+ {
+ list[i].in_use = 1;
+ list[i].age = heap->localAge;
+
+ /* remove_from_list(i)
+ */
+ list[(unsigned)list[i].next].prev = list[i].prev;
+ list[(unsigned)list[i].prev].next = list[i].next;
+
+ /* insert_at_head(list, i)
+ */
+ list[i].prev = heap->nrRegions;
+ list[i].next = list[heap->nrRegions].next;
+ list[(unsigned)list[heap->nrRegions].next].prev = i;
+ list[heap->nrRegions].next = i;
+ }
+}
+
+
+/* Called by the client on lock contention to determine whether
+ * textures have been stolen
+ */
+void driAgeTextures( driHeapPtr heap )
+{
+ driTexRegion *list = heap->shared->list;
+ int sz = 1 << (heap->logGranularity);
+ int i, nr = 0;
+
+ /* Have to go right round from the back to ensure stuff ends up
+ * LRU in the local list... Fix with a cursor pointer.
+ */
+ for (i = list[heap->nrRegions].prev ;
+ i != heap->nrRegions && nr < heap->nrRegions ;
+ i = list[i].prev, nr++)
+ {
+ if (list[i].age > heap->localAge)
+ heap->texturesGone( heap->driverContext, heap->heapId, i * sz, sz, 1);
+ }
+
+ /* Loop or uninitialized heap detected. Reset.
+ */
+ if (nr == heap->nrRegions) {
+ heap->texturesGone( heap->driverContext, heap->heapId, 0, heap->size, 0);
+ resetGlobalLRU( heap );
+ }
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h
new file mode 100644
index 000000000..e6cee567d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/common/shared_texture_lru.h
@@ -0,0 +1,76 @@
+#ifndef DRI_TEX_HEAP_H
+#define DRI_TEX_HEAP_H
+
+
+/* Private struct.
+ */
+typedef struct {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} driTexRegion;
+
+
+/* This is the global part of the shared texture mechanism.
+ *
+ * Do not use this struct directly - declare an equivalent one with a
+ * larger list[] array, tuned to suit your application.
+ *
+ * Your expanded struct should be placed in the driver-specific
+ * portion of the sarea.
+ */
+struct {
+ int globalAge;
+ driTexRegion list[1]; /* drivers will want to define a larger list */
+} driGlobalList;
+
+
+/* This is the client-private part of the mechanism.
+ *
+ * Clients will place one or more of these structs in their driver
+ * context struct to manage one or more global texture heaps. All
+ * fields except print_local_lru must be filled in.
+ */
+struct dri_tex_heap_t {
+
+ int heapId; /* client-supplied identifier */
+ void *driverContext; /* pointer to the client's context private */
+ int size; /* heap size in bytes */
+ int logGranularity; /* log base 2 of size of single heap region */
+ int nrRegions; /* number of elements in global list */
+ driGlobalList *shared; /* pointer to sarea driGlobalList struct */
+ int localAge; /* initialize to zero */
+
+ /* Callback to the client to let it know a region of texture
+ * space has changed age. The client must integrate this
+ * information with its local texture knowledge, in particular
+ * checking whether any of its own textures have been
+ * invalidated.
+ */
+ void (*textures_gone)( void *driverContext,
+ int heapId,
+ int offset,
+ int size,
+ int inUse );
+
+ /* Optional hook for debugging.
+ */
+ void (*print_local_lru)( void *driverContext,
+ int heapId );
+} driTexHeap;
+
+
+#define DRI_AGE_TEXTURES( heap ) \
+ if ((heap)->localAge > (heap)->shared->globalAge) \
+ driAgeTextures( heap );
+
+
+/* This should be called whenever there has been contention on the
+ * hardware lock. Clients can shortcircuit this slightly by using
+ * DRI_AGE_TEXTURES, above.
+ */
+void driAgeTextures( driTexHeap *heap );
+
+#endif
+
+
diff --git a/xc/lib/GL/mesa/src/drv/common/spantmp.h b/xc/lib/GL/mesa/src/drv/common/spantmp.h
index e10dca1a2..b475c6b18 100644
--- a/xc/lib/GL/mesa/src/drv/common/spantmp.h
+++ b/xc/lib/GL/mesa/src/drv/common/spantmp.h
@@ -1,37 +1,48 @@
+#ifndef DBG
+#define DBG 0
+#endif
static void TAG(WriteRGBASpan)( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
const GLubyte rgba[][4],
const GLubyte mask[] )
{
- GLuint x1,n1;
- LOCAL_VARS;
-
- y = Y_FLIP(y);
-
- if (DBG) fprintf(stderr, "WriteRGBASpan\n");
-
- HW_CLIPLOOP()
+ HW_LOCK()
{
- GLuint i = 0;
- CLIPSPAN(x,y,n,x1,n1,i);
- if (mask)
- {
- for (i=0;i<n1;i++,x1++)
- if (mask[i])
- WRITE_RGBA( x1, y,
- rgba[i][0], rgba[i][1],
- rgba[i][2], rgba[i][3] );
- }
- else
- {
- for (i=0;i<n1;i++,x1++)
- WRITE_RGBA( x1, y,
- rgba[i][0], rgba[i][1],
- rgba[i][2], rgba[i][3] );
- }
+ GLint x1;
+ GLint n1;
+ LOCAL_VARS;
+
+ y = Y_FLIP(y);
+
+
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+
+ if (DBG) fprintf(stderr, "WriteRGBASpan %d..%d (x1 %d)\n",
+ (int)i, (int)n1, (int)x1);
+
+ if (mask)
+ {
+ for (;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_RGBA( x1, y,
+ rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3] );
+ }
+ else
+ {
+ for (;i<n1;i++,x1++)
+ WRITE_RGBA( x1, y,
+ rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3] );
+ }
+ }
+ HW_ENDCLIPLOOP();
}
- HW_ENDCLIPLOOP();
+ HW_UNLOCK();
}
static void TAG(WriteRGBSpan)( const GLcontext *ctx,
@@ -39,32 +50,37 @@ static void TAG(WriteRGBSpan)( const GLcontext *ctx,
const GLubyte rgb[][3],
const GLubyte mask[] )
{
- GLuint x1,n1;
- LOCAL_VARS;
-
- y = Y_FLIP(y);
-
-
- if (DBG) fprintf(stderr, "WriteRGBSpan\n");
-
- HW_CLIPLOOP()
+ HW_LOCK()
{
- GLuint i = 0;
- CLIPSPAN(x,y,n,x1,n1,i);
-
- if (mask)
- {
- for (;i<n1;i++,x1++)
- if (mask[i])
- WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 );
- }
- else
- {
- for (;i<n1;i++,x1++)
- WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 );
- }
+ GLint x1;
+ GLint n1;
+ LOCAL_VARS;
+
+ y = Y_FLIP(y);
+
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+
+ if (DBG) fprintf(stderr, "WriteRGBSpan %d..%d (x1 %d)\n",
+ (int)i, (int)n1, (int)x1);
+
+ if (mask)
+ {
+ for (;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 );
+ }
+ else
+ {
+ for (;i<n1;i++,x1++)
+ WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 0 );
+ }
+ }
+ HW_ENDCLIPLOOP();
}
- HW_ENDCLIPLOOP();
+ HW_UNLOCK();
}
static void TAG(WriteRGBAPixels)( const GLcontext *ctx,
@@ -74,25 +90,29 @@ static void TAG(WriteRGBAPixels)( const GLcontext *ctx,
const GLubyte rgba[][4],
const GLubyte mask[] )
{
- GLuint i;
- LOCAL_VARS;
-
- if (DBG) fprintf(stderr, "WriteRGBAPixels\n");
-
- HW_CLIPLOOP()
+ HW_LOCK()
{
- for (i=0;i<n;i++)
- {
- if (mask[i]) {
- const int fy = Y_FLIP(y[i]);
- if (CLIPPIXEL(x[i],fy))
- WRITE_RGBA( x[i], fy,
- rgba[i][0], rgba[i][1],
- rgba[i][2], rgba[i][3] );
+ GLint i;
+ LOCAL_VARS;
+
+ if (DBG) fprintf(stderr, "WriteRGBAPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ {
+ if (mask[i]) {
+ const int fy = Y_FLIP(y[i]);
+ if (CLIPPIXEL(x[i],fy))
+ WRITE_RGBA( x[i], fy,
+ rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3] );
+ }
+ }
}
- }
+ HW_ENDCLIPLOOP();
}
- HW_ENDCLIPLOOP();
+ HW_UNLOCK();
}
@@ -100,23 +120,28 @@ static void TAG(WriteMonoRGBASpan)( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
const GLubyte mask[] )
{
- GLuint x1,n1;
- LOCAL_VARS;
- INIT_MONO_PIXEL(p);
-
- y = Y_FLIP( y );
-
- if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n");
-
- HW_CLIPLOOP()
+ HW_LOCK()
{
- GLuint i = 0;
- CLIPSPAN(x,y,n,x1,n1,i);
- for (;i<n1;i++,x1++)
- if (mask[i])
- WRITE_PIXEL( x1, y, p );
+ GLint x1;
+ GLint n1;
+ LOCAL_VARS;
+ INIT_MONO_PIXEL(p);
+
+ y = Y_FLIP( y );
+
+ if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n");
+
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+ for (;i<n1;i++,x1++)
+ if (mask[i])
+ WRITE_PIXEL( x1, y, p );
+ }
+ HW_ENDCLIPLOOP();
}
- HW_ENDCLIPLOOP();
+ HW_UNLOCK();
}
@@ -125,22 +150,26 @@ static void TAG(WriteMonoRGBAPixels)( const GLcontext *ctx,
const GLint x[], const GLint y[],
const GLubyte mask[] )
{
- GLuint i;
- LOCAL_VARS;
- INIT_MONO_PIXEL(p);
-
- if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n");
-
- HW_CLIPLOOP()
+ HW_LOCK()
{
- for (i=0;i<n;i++)
- if (mask[i]) {
- int fy = Y_FLIP(y[i]);
- if (CLIPPIXEL( x[i], fy ))
- WRITE_PIXEL( x[i], fy, p );
+ GLint i;
+ LOCAL_VARS;
+ INIT_MONO_PIXEL(p);
+
+ if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n");
+
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ if (mask[i]) {
+ int fy = Y_FLIP(y[i]);
+ if (CLIPPIXEL( x[i], fy ))
+ WRITE_PIXEL( x[i], fy, p );
+ }
}
- }
- HW_ENDCLIPLOOP();
+ HW_ENDCLIPLOOP();
+ }
+ HW_UNLOCK();
}
@@ -152,42 +181,50 @@ static void TAG(ReadRGBASpan)( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4])
{
- GLuint x1,n1;
- LOCAL_VARS;
+ HW_LOCK()
+ {
+ GLint x1,n1;
+ LOCAL_VARS;
- y = Y_FLIP(y);
+ y = Y_FLIP(y);
- if (DBG) fprintf(stderr, "ReadRGBASpan\n");
+ if (DBG) fprintf(stderr, "ReadRGBASpan\n");
- HW_CLIPLOOP()
- {
- GLuint i = 0;
- CLIPSPAN(x,y,n,x1,n1,i);
- for (;i<n1;i++)
- READ_RGBA( rgba[i], x1+i, y );
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN(x,y,n,x1,n1,i);
+ for (;i<n1;i++)
+ READ_RGBA( rgba[i], (x1+i), y );
+ }
+ HW_ENDCLIPLOOP();
}
- HW_ENDCLIPLOOP();
+ HW_UNLOCK();
}
static void TAG(ReadRGBAPixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLubyte rgba[][4], const GLubyte mask[] )
{
- GLuint i;
- LOCAL_VARS;
+ HW_LOCK()
+ {
+ GLint i;
+ LOCAL_VARS;
- if (DBG) fprintf(stderr, "ReadRGBAPixels\n");
+ if (DBG) fprintf(stderr, "ReadRGBAPixels\n");
- HW_CLIPLOOP()
- {
- for (i=0;i<n;i++)
- if (mask[i]) {
- int fy = Y_FLIP( y[i] );
- if (CLIPPIXEL( x[i], fy ))
- READ_RGBA( rgba[i], x[i], fy );
+ HW_CLIPLOOP()
+ {
+ for (i=0;i<n;i++)
+ if (mask[i]) {
+ int fy = Y_FLIP( y[i] );
+ if (CLIPPIXEL( x[i], fy ))
+ READ_RGBA( rgba[i], x[i], fy );
+ }
}
+ HW_ENDCLIPLOOP();
}
- HW_ENDCLIPLOOP();
+ HW_UNLOCK();
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile
index 5f1d93072..5c6a33796 100644
--- a/xc/lib/GL/mesa/src/drv/i810/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile
@@ -1,4 +1,6 @@
+#include <Threads.tmpl>
+
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
#define DoExtraLib SharedLibGlx
@@ -10,12 +12,14 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#endif
#if BuildXF86DRI
- DRI_DEFINES = GlxDefines -DFX -DFX_GLIDE3 -DGLIDE3 -DDRIVERTS
+ DRI_DEFINES = GlxDefines -DDRIVERTS
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
- -I$(XF86DRIVERSRC)/i810 \
- -I../../../include -I../.. -I../../X
+ -I$(XF86DRIVERSRC)/i810 \
+ -I../../../include -I../.. -I../common -I../../X \
+ -I$(XF86OSSRC)/linux/drm/kernel
#endif
MESA_INCLUDES = -I. -I.. -I../../include
@@ -23,20 +27,234 @@ MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
- DRISRCS = i810_init.c i810_inithw.c i810_xmesa.c i810clear.c \
- i810context.c i810dd.c i810depth.c i810dma.c \
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o
+
+
+ I810SRCS = i810_xmesa.c i810clear.c \
+ i810dd.c \
i810pipeline.c i810span.c i810state.c i810swap.c \
- i810tex.c i810tris.c i810vb.c
+ i810tex.c i810tris.c i810vb.c i810fastpath.c i810ioctl.c
- DRIOBJS = i810_init.o i810_inithw.o i810_xmesa.o i810clear.o \
- i810context.o i810dd.o i810depth.o i810dma.o \
+ I810OBJS = i810_xmesa.o i810clear.o \
+ i810dd.o \
i810pipeline.o i810span.o i810state.o i810swap.o \
- i810tex.o i810tris.o i810vb.o
+ i810tex.o i810tris.o i810vb.o i810fastpath.o i810ioctl.o
+
+ MESASRCS = ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.o \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ COMMONSRCS = ../common/mm.c ../common/hwlog.c
+ COMMONOBJS = ../common/mm.o ../common/hwlog.o
+
+ SRCS = $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(COMMONSRCS) $(I810SRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(COMMONOBJS) $(I810OBJS)
- SRCS = $(DRISRCS)
- OBJS = $(DRIOBJS)
+REQUIREDLIBS += -lm
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -57,7 +275,7 @@ LIBNAME = i810_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
index 677a35222..e4e274e9a 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
@@ -75,7 +75,8 @@
* 4: DR4_*
*/
#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
-#define DR1_RECT_CLIP_ENABLE (0x1<<31)
+#define DR1_RECT_CLIP_ENABLE (0x0<<31)
+#define DR1_RECT_CLIP_DISABLE (0x1<<31)
#define DR1_X_DITHER_BIAS_MASK (0x3<<26)
#define DR1_X_DITHER_BIAS_SHIFT 26
#define DR1_Y_DITHER_BIAS_MASK (0x3<<24)
@@ -107,6 +108,8 @@
#define LCS_UPDATE_LINEWIDTH (0x1<<15)
#define LCS_LINEWIDTH_MASK (0x7<<12)
#define LCS_LINEWIDTH_SHIFT 12
+#define LCS_LINEWIDTH_0_5 (0x1<<12)
+#define LCS_LINEWIDTH_1_0 (0x2<<12)
#define LCS_UPDATE_ALPHA_INTERP (0x1<<11)
#define LCS_ALPHA_FLAT (0x0<<10)
#define LCS_ALPHA_INTERP (0x1<<10)
@@ -238,18 +241,6 @@
#define SDM_DST_BOTH_SRC_ALPHA (0xc<<0)
#define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0)
-/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135
- */
-#define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1)
-#define CC1_UPDATE_CC_TEST_ENABLE (1<<28)
-#define CC1_CC_TEST_ENABLE (1<<27)
-#define CC1_UPDATE_CI_VALUE (1<<26)
-#define CC1_UPDATE_CK_LOW_VALUE (1<<25)
-#define CC1_UPDATE_CK_HI_VALUE (1<<24)
-#define CC1_CK_LOW_VALUE_MASK ((1<<24)-1)
-#define CC2_CI_VALUE_MASK (0xff<<24)
-#define CC2_CI_VALUE_SHIFT 24
-#define CC2_CK_HIGH_VALUE_MASK ((1<<24)-1)
/* GFXRENDERSTATE_COLOR_FACTOR, p134
*
@@ -628,13 +619,43 @@ typedef struct {
#define DV_PF_565 (0x2<<8)
+
+
+#define GFX_OP_ANTIALIAS ((0x3<<29)|(0x6<<24))
+#define AA_UPDATE_EDGEFLAG (1<<13)
+#define AA_ENABLE_EDGEFLAG (1<<12)
+#define AA_UPDATE_POLYWIDTH (1<<11)
+#define AA_POLYWIDTH_05 (1<<9)
+#define AA_POLYWIDTH_10 (2<<9)
+#define AA_POLYWIDTH_20 (3<<9)
+#define AA_POLYWIDTH_40 (4<<9)
+#define AA_UPDATE_LINEWIDTH (1<<8)
+#define AA_LINEWIDTH_05 (1<<6)
+#define AA_LINEWIDTH_10 (2<<6)
+#define AA_LINEWIDTH_20 (3<<6)
+#define AA_LINEWIDTH_40 (4<<6)
+#define AA_UPDATE_BB_EXPANSION (1<<5)
+#define AA_BB_EXPANSION_SHIFT 2
+#define AA_UPDATE_AA_ENABLE (1<<1)
+#define AA_ENABLE (1<<0)
+
+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define ST1_ENABLE (1<<16)
+#define ST1_MASK (0xffff)
+
+
/* Indices into buf.Setup where various bits of state are mirrored per
* context and per buffer. These can be fired at the card as a unit,
* or in a piecewise fashion as required.
*/
-/* Destbuffer state (includes zbuffer). Drawrect is the only thing
- * that needs to be restored for 2d???
+/* Destbuffer state
+ * - backbuffer linear offset and pitch -- invarient in the current dri
+ * - zbuffer linear offset and pitch -- also invarient
+ * - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
*/
#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
#define I810_DESTREG_DI1 1
@@ -667,14 +688,24 @@ typedef struct {
#define I810_CTXREG_B1 12 /* GFX_OP_BOOL_1 */
#define I810_CTXREG_B2 13 /* GFX_OP_BOOL_2 */
#define I810_CTXREG_LCS 14 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
-#define I810_CTXREG_SCI0 15 /* GFX_OP_SCISSOR_INFO (3 dwords) */
-#define I810_CTXREG_SCI1 16
-#define I810_CTXREG_SCI2 17
-#define I810_CTXREG_SC 18 /* GFX_OP_SCISSOR */
-#define I810_CTXREG_PV 19 /* GFX_OP_PV_RULE -- Invarient! */
-#define I810_CTXREG_ZA 20 /* GFX_OP_ZBIAS_ALPHAFUNC */
-
-#define I810_CTX_SETUP_SIZE (21+1) /* pad to qword */
+#define I810_CTXREG_PV 15 /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA 16 /* GFX_OP_ZBIAS_ALPHAFUNC */
+#define I810_CTXREG_ST0 17 /* GFX_OP_STIPPLE */
+#define I810_CTXREG_ST1 18
+#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
+#define I810_CTX_SETUP_SIZE (20) /* pad to qword */
+
+
+/* Cliprect state - keep seperate from context as it is used for
+ * drawing triangles to the shared backbuffer, and
+ * changes more frequently than the 'normal' context.
+ */
+#define I810_CLIPREG_SCI0 0 /* GFX_OP_SCISSOR_INFO (3 dwords) */
+#define I810_CLIPREG_SCI1 1
+#define I810_CLIPREG_SCI2 2
+#define I810_CLIPREG_SC 3 /* GFX_OP_SCISSOR */
+
+#define I810_CLIP_SETUP_SIZE 4
/* Texture state (per tex_buffer)
*/
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_init.c b/xc/lib/GL/mesa/src/drv/i810/i810_init.c
deleted file mode 100644
index 5f37cd769..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810_init.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <keithw@precisioninsight.com>
- *
- * based on tdfx driver by
- * Daryll Strauss <daryll@precisioninsight.com>
- *
- * $PI: #
- */
-
-#ifdef GLX_DIRECT_RENDERING
-
-#include <X11/Xlibint.h>
-#include "xf86dri.h"
-#include "i810_dri.h"
-#include "i810_init.h"
-
-#ifdef DEBUG_LOCKING
-char *prevLockFile=0;
-int prevLockLine=0;
-#endif
-
-static void performMagic(__DRIscreenPrivate *driScrnPriv)
-{
- i810ScreenPrivate *gPriv = (i810ScreenPrivate *)driScrnPriv->private;
- I810DRIPtr gDRIPriv = (I810DRIPtr)driScrnPriv->pDevPriv;
-
- gPriv->regs.handle=gDRIPriv->regs;
- gPriv->regs.size=gDRIPriv->regsSize;
- gPriv->deviceID=gDRIPriv->deviceID;
- gPriv->width=gDRIPriv->width;
- gPriv->height=gDRIPriv->height;
- gPriv->mem=gDRIPriv->mem;
- gPriv->cpp=gDRIPriv->cpp;
- gPriv->stride=gDRIPriv->stride;
- gPriv->fbOffset=gDRIPriv->fbOffset;
- gPriv->backOffset=gDRIPriv->backOffset;
- gPriv->depthOffset=gDRIPriv->depthOffset;
- gPriv->textureOffset=gDRIPriv->textureOffset;
- gPriv->textureSize=gDRIPriv->textureSize;
-}
-
-GLboolean i810MapAllRegions(__DRIscreenPrivate *driScrnPriv)
-{
- i810ScreenPrivate *gPriv = (i810ScreenPrivate *)driScrnPriv->private;
-
- /* First, pick apart pDevPriv & friends */
- performMagic(driScrnPriv);
-
- if (drmMap(driScrnPriv->fd, gPriv->regs.handle, gPriv->regs.size,
- &gPriv->regs.map)) {
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-void i810UnmapAllRegions(__DRIscreenPrivate *driScrnPriv)
-{
- i810ScreenPrivate *gPriv = (i810ScreenPrivate *)driScrnPriv->private;
-
- drmUnmap(gPriv->regs.map, gPriv->regs.size);
-}
-
-/*
- * Shutdown hardware - nothing to do...
- */
-void i810CloseHardware(void)
-{
-}
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_init.h b/xc/lib/GL/mesa/src/drv/i810/i810_init.h
index c7af9c443..804f66889 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810_init.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_init.h
@@ -27,7 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
- * Daryll Strauss <daryll@precisioninsight.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
*
*/
@@ -37,7 +37,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
#include <sys/time.h>
-#include <glide.h>
#include "dri_tmm.h"
#include "dri_mesaint.h"
#include "dri_mesa.h"
@@ -45,148 +44,88 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xmesaP.h"
typedef struct {
- drmHandle handle;
- drmSize size;
- drmAddress map;
+ drmHandle handle;
+ drmSize size;
+ char *map;
} i810Region, *i810RegionPtr;
typedef struct {
- i810Region regs;
- int deviceID;
- int width;
- int height;
- int mem;
- int cpp;
- int stride;
- int fbOffset;
- int backOffset;
- int depthOffset;
- int textureOffset;
- int textureSize;
- __DRIscreenPrivate *driScrnPriv;
-} i810ScreenPrivate;
+ i810Region front;
+ i810Region back;
+ i810Region depth;
+ i810Region tex;
-typedef struct {
- volatile int *fifoPtr;
- volatile int *fifoRead;
- volatile int fifoOwner;
- volatile int ctxOwner;
- volatile int texOwner;
-} I810SAREAPriv;
+ int deviceID;
+ int width;
+ int height;
+ int mem;
+
+ int cpp; /* for front and back buffers */
+ int bitsPerPixel;
+
+ int fbFormat;
+ int fbOffset;
+ int fbStride;
+
+ int backOffset;
+ int depthOffset;
+
+ int backPitch;
+ int backPitchBits;
+ int textureOffset;
+ int textureSize;
+ int logTextureGranularity;
+ __DRIscreenPrivate *driScrnPriv;
+ drmBufMapPtr bufs;
+
+} i810ScreenPrivate;
#include "i810context.h"
-extern GLboolean i810MapAllRegions(__DRIscreenPrivate *driScrnPriv);
-extern void i810UnmapAllRegions(__DRIscreenPrivate *driScrnPriv);
-extern GLboolean i810InitHW(XMesaContext c);
-
-extern void XMesaWindowMoved(XMesaContext *c);
-extern void XMesaUpdateState(XMesaContext *c, int windowMoved);
-extern void XMesaSetSAREA(XMesaContext *c);
-
-extern XMesaContext gCC;
-extern i810ContextPtr i810Ctx;
-
-/*
-You can turn this on to find locking conflicts.
-#define DEBUG_LOCKING
-*/
-
-#ifdef DEBUG_LOCKING
-extern char *prevLockFile;
-extern int prevLockLine;
-#define DEBUG_LOCK() \
- do { \
- prevLockFile=(__FILE__); \
- prevLockLine=(__LINE__); \
- } while (0)
-#define DEBUG_RESET() \
- do { \
- prevLockFile=0; \
- prevLockLine=0; \
- } while (0)
-#define DEBUG_CHECK_LOCK() \
- do { \
- if (prevLockFile) { \
- fprintf(stderr, "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
- prevLockFile, prevLockLine, __FILE__, __LINE__); \
- exit(1); \
- } \
- } while (0)
-#else
-#define DEBUG_LOCK()
-#define DEBUG_RESET()
-#define DEBUG_CHECK_LOCK()
-#endif
+extern void i810GetLock( i810ContextPtr imesa, GLuint flags );
+extern void i810EmitHwStateLocked( i810ContextPtr imesa );
+extern void i810EmitScissorValues( i810ContextPtr imesa, int box_nr, int emit );
+extern void i810EmitDrawingRectangle( i810ContextPtr imesa );
+extern void i810XMesaSetBackClipRects( i810ContextPtr imesa );
+extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa );
-/* !!! We may want to separate locks from locks with validation.
- This could be used to improve performance for those things
- commands that do not do any drawing !!! */
-
-#define DRM_LIGHT_LOCK_RETURN(fd,lock,context,__ret) \
- do { \
- DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
- if (__ret) drmGetLock(fd,context,0); \
- } while(0)
-
-/* Lock the hardware using the global current context */
-#define LOCK_HARDWARE() \
- do { \
- int stamp; \
- char __ret=0; \
- __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \
- __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \
- DEBUG_CHECK_LOCK(); \
- DRM_LIGHT_LOCK_RETURN(sPriv->fd, &sPriv->pSAREA->lock, \
- dPriv->driContextPriv->hHWContext, __ret); \
- if (__ret) __ret=1; \
- stamp=dPriv->lastStamp; \
- XMESA_VALIDATE_DRAWABLE_INFO(gCC->display, sPriv, dPriv); \
- if (*(dPriv->pStamp)!=stamp) __ret=2; \
- if (__ret) XMesaUpdateState(gCC, __ret==2); \
- DEBUG_LOCK(); \
- } while (0)
-/* Unlock the hardware using the global current context */
-#define UNLOCK_HARDWARE() \
- do { \
- __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \
- __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; \
- XMesaSetSAREA(gCC); \
- DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, \
- dPriv->driContextPriv->hHWContext); \
- DEBUG_RESET(); \
- } while (0)
+#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE( imesa ) imesa->sarea->last_enqueue
-#define BEGIN_BOARD_LOCK() LOCK_HARDWARE()
-#define END_BOARD_LOCK() UNLOCK_HARDWARE()
-/*
- This pair of macros makes a loop over the drawing operations
- so it is not self contained and doesn't have the nice single
- statement semantics of most macros
-*/
-#define BEGIN_CLIP_LOOP() \
- do { \
- __DRIdrawablePrivate *dPriv = gCC->driContextPriv->driDrawablePriv; \
- int _nc = dPriv->numClipRects; \
- LOCK_HARDWARE(); \
- while (_nc--) { \
- if (i810Ctx->needClip) { \
- i810Ctx->clipMinX=dPriv->pClipRects[_nc].x1; \
- i810Ctx->clipMaxX=dPriv->pClipRects[_nc].x2; \
- i810Ctx->clipMinY=dPriv->pClipRects[_nc].y1; \
- i810Ctx->clipMaxY=dPriv->pClipRects[_nc].y2; \
- i810SetScissorValues(i810Ctx->glCtx); \
- }
-
-#define END_CLIP_LOOP() \
- } \
- UNLOCK_HARDWARE(); \
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( imesa ) \
+ do { \
+ char __ret=0; \
+ DRM_CAS(imesa->driHwLock, imesa->hHWContext, \
+ (DRM_LOCK_HELD|imesa->hHWContext), __ret); \
+ if (__ret) \
+ i810GetLock( imesa, 0 ); \
} while (0)
+
+
+/* Unlock the hardware using the global current context
+ */
+#define UNLOCK_HARDWARE(imesa) \
+ DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext);
+
+
+/* This is the wrong way to do it, I'm sure. Otherwise the drm
+ * bitches that I've already got the heavyweight lock. At worst,
+ * this is 3 ioctls. The best solution probably only gets me down
+ * to 2 ioctls in the worst case.
+ */
+#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \
+ LOCK_HARDWARE( imesa ); \
+ i810RegetLockQuiescent( imesa ); \
+} while(0)
+
+
#endif
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_inithw.c b/xc/lib/GL/mesa/src/drv/i810/i810_inithw.c
deleted file mode 100644
index 6bcae44c7..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810_inithw.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Daryll Strauss <daryll@precisioninsight.com>
- *
- * $PI: $
- */
-
-#ifdef GLX_DIRECT_RENDERING
-
-#include "i810_init.h"
-#include <glide.h>
-
-GLboolean i810InitHW(XMesaContext c)
-{
- /* KW: Would be nice to make one of these a member of the other.
- */
- i810ContextPtr cPriv = (i810ContextPtr)c->private;
- __DRIdrawablePrivate *driDrawPriv = c->driContextPriv->driDrawablePriv;
- __DRIscreenPrivate *driScrnPriv = driDrawPriv->driScreenPriv;
- i810ScreenPrivate *sPriv = (i810ScreenPrivate*)driScrnPriv->private;
-
-#ifdef DEBUG_LOCKING
- fprintf(stderr, "Debug locking enabled\n");
-#endif
-
- if (cPriv->initDone) return GL_TRUE;
-
- cPriv->width=driDrawPriv->w;
- cPriv->height=driDrawPriv->h;
-
- DRM_LIGHT_LOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock,
- driDrawPriv->driContextPriv->hHWContext);
- FX_grGlideInit_NoLock();
-
-
- if (sPriv->deviceID==0x3)
- cPriv->haveTwoTMUs=GL_FALSE;
- else
- cPriv->haveTwoTMUs=GL_TRUE;
-
- /* !!! We are forcing these !!! */
- cPriv->haveDoubleBuffer=GL_TRUE;
- cPriv->haveAlphaBuffer=GL_FALSE;
- cPriv->haveZBuffer=GL_TRUE;
- cPriv->haveGlobalPaletteTexture=GL_FALSE;
-
- cPriv->glideContext = FX_grSstWinOpen_NoLock((FxU32)-1, GR_RESOLUTION_NONE,
- GR_REFRESH_NONE,
- GR_COLORFORMAT_ARGB,
- GR_ORIGIN_LOWER_LEFT, 2, 1);
-
-
- grDRIResetSAREA();
-
- DRM_UNLOCK(driScrnPriv->fd, &driScrnPriv->pSAREA->lock,
- driDrawPriv->driContextPriv->hHWContext);
-
- cPriv->needClip=1;
-
- if (!fxDDInitFxMesaContext( fxMesa ))
- return GL_FALSE;
-
- cPriv->initDone=GL_TRUE;
- return GL_TRUE;
-
-}
-
-#endif
-
-
-
-
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
index d4b540507..7716b4634 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
@@ -27,21 +27,54 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
- * Daryll Strauss <daryll@precisioninsight.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
*
*/
#ifdef GLX_DIRECT_RENDERING
#include <X11/Xlibint.h>
-#include <glide.h>
+#include <stdio.h>
+
#include "i810_init.h"
#include "context.h"
#include "vbxform.h"
#include "matrix.h"
+#include "simple_list.h"
+
+#include "i810dd.h"
+#include "i810state.h"
+#include "i810tex.h"
+#include "i810span.h"
+#include "i810tris.h"
+#include "i810swap.h"
+#include "i810pipeline.h"
+#include "i810ioctl.h"
+
+#include "i810_dri.h"
+
+
+
+#ifndef I810_DEBUG
+int I810_DEBUG = (0
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_RING */
+/* | DEBUG_VERBOSE_OUTREG */
+/* | DEBUG_VERBOSE_MSG */
+/* | DEBUG_NO_OUTRING */
+/* | DEBUG_NO_OUTREG */
+/* | DEBUG_VERBOSE_API */
+/* | DEBUG_VERBOSE_2D */
+/* | DEBUG_VERBOSE_DRI */
+/* | DEBUG_VALIDATE_RING */
+/* | DEBUG_VERBOSE_IOCTL */
+ );
+#endif
+
+
+static i810ContextPtr i810Ctx = 0;
-XMesaContext gCC = 0;
-i810ContextPtr *i810Ctx = 0;
+i810Glx_t i810glx;
static int count_bits(unsigned int n)
{
@@ -76,32 +109,106 @@ static int count_bits(unsigned int n)
*/
-GLboolean XMesaInitDriver(__DRIscreenPrivate *driScrnPriv)
+GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
{
- i810ScreenPrivate *gsp;
+ i810ScreenPrivate *i810Screen;
+ I810DRIPtr gDRIPriv = (I810DRIPtr)sPriv->pDevPriv;
/* Allocate the private area */
- gsp = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate));
- if (!gsp) return GL_FALSE;
+ i810Screen = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate));
+ if (!i810Screen) return GL_FALSE;
+
+ i810Screen->driScrnPriv = sPriv;
+ sPriv->private = (void *)i810Screen;
+
+ i810Screen->deviceID=gDRIPriv->deviceID;
+ i810Screen->width=gDRIPriv->width;
+ i810Screen->height=gDRIPriv->height;
+ i810Screen->mem=gDRIPriv->mem;
+ i810Screen->cpp=gDRIPriv->cpp;
+ i810Screen->fbStride=gDRIPriv->fbStride;
+ i810Screen->fbOffset=gDRIPriv->fbOffset;
+
+ if (gDRIPriv->bitsPerPixel == 15)
+ i810Screen->fbFormat = DV_PF_555;
+ else
+ i810Screen->fbFormat = DV_PF_565;
+
+ i810Screen->backOffset=gDRIPriv->backOffset;
+ i810Screen->depthOffset=gDRIPriv->depthOffset;
+ i810Screen->backPitch = gDRIPriv->auxPitch;
+ i810Screen->backPitchBits = gDRIPriv->auxPitchBits;
+ i810Screen->textureOffset=gDRIPriv->textureOffset;
+ i810Screen->textureSize=gDRIPriv->textureSize;
+ i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+
+ if (1)
+ fprintf(stderr, "Tex heap size %x, granularity %x bytes\n",
+ i810Screen->textureSize, 1<<(i810Screen->logTextureGranularity));
+
+ i810Screen->bufs = drmMapBufs(sPriv->fd);
+
+
+ i810Screen->back.handle = gDRIPriv->backbuffer;
+ i810Screen->back.size = gDRIPriv->backbufferSize;
+
+ if (drmMap(sPriv->fd,
+ i810Screen->back.handle,
+ i810Screen->back.size,
+ (drmAddress *)&i810Screen->back.map) != 0)
+ {
+ Xfree(i810Screen);
+ return GL_FALSE;
+ }
+
+ i810Screen->depth.handle = gDRIPriv->depthbuffer;
+ i810Screen->depth.size = gDRIPriv->depthbufferSize;
- gsp->driScrnPriv = driScrnPriv;
+ if (drmMap(sPriv->fd,
+ i810Screen->depth.handle,
+ i810Screen->depth.size,
+ (drmAddress *)&i810Screen->depth.map) != 0)
+ {
+ Xfree(i810Screen);
+ return GL_FALSE;
+ }
- driScrnPriv->private = (void *)gsp;
+ i810Screen->tex.handle = gDRIPriv->textures;
+ i810Screen->tex.size = gDRIPriv->textureSize;
- if (!i810MapAllRegions(driScrnPriv)) {
- Xfree(driScrnPriv->private);
+ if (drmMap(sPriv->fd,
+ i810Screen->tex.handle,
+ i810Screen->tex.size,
+ (drmAddress *)&i810Screen->tex.map) != 0)
+ {
+ Xfree(i810Screen);
return GL_FALSE;
}
+
+ /* Ditch i810glx in favor of i810Screen?
+ */
+ memset(&i810glx, 0, sizeof(i810glx));
+ i810glx.texVirtual = i810Screen->tex.map;
+
+ i810DDFastPathInit();
+ i810DDTrifuncInit();
+ i810DDSetupInit();
+
return GL_TRUE;
}
/* Accessed by dlsym from dri_mesa_init.c
*/
-void XMesaResetDriver(__DRIscreenPrivate *driScrnPriv)
+void XMesaResetDriver(__DRIscreenPrivate *sPriv)
{
- i810UnmapAllRegions(driScrnPriv); /* in i810_init.c */
- Xfree(driScrnPriv->private);
+ i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+
+ /* Need to unmap all the bufs and maps here:
+ */
+
+
+ Xfree(i810Screen);
}
/* Accessed by dlsym from dri_mesa_init.c
@@ -135,27 +242,18 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
v->display = display;
v->level = level;
-
- v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual));
+ v->gl_visual = gl_create_visual(rgb_flag, GL_FALSE, db_flag, stereo_flag,
+ depth_size, stencil_size, accum_size, 0,
+ count_bits(visinfo->red_mask),
+ count_bits(visinfo->green_mask),
+ count_bits(visinfo->blue_mask),
+ GL_FALSE);
if (!v->gl_visual) {
Xfree(v->visinfo);
- XFree(v);
- return 0;
+ Xfree(v);
+ return NULL;
}
-
- v->gl_visual->RGBAflag = rgb_flag;
- v->gl_visual->DBflag = db_flag;
- v->gl_visual->StereoFlag = stereo_flag;
-
- v->gl_visual->RedBits = count_bits(visinfo->red_mask);
- v->gl_visual->GreenBits = count_bits(visinfo->green_mask);
- v->gl_visual->BlueBits = count_bits(visinfo->blue_mask);
- v->gl_visual->AlphaBits = 0; /* Not currently supported */
-
- v->gl_visual->AccumBits = accum_size;
- v->gl_visual->DepthBits = depth_size;
- v->gl_visual->StencilBits = stencil_size;
-
+
return v;
}
@@ -169,71 +267,143 @@ void XMesaDestroyVisual(XMesaVisual v)
XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
__DRIcontextPrivate *driContextPriv)
{
+ GLcontext *ctx;
XMesaContext c;
- i810ContextPtr cPriv;
- __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
- i810ScreenPrivate *sPriv = (i810ScreenPrivate *)driScrnPriv->private;
- I810SAREAPriv *saPriv;
- GLcontext *shareCtx;
-/* int **fifoPtr; */
+ i810ContextPtr imesa;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
+ drm_i810_sarea_t *saPriv=(drm_i810_sarea_t *)(((char*)sPriv->pSAREA)+
+ sizeof(XF86DRISAREARec));
+
+ GLcontext *shareCtx = 0;
c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context));
- if (!c) return 0;
+ if (!c) {
+ return 0;
+ }
+
+ imesa = (i810ContextPtr)Xcalloc(sizeof(i810Context), 1);
+ if (!imesa) {
+ Xfree(c);
+ return 0;
+ }
c->driContextPriv = driContextPriv;
c->xm_visual = v;
c->xm_buffer = 0; /* Set by MakeCurrent */
c->display = v->display;
+ c->private = (void *)imesa;
- cPriv = (i810ContextPtr)Xmalloc(sizeof(i810Context));
- if (!cPriv) {
- Xfree(c);
- return NULL;
- }
+ if (share_list)
+ shareCtx=((i810ContextPtr)(share_list->private))->glCtx;
- cPriv->hHWContext = driContextPriv->hHWContext;
- cPriv->i810ScrnPriv = sPriv;
- c->private = (void *)cPriv;
+ ctx = imesa->glCtx = gl_create_context(v->gl_visual, shareCtx,
+ (void*)imesa, GL_TRUE);
- cPriv->glVis=v->gl_visual;
- cPriv->glBuffer=gl_create_framebuffer(v->gl_visual);
- cPriv->screen_width=sPriv->width;
- cPriv->screen_height=sPriv->height;
- cPriv->new_state = ~0;
+ /* Set the maximum texture size small enough that we can guarentee
+ * that both texture units can bind a maximal texture and have them
+ * in memory at once.
+ */
+ if (i810Screen->textureSize < 2*1024*1024) {
+ ctx->Const.MaxTextureLevels = 8;
+ ctx->Const.MaxTextureSize = 1<<8;
+ } else if (i810Screen->textureSize < 8*1024*1024) {
+ ctx->Const.MaxTextureLevels = 9;
+ ctx->Const.MaxTextureSize = 1<<9;
+ } else {
+ ctx->Const.MaxTextureLevels = 10;
+ ctx->Const.MaxTextureSize = 1<<10;
+ }
- if (share_list)
- shareCtx=((i810ContextPtr)(share_list->private))->glCtx;
- else
- shareCtx=0;
- cPriv->glCtx=gl_create_context(v->gl_visual, shareCtx, (void*)cPriv, GL_TRUE);
- cPriv->initDone=GL_FALSE;
- saPriv=(I810SAREAPriv*)((void*)driScrnPriv->pSAREA+sizeof(XF86DRISAREARec));
+ /* Dri stuff
+ */
+ imesa->display = v->display;
+ imesa->hHWContext = driContextPriv->hHWContext;
+ imesa->driFd = sPriv->fd;
+ imesa->driHwLock = &sPriv->pSAREA->lock;
+ imesa->i810Screen = i810Screen;
+ imesa->driScreen = sPriv;
+ imesa->sarea = saPriv;
- fprintf(stderr, "would call grDRIOpen here\n");
+ imesa->glBuffer = gl_create_framebuffer(v->gl_visual,
+ GL_FALSE,
+ v->gl_visual->StencilBits > 0,
+ v->gl_visual->AccumBits > 0,
+ v->gl_visual->AlphaBits > 0);
-/*
- grDRIOpen(driScrnPriv->pFB, sPriv->regs.map, sPriv->deviceID,
- sPriv->width, sPriv->height, sPriv->mem, sPriv->cpp, sPriv->stride,
- sPriv->fifoOffset, sPriv->fifoSize, sPriv->fbOffset,
- sPriv->backOffset, sPriv->depthOffset, sPriv->textureOffset,
- sPriv->textureSize, &saPriv->fifoPtr, &saPriv->fifoRead);
-*/
+ imesa->texHeap = mmInit( 0, i810Screen->textureSize );
+
+
+ /* Utah stuff
+ */
+ imesa->renderindex = -1; /* impossible value */
+ imesa->new_state = ~0;
+ imesa->dirty = ~0;
+
+ make_empty_list(&imesa->TexObjList);
+ make_empty_list(&imesa->SwappedOut);
+
+ imesa->TextureMode = ctx->Texture.Unit[0].EnvMode;
+ imesa->CurrentTexObj[0] = 0;
+ imesa->CurrentTexObj[1] = 0;
+
+ i810DDExtensionsInit( ctx );
+
+ i810DDInitStateFuncs( ctx );
+ i810DDInitTextureFuncs( ctx );
+ i810DDInitSpanFuncs( ctx );
+ i810DDInitDriverFuncs( ctx );
+ i810DDInitIoctlFuncs( ctx );
+
+ ctx->Driver.TriangleCaps = (DD_TRI_CULL|
+ DD_TRI_LIGHT_TWOSIDE|
+ DD_TRI_STIPPLE|
+ DD_TRI_OFFSET);
+
+ /* Ask mesa to clip fog coordinates for us.
+ */
+ ctx->TriangleCaps |= DD_CLIP_FOG_COORD;
+
+ ctx->Shared->DefaultD[2][0].DriverData = 0;
+ ctx->Shared->DefaultD[2][1].DriverData = 0;
+
+ if (ctx->VB)
+ i810DDRegisterVB( ctx->VB );
+
+ if (ctx->NrPipelineStages)
+ ctx->NrPipelineStages =
+ i810DDRegisterPipelineStages(ctx->PipelineStage,
+ ctx->PipelineStage,
+ ctx->NrPipelineStages);
+
+ i810DDInitState( imesa );
return c;
}
void XMesaDestroyContext(XMesaContext c)
{
- i810ContextPtr cPriv;
+ i810ContextPtr imesa = (i810ContextPtr) c->private;
+
+ if (imesa) {
+ i810TextureObjectPtr next_t, t;
- cPriv=(i810ContextPtr)c->private;
- if (cPriv) {
- gl_destroy_context(cPriv->glCtx);
- gl_destroy_framebuffer(cPriv->glBuffer);
+ gl_destroy_context(imesa->glCtx);
+ gl_destroy_framebuffer(imesa->glBuffer);
+
+ foreach_s (t, next_t, &(imesa->TexObjList))
+ i810DestroyTexObj(imesa, t);
+
+ foreach_s (t, next_t, &(imesa->SwappedOut))
+ i810DestroyTexObj(imesa, t);
+
+ Xfree(imesa);
+
+ c->private = 0;
}
}
@@ -254,137 +424,232 @@ void XMesaDestroyBuffer(XMesaBuffer b)
{
}
-void XMesaSwapBuffers(XMesaBuffer b)
+void XMesaSwapBuffers(XMesaBuffer bogus)
{
- FxI32 result;
- XMesaContext *xmc = b->xm_context;
- i810ContextPtr imesa;
-
- if (!xmc || !xmc->private) return;
+ i810ContextPtr imesa = i810Ctx;
- imesa = (i810ContextPtr) xmc->private;
+ FLUSH_VB( imesa->glCtx, "swap buffers" );
+ i810SwapBuffers(imesa);
+}
+
+static void i810InitClipRects( i810ContextPtr imesa )
+{
+ switch (imesa->numClipRects) {
+ case 0:
+ imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR );
+ imesa->ClipSetup[I810_CLIPREG_SCI1] = 0;
+ imesa->ClipSetup[I810_CLIPREG_SCI2] = 0;
+ break;
+ case 1:
+ break;
+ default:
+ break;
+ }
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+}
- fprintf(stderr, "imesa %x i810Ctx %x\n", imesa, i810Ctx );
- FLUSH_VB( imesa->glCtx, "swap buffers" );
- if (imesa->haveDoubleBuffer) {
- i810BackToFront(imesa);
- i810Ctx->stats.swapBuffer++;
+void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+ imesa->numClipRects = dPriv->numClipRects;
+ imesa->pClipRects = dPriv->pClipRects;
+ imesa->drawX = dPriv->x;
+ imesa->drawY = dPriv->y;
+
+ imesa->drawMap = imesa->driScreen->pFB;
+ i810EmitDrawingRectangle( imesa );
+ i810InitClipRects( imesa );
+}
+
+
+void i810XMesaSetBackClipRects( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ int i;
+
+ if (dPriv->numBackClipRects == 0)
+ {
+ if (I810_DEBUG & DEBUG_VERBOSE_DRI)
+ fprintf(stderr, "FRONT_CLIPRECTS, %d rects\n",
+ dPriv->numClipRects);
+
+ imesa->numClipRects = dPriv->numClipRects;
+ imesa->pClipRects = dPriv->pClipRects;
+ imesa->drawX = dPriv->x;
+ imesa->drawY = dPriv->y;
} else {
- fprintf(stderr, "No double buffer\n");
+ if (I810_DEBUG & DEBUG_VERBOSE_DRI)
+ fprintf(stderr, "BACK_RECTS, %d rects\n",
+ dPriv->numBackClipRects);
+
+ imesa->numClipRects = dPriv->numBackClipRects;
+ imesa->pClipRects = dPriv->pBackClipRects;
+ imesa->drawX = dPriv->backX;
+ imesa->drawY = dPriv->backY;
}
+
+ imesa->drawMap = imesa->i810Screen->back.map;
+ i810EmitDrawingRectangle( imesa );
+ i810InitClipRects( imesa );
+
+ if (I810_DEBUG & DEBUG_VERBOSE_DRI)
+ for (i = 0 ; i < imesa->numClipRects ; i++)
+ fprintf(stderr, "cliprect %d: %d,%d - %d,%d\n",
+ i,
+ imesa->pClipRects[i].x1,
+ imesa->pClipRects[i].y1,
+ imesa->pClipRects[i].x2,
+ imesa->pClipRects[i].y2);
+}
+
+
+static void i810XMesaWindowMoved( i810ContextPtr imesa )
+{
+ if (0)
+ fprintf(stderr, "i810XMesaWindowMoved\n\n");
+
+ switch (imesa->glCtx->Color.DriverDrawBuffer) {
+ case GL_FRONT_LEFT:
+ i810XMesaSetFrontClipRects( imesa );
+ break;
+ case GL_BACK_LEFT:
+ i810XMesaSetBackClipRects( imesa );
+ break;
+ default:
+ fprintf(stderr, "fallback buffer\n");
+ break;
+ }
+}
+
+
+GLboolean XMesaUnbindContext(XMesaContext c)
+{
+ if (c->private)
+ ((i810ContextPtr)c->private)->dirty = ~0;
+
+ return GL_TRUE;
}
-/* This looks buggy to me:
+
+/* This looks buggy to me - the 'b' variable isn't used anywhere...
+ * Hmm - It seems that the drawable is already hooked in to
+ * driDrawablePriv.
*/
GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
{
- __DRIdrawablePrivate *driDrawPriv;
+
+ if (c->private==(void *)i810Ctx) return GL_TRUE;
if (c) {
- if (c==gCC) return GL_TRUE;
- gCC = c;
- i810Ctx = (i810ContextPtr)c->private;
+ __DRIdrawablePrivate *dPriv = c->driContextPriv->driDrawablePriv;
- fprintf(stderr, "Make current\n");
- driDrawPriv = c->driContextPriv->driDrawablePriv;
- if (!i810Ctx->initDone) {
- i810Ctx->width=driDrawPriv->w;
- i810Ctx->height=driDrawPriv->h;
- if (!i810InitHW(c)) return GL_FALSE;
- /* Zap the width to force XMesaWindowMoved to execute */
- i810Ctx->width=0;
- }
- FX_grSstSelect(i810Ctx->board);
- XMesaWindowMoved();
+ i810Ctx = (i810ContextPtr)c->private;
- FX_grGlideSetState((GrState*)i810Ctx->state);
gl_make_current(i810Ctx->glCtx, i810Ctx->glBuffer);
- fxSetupDDPointers(i810Ctx->glCtx);
+
+ i810Ctx->driDrawable = dPriv;
+ i810Ctx->dirty = ~0;
+
+ i810XMesaWindowMoved( i810Ctx );
+
if (!i810Ctx->glCtx->Viewport.Width)
- gl_Viewport(i810Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h);
+ gl_Viewport(i810Ctx->glCtx, 0, 0, dPriv->w, dPriv->h);
+
} else {
gl_make_current(0,0);
- gCC = NULL;
i810Ctx = NULL;
}
return GL_TRUE;
}
-void i810XMesaWindowMoved( XMesaContext xmc )
+
+void i810GetLock( i810ContextPtr imesa, GLuint flags )
{
- i810ContextPtr imesa = (i810ContextPtr) xmc->private;
- __DRIdrawablePrivate *dPriv = xmc->driContextPriv->driDrawablePriv;
- GLcontext *ctx=imesa->glCtx;
-
-/* grDRIPosition(dPriv->x, dPriv->y, dPriv->w, dPriv->h, */
-/* dPriv->numClipRects, dPriv->pClipRects); */
-
-
- imesa->numClipRects=dPriv->numClipRects;
- imesa->pClipRects=dPriv->pClipRects;
- if (dPriv->x!=imesa->x_offset || dPriv->y!=imesa->y_offset ||
- dPriv->w!=imesa->width || dPriv->h!=imesa->height) {
- imesa->x_offset=dPriv->x;
- imesa->y_offset=dPriv->y;
- imesa->width=dPriv->w;
- imesa->height=dPriv->h;
- imesa->y_delta=imesa->screen_height-imesa->y_offset-imesa->height;
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ __DRIscreenPrivate *sPriv = imesa->driScreen;
+ drm_i810_sarea_t *sarea = imesa->sarea;
+ int me = imesa->hHWContext;
+ int stamp = dPriv->lastStamp;
+
+
+ if (0) fprintf(stderr, ".\n");
+
+ /* We know there has been contention.
+ */
+ drmGetLock(imesa->driFd, imesa->hHWContext, flags);
+
+
+ /* Note contention for throttling hint
+ */
+ imesa->any_contend = 1;
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ XMESA_VALIDATE_DRAWABLE_INFO(imesa->display, sPriv, dPriv);
+
+
+ if (0)
+ fprintf(stderr, "i810GetLock, last enque: %d last dispatch: %d\n",
+ sarea->last_enqueue,
+ sarea->last_dispatch);
+
+ /* If we lost context, need to dump all registers to hardware.
+ * Note that we don't care about 2d contexts, even if they perform
+ * accelerated commands, so the DRI locking in the X server is even
+ * more broken than usual.
+ */
+ if (sarea->ctxOwner != me) {
+ i810glx.c_ctxlost++;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+ sarea->ctxOwner = me;
}
- switch (dPriv->numClipRects) {
- case 0:
- imesa->clipMinX=dPriv->x;
- imesa->clipMaxX=dPriv->x+dPriv->w;
- imesa->clipMinY=dPriv->y;
- imesa->clipMaxY=dPriv->y+dPriv->h;
- fxSetScissorValues(ctx);
- imesa->needClip=0;
- break;
- case 1:
- imesa->clipMinX=dPriv->pClipRects[0].x1;
- imesa->clipMaxX=dPriv->pClipRects[0].x2;
- imesa->clipMinY=dPriv->pClipRects[0].y1;
- imesa->clipMaxY=dPriv->pClipRects[0].y2;
- fxSetScissorValues(ctx);
- imesa->needClip=0;
- break;
- default:
- imesa->needClip=1;
- }
-}
-void i810XMesaUpdateState(XMesaContext *xmc, int windowMoved) {
- __DRIdrawablePrivate *dPriv = xmc->driContextPriv->driDrawablePriv;
- __DRIscreenPrivate *sPriv = dPriv->driScreenPriv;
- I810SAREAPriv *saPriv=(I810SAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec));
-
- /* fprintf(stderr, "In FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */
- if (saPriv->fifoOwner!=dPriv->driContextPriv->hHWContext) {
- grDRIImportFifo(saPriv->fifoPtr, saPriv->fifoRead);
- }
- if (saPriv->ctxOwner!=dPriv->driContextPriv->hHWContext) {
- grDRIInvalidateAll();
- /* This shouldn't be needed if the state is reset by Glide */
- /* FX_grConstantColorValue_NoLock(FXCOLOR4(&i810Ctx->constColor)); */
- }
- if (saPriv->texOwner!=dPriv->driContextPriv->hHWContext) {
- fxTMRestoreTextures(i810Ctx);
- }
- if (windowMoved)
- XMesaWindowMoved( xmc );
-}
+ /* Shared texture managment - if another client has played with
+ * texture space, figure out which if any of our textures have been
+ * ejected, and update our global LRU.
+ */
+ if (sarea->texAge != imesa->texAge) {
+ int sz = 1 << (imesa->i810Screen->logTextureGranularity);
+ int idx, nr = 0;
+
+ /* Have to go right round from the back to ensure stuff ends up
+ * LRU in our local list...
+ */
+ for (idx = sarea->texList[I810_NR_TEX_REGIONS].prev ;
+ idx != I810_NR_TEX_REGIONS && nr < I810_NR_TEX_REGIONS ;
+ idx = sarea->texList[idx].prev, nr++)
+ {
+ if (sarea->texList[idx].age > imesa->texAge)
+ i810TexturesGone(imesa, idx * sz, sz, sarea->texList[idx].in_use);
+ }
-void i810XMesaSetSAREA( XMesaContext *xmc ) {
- __DRIdrawablePrivate *dPriv = xmc->driContextPriv->driDrawablePriv;
- __DRIscreenPrivate *sPriv = dPriv->driScreenPriv;
- I810SAREAPriv *saPriv=(I810SAREAPriv*)(((char*)sPriv->pSAREA)+sizeof(XF86DRISAREARec));
+ if (nr == I810_NR_TEX_REGIONS) {
+ i810TexturesGone(imesa, 0, imesa->i810Screen->textureSize, 0);
+ i810ResetGlobalLRU( imesa );
+ }
+
+ if (0) fprintf(stderr, "imesa %d sarea %d\n", imesa->texAge, sarea->texAge);
+ imesa->dirty |= I810_UPLOAD_TEX0IMAGE;
+ imesa->dirty |= I810_UPLOAD_TEX1IMAGE;
+ imesa->texAge = sarea->texAge;
+ }
- saPriv->fifoOwner=dPriv->driContextPriv->hHWContext;
- saPriv->ctxOwner=dPriv->driContextPriv->hHWContext;
- saPriv->texOwner=dPriv->driContextPriv->hHWContext;
- grDRIResetSAREA();
- /* fprintf(stderr, "Out FifoPtr=%d FifoRead=%d\n", saPriv->fifoPtr, saPriv->fifoRead); */
+
+ if (dPriv->lastStamp != stamp)
+ i810XMesaWindowMoved( imesa );
+
+
+ sarea->last_quiescent = -1; /* just kill it for now */
}
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810buf.h b/xc/lib/GL/mesa/src/drv/i810/i810buf.h
deleted file mode 100644
index e72b0f225..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810buf.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * GLX Hardware Device Driver for Intel 810
- * Copyright (C) 1999 Keith Whitwell
- *
- * 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 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
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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.
- *
- * Keith Whitwell <keithw@precisioninsight.com>
- *
- * based on matrox driver by
- * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de>
- * and others.
- */
-
-#ifndef I810BUF_INC
-#define I810BUF_INC
-
-#include "i810common.h"
-#include "i810_3d_reg.h"
-#include "types.h"
-#include "mm.h"
-
-#define VALID_I810_BUFFER(b) (b)
-
-
-struct i810_dest_buffer
-{
- int refcount;
- PMemBlock MemBlock;
- GLuint Setup[I810_DEST_SETUP_SIZE];
-
- int Format;
- int Width; /* in pixels */
- int Height;
- int Pitch;
- int BytesPerPixel;
- int Size;
- int Drawable;
- char *BufAddr;
- struct i810_z_buffer *ZBuffer;
-};
-
-struct i810_z_buffer
-{
- int refcount;
- PMemBlock MemBlock;
-
- int Format;
- char *BufAddr;
-
- int Pitch;
-};
-
-
-
-/* Don't bother trying to hide the differences between these types of
- * buffer.
- */
-struct i810_dest_buffer *i810CreateDestBuffer(int Format,
- int Width,
- int Height);
-void i810DestroyDestBuffer(struct i810_dest_buffer *buf);
-
-
-
-/* Parent is a dest-buffer, supplies geometry info.
- */
-struct i810_z_buffer *i810CreateZBuffer( struct i810_dest_buffer *parent );
-void i810FreeZBuffer(struct i810_z_buffer *buf);
-
-
-
-
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.c b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
index 3749b9659..f6e74beb8 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810clear.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
@@ -1,144 +1,145 @@
-#include "xsmesaP.h"
-#include "mesaglx/types.h"
+#include "types.h"
#include "vbrender.h"
-#include "glx_log.h"
-
-#include "vga.h"
-#include "vgaPCI.h"
+#include "i810log.h"
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include "mm.h"
#include "i810lib.h"
#include "i810dd.h"
-#include "i810glx.h"
#include "i810clear.h"
#include "i810state.h"
#include "i810tris.h"
+#include "i810ioctl.h"
+
+#define DEPTH_SCALE 65535.0F
+
+static void i810_clear_buffer( GLcontext *ctx,
+ GLboolean all,
+ GLint cx, GLint cy,
+ GLint cwidth,
+ GLint cheight,
+ GLushort value,
+ GLuint offset )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+
+ int _nc = imesa->numClipRects;
+ XF86DRIClipRectPtr box = imesa->pClipRects;
+
+ cy = dPriv->h-cy-cheight;
+ cx += imesa->drawX;
+ cy += imesa->drawY;
+
+ while (_nc--) {
+ GLint x = box[_nc].x1;
+ GLint y = box[_nc].y1;
+ GLint width = box[_nc].x2 - x;
+ GLint height = box[_nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) width -= cx - x, x = cx;
+ if (y < cy) height -= cy - y, y = cy;
+ if (x + width > cx + cwidth) width = cx + cwidth - x;
+ if (y + height > cy + cheight) height = cy + cheight - y;
+ if (width <= 0) continue;
+ if (height <= 0) continue;
+ }
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "clear color rect %d,%d %dx%d\n",
+ (int) x, (int) y, (int) width, (int) height);
+
+
+ {
+ int start = (offset +
+ y * i810Screen->backPitch +
+ x * i810Screen->cpp);
+
+ BEGIN_BATCH( imesa, 6 );
+
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810Screen->backPitch );
+ OUT_BATCH( (height << 16) | (width * i810Screen->cpp));
+ OUT_BATCH( start );
+ OUT_BATCH( value );
+ OUT_BATCH( 0 );
+
+ ADVANCE_BATCH();
+ }
+ }
+}
+
/*
* i810Clear
- * perform hardware accelerated clearing of the color and/or depth
- * buffer. Software may still clear stencil buffers.
- * If all==GL_TRUE, clear whole buffer, else just clear region defined
- * by x,y,width,height
+ *
+ * Clear the color and/or depth buffers. If 'all' is GL_TRUE, clear
+ * whole buffer, otherwise clear the region defined by the remaining
+ * parameters.
*/
-
-
GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
- GLint x, GLint y, GLint width, GLint height )
+ GLint cx, GLint cy, GLint cwidth, GLint cheight )
{
- XSMesaContext xsmesa = (XSMesaContext) ctx->DriverCtx;
- GLubyte *c;
- GLuint zval;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
- i810Msg(10, "i810Clear( %i, %i, %i, %i, %i )\n",
- mask, x, y, width, height );
+ if (I810_DEBUG&DEBUG_VERBOSE_API)
+ fprintf(stderr, "i810Clear( %d, %d, %d, %d, %d )\n",
+ (int)mask, (int)cx, (int)cy, (int)cwidth, (int)cheight );
- CHECK_CONTEXT( return mask; );
-
- if (all == GL_TRUE) {
- x = 0;
- y = 0;
- width = i810DB->Width;
- height = i810DB->Height;
- }
-
- if ( y + height > i810DB->Height ) {
- height = i810DB->Height - y;
- }
- if ( x + width > i810DB->Width ) {
- width = i810DB->Width - x;
- }
- if ( x < 0 ) {
- width += x;
- x = 0;
- }
- if ( y < 0 ) {
- height += y;
- y = 0;
- }
- if ( x >= i810DB->Width || y >= i810DB->Height || width < 1 || height < 1 ) {
- return 0;
- }
-
- /* flip top to bottom */
- y = i810DB->Height-y-height;
- c = xsmesa->clearcolor;
- zval = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
-
- i810FinishPrimitive();
+ FLUSH_BATCH(imesa);
+
+ LOCK_HARDWARE(imesa);
+ i810GetGeneralDmaBufferLocked( imesa );
- if (1)
{
- BEGIN_BATCH(2);
+ BEGIN_BATCH( imesa, 2 );
OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
- OUT_BATCH( 0 ); /* pad to quadword */
+ OUT_BATCH( 0 );
ADVANCE_BATCH();
}
- /* color buffer */
- if (mask & GL_COLOR_BUFFER_BIT)
- {
- int start = (i810DB->MemBlock->ofs +
- y * i810DB->Pitch +
- x * vgaBytesPerPixel);
-
- BEGIN_BATCH(6);
-
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
- OUT_BATCH( BR13_SOLID_PATTERN |
- (0xF0 << 16) |
- i810DB->Pitch );
- OUT_BATCH( (height << 16) | (width * vgaBytesPerPixel));
- OUT_BATCH( start );
- OUT_BATCH( i810PackColor( i810DB->Format, c[0], c[1], c[2], c[3] ) );
- OUT_BATCH( 0 );
-
- ADVANCE_BATCH();
-
- mask &= ~GL_COLOR_BUFFER_BIT;
+ if ( (mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
+ i810_clear_buffer( ctx, all, cx, cy, cwidth, cheight,
+ imesa->ClearColor,
+ imesa->i810Screen->fbOffset);
+ mask &= ~DD_FRONT_LEFT_BIT;
}
- /* depth buffer */
- if ( (mask & GL_DEPTH_BUFFER_BIT) &&
- i810DB->ZBuffer &&
- ctx->Depth.Mask )
- {
- int start = (i810DB->ZBuffer->MemBlock->ofs +
- y * i810DB->ZBuffer->Pitch +
- x * 2);
-
- BEGIN_BATCH(6);
-
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
- OUT_BATCH( BR13_SOLID_PATTERN |
- (0xF0 << 16) |
- i810DB->ZBuffer->Pitch );
- OUT_BATCH( (height << 16) | (width * 2));
- OUT_BATCH( start );
- OUT_BATCH( zval );
- OUT_BATCH( 0 );
-
- ADVANCE_BATCH();
-
- mask &= ~GL_DEPTH_BUFFER_BIT;
+ if ( (mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
+ i810_clear_buffer( ctx, all, cx, cy, cwidth, cheight,
+ imesa->ClearColor,
+ imesa->i810Screen->backOffset);
+ mask &= ~DD_BACK_LEFT_BIT;
}
- if (1)
+ if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) {
+ i810_clear_buffer( ctx, all, cx, cy, cwidth, cheight,
+ ctx->Depth.Clear * DEPTH_SCALE,
+ imesa->i810Screen->depthOffset);
+ mask &= ~DD_DEPTH_BIT;
+ }
+
{
- BEGIN_BATCH(2);
+ BEGIN_BATCH( imesa, 2 );
OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
- OUT_BATCH( 0 ); /* pad to quadword */
+ OUT_BATCH( 0 );
ADVANCE_BATCH();
}
+ i810FlushGeneralLocked(imesa);
+ UNLOCK_HARDWARE( imesa );
return mask;
}
-
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.c b/xc/lib/GL/mesa/src/drv/i810/i810context.c
deleted file mode 100644
index a9bd855d5..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810context.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * GLX Hardware Device Driver for Intel i810
- * Copyright (C) 1999 Keith Whitwell
- *
- * 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 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
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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 "xsmesaP.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <GL/gl.h>
-
-#include "i810context.h"
-#include "i810lib.h"
-#include "i810log.h"
-#include "i810dd.h"
-#include "i810pipeline.h"
-/* #include "i810render.h" */
-#include "i810state.h"
-#include "i810tris.h"
-#include "simple_list.h"
-
-
-
-i810ContextPtr i810CreateContext(GLcontext *ctx)
-{
- i810ContextPtr c;
-
- c = (i810ContextPtr) calloc(1,sizeof(i810Context));
- if (!c)
- return NULL;
-
- c->gl_ctx = ctx;
-
- c->renderindex = -1; /* impossible value */
- c->new_state = ~0;
- c->reg_dirty = ~0;
-
- make_empty_list(&c->SwappedOut);
- make_empty_list(&c->TexObjList);
-
- c->TextureMode = ctx->Texture.Unit[0].EnvMode;
-
- c->CurrentTex0Obj = 0;
- c->CurrentTex1Obj = 0;
- ctx->Shared->DefaultD[2][0].DriverData = 0;
- ctx->Shared->DefaultD[2][1].DriverData = 0;
-
- if (ctx->VB)
- i810DDRegisterVB( ctx->VB );
-
- if (ctx->NrPipelineStages)
- ctx->NrPipelineStages =
- i810DDRegisterPipelineStages(ctx->PipelineStage,
- ctx->PipelineStage,
- ctx->NrPipelineStages);
-
-
- /* Ask mesa to clip fog coordinates for us.
- */
- ctx->TriangleCaps |= DD_CLIP_FOG_COORD;
-
-
-#if 0
- if (!getenv("I810_NO_FAST_PATH"))
- ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline;
-
- i810DDRenderInit();
- i810DDFastPathInit();
-#endif
-
-
- i810DDTrifuncInit();
- i810DDSetupInit();
- i810DDExtensionsInit( ctx );
-
- i810_setup_DD_pointers( ctx );
- i810DDInitState( c );
-
- if (MESA_VERBOSE&VERBOSE_DRIVER)
- fprintf(stderr,"i810CreateContext(): successful.\n");
-
- return c;
-}
-
-int i810DestroyContext(i810ContextPtr ctx)
-{
- i810TextureObjectPtr next_t, t;
-
- if (!ctx)
- return 0;
-
- if (--(ctx->refcount) > 0)
- return 0;
-
- foreach_s (t, next_t, &(ctx->TexObjList))
- i810DestroyTexObj(ctx, t);
-
- foreach_s (t, next_t, &(ctx->SwappedOut))
- i810DestroyTexObj(ctx, t);
-
- free(ctx);
-
- if (MESA_VERBOSE&VERBOSE_DRIVER)
- fprintf(stderr,"i810DestroyContext(): successfully destroyed.\n");
-
- return 0;
-}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h
index 754a0e3f1..6a7ffa968 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810context.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h
@@ -26,60 +26,82 @@
#ifndef I810CONTEXT_INC
#define I810CONTEXT_INC
+typedef struct i810_context_t i810Context;
+typedef struct i810_context_t *i810ContextPtr;
+
+#include <X11/Xlibint.h>
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+#include "dri_mesa.h"
+#include "xmesaP.h"
-#include "mesaglx/types.h"
+#include "types.h"
+#include "i810_init.h"
+#include "drm.h"
-#include "i810common.h"
-#include "i810buf.h"
#include "i810tex.h"
#include "i810vb.h"
-#include "xsmesaP.h"
-/* Hmmm */
-#define FALLBACK_TEXTURE 1
+
+#define I810_FALLBACK_TEXTURE 0x1
+#define I810_FALLBACK_DRAW_BUFFER 0x2
+#define I810_FALLBACK_READ_BUFFER 0x4
+#define I810_FALLBACK_COLORMASK 0x8
+#define I810_FALLBACK_STIPPLE 0x10
+#define I810_FALLBACK_SPECULAR 0x20
+
+/* for i810ctx.new_state - manage GL->driver state changes
+ */
+#define I810_NEW_TEXTURE 0x1
+
+/* for i810ctx.dirty - manage driver->hw state changes, including
+ * lost contexts.
+ */
+#define I810_WAIT_AGE 0x1
+#define I810_UPLOAD_TEX0IMAGE 0x2
+#define I810_UPLOAD_TEX1IMAGE 0x4
+#define I810_UPLOAD_CTX 0x8
+#define I810_UPLOAD_BUFFERS 0x10
+#define I810_REFRESH_RING 0x20
+#define I810_EMIT_CLIPRECT 0x40
-#define I810_NEW_TEXTURE 0x20
-#define I810_NEW_CONTEXT 0x100
+typedef void (*i810_interp_func)( GLfloat t,
+ GLfloat *result,
+ const GLfloat *in,
+ const GLfloat *out );
+
struct i810_context_t {
GLint refcount;
- struct i810_dest_buffer *DB;
- GLcontext *gl_ctx;
+ GLcontext *glCtx;
- i810TextureObjectPtr CurrentTex0Obj;
- i810TextureObjectPtr CurrentTex1Obj;
+ i810TextureObjectPtr CurrentTexObj[2];
- struct i810_texture_object_t TexObjList, SwappedOut;
+ struct i810_texture_object_t TexObjList;
+ struct i810_texture_object_t SwappedOut;
int TextureMode;
- /* flags
- */
- int GlobalPaletteUpdated:1;
-
-
/* Hardware state
*/
GLuint Setup[I810_CTX_SETUP_SIZE];
+ GLuint BufferSetup[I810_DEST_SETUP_SIZE];
+ GLuint ClipSetup[I810_CLIP_SETUP_SIZE];
- /* Context hardware state mirrors.
- */
- GLushort GlobalPalette[256];
-
/* Support for CVA and the fast paths.
*/
GLuint setupdone;
GLuint setupindex;
GLuint renderindex;
GLuint using_fast_path;
-/* gl_vertex_interp_func interp; */
+ i810_interp_func interp;
/* Shortcircuit some state changes.
*/
@@ -90,39 +112,98 @@ struct i810_context_t {
/* Manage our own state */
GLuint new_state;
- GLuint reg_dirty;
-
+
+ /* Manage hardware state */
+ GLuint dirty;
+ memHeap_t *texHeap;
+
/* One of the few bits of hardware state that can't be calculated
* completely on the fly:
*/
GLuint LcsCullMode;
- /* For mono span and pixel funcs.
+ /* Funny mesa mirrors
*/
- GLushort CurrentColor;
+ GLushort MonoColor;
+ GLushort ClearColor;
/* DRI stuff
*/
- GLuint needClip;
- GLuint clipMinX;
- GLuint clipMaxX;
- GLuint clipMinY;
- GLuint clipMaxY;
+ drmBufPtr dma_buffer;
+ drmBufPtr vertex_dma_buffer;
+
+ GLframebuffer *glBuffer;
+ /* Two flags to keep track of fallbacks.
+ */
+ GLuint IndirectTriangles;
+ GLuint Fallback;
- drmContext hHWContext;
- int numClipRects;
+
+ GLuint needClip;
+
+ /* These refer to the current draw (front vs. back) buffer:
+ */
+ char *drawMap; /* draw buffer address in virtual mem */
+ char *readMap;
+ int drawX; /* origin of drawable in draw buffer */
+ int drawY;
+ GLuint numClipRects; /* cliprects for that buffer */
XF86DRIClipRectPtr pClipRects;
- i810ScreenPrivate *i810ScrnPriv;
+
+ int lastSwap;
+ int secondLastSwap;
+ int texAge;
+ int ctxAge;
+ int dirtyAge;
+ int any_contend; /* throttle me harder */
+
+ int scissor;
+
+ int lines_are_tris; /* not used */
+ int horiz_line_stipple;
+ int vert_line_stipple;
+
+ int poly_stipple;
+
+ drm_clip_rect_t draw_rect;
+ drm_clip_rect_t scissor_rect;
+
+ drmContext hHWContext;
+ drmLock *driHwLock;
+ int driFd;
+ Display *display;
+
+ __DRIdrawablePrivate *driDrawable;
+ __DRIscreenPrivate *driScreen;
+ i810ScreenPrivate *i810Screen;
+ drm_i810_sarea_t *sarea;
};
-typedef struct i810_context_t i810Context;
-typedef struct i810_context_t *i810ContextPtr;
+
+/* To remove all debugging, make sure I810_DEBUG is defined as a
+ * preprocessor symbol, and equal to zero.
+ */
+#define I810_DEBUG 0
+#ifndef I810_DEBUG
+#warning "Debugging enabled - expect reduced performance"
+extern int I810_DEBUG;
+#endif
+
+#define DEBUG_VERBOSE_2D 0x1
+#define DEBUG_VERBOSE_RING 0x8
+#define DEBUG_VERBOSE_OUTREG 0x10
+#define DEBUG_ALWAYS_SYNC 0x40
+#define DEBUG_VERBOSE_MSG 0x80
+#define DEBUG_NO_OUTRING 0x100
+#define DEBUG_NO_OUTREG 0x200
+#define DEBUG_VERBOSE_API 0x400
+#define DEBUG_VALIDATE_RING 0x800
+#define DEBUG_VERBOSE_LRU 0x1000
+#define DEBUG_VERBOSE_DRI 0x2000
+#define DEBUG_VERBOSE_IOCTL 0x4000
-i810ContextPtr i810CreateContext(GLcontext *ctx); /* Do I need visual info? */
-int i810DestroyContext(i810ContextPtr ctx);
-int i810BindBuffer(i810ContextPtr ctx, struct i810_dest_buffer *buf);
extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
const struct gl_pipeline_stage *in,
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
index 7a762ce9b..954f60a79 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810dd.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
@@ -30,17 +30,15 @@
#include "mm.h"
#include "i810lib.h"
-#include "i810glx.h"
#include "i810clear.h"
#include "i810dd.h"
-#include "i810direct.h"
-#include "i810depth.h"
#include "i810log.h"
#include "i810state.h"
#include "i810span.h"
#include "i810tex.h"
#include "i810tris.h"
#include "i810vb.h"
+#include "i810pipeline.h"
#include "extensions.h"
#include "vb.h"
#include "dd.h"
@@ -54,18 +52,39 @@ extern int xf86VTSema;
***************************************/
-const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name )
+static const GLubyte *i810DDGetString( GLcontext *ctx, GLenum name )
{
switch (name) {
case GL_VENDOR:
return "Keith Whitwell, Precision Insight Inc.";
case GL_RENDERER:
- return "GLX-I810";
+ return "DRI-I810";
default:
return 0;
}
}
+static GLint i810GetParameteri(const GLcontext *ctx, GLint param)
+{
+ switch (param) {
+ case DD_HAVE_HARDWARE_FOG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+
+static void i810BufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ *width = imesa->driDrawable->w;
+ *height = imesa->driDrawable->h;
+}
+
+
+
void i810DDExtensionsInit( GLcontext *ctx )
{
@@ -86,77 +105,26 @@ void i810DDExtensionsInit( GLcontext *ctx )
gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" );
+ if (0) gl_extensions_disable( ctx, "GL_ARB_multitexture" );
+
+
/* We do support tex_env_add, however
*/
gl_extensions_enable( ctx, "GL_EXT_texture_env_add" );
}
-static GLint i810GetParameteri(const GLcontext *ctx, GLint param)
-{
- switch (param) {
- case DD_HAVE_HARDWARE_FOG:
- return 1;
- default:
- return 0;
- }
-}
-GLboolean i810IsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
+void i810DDInitDriverFuncs( GLcontext *ctx )
{
- i810TextureObjectPtr mt = (i810TextureObjectPtr)t->DriverData;
- return mt && mt->MemBlock;
-}
-
-
-
-
-void i810_setup_DD_pointers( GLcontext *ctx )
-{
- i810DDInitStatePointers(ctx);
-
+ ctx->Driver.GetBufferSize = i810BufferSize;
ctx->Driver.GetString = i810DDGetString;
- ctx->Driver.UpdateState = i810DDUpdateState;
+ ctx->Driver.GetParameteri = i810GetParameteri;
ctx->Driver.RegisterVB = i810DDRegisterVB;
ctx->Driver.UnregisterVB = i810DDUnregisterVB;
ctx->Driver.Clear = i810Clear;
- ctx->Driver.GetParameteri = i810GetParameteri;
- ctx->Driver.TexEnv = i810TexEnv;
- ctx->Driver.TexImage = i810TexImage;
- ctx->Driver.TexSubImage = i810TexSubImage;
- ctx->Driver.BindTexture = i810BindTexture;
- ctx->Driver.DeleteTexture = i810DeleteTexture;
- ctx->Driver.TexParameter = i810TexParameter;
- ctx->Driver.UpdateTexturePalette = i810UpdateTexturePalette;
- ctx->Driver.IsTextureResident = i810IsTextureResident;
-
- ctx->Driver.TriangleCaps = (DD_TRI_CULL|
- DD_TRI_LIGHT_TWOSIDE|
- DD_TRI_OFFSET);
-
- i810DDInitSpans( ctx );
-
- ctx->Driver.ReadDepthSpanFloat = i810_read_depth_span_float;
- ctx->Driver.ReadDepthSpanInt = i810_read_depth_span_int;
- if (ctx->Depth.Test) {
- switch (ctx->Depth.Func) {
- case GL_LESS:
- ctx->Driver.DepthTestSpan = i810_depth_test_span_less;
- ctx->Driver.DepthTestPixels = i810_depth_test_pixels_less;
- break;
- case GL_GREATER:
- ctx->Driver.DepthTestSpan = i810_depth_test_span_greater;
- ctx->Driver.DepthTestPixels = i810_depth_test_pixels_greater;
- break;
- default:
- ctx->Driver.DepthTestSpan = i810_depth_test_span_generic;
- ctx->Driver.DepthTestPixels = i810_depth_test_pixels_generic;
- break;
- }
- }
- /* Also do the normal GL state-change checks.
- */
- i810DDUpdateState( ctx );
+
+ ctx->Driver.BuildPrecalcPipeline = i810DDBuildPrecalcPipeline;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.h b/xc/lib/GL/mesa/src/drv/i810/i810dd.h
index 1274e66e2..86a8618d0 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810dd.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.h
@@ -25,23 +25,9 @@
#ifndef I810DD_INC
#define I810DD_INC
-#include "mesaglx/context.h"
+#include "context.h"
-#include "i810buf.h"
-
-void i810_setup_DD_pointers( GLcontext *ctx );
-void i810DDRegisterVB( struct vertex_buffer *VB );
-
-void i810DDFastPath( struct vertex_buffer *VB );
-void i810DDImmediateFastPath( struct vertex_buffer *VB );
-void i810DDFastPathInit();
void i810DDExtensionsInit( GLcontext *ctx );
-
-void i810_setup_DD_pointers_no_accel( GLcontext *ctx );
-/* void i810FinishPrimitive( void ); */
-
-#define i810FinishPrimitive()
-
-
+void i810DDInitDriverFuncs( GLcontext *ctx );
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.c b/xc/lib/GL/mesa/src/drv/i810/i810depth.c
deleted file mode 100644
index 9b089f7de..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810depth.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 3.1
- *
- * Copyright (C) 1999 Brian Paul 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, 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 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
- * BRIAN PAUL 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.
- */
-
-/*
- * This file has been modified by Wittawat Yamwong for GLX module.
- */
-
-/*
- * Depth buffer functions
- */
-
-
-#ifdef PC_HEADER
-#include "all.h"
-#else
-#include <stdlib.h>
-#include <string.h>
-#include "mesaglx/context.h"
-#include "i810depth.h"
-#include "mesaglx/types.h"
-#include "mm.h"
-#include "i810lib.h"
-#endif
-
-
-
-/*
- * Return the address of the Z-buffer value for window coordinate (x,y):
- */
-#define Z_SETUP \
- GLdepth *zbstart = (GLdepth *)i810DB->ZBuffer->BufAddr; \
- GLint zbpitch = i810DB->ZBuffer->Pitch;
-#define Z_ADDRESS( X, Y ) \
- (zbstart + zbpitch * (Y) + (X))
-
-
-/**********************************************************************/
-/***** Depth Testing Functions *****/
-/**********************************************************************/
-
-
-/*
- * Depth test horizontal spans of fragments. These functions are called
- * via ctx->Driver.depth_test_span only.
- *
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in span in window coords
- * z - array [n] of integer depth values
- * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
- * Return: number of pixels which passed depth test
- */
-
-
-/*
- * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
- */
-GLuint i810_depth_test_span_generic( GLcontext* ctx,
- GLuint n, GLint x, GLint y,
- const GLdepth z[],
- GLubyte mask[] )
-{
- Z_SETUP
- GLdepth *zptr = Z_ADDRESS( x, y );
- GLubyte *m = mask;
- GLuint i;
- GLuint passed = 0;
-
- i810WaitDrawingEngine();
-
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++,zptr++,m++) {
- if (*m) {
- if (z[i] < *zptr) {
- /* pass */
- *zptr = z[i];
- passed++;
- }
- else {
- /* fail */
- *m = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++,zptr++,m++) {
- if (*m) {
- if (z[i] < *zptr) {
- /* pass */
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] <= *zptr) {
- *zptr = z[i];
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] <= *zptr) {
- /* pass */
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] >= *zptr) {
- *zptr = z[i];
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] >= *zptr) {
- /* pass */
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] > *zptr) {
- *zptr = z[i];
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] > *zptr) {
- /* pass */
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] != *zptr) {
- *zptr = z[i];
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] != *zptr) {
- /* pass */
- passed++;
- }
- else {
- *m = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] == *zptr) {
- *zptr = z[i];
- passed++;
- }
- else {
- *m =0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- if (z[i] == *zptr) {
- /* pass */
- passed++;
- }
- else {
- *m =0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0;i<n;i++,zptr++,m++) {
- if (*m) {
- *zptr = z[i];
- passed++;
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- passed = n;
- }
- break;
- case GL_NEVER:
- for (i=0;i<n;i++) {
- mask[i] = 0;
- }
- break;
- default:
- gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic");
- } /*switch*/
-
- return passed;
-}
-
-
-
-/*
- * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
- */
-GLuint i810_depth_test_span_less( GLcontext* ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- GLubyte mask[] )
-{
- Z_SETUP
- GLdepth *zptr = Z_ADDRESS( x, y );
- GLuint i;
- GLuint passed = 0;
-
- i810WaitDrawingEngine();
-
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zptr[i]) {
- /* pass */
- zptr[i] = z[i];
- passed++;
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- return passed;
-}
-
-
-/*
- * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
- */
-GLuint i810_depth_test_span_greater( GLcontext* ctx,
- GLuint n, GLint x, GLint y,
- const GLdepth z[],
- GLubyte mask[] )
-{
- Z_SETUP
- GLdepth *zptr = Z_ADDRESS( x, y );
- GLuint i;
- GLuint passed = 0;
-
- i810WaitDrawingEngine();
-
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] > zptr[i]) {
- /* pass */
- zptr[i] = z[i];
- passed++;
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- return passed;
-}
-
-
-
-/*
- * Depth test an array of randomly positioned fragments.
- */
-
-/*
- * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
- */
-void i810_depth_test_pixels_generic( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- Z_SETUP
- register GLdepth *zptr;
- register GLuint i;
-
- i810WaitDrawingEngine();
-
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] <= *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] <= *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] >= *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] >= *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] != *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] != *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] == *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] == *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- *zptr = z[i];
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- }
- break;
- case GL_NEVER:
- /* depth test never passes */
- for (i=0;i<n;i++) {
- mask[i] = 0;
- }
- break;
- default:
- gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic");
- } /*switch*/
-}
-
-
-
-/*
- * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
- */
-void i810_depth_test_pixels_less( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- Z_SETUP
- GLdepth *zptr;
- GLuint i;
-
- i810WaitDrawingEngine();
-
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
-}
-
-
-/*
- * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
- */
-void i810_depth_test_pixels_greater( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- Z_SETUP
- GLdepth *zptr;
- GLuint i;
-
- i810WaitDrawingEngine();
-
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zptr = Z_ADDRESS(x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
-}
-
-
-
-
-/**********************************************************************/
-/***** Read Depth Buffer *****/
-/**********************************************************************/
-
-
-/*
- * Return a span of depth values from the depth buffer as floats in [0,1].
- * This function is only called through Driver.read_depth_span_float()
- * Input: n - how many pixels
- * x,y - location of first pixel
- * Output: depth - the array of depth values
- */
-void i810_read_depth_span_float( GLcontext* ctx,
- GLuint n, GLint x, GLint y, GLfloat depth[] )
-{
- Z_SETUP
- GLdepth *zptr;
- GLfloat scale;
- GLuint i;
-
- i810WaitDrawingEngine();
-
- scale = 1.0F / DEPTH_SCALE;
-
- if (ctx->Buffer->Depth) {
- zptr = Z_ADDRESS( x, y );
- for (i=0;i<n;i++) {
- depth[i] = (GLfloat) zptr[i] * scale;
- }
- }
- else {
- for (i=0;i<n;i++) {
- depth[i] = 0.0F;
- }
- }
-}
-
-
-/*
- * Return a span of depth values from the depth buffer as integers in
- * [0,MAX_DEPTH].
- * This function is only called through Driver.read_depth_span_int()
- * Input: n - how many pixels
- * x,y - location of first pixel
- * Output: depth - the array of depth values
- */
-void i810_read_depth_span_int( GLcontext* ctx,
- GLuint n, GLint x, GLint y, GLdepth depth[] )
-{
- Z_SETUP
-
- i810WaitDrawingEngine();
-
- if (ctx->Buffer->Depth) {
- GLdepth *zptr = Z_ADDRESS( x, y );
- MEMCPY( depth, zptr, n * sizeof(GLdepth) );
- }
- else {
- GLuint i;
- for (i=0;i<n;i++) {
- depth[i] = 0;
- }
- }
-}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810depth.h b/xc/lib/GL/mesa/src/drv/i810/i810depth.h
deleted file mode 100644
index 878fbefe8..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810depth.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 3.1
- *
- * Copyright (C) 1999 Brian Paul 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, 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 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
- * BRIAN PAUL 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.
- */
-
-/*
- * This file has been modified by Wittawat Yamwong for GLX module.
- */
-
-
-#ifndef I810DEPTH_INC
-#define I810DEPTH_INC
-
-
-#include "mesaglx/types.h"
-
-
-
-
-
-extern GLuint
-i810_depth_test_span_generic( GLcontext* ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-extern GLuint
-i810_depth_test_span_less( GLcontext* ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-extern GLuint
-i810_depth_test_span_greater( GLcontext* ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-
-
-extern void
-i810_depth_test_pixels_generic( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
-
-extern void
-i810_depth_test_pixels_less( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
-
-extern void
-i810_depth_test_pixels_greater( GLcontext* ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
-
-
-extern void i810_read_depth_span_float( GLcontext* ctx,
- GLuint n, GLint x, GLint y,
- GLfloat depth[] );
-
-
-extern void i810_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y,
- GLdepth depth[] );
-
-
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.c b/xc/lib/GL/mesa/src/drv/i810/i810dma.c
deleted file mode 100644
index f745d272f..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810dma.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* -*- mode: C; c-basic-offset:8 -*- */
-/*
- * GLX Hardware Device Driver for Intel i810
- * Copyright (C) 1999 Keith Whitwell
- *
- * 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 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
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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.
- *
- * based on the original mgadma.c by Jeff Hartmann <slicer@ionet.net>
- * as rewritten by John Carmack <johnc@idsoftware.com>
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include "mm.h"
-#include "i810buf.h"
-#include "i810dd.h"
-#include "i810lib.h"
-#include "i810log.h"
-#include "i810tris.h"
-#include "i810direct.h"
-#include "i810state.h"
-
-#include "pb.h"
-
-/* X server include:
- */
-#include "i810.h"
-
-
-
-/* This will be overwritten from the default values when glx.so is
- * loaded on the client.
- */
-void i810ServerDmaFlush( int wait );
-GLuint i810ActiveDmaBuffer = 0;
-
-
-
-#ifndef I810_DEBUG
-int I810_DEBUG = (0
-/* | DEBUG_ALWAYS_SYNC */
-/* | DEBUG_VERBOSE_ACCEL */
-/* | DEBUG_VERBOSE_SYNC */
-/* | DEBUG_VERBOSE_VGA */
-/* | DEBUG_VERBOSE_RING */
-/* | DEBUG_VERBOSE_OUTREG */
-/* | DEBUG_VERBOSE_MEMORY */
-/* | DEBUG_ALWAYS_SYNC */
-/* | DEBUG_VERBOSE_MSG */
- );
-#endif
-
-
-
-static void delay( void ) {
-}
-
-
-
-int i810WaitForDmaCompletion( void )
-{
- int start, end;
-
- if (I810LpRing.head == I810LpRing.tail && I810LpRing.space)
- return 0;
-
- start = i810_usec();
- I810LpRing.head = INREG(I810LpRing.base_reg + RING_HEAD);
- end = i810_usec();
-
- if (0 && start + 100 < end)
- fprintf(stderr, "INREG in WaitForDma: %d usec\n", end - start);
-
- I810LpRing.head &= HEAD_ADDR;
- I810LpRing.space = I810LpRing.head - (I810LpRing.tail + 8);
- if (I810LpRing.space < 0)
- I810LpRing.space += I810LpRing.mem.Size;
-
- if (I810LpRing.head == I810LpRing.tail)
- return 0;
-
- start = i810_usec();
- I810Sync();
- end = i810_usec();
-
- return 1;
-}
-
-
-
-/*
- * i810DmaResetBuffer
- */
-void i810DmaResetBuffer( void ) {
-
- i810glx.dma_buffer = dmaBuffers[ i810ActiveDmaBuffer ];
- i810glx.dma_buffer->head = 0;
- i810glx.dma_buffer->space = 0;
- i810glx.dma_buffer->additional_space =
- i810glx.dma_buffer->mem.Size - 256;
-
- i810DmaOverflow( 0 );
-
- if (i810glx.dma_buffer_age < i810glx.dma_buffer->texture_age)
- i810glx.dma_buffer_age = i810glx.dma_buffer->texture_age;
-}
-
-
-
-
-/*
- * i810FlushRealDma
- */
-void i810FlushRealDma( void ) {
-
- GLuint start;
-
- if (MESA_VERBOSE&VERBOSE_DRIVER)
- fprintf(stderr, "i810FlushRealDma()\n" );
-
-
- if ( i810glx.skipDma || !I810_USE_BATCH )
- return;
-
-
- if (i810glx.dma_buffer->head & 0x4) {
- FatalError( "Misaligned batch buffer\n" );
- }
-
- if ( (I810_DEBUG&DEBUG_VERBOSE_OUTREG) && 0)
- {
- int i;
- for (i = 0 ; i <= i810glx.dma_buffer->head ; i+=4)
- fprintf(stderr,
- " 0x%05x : 0x%08x\n",
- i/4,
- *(GLuint *)(i810glx.dma_buffer->virtual_start +
- i));
- }
-
-
- /* fire the batch buffer */
- for (start = 0 ; start < i810glx.dma_buffer->head ; start += MAX_BATCH)
- {
- GLuint ofs = i810glx.dma_buffer->mem.Start;
- GLuint end = MIN2(start + MAX_BATCH, i810glx.dma_buffer->head);
-
- BEGIN_LP_RING(4);
- OUT_RING( CMD_OP_BATCH_BUFFER );
- OUT_RING( (ofs + start) | BB1_PROTECTED );
- OUT_RING( (ofs + end) - 4 );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
- }
-
- {
- BEGIN_LP_RING(2);
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH |
- INST_FLUSH_MAP_CACHE );
- OUT_RING( 0 );
- }
-}
-
-/*
- * i810DmaFlush
- * Send all pending commands off to the hardware.
- * If we are running async, the hardware will be drawing
- * while we return to do other things.
- */
-void i810ServerDmaFlush( int wait ) {
- int start, end;
-
- if (I810_DEBUG)
- fprintf(stderr,
- "i810ServerDmaFlush, buffer %d, head %x space %x\n",
- i810ActiveDmaBuffer,
- i810glx.dma_buffer->head,
- i810glx.dma_buffer->space);
-
- if ( i810glx.dma_buffer->head == 0 )
- {
- if (wait && !i810WaitForDmaCompletion())
- i810glx.hardwareWentIdle = 1;
-
- return;
- }
-
- i810glx.c_dmaFlush++;
-
- /* wait for the last buffer to complete */
- if ( !i810WaitForDmaCompletion() )
- i810glx.hardwareWentIdle = 1;
-
-
- /* collect timing information if we are going syncronously */
- if ( i810glx.dmaDriver != 3 ) {
- start = i810_usec();
- } else {
- start = end = 0;
- }
-
- i810FlushRealDma();
-
- if ( i810glx.dmaDriver == 2 ) {
- /* wait until the dma completes */
- i810WaitForDmaCompletion();
- }
-
- if ( i810glx.dmaDriver != 3 ) {
- end = i810_usec();
- }
-
- i810Msg(10, "flushmode %i, buffer %i: prim dwords:%i usec:%i\n",
- i810glx.dmaDriver, i810ActiveDmaBuffer,
- i810glx.dma_buffer->head / 4,
- end - start );
-
- /* swap to using the other buffer */
- i810ActiveDmaBuffer ^= 1;
- i810DmaResetBuffer();
-
- if ( wait )
- i810WaitForDmaCompletion();
-}
-
-
-/*
- * i810DmaFlush
- */
-void i810DmaFlush( void ) {
- i810FinishPrimitive();
- i810glx.dma_buffer->texture_age = ++i810glx.current_texture_age;
-
- if ( i810Ctx && i810Ctx->CurrentTex0Obj )
- i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age;
-
- if ( i810Ctx && i810Ctx->CurrentTex1Obj )
- i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age;
-
- i810ServerDmaFlush( 0 );
-}
-
-
-/*
- * i810DmaFinish
- */
-void i810DmaFinish( void ) {
- i810FinishPrimitive();
- i810ServerDmaFlush( 1 );
-
- i810glx.dma_buffer_age = ++i810glx.current_texture_age;
-
- if ( i810Ctx && i810Ctx->CurrentTex0Obj )
- i810Ctx->CurrentTex0Obj->age = ++i810glx.current_texture_age;
-
- if ( i810Ctx && i810Ctx->CurrentTex1Obj )
- i810Ctx->CurrentTex1Obj->age = ++i810glx.current_texture_age;
-}
-
-
-/*
- * i810DmaOverflow
- * This is called when I810DMAGETPTR is at the end of the buffer
- */
-void i810DmaOverflow( int newDwords ) {
-
- if (i810glx.dma_buffer->additional_space) {
- GLuint incr = MAX_BATCH;
-
- if (i810glx.dma_buffer->additional_space < incr)
- incr = i810glx.dma_buffer->additional_space;
-
- while (i810glx.dma_buffer->head & (MAX_BATCH - 1)) {
- GLuint outbatch = i810glx.dma_buffer->head;
- GLubyte *virt = i810glx.dma_buffer->virtual_start;
-
- *(volatile unsigned int *)(virt + outbatch) = 0;
- i810glx.dma_buffer->head += 4;
- }
-
- i810glx.dma_buffer->space += incr;
- i810glx.dma_buffer->additional_space -= incr;
-
- if (0)
- fprintf(stderr, "overflow, head %x space %x\n",
- i810glx.dma_buffer->head,
- i810glx.dma_buffer->space);
- return;
- }
-
- i810Msg( 9, "i810DmaOverflow(%i)\n", newDwords );
-
- /* flush all the current commands so we will have another
- empty buffer */
- i810DmaFlush();
-
- i810glx.c_overflows++;
-
- if ( newDwords > i810glx.dma_buffer->space )
- FatalError("i810DmaOverflow > maxPrimaryDwords");
-}
-
-
-/*
- * i810WaitDrawingEngine
- * This will not return until the drawing engine has completed
- * drawing pixels and it is safe to read or write the framebuffer
- * for software rendering.
- */
-int i810WaitDrawingEngine( void ) {
- /* note this for the performance block display */
- i810glx.c_drawWaits++;
-
- /* make sure all pending dma has completed */
- i810DmaFinish();
- return 0;
-}
-
-
-/*
- * i810DmaExecute
- * Add a block of data to the dma buffer
- */
-void i810DmaExecute( GLuint *code, int dwords )
-{
- int i;
- BEGIN_BATCH(dwords);
-
- if (dwords & 1)
- FatalError( "Misaligned buffer in i810DmaExecute\n" );
-
- for ( i = 0 ; i < dwords ; i++ )
- OUT_BATCH( code[i] );
- ADVANCE_BATCH();
-}
-
-
-
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.h b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
index 55adbcddd..3fd995cb3 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810dma.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
@@ -1,138 +1,44 @@
-/*
- GLX Hardware Device Driver for Intel i810
- Copyright (C) 1999 Keith Whitwell <keithw@precisioninsight.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- original by Jeff Hartmann <slicer@ionet.net>
- 6/16/99: rewrite by John Carmack <johnc@idsoftware.com>
- Oct 99: port to i180 by Keith Whitwell <keithw@precisioninsight.com>
-*/
#ifndef I810DMA_H
#define I810DMA_H
-#include "i810common.h"
#include "i810lib.h"
-#include "i810.h"
+#include "i810_init.h"
#include "mm.h"
-/* the main initialization of the entire i810 hardware driver */
-GLboolean i810InitGLX( void );
-/* a flush command will guarantee that all data added to the dma buffer
-is on its way to the card, and will eventually complete with no more
-intervention.
-*/
-void i810DmaFlush(void);
-
-/* the overflow function is called when a block can't be allocated
-in the current dma buffer. It flushes the current buffer and
-records some information */
-void i810DmaOverflow(int newDwords);
-
-/* a finish command will guarantee that all dma commands have actually
-been consumed by the card. Note that there may still be a couple primitives
-that have not yet been executed out of the internal FIFO, so this does not
-guarantee that the drawing engine is idle. */
-void i810DmaFinish( void );
-
-/* a i810WaitDrawingEngine command will guarantee that the framebuffer
-is safe to read or write for software rendering */
-int i810WaitDrawingEngine( void );
-
-
-
-
-
-typedef struct {
- I810MemRange mem;
- char *virtual_start;
- int head;
- int space;
- int additional_space;
- int texture_age;
-} i810BatchBuffer;
-
-
-
-#define I810_USE_BATCH 1
-#if I810_USE_BATCH
-
-#define BEGIN_BATCH(n) \
+/* Vertex data does not use these macros.
+ */
+#define BEGIN_BATCH( imesa, n ) \
unsigned int outbatch; \
volatile char *virt; \
if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, \
- "BEGIN_BATCH(%d) in %s\n" \
- "(spc left %d/%d, head %x vstart %x start %x)\n", \
- n, __FUNCTION__, i810glx.dma_buffer->space, \
- i810glx.dma_buffer->mem.Size - i810glx.dma_buffer->head, \
- i810glx.dma_buffer->head, \
- i810glx.dma_buffer->virtual_start, \
- i810glx.dma_buffer->mem.Start ); \
- if (i810glx.dma_buffer->space < n*4) \
- i810DmaOverflow(n); \
- outbatch = i810glx.dma_buffer->head; \
- virt = i810glx.dma_buffer->virtual_start;
-
-
-#define OUT_BATCH(val) { \
- *(volatile unsigned int *)(virt + outbatch) = val; \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, "OUT_BATCH %x: %x\n", outbatch/4, val); \
- outbatch += 4; \
-}
+ fprintf(stderr, "BEGIN_BATCH(%d) in %s\n", n, __FUNCTION__); \
+ if (imesa->dma_buffer->total - imesa->dma_buffer->used < n*4) { \
+ i810FlushGeneralLocked( imesa ); \
+ i810GetGeneralDmaBufferLocked( imesa ); \
+ } \
+ outbatch = imesa->dma_buffer->used; \
+ virt = imesa->dma_buffer->address;
+
+
+#define OUT_BATCH(val) do { \
+ *(volatile unsigned int *)(virt + outbatch) = val; \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "OUT_BATCH %x: %x\n", \
+ (int)(outbatch/4), (int)(val)); \
+ outbatch += 4; \
+} while (0)
-#define ADVANCE_BATCH() { \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, "ADVANCE_BATCH(%f) in %s\n", \
- (outbatch - i810glx.dma_buffer->head) / 4.0, \
- __FUNCTION__); \
- i810glx.dma_buffer->space -= outbatch - i810glx.dma_buffer->head; \
- i810glx.dma_buffer->head = outbatch; \
-}
+#define ADVANCE_BATCH() do { \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ fprintf(stderr, "ADVANCE_BATCH(%.1f) in %s\n", \
+ (outbatch - imesa->dma_buffer->used) / 4.0, \
+ __FUNCTION__); \
+ imesa->dma_buffer->used = outbatch; \
+} while(0)
#define FINISH_PRIM()
-#else
-
-/* Need some work to be able to do primitives this way.
- */
-#define BEGIN_BATCH(n) BEGIN_LP_RING(n)
-#define ADVANCE_BATCH() ADVANCE_LP_RING()
-#define OUT_BATCH(val) OUT_RING(val)
-#define FINISH_PRIM() OUTREG(I810LpRing.base_reg + RING_TAIL, I810LpRing.tail)
-
-#endif
-
-
-/* These are only required by i810direct.c:
- */
-extern GLuint i810ActiveDmaBuffer;
-extern void (*i810DoDmaFlush)( int );
-extern i810BatchBuffer *dmaBuffers[2];
-
-extern int i810WaitForDmaCompletion( void );
-extern void i810DmaResetBuffer( void );
-
-extern void i810DmaExecute( GLuint *code, int dwords );
-
-extern void I810Sync( void ) ;
-extern void I810WaitLpRing( int n );
-
-
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c b/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c
deleted file mode 100644
index 335c4a612..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810dmainit.c
+++ /dev/null
@@ -1,389 +0,0 @@
-
-/* -*- mode: C; c-basic-offset:8 -*- */
-/*
- * GLX Hardware Device Driver for Intel i810
- * Copyright (C) 1999 Keith Whitwell
- *
- * 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 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
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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.
- *
- *
- * based on the original by Jeff Hartmann <slicer@ionet.net>
- * as rewritten by John Carmack <johnc@idsoftware.com>
- */
-
-/*
-
-This file is only entered at startup. After i810GlxInit completes,
-nothing here will be executed again.
-
-*/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include "context.h"
-#include "depth.h"
-#include "macros.h"
-#include "texstate.h"
-#include "triangle.h"
-#include "vb.h"
-#include "types.h"
-
-#include "xsmesaP.h"
-#include "glx_log.h"
-#include "mesaglx/context.h"
-#include "mesaglx/matrix.h"
-#include "mesaglx/types.h"
-
-#define GC XXGC
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "servermd.h" /* PixmapBytePad */
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "windowstr.h"
-#undef GC
-
-#include "vga.h"
-#include "vgaPCI.h"
-#include "i810.h"
-#include "xaa/xf86xaa.h"
-
-#include "mm.h"
-#include "i810buf.h"
-#include "i810dd.h"
-#include "i810lib.h"
-#include "i810log.h"
-#include "i810direct.h"
-#include "i810glx.h"
-
-#include <agpgart.h>
-
-/* private vars */
-i810BatchBuffer *dmaBuffers[2];
-static I810MemRange I810SysMem2;
-
-
-static const char *getenvSafe(const char *name ) {
- const char *r;
-
- r = getenv( name );
- if ( !r ) {
- return "";
- }
- return r;
-}
-
-
-static void AllocateCommandBuffers( void )
-{
- PMemBlock block;
- GLuint bufferBytes = i810glx.cmdSize;
- GLuint start, i;
-
- if ( 1 || !bufferBytes ) {
- fprintf(stderr,"temporarily hardwiring GLX_I810_CMDSIZE = 1\n" );
- bufferBytes = 1;
- }
-
- bufferBytes *= 0x100000;
-
- block = mmAllocMem( i810glx.sysmemHeap, bufferBytes, 8, 0 );
-
- if ( !block ) {
- fprintf(stderr,
- "failed to allocate 0x%x bytes from "
- "sysmemHeap for command buffers.\n",
- bufferBytes );
-
- FatalError("Couldn't get dma buffer\n");
- }
-
- start = block->ofs;
-
- /* setup the two buffers that will be ping-ponged
- */
- for (i = 0 ; i < 2 ; i++) {
- dmaBuffers[i] = calloc(1,sizeof(i810BatchBuffer));
- dmaBuffers[i]->virtual_start = i810glx.sysmemVirtual + start;
- dmaBuffers[i]->mem.Start = start;
- dmaBuffers[i]->mem.Size = bufferBytes / 2;
- dmaBuffers[i]->mem.End = (start += bufferBytes / 2);
- }
-
- i810DmaResetBuffer();
-}
-
-
-/* Another bit of duplication caused by 'static' code in the X server.
- */
-static int gartfd;
-static struct gart_info gartinf;
-static char *gart_buf;
-
-static int AllocateGARTMemory( int size )
-{
- int i, pages = size / 4096;
- int start = vga256InfoRec.videoRam / 4; /* a crock! */
- struct stat sb;
-
- if (stat("/dev/agpgart", &sb) != 0) {
- ErrorF("Stat failed on /dev/agpgart: %s\n",
- sys_errlist[errno]);
- return -1;
- }
-
- gartfd = open("/dev/agpgart", O_RDWR);
- if (gartfd == -1) {
- ErrorF("unable to open /dev/agpgart: %s\n",
- sys_errlist[errno]);
- FatalError("Aborting");
- }
-
- if (ioctl(gartfd, GARTIOCINFO, &gartinf) != 0) {
- ErrorF("error doing ioctl(GARTIOCINFO): %s\n",
- sys_errlist[errno]);
- FatalError("Aborting");
- }
-
- /* Treat the gart like video memory - we assume we own all that is
- * there, so ignore EBUSY errors. Don't try to remove it on
- * failure, either.
- */
- for (i = start; i < start+pages; i++)
- if (ioctl(gartfd, GARTIOCINSERT, &i) != 0) {
- if (errno != EBUSY)
- {
- perror("gart insert");
- ErrorF("GART: allocation of %d pages failed at page %d\n",
- pages, i);
- FatalError("Aborting");
- }
- }
-
- ErrorF("GART: allocated %dK system ram\n", pages * 4);
-
- I810SysMem2.Start = start * 4096;
- I810SysMem2.End = (start + pages) * 4096;
- I810SysMem2.Size = pages * 4096;
-
- gart_buf = mmap( 0,
- gartinf.size * 0x100000,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- gartfd,
- 0 );
-
- if ((unsigned int)gart_buf == ~0) {
- perror("/dev/agpgart");
- FatalError("Couldn't mmap /dev/agpgart - aborting");
- }
-
- return 0;
-}
-
-
-/*
- * AllocateSystemMemory
- * Looks at environment variables to determine if a block
- * of physical memory has been left for graphics after the
- * memory available to the kernel.
- * System memory can be used for dma command buffers or
- * textures.
- */
-static void AllocateSystemMemory( void )
-{
- GLuint sysmemBytes = i810glx.dmaSize;
-
- if ( !sysmemBytes )
- sysmemBytes = 8;
-
- sysmemBytes *= 0x100000;
-
- if (AllocateGARTMemory(sysmemBytes) != 0)
- FatalError( "AllocateGARTMemory failed.\n" );
-
-
- i810glx.sysmemVirtual = (unsigned char *)gart_buf;
-
- /* Suck in any leftover memory from the 2d server.
-
- i810glx.sysmemHeap = mmInit( I810SysMem.Start,
- I810SysMem.Size );
- */
-
- /* Add our new memory.
- */
- i810glx.sysmemHeap =
-/* mmAddRange( i810glx.sysmemHeap, */
- mmInit(
- I810SysMem2.Start,
- I810SysMem2.Size );
-
-
- /* Manage dcache mem via. a seperate heap.
- */
- i810glx.cardHeap = mmInit( I810DcacheMem.Start,
- I810DcacheMem.Size );
-
- i810Msg( 1, "sysmemSize: 0x%x\n", sysmemBytes );
- i810Msg( 1, "cardSize: 0x%lx\n", I810DcacheMem.Size );
-}
-
-
-
-/*
- * i810DmaInit
- *
-*/
-void i810DmaInit(void) {
-
- /* Server init - queries environment variables. The client
- * gets these values from the sever and initializes them in
- * i810direct.c
- */
- if (__glx_is_server) {
- i810glx.dmaDriver = atoi( getenvSafe("GLX_I810_DMA") );
- i810glx.dmaSize = atoi( getenvSafe("GLX_I810_DMASIZE") );
- i810glx.cmdSize = atoi( getenvSafe("GLX_I810_CMDSIZE") );
-
- if (i810glx.dmaDriver != 3)
- FatalError("GLX_I810_DMA not set\n");
- }
-
- /* get some system memory and make it write combining if we can */
- AllocateSystemMemory();
-
- /* read the command environment variable */
- i810Msg(1,"i810DmaInit: GLX_I810_DMA = %i\n", i810glx.dmaDriver );
-
- /* setup the two command buffers in the apropriate memory space */
- AllocateCommandBuffers();
-
- /* prepare the first buffer for use */
- i810DmaResetBuffer();
-}
-
-
-/*
- * This function should only verify that the current hardware is supported.
- * It should do no setup.
- */
-static GLboolean i810_detect_hw( void )
-{
- if (I810Chipset == -1)
- return GL_FALSE;
-
- if (vga256InfoRec.depth != 15 &&
- vga256InfoRec.depth != 16)
- {
- i810Error("Unsupported depth: %d, only 15 and 16d bpp "
- "are supported right now\n",
- vga256InfoRec.depth);
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-/*
- * i810InitLogging
- *
- */
-void i810InitLogging( void )
-{
- i810glx.logLevel = 100;
-}
-
-
-
-/*
- * i810InitGLX
- * This is the initial entry point for the i810 hardware driver,
- * called at X server module load time, or libGL direct rendering
- * init time.
- */
-GLboolean i810InitGLX( void ) {
-
- fprintf(stderr, "\n\n\n\ni810InitGLX\n");
-
- i810InitLogging();
-
- i810Msg(1,"virtual (x, y) (%d, %d)\n", vga256InfoRec.virtualX,
- vga256InfoRec.virtualY);
- i810Msg(1,"width: %d\n", vga256InfoRec.displayWidth);
- i810Msg(1,"depth: %d\n", vga256InfoRec.depth);
- i810Msg(1,"memBase: %p\n", vgaLinearBase);
- i810Msg(1,"videoRam: 0x%08x\n", vga256InfoRec.videoRam);
-
- if (!i810_detect_hw()) {
- ErrorF("Couldn't find i810 hardware\n\n\n");
- return GL_FALSE;
- }
-
- /* init the dma system */
- i810DmaInit();
-
- /* Register as a glx driver */
- GLXProcs.CreateContext = i810GLXCreateContext;
- GLXProcs.DestroyContext = i810GLXDestroyContext;
- GLXProcs.SwapBuffers = i810GLXSwapBuffers;
- GLXProcs.CreateImage = i810GLXCreateImage;
- GLXProcs.DestroyImage = i810GLXDestroyImage;
- GLXProcs.CreateDepthBuffer = i810GLXCreateDepthBuffer;
- GLXProcs.MakeCurrent = i810GLXMakeCurrent;
- GLXProcs.BindBuffer = i810GLXBindBuffer;
- GLXProcs.SwapBuffers = i810GLXSwapBuffers;
- GLXProcs.VendorPrivate = i810GLXVendorPrivate;
- GLXProcs.AllowDirect = i810GLXAllowDirect;
-
- if (!__glx_is_server) {
- GLXProcs.ValidateFrontBuffer = i810ClientGetGeometry;
- }
-
- /* these vars can be changed between invocations of direct clients */
- if (getenv("GLX_I810_NULLPRIMS") ) {
- i810Msg( 1, "enabling GLX_I810_NULLPRIMS\n" );
- i810glx.nullprims = 1;
- }
- if (getenv("GLX_I810_SKIPDMA") ) {
- i810Msg( 1, "enabling GLX_I810_SKIPDMA\n" );
- i810glx.skipDma = 1;
- }
- if (getenv("GLX_I810_BOXES") ) {
- i810Msg( 1, "enabling GLX_I810_BOXES\n" );
- i810glx.boxes = 1;
- }
- if (getenv("GLX_I810_NOFALLBACK") ) {
- i810Msg( 1, "enabling GLX_I810_NOFALLBACK\n" );
- i810glx.noFallback = 1;
- }
-
- i810Error("i810InitGLX completed\n");
- return GL_TRUE;
-}
-
-
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c b/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c
index 9223060e7..3e4887619 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810fastpath.c
@@ -116,14 +116,10 @@ static void i810_render_elements_direct( struct vertex_buffer *VB )
if (imesa->new_state)
i810DDUpdateHwState( ctx );
- BEGIN_CLIP_LOOP(imesa)
- {
- do {
- func( VB, 0, nr, 0 );
- } while (ctx->Driver.MultipassFunc &&
- ctx->Driver.MultipassFunc( VB, ++p ));
- }
- END_CLIP_LOOP(imesa);
+ do {
+ func( VB, 0, nr, 0 );
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ));
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810glx.h b/xc/lib/GL/mesa/src/drv/i810/i810glx.h
deleted file mode 100644
index df5c08674..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810glx.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * GLX Hardware Device Driver for Intel i810
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * 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 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
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 I810GLX_INC
-#define I810GLX_INC
-
-void i810DumpDB(struct i810_dest_buffer *buf);
-void i810GLXCreateDepthBuffer(GLcontext* ctx);
-void i810GLXDestroyImage(GLXImage* image);
-GLXImage* i810GLXCreateImage(WindowPtr pwindow, int depth, int width, int height);
-GLboolean i810GLXMakeCurrent( XSMesaContext c );
-GLboolean i810GLXBindBuffer( XSMesaContext c, XSMesaBuffer b );
-XSMesaContext i810GLXCreateContext( XSMesaVisual v,
- XSMesaContext share_list );
-void i810GLXDestroyContext( XSMesaContext c );
-
-extern int i810BackToFront(DrawablePtr drawable, struct i810_dest_buffer *buf);
-extern void (*i810GLXSwapBuffers)(XSMesaBuffer b);
-extern void i810PerformanceBoxes( int is_direct );
-
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c
new file mode 100644
index 000000000..93e2f4492
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c
@@ -0,0 +1,436 @@
+#include <stdio.h>
+
+
+#include "types.h"
+#include "pb.h"
+#include "dd.h"
+
+#include "mm.h"
+#include "i810context.h"
+#include "i810log.h"
+#include "i810ioctl.h"
+
+#include "drm.h"
+#include <sys/ioctl.h>
+
+static int _tot_used, _tot_size;
+
+void i810FlushGeneralLocked( i810ContextPtr imesa )
+{
+ int retcode;
+ drm_i810_general_t dma;
+ drmBufPtr buf = imesa->dma_buffer;
+
+ if (!buf) {
+ fprintf(stderr, "i810FlushGeneralLocked: no buffer\n");
+ return;
+ }
+
+ _tot_used += buf->used;
+ _tot_size += buf->total;
+
+ dma.idx = buf->idx;
+ dma.used = buf->used;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_I810_DMA idx %d used %d\n",
+ dma.idx, dma.used);
+
+ if ((retcode = ioctl(imesa->driFd, DRM_IOCTL_I810_DMA, &dma))) {
+ printf("send dma retcode = %d\n", retcode);
+ exit(1);
+ }
+
+ imesa->dma_buffer = 0;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished general dma put\n");
+}
+
+static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa )
+{
+ int idx = 0;
+ int size = 0;
+ drmDMAReq dma;
+ int retcode;
+ drmBufPtr buf;
+ int cnt = 0;
+
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Getting dma buffer\n");
+
+ dma.context = imesa->hHWContext;
+ dma.send_count = 0;
+ dma.send_list = NULL;
+ dma.send_sizes = NULL;
+ dma.flags = 0;
+ dma.request_count = 1;
+ dma.request_size = I810_DMA_BUF_SZ;
+ dma.request_list = &idx;
+ dma.request_sizes = &size;
+ dma.granted_count = 0;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
+ dma.context, dma.request_count,
+ dma.request_size);
+
+ while (1) {
+ retcode = drmDMA(imesa->driFd, &dma);
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
+ retcode,
+ dma.request_sizes[0],
+ dma.request_list[0],
+ dma.granted_count);
+
+ if (retcode == 0 &&
+ dma.request_list[0] &&
+ dma.request_sizes[0] &&
+ dma.granted_count)
+ break;
+
+ if (++cnt > 1000) {
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) {
+ fprintf(stderr, "\n\nflush retcode %d idx %d sz %d count %d\n",
+ retcode, dma.request_list[0],
+ dma.request_sizes[0], dma.granted_count);
+
+ fprintf(stderr, "used %d size %d (ratio %.3f)\n",
+ _tot_used, _tot_size, (float)_tot_size / (float)_tot_used);
+ }
+
+ ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH);
+ }
+ }
+
+
+
+ buf = &(imesa->i810Screen->bufs->list[idx]);
+ buf->used = 0;
+
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr,
+ "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
+ "dma_buffer now: buf idx: %d size: %d used: %d\n",
+ dma.request_sizes[0], dma.request_list[0],
+ buf->idx, buf->total,
+ buf->used);
+
+ return buf;
+}
+
+
+
+void i810GetGeneralDmaBufferLocked( i810ContextPtr imesa )
+{
+ if (imesa->dma_buffer) {
+ fprintf(stderr, "i810GetGeneralDmaBufferLocked - dma_buffer not zero\n");
+ exit(1);
+ }
+
+ imesa->dma_buffer = i810_get_buffer_ioctl( imesa );
+}
+
+
+
+/* This waits for *everybody* to finish rendering -- overkill.
+ */
+void i810DmaFinish( i810ContextPtr imesa )
+{
+ FLUSH_BATCH( imesa );
+
+ if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) {
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810DmaFinish\n");
+
+ LOCK_HARDWARE( imesa );
+ i810RegetLockQuiescent( imesa );
+ UNLOCK_HARDWARE( imesa );
+ imesa->sarea->last_quiescent = imesa->sarea->last_enqueue;
+ }
+}
+
+
+void i810RegetLockQuiescent( i810ContextPtr imesa )
+{
+ if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) {
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810RegetLockQuiescent\n");
+
+ drmUnlock(imesa->driFd, imesa->hHWContext);
+ i810GetLock( imesa, DRM_LOCK_QUIESCENT );
+ imesa->sarea->last_quiescent = imesa->sarea->last_enqueue;
+ }
+}
+
+void i810WaitAgeLocked( i810ContextPtr imesa, int age )
+{
+ int i = 0;
+
+ if (0) fprintf(stderr, "waitagelocked\n");
+
+ while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) {
+ ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE);
+ }
+
+ if (GET_DISPATCH_AGE(imesa) < age) {
+ if (0)
+ fprintf(stderr, "wait locked %d %d\n", age, GET_DISPATCH_AGE(imesa));
+ ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH);
+ }
+}
+
+
+void i810WaitAge( i810ContextPtr imesa, int age )
+{
+ int i = 0;
+
+ while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) {
+ ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE);
+ }
+
+ if (GET_DISPATCH_AGE(imesa) >= age)
+ return;
+
+ i = 0;
+ while (++i < 1000 && GET_DISPATCH_AGE(imesa) < age) {
+ ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE);
+ usleep(1000);
+ }
+
+ /* To be effective at letting other clients at the hardware,
+ * particularly the X server which regularly needs quiescence to
+ * touch the framebuffer, we really need to sleep *beyond* the
+ * point where our last buffer clears the hardware.
+ */
+ if (imesa->any_contend) {
+ usleep(3000);
+ }
+
+ imesa->any_contend = 0;
+
+ if (GET_DISPATCH_AGE(imesa) < age) {
+ LOCK_HARDWARE(imesa);
+ if (GET_DISPATCH_AGE(imesa) < age)
+ ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH);
+ UNLOCK_HARDWARE(imesa);
+ }
+}
+
+
+
+void i810FlushVertices( i810ContextPtr imesa )
+{
+ if (!imesa->vertex_dma_buffer) return;
+
+ LOCK_HARDWARE( imesa );
+ i810FlushVerticesLocked( imesa );
+ UNLOCK_HARDWARE( imesa );
+}
+
+
+static int intersect_rect( drm_clip_rect_t *out,
+ drm_clip_rect_t *a,
+ drm_clip_rect_t *b )
+{
+ *out = *a;
+ if (b->x1 > out->x1) out->x1 = b->x1;
+ if (b->y1 > out->y1) out->y1 = b->y1;
+ if (b->x2 < out->x2) out->x2 = b->x2;
+ if (b->y2 < out->y2) out->y2 = b->y2;
+ if (out->x1 >= out->x2) return 0;
+ if (out->y1 >= out->y2) return 0;
+ return 1;
+}
+
+
+static void age_imesa( i810ContextPtr imesa, int age )
+{
+ if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->age = age;
+ if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->age = age;
+}
+
+void i810FlushVerticesLocked( i810ContextPtr imesa )
+{
+ drm_clip_rect_t *pbox = (drm_clip_rect_t *)imesa->pClipRects;
+ int nbox = imesa->numClipRects;
+ drmBufPtr buffer = imesa->vertex_dma_buffer;
+ drm_i810_vertex_t vertex;
+ int i;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810FlushVerticesLocked, buf %p\n", buffer);
+
+ if (!buffer)
+ return;
+
+ if (imesa->dirty & ~I810_EMIT_CLIPRECT)
+ i810EmitHwStateLocked( imesa );
+
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810FlushVerticesLocked, used %d\n",
+ buffer->used);
+
+ _tot_used += buffer->used;
+ _tot_size += buffer->total;
+
+ imesa->vertex_dma_buffer = 0;
+
+ vertex.idx = buffer->idx;
+ vertex.used = buffer->used;
+ vertex.discard = 0;
+
+ if (!nbox)
+ vertex.used = 0;
+
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+
+ if (!vertex.used || !(imesa->dirty & I810_EMIT_CLIPRECT))
+ {
+ if (nbox == 1)
+ imesa->sarea->nbox = 0;
+ else
+ imesa->sarea->nbox = nbox;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_I810_VERTEX CASE1 nbox %d used %d\n",
+ nbox, vertex.used);
+
+ vertex.discard = 1;
+ ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex);
+ age_imesa(imesa, imesa->sarea->last_enqueue);
+ }
+ else
+ {
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox);
+ drm_clip_rect_t *b = imesa->sarea->boxes;
+
+ if (imesa->scissor) {
+ imesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++) {
+ b->x1 = pbox[i].x1 - imesa->drawX;
+ b->y1 = pbox[i].y1 - imesa->drawY;
+ b->x2 = pbox[i].x2 - imesa->drawX;
+ b->y2 = pbox[i].y2 - imesa->drawY;
+
+ if (intersect_rect(b, b, &imesa->scissor_rect)) {
+ imesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if (!imesa->sarea->nbox) {
+ if (nr < nbox) continue;
+ vertex.used = 0;
+ }
+ } else {
+ imesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++, b++) {
+ b->x1 = pbox[i].x1 - imesa->drawX;
+ b->y1 = pbox[i].y1 - imesa->drawY;
+ b->x2 = pbox[i].x2 - imesa->drawX;
+ b->y2 = pbox[i].y2 - imesa->drawY;
+ }
+ }
+
+ /* Finished with the buffer?
+ */
+ if (nr == nbox)
+ vertex.discard = 1;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_I810_VERTEX nbox %d used %d\n",
+ nbox, vertex.used);
+
+ ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex);
+ age_imesa(imesa, imesa->sarea->last_enqueue);
+ }
+ }
+
+ imesa->dirty = 0;
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished i810FlushVerticesLocked\n");
+}
+
+
+GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords )
+{
+ GLuint orig_dwords = dwords;
+ GLuint *start;
+
+ dwords++;
+ dwords&=~1;
+
+ if (!imesa->vertex_dma_buffer)
+ {
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810AllocPrimitiveVerts -- get buf\n");
+ LOCK_HARDWARE(imesa);
+ imesa->vertex_dma_buffer = i810_get_buffer_ioctl( imesa );
+ UNLOCK_HARDWARE(imesa);
+ }
+ else if (imesa->vertex_dma_buffer->used + dwords * 4 >
+ imesa->vertex_dma_buffer->total)
+ {
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810AllocPrimitiveVerts -- flush\n");
+ i810FlushVertices( imesa );
+ LOCK_HARDWARE(imesa);
+ imesa->vertex_dma_buffer = i810_get_buffer_ioctl( imesa );
+ UNLOCK_HARDWARE(imesa);
+ }
+
+ if (0)
+ fprintf(stderr, "i810AllocPrimitiveVerts %d, buf %d, used %d\n",
+ dwords, imesa->vertex_dma_buffer->idx,
+ imesa->vertex_dma_buffer->used);
+
+
+ start = (GLuint *)((char *)imesa->vertex_dma_buffer->address +
+ imesa->vertex_dma_buffer->used);
+
+ imesa->vertex_dma_buffer->used += dwords * 4;
+
+ if (orig_dwords & 1)
+ *start++ = 0;
+
+ return start;
+}
+
+
+
+
+
+
+static void i810DDFlush( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ FLUSH_BATCH( imesa );
+}
+
+
+static void i810DDFinish( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810DmaFinish( imesa );
+}
+
+
+void i810DDInitIoctlFuncs( GLcontext *ctx )
+{
+ ctx->Driver.Flush = i810DDFlush;
+ ctx->Driver.Finish = i810DDFinish;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h
new file mode 100644
index 000000000..ac213bf1e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h
@@ -0,0 +1,32 @@
+#ifndef MGA_IOCTL_H
+#define MGA_IOCTL_H
+
+#include "i810context.h"
+
+
+GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords );
+
+void i810GetGeneralDmaBufferLocked( i810ContextPtr mmesa );
+
+void i810FlushVertices( i810ContextPtr mmesa );
+void i810FlushVerticesLocked( i810ContextPtr mmesa );
+
+void i810FlushGeneralLocked( i810ContextPtr imesa );
+void i810WaitAgeLocked( i810ContextPtr imesa, int age );
+void i810WaitAge( i810ContextPtr imesa, int age );
+
+void i810DmaFinish( i810ContextPtr imesa );
+
+void i810RegetLockQuiescent( i810ContextPtr imesa );
+
+void i810DDInitIoctlFuncs( GLcontext *ctx );
+
+
+#define FLUSH_BATCH(imesa) do { \
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) \
+ fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \
+ if (imesa->vertex_dma_buffer) i810FlushVertices(imesa); \
+} while (0)
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810lib.h b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
index ec07995a0..ad80674f0 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810lib.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
@@ -28,29 +28,34 @@
#include <stdio.h>
-#include "i810common.h"
-#include "i810buf.h"
#include "i810context.h"
#include "mm.h"
#include "i810log.h"
-#include "i810dma.h"
-#ifndef MESA31
-#error "The I810 driver now requires Mesa 3.1 or higher"
-#endif
+struct i810_mem_range {
+ unsigned long Start;
+ unsigned long End;
+ unsigned long Size;
+};
+
+struct i810_batch_buffer;
+
+struct i810_ring_buffer {
+ int tail_mask;
+ struct i810_mem_range mem;
+ char *virtual_start;
+ int head;
+ int tail;
+ int space;
+ int synced;
+};
typedef struct {
/* logging stuff */
GLuint logLevel;
FILE *logFile;
- /* dma stuff */
- GLuint dmaDriver;
- GLuint dmaSize;
- GLuint dmaAdr;
- GLuint cmdSize;
-
/* bookkeeping for texture swaps */
GLuint dma_buffer_age;
GLuint current_texture_age;
@@ -68,37 +73,28 @@ typedef struct {
GLuint c_lines;
GLuint c_drawWaits;
GLuint c_textureSwaps;
- GLuint c_signals;
GLuint c_dmaFlush;
GLuint c_overflows;
+
+ GLuint c_ringlost;
+ GLuint c_texlost;
+ GLuint c_ctxlost;
GLuint hardwareWentIdle; /* cleared each swapbuffers, set if a
waitfordmacompletion ever exited
without having to wait */
- /* Primitive managment (like warpSerie) */
- GLuint prim_start;
- GLuint prim_dwords;
-
- /* card == dcache
- * sysmem == normal gart memory
- */
- memHeap_t *cardHeap;
- memHeap_t *sysmemHeap;
- unsigned char *sysmemVirtual;
+ unsigned char *texVirtual;
- i810BatchBuffer *dma_buffer;
+
+ struct i810_batch_buffer *dma_buffer;
+ struct i810_ring_buffer LpRing;
+ unsigned char *MMIOBase;
} i810Glx_t;
extern i810Glx_t i810glx;
-int i810_usec( void );
-void i810LibInit();
-void i810SoftReset();
-
-int i810MakeCurrent(i810ContextPtr ctx, struct i810_dest_buffer *buf);
-void i810LoadTexturePalette(unsigned short *pal, int start, int len);
#define I810PACKCOLOR1555(r,g,b,a) \
((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
@@ -123,6 +119,7 @@ static __inline__ GLuint i810PackColor(GLuint format,
case DV_PF_565:
return I810PACKCOLOR565(r,g,b);
default:
+ fprintf(stderr, "unknown format %d\n", (int)format);
return 0;
}
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
index 2cd53b42e..06269a818 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
@@ -1,15 +1,16 @@
/* #include "i810pipeline.h" */
#include <stdio.h>
-#include "xsmesaP.h"
+
+#include "types.h"
+#include "fog.h"
+
#include "i810vb.h"
#include "i810dd.h"
#include "i810lib.h"
#include "i810tris.h"
+#include "i810pipeline.h"
-#include "fog.h"
-
-#if 0
static struct gl_pipeline_stage i810_fast_stage = {
"I810 fast path",
@@ -68,11 +69,6 @@ GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx )
}
-#endif
-
-
-
-
GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
const struct gl_pipeline_stage *in,
@@ -83,7 +79,6 @@ GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
for (i = o = 0 ; i < nr ; i++) {
switch (in[i].ops) {
-#if 0
case PIPE_OP_RAST_SETUP_0:
out[o] = in[i];
out[o].cva_state_change = NEW_LIGHTING|NEW_TEXTURING|NEW_RASTER_OPS;
@@ -98,7 +93,6 @@ GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
out[o].run = i810DDDoRasterSetup;
o++;
break;
-#endif
/* Completely replace Mesa's fog processing to generate fog
* coordinates instead of messing with colors.
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
index 350f23431..87b95455d 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.h
@@ -7,4 +7,8 @@ extern GLuint i810DDRegisterPipelineStages( struct gl_pipeline_stage *out,
extern GLboolean i810DDBuildPrecalcPipeline( GLcontext *ctx );
+extern void i810DDFastPath( struct vertex_buffer *VB );
+extern void i810DDFastPathInit( void );
+
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ring.c b/xc/lib/GL/mesa/src/drv/i810/i810ring.c
deleted file mode 100644
index 2e5909e9f..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810ring.c
+++ /dev/null
@@ -1,162 +0,0 @@
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include "mm.h"
-#include "i810dd.h"
-#include "i810lib.h"
-#include "i810state.h"
-
-
-#include "i810dma.h"
-
-static void
-I810PrintErrorState( void )
-{
- fprintf(stderr, "pgetbl_ctl: 0x%x pgetbl_err: 0x%x\n",
- INREG(PGETBL_CTL),
- INREG(PGE_ERR));
-
- fprintf(stderr, "ipeir: %x iphdr: %x\n",
- INREG(IPEIR),
- INREG(IPEHR));
-
- fprintf(stderr, "LP ring tail: %x head: %x len: %x start %x\n",
- INREG(LP_RING + RING_TAIL),
- INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
- INREG(LP_RING + RING_LEN),
- INREG(LP_RING + RING_START));
-
- fprintf(stderr, "eir: %x esr: %x emr: %x\n",
- INREG16(EIR),
- INREG16(ESR),
- INREG16(EMR));
-
- fprintf(stderr, "instdone: %x instpm: %x\n",
- INREG16(INST_DONE),
- INREG8(INST_PM));
-
- fprintf(stderr, "memmode: %x instps: %x\n",
- INREG(MEMMODE),
- INREG(INST_PS));
-
- fprintf(stderr, "hwstam: %x ier: %x imr: %x iir: %x\n",
- INREG16(HWSTAM),
- INREG16(IER),
- INREG16(IMR),
- INREG16(IIR));
-}
-
-
-
-
-static int
-I810USec( void )
-{
- struct timeval tv;
- struct timezone tz;
- gettimeofday( &tv, &tz );
- return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec;
-}
-
-
-
-void
-_I810RefreshLpRing( i810ContextPtr imesa, int update )
-{
- struct i810_ring_buffer *ring = &(i810glx.LpRing);
-
- ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->tail = INREG(LP_RING + RING_TAIL);
- ring->space = ring->head - (ring->tail+8);
-
- if (ring->space < 0) {
- ring->space += ring->mem.Size;
- if (update)
- imesa->sarea->lastWrap = ++imesa->sarea->ringAge;
- }
-}
-
-int
-_I810WaitLpRing( i810ContextPtr imesa, int n, int timeout_usec )
-{
- struct i810_ring_buffer *ring = &(i810glx.LpRing);
- int iters = 0;
- int startTime = 0;
- int curTime = 0;
-
- if (timeout_usec == 0)
- timeout_usec = 15000000;
-
- if (I810_DEBUG & DEBUG_VERBOSE_API)
- fprintf(stderr, "I810WaitLpRing %d\n", n);
-
- while (ring->space < n)
- {
- int i;
-
- ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->space = ring->head - (ring->tail+8);
-
- if (ring->space < 0) {
- imesa->sarea->lastWrap = ++imesa->sarea->ringAge;
- ring->space += ring->mem.Size;
- }
-
- iters++;
- curTime = I810USec();
- if ( startTime == 0 || curTime < startTime /*wrap case*/) {
- startTime = curTime;
- } else if ( curTime - startTime > timeout_usec ) {
- I810PrintErrorState();
- fprintf(stderr, "space: %d wanted %d\n",
- ring->space, n );
- UNLOCK_HARDWARE(imesa);
- exit(1);
- }
-
- for (i = 0 ; i < 2000 ; i++)
- ;
- }
-
- return iters;
-}
-
-int
-_I810Sync( i810ContextPtr imesa )
-{
- int rv;
-
- if (I810_DEBUG & DEBUG_VERBOSE_API)
- fprintf(stderr, "I810Sync\n");
-
- /* 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( imesa, 2 );
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH );
- OUT_RING( 0 ); /* pad to quadword */
- ADVANCE_LP_RING();
- }
-
-
- i810glx.LpRing.synced = 1; /* ?? */
-
- rv = _I810WaitLpRing( imesa, i810glx.LpRing.mem.Size - 8, 0 );
- imesa->sarea->lastSync = ++imesa->sarea->ringAge;
-
- return rv;
-}
-
-
-
-
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c
index ce55c6f70..c47bf2f40 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810span.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c
@@ -1,149 +1,174 @@
#include "types.h"
-#include "i810buf.h"
#include "i810dd.h"
#include "i810lib.h"
#include "i810dma.h"
#include "i810log.h"
+#include "i810span.h"
+#include "i810ioctl.h"
-static void (*xsmWriteRGBASpan)( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- CONST GLubyte rgba[][4],
- const GLubyte mask[] );
-static void (*xsmWriteRGBSpan)( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- CONST GLubyte rgb[][3], const GLubyte mask[] );
-static void (*xsmWriteMonoRGBASpan)(const GLcontext *ctx, GLuint n,
- GLint x, GLint y,const GLubyte mask[] );
-static void (*xsmWriteRGBAPixels)(const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- CONST GLubyte rgba[][4],
- const GLubyte mask[] );
-static void (*xsmWriteMonoRGBAPixels)(const GLcontext *ctx,GLuint n,
- const GLint x[], const GLint y[],
- const GLubyte mask[] );
-static void (*xsmReadRGBASpan)(const GLcontext *ctx, GLuint n,
- GLint x, GLint y,GLubyte rgba[][4] );
-static void (*xsmReadRGBAPixels)(const GLcontext *ctx,GLuint n,
- const GLint x[], const GLint y[],
- GLubyte rgba[][4], const GLubyte mask[] );
-
-/* Wrapper functions */
-
-static void WriteRGBASpan( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- CONST GLubyte rgba[][4],
- const GLubyte mask[] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmWriteRGBASpan)(ctx,n,x,y,rgba,mask);
-}
-static void WriteRGBSpan( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- CONST GLubyte rgb[][3], const GLubyte mask[] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmWriteRGBSpan)(ctx,n,x,y,rgb,mask);
-}
+#define DBG 0
-static void WriteMonoRGBASpan(const GLcontext *ctx, GLuint n,
- GLint x, GLint y,const GLubyte mask[] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmWriteMonoRGBASpan)(ctx,n,x,y,mask);
-}
+#define LOCAL_VARS \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ i810ScreenPrivate *i810Screen = imesa->i810Screen; \
+ GLuint pitch = i810Screen->backPitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(imesa->drawMap + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch); \
+ char *read_buf = (char *)(imesa->readMap + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch); \
+ GLushort p = I810_CONTEXT( ctx )->MonoColor; \
+ (void) read_buf; (void) buf; (void) p
-static void WriteRGBAPixels(const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- CONST GLubyte rgba[][4],
- const GLubyte mask[] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmWriteRGBAPixels)(ctx,n,x,y,rgba,mask);
-}
+#define LOCAL_DEPTH_VARS \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ i810ScreenPrivate *i810Screen = imesa->i810Screen; \
+ GLuint pitch = i810Screen->backPitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(i810Screen->depth.map + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch)
-static void WriteMonoRGBAPixels(const GLcontext *ctx,GLuint n,
- const GLint x[], const GLint y[],
- const GLubyte mask[] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmWriteMonoRGBAPixels)(ctx,n,x,y,mask);
-}
+#define INIT_MONO_PIXEL(p)
-static void ReadRGBASpan(const GLcontext *ctx, GLuint n,
- GLint x, GLint y,GLubyte rgba[][4] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmReadRGBASpan)(ctx,n,x,y,rgba);
-}
+#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
+ _y >= miny && _y < maxy)
-static void ReadRGBAPixels(const GLcontext *ctx,GLuint n,
- const GLint x[], const GLint y[],
- GLubyte rgba[][4], const GLubyte mask[] )
-{
- i810Msg(12,__FUNCTION__ "\n");
- i810WaitDrawingEngine();
- (*xsmReadRGBAPixels)(ctx,n,x,y,rgba,mask);
-}
-#define WRAP(x) \
- xsm ## x = ctx->Driver.x; \
- ctx->Driver.x = x
+#define CLIPSPAN(_x,_y,_n,_x1,_n1,_i) \
+ if (_y < miny || _y >= maxy) _n1 = 0, _x1 = x; \
+ else { \
+ _n1 = _n; \
+ _x1 = _x; \
+ if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \
+ if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \
+ }
-void i810DDInitSpans( GLcontext *ctx )
-{
- /* Need another hook from mesa to synchronize hardware before
- * write-pixels and read-spans/pixels.
- */
- WRAP(WriteRGBASpan);
- WRAP(WriteRGBSpan);
- WRAP(WriteMonoRGBASpan);
- WRAP(WriteRGBAPixels);
- WRAP(WriteMonoRGBAPixels);
- WRAP(ReadRGBASpan);
- WRAP(ReadRGBAPixels);
-}
+#define Y_FLIP(_y) (height - _y - 1)
+#define HW_LOCK() \
+ i810ContextPtr imesa = I810_CONTEXT(ctx); \
+ LOCK_HARDWARE_QUIESCENT(imesa);
+#define HW_CLIPLOOP() \
+ do { \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
+ int _nc = dPriv->numClipRects; \
+ while (_nc--) { \
+ int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
+ int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
+ int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
+ int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+#define HW_ENDCLIPLOOP() \
+ } \
+ } while (0)
+#define HW_UNLOCK() \
+ UNLOCK_HARDWARE(imesa);
-void fxUpdateDDSpanPointers(GLcontext *ctx)
-{
- ctx->Driver.DepthTestSpan=fxDDDepthTestSpanGeneric;
- ctx->Driver.DepthTestPixels=fxDDDepthTestPixelsGeneric;
- ctx->Driver.ReadDepthSpanFloat=fxDDReadDepthSpanFloat;
- ctx->Driver.ReadDepthSpanInt=fxDDReadDepthSpanInt;
-}
+/* 16 bit, 565 rgb color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
+ (((int)g & 0xfc) << 3) | \
+ (((int)b & 0xf8) >> 3))
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 8) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xfc; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) i810##x##_565
+#include "spantmp.h"
+
+
+
+
+/* 15 bit, 555 rgb color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
+ ((g & 0xf8) << 3) | \
+ ((b & 0xf8) >> 3))
+
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 7) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xf8; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0; /* or 255? */ \
+} while(0)
+
+#define TAG(x) i810##x##_555
+#include "spantmp.h"
+
+
+
+
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLdepth *)(buf + _x*2 + _y*pitch) = d;
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLdepth *)(buf + _x*2 + _y*pitch);
+
+/* d = 0xffff; */
+
+#define TAG(x) i810##x##_16
+#include "depthtmp.h"
+
+
-void fxSetupDDSpanPointers(GLcontext *ctx)
+void i810DDInitSpanFuncs( GLcontext *ctx )
{
- ctx->Driver.WriteRGBASpan =fxDDWriteRGBASpan;
- ctx->Driver.WriteRGBSpan =fxDDWriteRGBSpan;
- ctx->Driver.WriteMonoRGBASpan =fxDDWriteMonoRGBASpan;
- ctx->Driver.WriteRGBAPixels =fxDDWriteRGBAPixels;
- ctx->Driver.WriteMonoRGBAPixels =fxDDWriteMonoRGBAPixels;
-
- ctx->Driver.WriteCI8Span =NULL;
- ctx->Driver.WriteCI32Span =NULL;
- ctx->Driver.WriteMonoCISpan =NULL;
- ctx->Driver.WriteCI32Pixels =NULL;
- ctx->Driver.WriteMonoCIPixels =NULL;
-
- ctx->Driver.ReadRGBASpan =fxDDReadRGBASpan;
- ctx->Driver.ReadRGBAPixels =fxDDReadRGBAPixels;
-
- ctx->Driver.ReadCI32Span =NULL;
- ctx->Driver.ReadCI32Pixels =NULL;
+ if (1) {
+ ctx->Driver.WriteRGBASpan = i810WriteRGBASpan_565;
+ ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_565;
+ ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_565;
+ ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_565;
+ ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565;
+ ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_565;
+ ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_565;
+ } else {
+ ctx->Driver.WriteRGBASpan = i810WriteRGBASpan_555;
+ ctx->Driver.WriteRGBSpan = i810WriteRGBSpan_555;
+ ctx->Driver.WriteMonoRGBASpan = i810WriteMonoRGBASpan_555;
+ ctx->Driver.WriteRGBAPixels = i810WriteRGBAPixels_555;
+ ctx->Driver.WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_555;
+ ctx->Driver.ReadRGBASpan = i810ReadRGBASpan_555;
+ ctx->Driver.ReadRGBAPixels = i810ReadRGBAPixels_555;
+ }
+
+ ctx->Driver.ReadDepthSpan = i810ReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = i810WriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = i810ReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = i810WriteDepthPixels_16;
+
+ ctx->Driver.WriteCI8Span =NULL;
+ ctx->Driver.WriteCI32Span =NULL;
+ ctx->Driver.WriteMonoCISpan =NULL;
+ ctx->Driver.WriteCI32Pixels =NULL;
+ ctx->Driver.WriteMonoCIPixels =NULL;
+ ctx->Driver.ReadCI32Span =NULL;
+ ctx->Driver.ReadCI32Pixels =NULL;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.h b/xc/lib/GL/mesa/src/drv/i810/i810span.h
index 07276cd86..17a52085b 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810span.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.h
@@ -1,6 +1,6 @@
#ifndef _I810_SPAN_H
#define _I810_SPAN_H
-extern void i810DDInitSpans( GLcontext *ctx );
+extern void i810DDInitSpanFuncs( GLcontext *ctx );
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c
index e4a77efc1..caf9fafd6 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810state.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c
@@ -1,33 +1,33 @@
#include <stdio.h>
-#include "xsmesaP.h"
-
#include "types.h"
+#include "enums.h"
#include "pb.h"
#include "dd.h"
-#include "glx_log.h"
#include "mm.h"
#include "i810lib.h"
-#include "i810glx.h"
#include "i810dd.h"
#include "i810context.h"
#include "i810state.h"
-#include "i810depth.h"
#include "i810tex.h"
#include "i810log.h"
#include "i810vb.h"
#include "i810tris.h"
+#include "i810ioctl.h"
+
+
static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
-
CARD32 a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
+ FLUSH_BATCH(imesa);
+
switch (ctx->Color.AlphaFunc) {
case GL_NEVER: a |= ZA_ALPHA_NEVER; break;
case GL_LESS: a |= ZA_ALPHA_LESS; break;
@@ -42,21 +42,17 @@ static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
a |= ctx->Color.AlphaRef << ZA_ALPHAREF_SHIFT;
- imesa->reg_dirty |= (1<<I810_CTXREG_ZA);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK);
imesa->Setup[I810_CTXREG_ZA] |= a;
}
-/* This shouldn't get called, as the extension is disabled. However,
- * there are internal Mesa calls, and rouge use of the api which must be
- * caught.
- */
static void i810DDBlendEquation(GLcontext *ctx, GLenum mode)
{
if (mode != GL_FUNC_ADD_EXT) {
ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
- FatalError("Unsupported blend equation");
- gl_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
+ i810Error("Unsupported blend equation");
+ exit(1);
}
}
@@ -65,6 +61,9 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
i810ContextPtr imesa = I810_CONTEXT(ctx);
GLuint a;
+ FLUSH_BATCH(imesa);
+
+
a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
switch (ctx->Color.BlendSrcRGB) {
@@ -80,7 +79,8 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
a |= SDM_SRC_SRC_ALPHA; /* use GFXRENDERSTATE_COLOR_FACTOR ??? */
break;
default:
- FatalError("unknown blend source func");
+ i810Error("unknown blend source func");
+ exit(1);
return;
}
@@ -94,11 +94,12 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
case GL_DST_ALPHA: a |= SDM_DST_ONE; break;
case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
default:
- FatalError("unknown blend dst func");
+ i810Error( "unknown blend dst func");
+ exit(1);
return;
}
- imesa->reg_dirty |= (1<<I810_CTXREG_SDM);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK);
imesa->Setup[I810_CTXREG_SDM] |= a;
}
@@ -124,6 +125,8 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func)
i810ContextPtr imesa = I810_CONTEXT(ctx);
int zmode;
+ FLUSH_BATCH(imesa);
+
switch(func) {
case GL_NEVER: zmode = LCS_Z_NEVER; break;
case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
@@ -135,43 +138,161 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func)
case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
default: return;
}
-
- /* Could just fire it off now...
- */
+
imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode;
- imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+
+ imesa->dirty |= I810_UPLOAD_CTX;
}
static void i810DDDepthMask(GLcontext *ctx, GLboolean flag)
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
- imesa->reg_dirty |= (1<<I810_CTXREG_B2);
+ FLUSH_BATCH(imesa);
+
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
- imesa->Setup[I810_CTXREG_B2] |= B2_UPDATE_ZB_WRITE_ENABLE;
if (flag)
imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
+}
-/*
- Possible technique to reduce the amount of checking for small state
- changes. Large ones detect wrap on update_count & just send the
- whole state...
- {
- imesa->Update[imesa->update_count & MAX_UPDATE] =
- ( imesa->Setup[I810_CTXREG_B2] &
- (B1_ZB_WRITE_ENABLE | B1_UPDATE_ZB_WRITE_ENABLE | GFX_OP_BOOL_1)
- );
- imesa->update_count++;
- }
-*/
+/* =============================================================
+ * Polygon stipple
+ *
+ * The i810 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern. Could
+ * also consider using a multitexturing mechanism for this, but
+ * that has real issues, too.
+ */
+static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ const GLubyte *m = mask;
+ GLubyte p[4];
+ int i,j,k;
+ int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON);
+
+ FLUSH_BATCH(imesa);
+ ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE;
+
+ if (active) {
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ }
+
+ p[0] = mask[0] & 0xf; p[0] |= p[0] << 4;
+ p[1] = mask[4] & 0xf; p[1] |= p[1] << 4;
+ p[2] = mask[8] & 0xf; p[2] |= p[2] << 4;
+ p[3] = mask[12] & 0xf; p[3] |= p[3] << 4;
+
+ for (k = 0 ; k < 8 ; k++)
+ for (j = 0 ; j < 4; j++)
+ for (i = 0 ; i < 4 ; i++)
+ if (*m++ != p[j]) {
+ ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE;
+ return;
+ }
+
+
+
+ imesa->poly_stipple = ( ((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12) );
+
+ if (1) {
+ imesa->Setup[I810_CTXREG_ST1] &= ~0xffff;
+ imesa->Setup[I810_CTXREG_ST1] |= ( ((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12) );
+ }
+
+ if (active)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
}
+/* ============================================================
+ * Line stipple -- not completed
+ * - need to cope with stipplecounter
+ */
+#if 0
+static void i810DDLineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ GLushort p, h, test;
+
+ FLUSH_BATCH(imesa);
+ ctx->Driver.TriangleCaps |= DD_LINE_STIPPLE;
+
+ if (ctx->Line.StippleFlag) {
+ imesa->lines_are_tris |= I810_LINE_STIPPLE;
+
+ if (ctx->PB->primitive == GL_LINE) {
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ }
+ }
+
+ switch (factor) {
+ case 1:
+ p = pattern & 0xf;
+ p |= p << 4;
+ p |= p << 8;
+ test = p;
+ break;
+ case 2:
+ p = pattern & 1;
+ p |= (pattern & 2) << 2;
+ p |= p << 1;
+ p |= p << 4;
+ p |= p << 8;
+ test = pattern & 3;
+ test |= test << 2;
+ test |= test << 4;
+ test |= test << 8;
+ break;
+ default:
+ p = 0;
+ if (pattern)
+ p = 0xffff;
+ test = p;
+ break;
+ }
+
+ if (pattern != test) {
+ ctx->Driver.TriangleCaps &= ~DD_LINE_STIPPLE;
+ imesa->lines_are_tris &= ~I810_LINE_STIPPLE;
+ return;
+ }
+
+ h = (((p & 1) << 0) |
+ ((p & 2) << 4) |
+ ((p & 3) << 8) |
+ ((p & 4) << 12));
+
+ h |= h << 1;
+ h |= h << 2;
+
+ imesa->vert_line_stipple = p;
+ imesa->horiz_line_stipple = h;
+
+ if (ctx->Line.Stipple && ctx->PB->primitive == GL_LINE)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+}
+#endif
+
+/* ============================================================
+ * Antialiased lines and triangles
+ */
+/* Nothing to do...
+ */
@@ -184,36 +305,105 @@ static void i810DDDepthMask(GLcontext *ctx, GLboolean flag)
static void i810DDScissor( GLcontext *ctx, GLint x, GLint y,
- GLsizei w, GLsizei h )
+ GLsizei w, GLsizei h )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ FLUSH_BATCH(imesa);
+ imesa->scissor_rect.x1 = x;
+ imesa->scissor_rect.y1 = imesa->driDrawable->h - (y+h);
+ imesa->scissor_rect.x2 = x+w;
+ imesa->scissor_rect.y2 = imesa->driDrawable->h - y;
+
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n",
+ imesa->scissor_rect.x1,
+ imesa->scissor_rect.y1,
+ imesa->scissor_rect.x2,
+ imesa->scissor_rect.y2);
+
+
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+}
+
+
+static void i810DDDither(GLcontext *ctx, GLboolean enable)
+{
+}
+
+
+static GLboolean i810DDSetDrawBuffer(GLcontext *ctx, GLenum mode )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
- int x1,x2,y1,y2;
- x1 = ctx->Scissor.X;
- x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
- y1 = i810DB->Height - ctx->Scissor.Y - ctx->Scissor.Height;
- y2 = i810DB->Height - ctx->Scissor.Y - 1;
-
- if (x1 < 0) x1 = 0;
- if (y1 < 0) y1 = 0;
- if (x2 >= i810DB->Width) x2 = i810DB->Width-1;
- if (y2 >= i810DB->Height) y2 = i810DB->Height-1;
-
- if (x1 > x2 || y1 > y2) {
- x1 = 0; x2 = 0;
- y2 = 0; y1 = 1;
+ FLUSH_BATCH(imesa);
+
+ imesa->Fallback &= ~I810_FALLBACK_DRAW_BUFFER;
+
+ if (mode == GL_FRONT_LEFT)
+ {
+ imesa->drawMap = imesa->driScreen->pFB;
+ imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset |
+ imesa->i810Screen->backPitchBits);
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+ i810XMesaSetFrontClipRects( imesa );
+ return GL_TRUE;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ imesa->drawMap = imesa->i810Screen->back.map;
+ imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset |
+ imesa->i810Screen->backPitchBits);
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+ i810XMesaSetBackClipRects( imesa );
+ return GL_TRUE;
}
- /* Turn it off if full screen?
- */
- imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO;
- imesa->Setup[I810_CTXREG_SCI1] = (y1<<16)|x1;
- imesa->Setup[I810_CTXREG_SCI2] = (y2<<16)|x2;
+ imesa->Fallback |= I810_FALLBACK_DRAW_BUFFER;
+ return GL_FALSE;
+}
+static void i810DDSetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
+ GLenum mode )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
- imesa->reg_dirty |= ((1<<I810_CTXREG_SCI0) |
- (1<<I810_CTXREG_SCI1) |
- (1<<I810_CTXREG_SCI2));
+ if (mode == GL_FRONT_LEFT)
+ {
+ imesa->readMap = imesa->driScreen->pFB;
+ imesa->Fallback &= ~I810_FALLBACK_READ_BUFFER;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ imesa->readMap = imesa->i810Screen->back.map;
+ imesa->Fallback &= ~I810_FALLBACK_READ_BUFFER;
+ }
+ else
+ imesa->Fallback |= I810_FALLBACK_READ_BUFFER;
+}
+
+
+
+static void i810DDSetColor(GLcontext *ctx,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat,
+ r, g, b, a );
+}
+
+
+static void i810DDClearColor(GLcontext *ctx,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat,
+ r, g, b, a );
}
@@ -226,6 +416,8 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
i810ContextPtr imesa = I810_CONTEXT(ctx);
GLuint mode = LCS_CULL_BOTH;
+ FLUSH_BATCH(imesa);
+
if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
mode = LCS_CULL_CW;
if (ctx->Polygon.CullFaceMode == GL_FRONT)
@@ -238,25 +430,55 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
if (ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON)
{
- imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ imesa->Setup[I810_CTXREG_LCS] |= mode;
}
}
static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
{
- if (ctx->Polygon.CullFlag) {
- i810ContextPtr imesa = I810_CONTEXT(ctx);
- GLuint mode = imesa->LcsCullMode;
-
- if (ctx->PB->primitive != GL_POLYGON)
- mode = LCS_CULL_DISABLE;
-
- imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
- imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ FLUSH_BATCH(imesa);
+
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+
+ switch (ctx->PB->primitive) {
+ case GL_POLYGON:
+ if (ctx->Polygon.StippleFlag &&
+ (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE))
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+ if (ctx->Polygon.CullFlag)
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
+ else
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ if (ctx->Polygon.SmoothFlag)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ break;
+ case GL_LINES:
+#if 0
+ if (ctx->Line.StippleFlag && (ctx->Driver.TriangleCaps & DD_LINE_STIPPLE))
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+#endif
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+ if (ctx->Line.SmoothFlag) {
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+ }
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
+ case GL_POINTS:
+ if (ctx->Point.SmoothFlag)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
+ default:
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
}
}
@@ -266,15 +488,36 @@ static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
* Color masks
*/
-/* Mesa calls this from the wrong place.
+/* Mesa calls this from the wrong place - it is called a very large
+ * number of redundant times.
*
- * Its a fallback...
+ * Colormask can be simulated by multipass or multitexture techniques.
*/
static GLboolean i810DDColorMask(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a )
{
- return 1;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint tmp = 0;
+ GLuint rv = 1;
+
+ imesa->Fallback &= ~I810_FALLBACK_COLORMASK;
+
+ if (r && g && b) {
+ tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE;
+ } else if (!r && !g && !b) {
+ tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE;
+ } else {
+ rv = 0;
+ imesa->Fallback |= I810_FALLBACK_COLORMASK;
+ }
+
+ if (tmp != imesa->Setup[I810_CTXREG_B2]) {
+ FLUSH_BATCH(imesa);
+ imesa->Setup[I810_CTXREG_B2] = tmp;
+ }
+
+ return rv;
}
/* Seperate specular not fully implemented in hardware... Needs
@@ -284,7 +527,16 @@ static GLboolean i810DDColorMask(GLcontext *ctx,
static void i810DDLightModelfv(GLcontext *ctx, GLenum pname,
const GLfloat *param)
{
- if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+ {
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ FLUSH_BATCH(imesa);
+
+ imesa->Fallback &= ~I810_FALLBACK_SPECULAR;
+
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ imesa->Fallback |= I810_FALLBACK_SPECULAR;
+
I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE;
}
}
@@ -295,7 +547,7 @@ static void i810DDLightModelfv(GLcontext *ctx, GLenum pname,
* Fog
*/
-void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+static void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
@@ -304,7 +556,7 @@ void i810DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
- imesa->reg_dirty |= (1<<I810_CTXREG_FOG);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) &
~FOG_RESERVED_MASK);
}
@@ -320,66 +572,126 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
switch(cap) {
case GL_ALPHA_TEST:
- imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_ALPHA_TEST_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
break;
case GL_BLEND:
- imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_BLEND_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
break;
case GL_DEPTH_TEST:
- imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_Z_TEST_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
break;
case GL_SCISSOR_TEST:
- imesa->reg_dirty |= (1<<I810_CTXREG_SC);
- imesa->Setup[I810_CTXREG_SC] &= ~SC_ENABLE_MASK;
- imesa->Setup[I810_CTXREG_SC] |= SC_UPDATE_SCISSOR;
- if (state)
- imesa->Setup[I810_CTXREG_SC] |= SC_ENABLE;
+ FLUSH_BATCH(imesa);
+ imesa->scissor = state;
+ imesa->dirty |= I810_EMIT_CLIPRECT;
+ break;
+ case GL_POLYGON_STIPPLE:
+ if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) &&
+ ctx->PB->primitive == GL_POLYGON)
+ {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+ }
+ break;
+ case GL_LINE_STIPPLE:
+#if 0
+ if (ctx->Driver.TriangleCaps & DD_LINE_STIPPLE)
+ {
+ imesa->lines_are_tris &= ~I810_LINE_STIPPLE;
+ if (state)
+ imesa->lines_are_tris |= I810_LINE_STIPPLE;
+
+ if (ctx->PB->primitive == GL_LINE) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+ }
+ }
+#endif
+ break;
+ case GL_LINE_SMOOTH:
+ if (ctx->PB->primitive == GL_LINE) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+ if (state) {
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+ }
+ }
+ break;
+ case GL_POINT_SMOOTH:
+ if (ctx->PB->primitive == GL_POINT) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ }
+ break;
+ case GL_POLYGON_SMOOTH:
+ if (ctx->PB->primitive == GL_POLYGON) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ }
break;
case GL_FOG:
- imesa->reg_dirty |= (1<<I810_CTXREG_B1);
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_FOG_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
break;
case GL_CULL_FACE:
if (ctx->PB->primitive == GL_POLYGON) {
- imesa->reg_dirty |= (1<<I810_CTXREG_LCS);
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_CULL_MODE;
if (state)
imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
else
imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
}
break;
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_3D:
+ FLUSH_BATCH(imesa);
+ imesa->new_state |= I810_NEW_TEXTURE;
+ break;
case GL_TEXTURE_2D:
- imesa->reg_dirty |= (1<<I810_CTXREG_MT);
+ FLUSH_BATCH(imesa);
+ imesa->new_state |= I810_NEW_TEXTURE;
+ imesa->dirty |= I810_UPLOAD_CTX;
if (ctx->Texture.CurrentUnit == 0) {
imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
- imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL0_STATE;
if (state)
imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
} else {
imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
- imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL1_STATE;
if (state)
imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
}
-
- I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE;
break;
default:
;
@@ -387,26 +699,6 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
}
-/* Don't use the regs parm yet.
- */
-static void i810UpdateRegs( GLcontext *ctx, GLuint regs )
-{
- i810ContextPtr imesa = I810_CONTEXT(ctx);
- int i;
-
- {
- BEGIN_BATCH( I810_CTX_SETUP_SIZE );
-
- for (i = 0 ; i < I810_CTX_SETUP_SIZE ; i++) {
- OUT_BATCH( imesa->Setup[i] );
- }
-
- ADVANCE_BATCH();
- }
-
- imesa->reg_dirty = 0;
-}
-
/* =============================================================
*/
@@ -417,50 +709,158 @@ void i810DDPrintState( const char *msg, GLuint state )
{
fprintf(stderr, "%s (0x%x): %s\n",
msg,
- state,
+ (unsigned int) state,
(state & I810_NEW_TEXTURE) ? "texture, " : "");
}
+
+
void i810DDUpdateHwState( GLcontext *ctx )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
- if (imesa->new_state & I810_NEW_TEXTURE)
+ if (imesa->new_state & I810_NEW_TEXTURE) {
+ FLUSH_BATCH(imesa);
i810UpdateTextureState( ctx );
+ }
imesa->new_state = 0;
+}
+
- if (imesa->reg_dirty) {
- i810FinishPrimitive();
- i810UpdateRegs( ctx, imesa->reg_dirty );
+
+/*
+ * i810DmaExecute
+ * Add a block of data to the dma buffer
+ *
+ * -- In ring buffer mode, must be called with lock held, and translates to
+ * OUT_RING rather than outbatch
+ *
+ * -- In dma mode, probably won't be used because state updates will have
+ * to be done via the kernel for security...
+ */
+static void i810DmaExecute( i810ContextPtr imesa,
+ GLuint *code, int dwords, const char *where )
+{
+ if (I810_DEBUG & DEBUG_VERBOSE_RING)
+ fprintf(stderr, "i810DmaExecute (%s)\n", where);
+
+ if (dwords & 1) {
+ i810Error( "Misaligned buffer in i810DmaExecute\n" );
+ exit(1);
+ }
+
+ {
+ int i;
+ BEGIN_BATCH( imesa, dwords);
+
+ for ( i = 0 ; i < dwords ; i++ ) {
+ OUT_BATCH( code[i] );
+ }
+
+ ADVANCE_BATCH();
}
}
-void i810DDInitStatePointers(GLcontext *ctx)
+
+void i810EmitDrawingRectangle( i810ContextPtr imesa )
{
- ctx->Driver.Enable = i810DDEnable;
- ctx->Driver.LightModelfv = i810DDLightModelfv;
- ctx->Driver.AlphaFunc = i810DDAlphaFunc;
- ctx->Driver.BlendEquation = i810DDBlendEquation;
- ctx->Driver.BlendFunc = i810DDBlendFunc;
- ctx->Driver.BlendFuncSeparate = i810DDBlendFuncSeparate;
- ctx->Driver.DepthFunc = i810DDDepthFunc;
- ctx->Driver.DepthMask = i810DDDepthMask;
- ctx->Driver.Fogfv = i810DDFogfv;
- ctx->Driver.Scissor = i810DDScissor;
- ctx->Driver.CullFace = i810DDCullFaceFrontFace;
- ctx->Driver.FrontFace = i810DDCullFaceFrontFace;
- ctx->Driver.ColorMask = i810DDColorMask;
- ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange;
- ctx->Driver.RenderStart = i810DDUpdateHwState;
- ctx->Driver.RenderFinish = 0;
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ int x0 = imesa->drawX;
+ int y0 = imesa->drawY;
+ int x1 = x0 + dPriv->w;
+ int y1 = y0 + dPriv->h;
+
+
+ /* Coordinate origin of the window - may be offscreen.
+ */
+ imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) |
+ (((unsigned)x0)&0xFFFF));
+
+ /* Clip to screen.
+ */
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 > i810Screen->width-1) x1 = i810Screen->width-1;
+ if (y1 > i810Screen->height-1) y1 = i810Screen->height-1;
+
+
+ /* Onscreen drawing rectangle.
+ */
+ imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0);
+ imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
+ imesa->dirty |= I810_UPLOAD_BUFFERS;
+}
+
+
+static void i810DDPrintDirty( const char *msg, GLuint state )
+{
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
+ msg,
+ (unsigned int) state,
+ (state & I810_REFRESH_RING) ? "read-lp-ring, " : "",
+ (state & I810_WAIT_AGE) ? "wait-age, " : "",
+ (state & I810_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "",
+ (state & I810_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "",
+ (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "",
+ (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
+ (state & I810_EMIT_CLIPRECT) ? "emit-single-cliprect, " : ""
+ );
}
+/* Spew the state onto the ring/batch buffer and/or texture memory.
+ */
+void i810EmitHwStateLocked( i810ContextPtr imesa )
+{
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ i810DDPrintDirty( "\n\n\ni810EmitHwStateLocked", imesa->dirty );
+
+ if (imesa->dirty & ~(I810_WAIT_AGE|I810_EMIT_CLIPRECT))
+ {
+ i810GetGeneralDmaBufferLocked( imesa );
+
+ if ((imesa->dirty & I810_UPLOAD_TEX0IMAGE) && imesa->CurrentTexObj[0])
+ i810UploadTexImages(imesa, imesa->CurrentTexObj[0]);
+
+ if ((imesa->dirty & I810_UPLOAD_TEX1IMAGE) && imesa->CurrentTexObj[1])
+ i810UploadTexImages(imesa, imesa->CurrentTexObj[1]);
+
+ if ((imesa->dirty & I810_UPLOAD_CTX)) {
+ i810DmaExecute( imesa, imesa->Setup, I810_CTX_SETUP_SIZE, "context" );
+
+ if (imesa->CurrentTexObj[0])
+ i810DmaExecute( imesa, imesa->CurrentTexObj[0]->Setup,
+ I810_TEX_SETUP_SIZE, "tex-0");
+
+ if (imesa->CurrentTexObj[1])
+ i810DmaExecute( imesa, imesa->CurrentTexObj[1]->Setup,
+ I810_TEX_SETUP_SIZE, "tex-1");
+ }
+
+ if (imesa->dirty & I810_UPLOAD_BUFFERS)
+ i810DmaExecute( imesa, imesa->BufferSetup,
+ I810_DEST_SETUP_SIZE, "buffers" );
+
+ i810FlushGeneralLocked( imesa );
+ }
+
+ /* Clear everything but the cliprect dirty flag:
+ */
+ imesa->dirty &= (I810_EMIT_CLIPRECT|I810_WAIT_AGE);
+}
+
+
+
void i810DDInitState( i810ContextPtr imesa )
{
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ memset(imesa->Setup, 0, sizeof(imesa->Setup));
imesa->Setup[I810_CTXREG_VF] = (GFX_OP_VERTEX_FMT |
VF_TEXCOORD_COUNT_2 |
@@ -562,6 +962,8 @@ void i810DDInitState( i810ContextPtr imesa )
imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO |
+ SDM_UPDATE_MONO_ENABLE |
+ 0 |
SDM_UPDATE_SRC_BLEND |
SDM_SRC_ONE |
SDM_UPDATE_DST_BLEND |
@@ -627,7 +1029,7 @@ void i810DDInitState( i810ContextPtr imesa )
LCS_UPDATE_ZMODE |
LCS_Z_LESS |
LCS_UPDATE_LINEWIDTH |
- (0x2<<LCS_LINEWIDTH_SHIFT) |
+ LCS_LINEWIDTH_1_0 |
LCS_UPDATE_ALPHA_INTERP |
LCS_ALPHA_INTERP |
LCS_UPDATE_FOG_INTERP |
@@ -641,14 +1043,6 @@ void i810DDInitState( i810ContextPtr imesa )
imesa->LcsCullMode = LCS_CULL_CW;
- imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO;
- imesa->Setup[I810_CTXREG_SCI1] = 0;
- imesa->Setup[I810_CTXREG_SCI2] = 0;
-
- imesa->Setup[I810_CTXREG_SC] = ( GFX_OP_SCISSOR |
- SC_UPDATE_SCISSOR |
- 0 );
-
imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE |
PV_UPDATE_PIXRULE |
PV_PIXRULE_ENABLE |
@@ -659,8 +1053,59 @@ void i810DDInitState( i810ContextPtr imesa )
PV_UPDATE_TRISTRIP |
PV_TRISTRIP_PV0 );
-}
+ imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE;
+ imesa->Setup[I810_CTXREG_ST1] = 0;
+
+
+
+ imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS |
+ AA_UPDATE_EDGEFLAG |
+ AA_ENABLE_EDGEFLAG | /* ? */
+ AA_UPDATE_POLYWIDTH |
+ AA_POLYWIDTH_05 |
+ AA_UPDATE_LINEWIDTH |
+ AA_LINEWIDTH_05 |
+ AA_UPDATE_BB_EXPANSION |
+ 0 |
+ AA_UPDATE_AA_ENABLE |
+ 0 );
+
+
+
+ /* This stuff is all invarient as long as we are using
+ * shared back and depth buffers.
+ */
+ memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
+ imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
+
+ if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ imesa->drawMap = i810Screen->back.map;
+ imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset |
+ i810Screen->backPitchBits);
+ } else {
+ imesa->drawMap = imesa->driScreen->pFB;
+ imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset |
+ i810Screen->backPitchBits);
+ }
+
+ if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ imesa->readMap = i810Screen->back.map;
+ } else {
+ imesa->readMap = imesa->driScreen->pFB;
+ }
+
+ imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
+ imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
+ DV_VORG_BIAS_OGL |
+ i810Screen->fbFormat);
+ imesa->BufferSetup[I810_DESTREG_ZB0] = CMD_OP_Z_BUFFER_INFO;
+ imesa->BufferSetup[I810_DESTREG_ZB1] = (i810Screen->depthOffset |
+ i810Screen->backPitchBits);
+
+ imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
+ imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE;
+}
#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
@@ -672,16 +1117,66 @@ void i810DDUpdateState( GLcontext *ctx )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
+ /* Have to do this here to detect texture fallbacks in time:
+ */
+ if (I810_CONTEXT(ctx)->new_state & I810_NEW_TEXTURE)
+ i810DDUpdateHwState( ctx );
+
+
if (ctx->NewState & INTERESTED) {
- i810FinishPrimitive();
i810DDChooseRenderState(ctx);
i810ChooseRasterSetupFunc(ctx);
}
+
+ if (0)
+ fprintf(stderr, "IndirectTriangles %x Fallback %x\n",
+ imesa->IndirectTriangles, imesa->Fallback);
- /* TODO: stop mesa from clobbering these.
- */
- ctx->Driver.PointsFunc=imesa->PointsFunc;
- ctx->Driver.LineFunc=imesa->LineFunc;
- ctx->Driver.TriangleFunc=imesa->TriangleFunc;
- ctx->Driver.QuadFunc=imesa->QuadFunc;
+ if (!imesa->Fallback)
+ {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= imesa->IndirectTriangles;
+
+ ctx->Driver.PointsFunc=imesa->PointsFunc;
+ ctx->Driver.LineFunc=imesa->LineFunc;
+ ctx->Driver.TriangleFunc=imesa->TriangleFunc;
+ ctx->Driver.QuadFunc=imesa->QuadFunc;
+ }
+}
+
+
+void i810DDInitStateFuncs(GLcontext *ctx)
+{
+ ctx->Driver.UpdateState = i810DDUpdateState;
+ ctx->Driver.Enable = i810DDEnable;
+ ctx->Driver.LightModelfv = i810DDLightModelfv;
+ ctx->Driver.AlphaFunc = i810DDAlphaFunc;
+ ctx->Driver.BlendEquation = i810DDBlendEquation;
+ ctx->Driver.BlendFunc = i810DDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = i810DDBlendFuncSeparate;
+ ctx->Driver.DepthFunc = i810DDDepthFunc;
+ ctx->Driver.DepthMask = i810DDDepthMask;
+ ctx->Driver.Fogfv = i810DDFogfv;
+ ctx->Driver.Scissor = i810DDScissor;
+ ctx->Driver.CullFace = i810DDCullFaceFrontFace;
+ ctx->Driver.FrontFace = i810DDCullFaceFrontFace;
+ ctx->Driver.ColorMask = i810DDColorMask;
+ ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange;
+ ctx->Driver.RenderStart = i810DDUpdateHwState;
+ ctx->Driver.RenderFinish = 0;
+
+ ctx->Driver.PolygonStipple = i810DDPolygonStipple;
+ ctx->Driver.LineStipple = 0;
+
+ ctx->Driver.SetReadBuffer = i810DDSetReadBuffer;
+ ctx->Driver.SetDrawBuffer = i810DDSetDrawBuffer;
+
+ ctx->Driver.Color = i810DDSetColor;
+ ctx->Driver.ClearColor = i810DDClearColor;
+ ctx->Driver.Dither = i810DDDither;
+
+ ctx->Driver.Index = 0;
+ ctx->Driver.ClearIndex = 0;
+ ctx->Driver.IndexMask = 0;
}
+
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.h b/xc/lib/GL/mesa/src/drv/i810/i810state.h
index 1cccb44bb..d0551631e 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810state.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.h
@@ -2,10 +2,12 @@
#define _I810_STATE_H
-extern void i810DDInitStatePointers(GLcontext *ctx);
extern void i810DDUpdateHwState( GLcontext *ctx );
extern void i810DDUpdateState( GLcontext *ctx );
extern void i810DDInitState( i810ContextPtr imesa );
+extern void i810DDInitStateFuncs( GLcontext *ctx );
+
+extern void i810DDPrintState( const char *msg, GLuint state );
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.c b/xc/lib/GL/mesa/src/drv/i810/i810swap.c
index 3c78921e3..a0f6d8938 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810swap.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810swap.c
@@ -1,66 +1,71 @@
+
+#include "types.h"
+#include "vbrender.h"
+#include "i810log.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm.h"
+#include "i810lib.h"
+#include "i810dd.h"
+#include "i810dma.h"
+#include "i810state.h"
+#include "i810swap.h"
+#include "i810dma.h"
+#include "i810ioctl.h"
+
/*
* i810BackToFront
*
- * Blit the visible rectangles from the back buffer to the screen
- * Can't really do this from a direct context - don't have the clip
- * info, and getting it would be a lot slower than just sending a
- * request to the server to do the blit there.
- *
- * drawable -- front buffer
- * buf -- back buffer
+ * Blit the visible rectangles from the back buffer to the screen.
+ * Respects the frontbuffer cliprects, and applies the offset
+ * necessary if the backbuffer is positioned elsewhere in the screen.
*/
-int i810BackToFront(DrawablePtr drawable,
- struct i810_dest_buffer *buf)
+static int i810BackToFront( i810ContextPtr imesa )
{
- RegionPtr prgnClip;
- BoxPtr pbox;
- int i,nbox;
- int ofs, xorg, yorg, pitch;
-
- if ( !xf86VTSema ) {
- i810Error("BackToFront(): !xf86VTSema\n");
- return BadMatch; /* Is this really an error? */
- }
-
- if ( drawable->width != buf->Width ||
- drawable->height != buf->Height ||
- drawable->type != DRAWABLE_WINDOW ) {
- i810Error("BackToFront(): bad drawable\n");
- return BadMatch;
- }
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
- prgnClip = &((WindowPtr)drawable)->clipList;
- pbox = REGION_RECTS(prgnClip);
- nbox = REGION_NUM_RECTS(prgnClip);
- if( !nbox ) return Success;
- xorg = drawable->x;
- yorg = drawable->y;
- pitch = buf->Pitch;
- ofs = buf->MemBlock->ofs;
+ /* Use the frontbuffer cliprects:
+ */
+ XF86DRIClipRectPtr pbox = dPriv->pClipRects;
+ int nbox = dPriv->numClipRects;
+ if( nbox )
{
- unsigned int BR13 = ((vga256InfoRec.displayWidth * vgaBytesPerPixel) |
+ int i;
+ int pitch = i810Screen->backPitch;
+
+ int dx = dPriv->backX - dPriv->x;
+ int dy = dPriv->backY - dPriv->y;
+ int ofs = ( i810Screen->backOffset +
+ dy * i810Screen->backPitch +
+ dx * i810Screen->cpp);
+
+ unsigned int BR13 = ((i810Screen->fbStride) |
(0xCC << 16));
for (i=0; i < nbox; i++, pbox++) {
- int x = pbox->x1 - xorg;
- int y = pbox->y1 - yorg;
int w = pbox->x2 - pbox->x1;
int h = pbox->y2 - pbox->y1;
- int start = ofs + x*vgaBytesPerPixel + y*pitch;
- int dst = ((pbox->x1 + pbox->y1 * vga256InfoRec.displayWidth) *
- vgaBytesPerPixel);
+ int start = ofs + pbox->x1*i810Screen->cpp + pbox->y1*pitch;
+ int dst = pbox->x1*i810Screen->cpp + pbox->y1*i810Screen->fbStride;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "i810BackToFront %d,%d-%dx%d\n",
+ pbox->x1,pbox->y1,w,h);
{
- BEGIN_BATCH( 6 );
+ BEGIN_BATCH( imesa, 6 );
OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
OUT_BATCH( BR13 ); /* dest pitch, rop */
- OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel));
+ OUT_BATCH( (h << 16) | (w * i810Screen->cpp));
OUT_BATCH( dst );
OUT_BATCH( pitch ); /* src pitch */
@@ -76,33 +81,70 @@ int i810BackToFront(DrawablePtr drawable,
/*
* ClearBox
- * Add hardware commands to draw a filled box for the
- * debugging display.
+ *
+ * Add hardware commands to draw a filled box for the debugging
+ * display. These are drawn into the current drawbuffer, so should
+ * work with both front and backbuffer rendering. (However, it
+ * is only ever called on swapbuffer - ie backbuffer rendering).
*/
-static void ClearBox( int x, int y, int w, int h, int r, int g, int b )
+static void ClearBox( i810ContextPtr imesa,
+ int cx, int cy, int cw, int ch,
+ int r, int g, int b )
{
- int start = (i810DB->MemBlock->ofs +
- y * i810DB->Pitch +
- x * vgaBytesPerPixel);
-
- BEGIN_BATCH(6);
-
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
- OUT_BATCH( BR13_SOLID_PATTERN |
- (0xF0 << 16) |
- i810DB->Pitch );
- OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel));
- OUT_BATCH( start );
- OUT_BATCH( i810PackColor( i810DB->Format, r, g, b, 0 ) );
- OUT_BATCH( 0 );
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ i810ScreenPrivate *i810Screen = imesa->i810Screen;
+
+ int _nc = imesa->numClipRects;
+
+ while (_nc--) {
+ int x1 = cx + dPriv->x;
+ int y1 = cy + dPriv->y;
+ int x2 = x1 + cw;
+ int y2 = y1 + ch;
+
+ {
+ int rx1 = imesa->pClipRects[_nc].x1;
+ int ry1 = imesa->pClipRects[_nc].y1;
+ int rx2 = imesa->pClipRects[_nc].x2;
+ int ry2 = imesa->pClipRects[_nc].y2;
+
+
+ if (x2 < rx1) continue;
+ if (y2 < ry1) continue;
+ if (x1 > rx2) continue;
+ if (y1 > ry2) continue;
+ if (x1 < rx1) x1 = rx1;
+ if (y1 < ry1) y1 = ry1;
+ if (x2 > rx2) x2 = rx2;
+ if (y2 > ry2) y2 = ry2;
+ }
- if (0)
- fprintf(stderr, "box %d,%x %dx%d col %x (%d,%d,%d)\n", x,y,w,h,
- i810PackColor( i810DB->Format, r, g, b, 0 ), r, g, b);
- ADVANCE_BATCH();
+ {
+ int start = (0 +
+ y1 * i810Screen->backPitch +
+ x1 * i810Screen->cpp);
+ BEGIN_BATCH( imesa, 6 );
+ OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
+ OUT_BATCH( BR13_SOLID_PATTERN |
+ (0xF0 << 16) |
+ i810Screen->backPitch );
+ OUT_BATCH( ((y2-y1) << 16) | ((x2-x1) * i810Screen->cpp));
+ OUT_BATCH( start );
+ OUT_BATCH( i810PackColor( i810Screen->fbFormat, r, g, b, 0 ) );
+ OUT_BATCH( 0 );
+
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "box %d,%x %d,%d col %x (%d,%d,%d)\n",
+ (int)x1,(int)y1, (int)x2,(int)y2,
+ (int)i810PackColor( i810Screen->fbFormat, r, g, b, 0 ),
+ (int)r, (int)g, (int)b);
+
+ ADVANCE_BATCH();
+ }
+ }
}
@@ -111,143 +153,110 @@ static void ClearBox( int x, int y, int w, int h, int r, int g, int b )
* Draw some small boxesin the corner of the buffer
* based on some performance information
*/
-void i810PerformanceBoxes( int is_direct ) {
- int w, t;
+static void i810PerformanceBoxes( i810ContextPtr imesa ) {
- if ( !i810glx.boxes )
- return;
-
-
- /* draw a box to show we are active, so if it is't seen
- it means that it is completely software based rendering */
- /* draw a purple box if we are direct rendering */
- if ( is_direct ) { /* purple = direct (client dma) rendering */
- ClearBox( 4, 4, 8, 8, 255, 0, 255 );
- } else if ( i810glx.dmaDriver ) { /* white = server dma rendering */
- ClearBox( 4, 4, 8, 8, 255, 255, 255 );
- } else { /* grey = servery PDMA */
- ClearBox( 4, 4, 8, 8, 128, 128, 128 );
- }
+
+ /* draw a box to show we are active, so if it is't seen it means
+ that it is completely software based. Purple is traditional for
+ direct rendering */
+ ClearBox( imesa, 4, 4, 8, 8, 255, 0, 255 );
/* draw a red box if we had to wait for drawing to complete
(software render or texture swap) */
if ( i810glx.c_drawWaits ) {
- ClearBox( 16, 4, 8, 8, 255, 0, 0 );
+ ClearBox( imesa, 16, 4, 8, 8, 255, 0, 0 );
i810glx.c_drawWaits = 0;
}
- /* draw a blue box if the register protection signal was hit */
- if ( i810glx.c_signals ) {
- ClearBox( 28, 4, 8, 8, 0, 0, 255 );
- i810glx.c_signals = 0;
+ /* draw a blue box if the 3d context was lost
+ */
+ if ( i810glx.c_ctxlost ) {
+ ClearBox( imesa, 28, 4, 8, 8, 0, 0, 255 );
+ i810glx.c_ctxlost = 0;
}
+ /* draw an orange box if texture state was stomped */
+ if ( i810glx.c_texlost ) {
+ ClearBox( imesa, 40, 4, 8, 8, 255, 128, 0 );
+ i810glx.c_texlost = 0;
+ }
+
/* draw a yellow box if textures were swapped */
if ( i810glx.c_textureSwaps ) {
- ClearBox( 40, 4, 8, 8, 255, 255, 0 );
+ ClearBox( imesa, 56, 4, 8, 8, 255, 255, 0 );
i810glx.c_textureSwaps = 0;
}
-
-
+
/* draw a green box if we had to wait for dma to complete (full utilization)
on the previous frame */
if ( !i810glx.hardwareWentIdle ) {
- ClearBox( 64, 4, 8, 8, 0, 255, 0 );
+ ClearBox( imesa, 72, 4, 8, 8, 0, 255, 0 );
}
i810glx.hardwareWentIdle = 0;
+#if 0
/* show buffer utilization */
if ( i810glx.c_dmaFlush > 1 ) {
/* draw a solid bar if we flushed more than one buffer */
- ClearBox( 4, 16, 252, 4, 255, 32, 32 );
+ ClearBox( imesa, 4, 16, 252, 4, 255, 32, 32 );
} else {
- /* draw bars to represent the utilization of primary and secondary buffers */
- ClearBox( 4, 16, 252, 4, 32, 32, 32 );
+ /* draw bars to represent the utilization of primary and
+ secondary buffers */
+ ClearBox( imesa, 4, 16, 252, 4, 32, 32, 32 );
t = i810glx.dma_buffer->mem.Size;
w = 252 * i810glx.dma_buffer->head / t;
if ( w < 1 ) {
w = 1;
}
- ClearBox( 4, 16, w, 4, 196, 128, 128 );
+ ClearBox( imesa, 4, 16, w, 4, 196, 128, 128 );
}
+#endif
+
i810glx.c_dmaFlush = 0;
}
-static void i810SendDmaFlush( void )
+
+static void i810EmitFlush( i810ContextPtr imesa )
{
- BEGIN_BATCH(2);
+ BEGIN_BATCH( imesa, 2 );
OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
-
-/*
- * Copy the back buffer to the front buffer. If there's no back buffer
- * this is a no-op. Only called in indirect contexts.
- */
-static void i810ServerSwapBuffers( XSMesaBuffer b )
+void i810SwapBuffers( i810ContextPtr imesa )
{
- /* make sure mesa gives us everything */
- if (i810Ctx && i810Ctx->gl_ctx)
- glFlush();
+ int tmp;
- if ( !b->db_state ) {
- /* not double buffered, so do nothing */
- } else {
- ValidateGC(b->frontbuffer, b->cleargc);
- if ( b->backimage ) {
-
- struct i810_dest_buffer *buf =
- (struct i810_dest_buffer *)b->backimage->devPriv;
+ if (I810_DEBUG & DEBUG_VERBOSE_API)
+ fprintf(stderr, "i810SwapBuffers()\n");
- if ( buf && buf->Drawable ) {
+ FLUSH_BATCH( imesa );
+ LOCK_HARDWARE( imesa );
+
+ i810GetGeneralDmaBufferLocked( imesa );
+ i810EmitFlush( imesa );
- /* flush the last primitive */
- i810FinishPrimitive();
+ if ( i810glx.boxes )
+ i810PerformanceBoxes( imesa );
- /* Drop a flush op into the dma stream */
- i810SendDmaFlush();
+ i810BackToFront( imesa );
+ i810EmitFlush( imesa );
+ i810FlushGeneralLocked( imesa );
- /* diagnostic drawing tools */
- i810PerformanceBoxes( 0 );
+ /* Throttle app if the last swap hasn't dispatched yet
+ */
+ if (0)
+ fprintf(stderr, "dispatch age: %d last swap: %d\n",
+ GET_DISPATCH_AGE(imesa), imesa->lastSwap);
+
+ tmp = GET_ENQUEUE_AGE(imesa);
- /* hardware accelerated back to front blit */
- i810BackToFront( (DrawablePtr)b->frontbuffer,buf );
+ UNLOCK_HARDWARE( imesa );
- /* make sure all dma is going to get executed if
- * everything has gone well, this will be the only flush
- * each frame
- */
- i810DmaFlush();
+ if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap)
+ i810WaitAge(imesa, imesa->lastSwap);
- } else {
- /* Use backimage's dimension (not buffer's) */
- (*b->cleargc->ops->PutImage)((DrawablePtr)b->frontbuffer,
- b->cleargc,
- b->frontbuffer->depth,
- 0, 0,
- b->backimage->width,
- b->backimage->height,
- 0, ZPixmap, b->backimage->data);
- }
- } else {
- /* Copy pixmap to window on server */
- (*b->cleargc->ops->CopyArea)((DrawablePtr)b->backpixmap,
- b->frontbuffer,
- b->cleargc,
- 0, 0, b->width, b->height,
- 0, 0);
- }
- }
-
- /* report performance counters */
- i810Msg(10, "swapBuffers: c_triangles:%i c_lines:%i c_points:%i c_setup:%i c_textures:%i\n",
- i810glx.c_triangles, i810glx.c_lines, i810glx.c_points, i810glx.c_setupPointers,
- i810glx.c_textureSwaps );
- i810glx.c_triangles = 0;
- i810glx.c_lines = 0;
- i810glx.c_points = 0;
- i810glx.c_setupPointers = 0;
- i810Msg(10, "---------------------------------------------------------\n" );
+ imesa->secondLastSwap = imesa->lastSwap;
+ imesa->lastSwap = tmp;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
index 5b1d00398..35c395296 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
@@ -22,7 +22,6 @@
*
*/
-#include "xsmesaP.h"
#include <stdlib.h>
#include <stdio.h>
@@ -32,6 +31,7 @@
#include "i810lib.h"
#include "i810tex.h"
#include "i810log.h"
+#include "i810ioctl.h"
#include "simple_list.h"
#include "enums.h"
@@ -49,7 +49,6 @@ static void i810SetTexWrapping(i810TextureObjectPtr tex, GLenum s, GLenum t)
val ^= (MCS_V_WRAP^MCS_V_CLAMP);
tex->Setup[I810_TEXREG_MCS] = val;
- tex->reg_dirty |= (1 << I810_TEXREG_MCS);
}
static void i810SetTexFilter(i810TextureObjectPtr t, GLenum minf, GLenum magf)
@@ -136,10 +135,6 @@ static void i810SetTexFilter(i810TextureObjectPtr t, GLenum minf, GLenum magf)
MLC_LOD_BIAS_MASK,
0x0);
}
-
- t->reg_dirty |= ((1<<I810_TEXREG_MLC) |
- (1<<I810_TEXREG_MLL) |
- (1<<I810_TEXREG_MF));
}
@@ -161,8 +156,8 @@ static void ReplicateMesaTexState(i810TextureObjectPtr t,
i810SetTexBorderColor(t,mesatex->BorderColor);
}
-i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
- struct gl_texture_object *tObj)
+static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa,
+ struct gl_texture_object *tObj)
{
i810TextureObjectPtr t;
GLuint height, width, pitch, i, textureFormat, log_pitch;
@@ -194,7 +189,6 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
case GL_COLOR_INDEX:
textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
t->texelBytes = 1;
- t->UsePalette = 1;
break;
default:
i810Error( "i810CreateTexObj: bad image->Format\n" );
@@ -211,6 +205,7 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
log_pitch++;
t->dirty_images = 0;
+ t->bound = 0;
for ( height = i = 0 ; i < I810_TEX_MAXLEVELS && tObj->Image[i] ; i++ ) {
t->image[i].image = tObj->Image[i];
@@ -226,7 +221,6 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
t->min_level = 0;
t->globj = tObj;
t->age = 0;
- t->reg_dirty = ~0;
t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO;
@@ -279,89 +273,72 @@ i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
ReplicateMesaTexState(t,tObj);
tObj->DriverData = t;
- insert_at_head(&ctx->SwappedOut, t);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ make_empty_list( t );
return t;
}
-int i810DestroyTexObj(i810ContextPtr ctx, i810TextureObjectPtr t)
+void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
{
- if (t) {
- if (t->age > i810glx.dma_buffer_age)
- i810WaitDrawingEngine();
+ if (!t) return;
+ /* This is sad - need to sync *in case* we upload a texture
+ * to this newly free memory...
+ */
+ if (t->MemBlock) {
mmFreeMem(t->MemBlock);
- t->MemBlock = 0;
- remove_from_list(t);
- free(t);
+ t->MemBlock = 0;
+
+ if (t->age > imesa->dirtyAge)
+ imesa->dirtyAge = t->age;
}
- return 0;
+
+ if (t->globj)
+ t->globj->DriverData = 0;
+
+ if (t->bound)
+ imesa->CurrentTexObj[t->bound - 1] = 0;
+
+ remove_from_list(t);
+ free(t);
}
-/* Card memory management
- */
-static void i810SwapOutOldestTexObj( i810ContextPtr ctx )
+static void i810SwapOutTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
{
- i810TextureObjectPtr t = ctx->TexObjList.prev;
-
- fprintf(stderr, "swap out oldest, age %d, dma age %d\n",
- t->age, i810glx.dma_buffer_age);
+ if (t->MemBlock) {
+ mmFreeMem(t->MemBlock);
+ t->MemBlock = 0;
- if (t->age > i810glx.dma_buffer_age)
- i810WaitDrawingEngine();
+ if (t->age > imesa->dirtyAge)
+ imesa->dirtyAge = t->age;
+ }
- mmFreeMem( t->MemBlock );
- t->MemBlock = 0;
t->dirty_images = ~0;
- move_to_tail(&ctx->SwappedOut, t);
+ move_to_tail(&(imesa->SwappedOut), t);
}
-/* Just allocates the memory - doesn't do the upload.
- */
-static int i810SwapInTexObj( i810ContextPtr ctx, i810TextureObjectPtr t)
-{
- i810Msg(10," Swapping in texture.\n");
- i810glx.c_textureSwaps++;
-
- /* Try to allocate textureHeap memory, swapping out stuff until we
- * can.
- */
- while (1)
- {
- t->MemBlock = mmAllocMem( i810glx.sysmemHeap, t->totalSize, 12, 0 );
-
- if (t->MemBlock)
- break;
- if (is_empty_list(&ctx->TexObjList))
- return -1;
-
- i810SwapOutOldestTexObj( ctx );
- }
-
- t->Setup[I810_TEXREG_MI3] = t->MemBlock->ofs;
- t->BufAddr = i810glx.sysmemVirtual + t->MemBlock->ofs;
- t->reg_dirty |= ((1<<I810_TEXREG_MI0) |
- (1<<I810_TEXREG_MI1) |
- (1<<I810_TEXREG_MI2) |
- (1<<I810_TEXREG_MI3));
- return 0;
-}
/* Upload an image from mesa's internal copy.
*/
-static int i810UploadTexLevel( i810TextureObjectPtr t, int level )
+static void i810UploadTexLevel( i810TextureObjectPtr t, int level )
{
const struct gl_texture_image *image = t->image[level].image;
int i,j;
- i810Msg(10,"CopyImage():\n");
+ if (I810_DEBUG & DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "i810UploadTexLevel %d, BufAddr %p offset %x\n",
+ level, t->BufAddr, t->image[level].offset);
/* Need triangle (rather than pixel) fallbacks to simulate this using
* normal textured triangles.
- */
+ *
+ * DO THIS IN DRIVER STATE MANAGMENT, not hardware state.
+ *
if (image->Border != 0)
- i810Error("Not supported texture border %d.\n",image->Border);
+ i810Error("Not supported texture border %d.\n", (int) image->Border);
+ */
switch (t->image[level].internalFormat) {
case GL_RGB:
@@ -440,6 +417,8 @@ static int i810UploadTexLevel( i810TextureObjectPtr t, int level )
}
break;
+ /* TODO: Translate color indices *now*:
+ */
case GL_COLOR_INDEX:
{
GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset);
@@ -452,38 +431,221 @@ static int i810UploadTexLevel( i810TextureObjectPtr t, int level )
src += 1;
}
}
-
- t->UsePalette = I810_USE_PALETTE;
}
break;
default:
- i810Error("Not supported texture format %d\n",image->Format);
- FatalError("bummer");
- return -1;
+ i810Error("Not supported texture format %d\n",(int)image->Format);
+ exit(1);
}
+}
- return 0;
+
+
+void i810PrintLocalLRU( i810ContextPtr imesa )
+{
+ i810TextureObjectPtr t;
+ int sz = 1 << (imesa->i810Screen->logTextureGranularity);
+
+ foreach( t, &imesa->TexObjList ) {
+ if (!t->globj)
+ fprintf(stderr, "Placeholder %d at %x sz %x\n",
+ t->MemBlock->ofs / sz,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+ else
+ fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
+ t->bound,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+
+ }
+}
+
+void i810PrintGlobalLRU( i810ContextPtr imesa )
+{
+ int i, j;
+ drm_i810_tex_region_t *list = imesa->sarea->texList;
+
+ for (i = 0, j = I810_NR_TEX_REGIONS ; i < I810_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev);
+ j = list[j].next;
+ if (j == I810_NR_TEX_REGIONS) break;
+ }
+
+ if (j != I810_NR_TEX_REGIONS)
+ fprintf(stderr, "Loop detected in global LRU\n");
+}
+
+
+void i810ResetGlobalLRU( i810ContextPtr imesa )
+{
+ drm_i810_tex_region_t *list = imesa->sarea->texList;
+ int sz = 1 << imesa->i810Screen->logTextureGranularity;
+ int i;
+
+ /* (Re)initialize the global circular LRU list. The last element
+ * in the array (I810_NR_TEX_REGIONS) is the sentinal. Keeping it
+ * at the end of the array allows it to be addressed rationally
+ * when looking up objects at a particular location in texture
+ * memory.
+ */
+ for (i = 0 ; (i+1) * sz <= imesa->i810Screen->textureSize ; i++) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ i--;
+ list[0].prev = I810_NR_TEX_REGIONS;
+ list[i].prev = i-1;
+ list[i].next = I810_NR_TEX_REGIONS;
+ list[I810_NR_TEX_REGIONS].prev = i;
+ list[I810_NR_TEX_REGIONS].next = 0;
+ imesa->sarea->texAge = 0;
}
+static void i810UpdateTexLRU( i810ContextPtr imesa, i810TextureObjectPtr t )
+{
+ int i;
+ int logsz = imesa->i810Screen->logTextureGranularity;
+ int start = t->MemBlock->ofs >> logsz;
+ int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
+ drm_i810_tex_region_t *list = imesa->sarea->texList;
+
+ imesa->texAge = ++imesa->sarea->texAge;
+
+ /* Update our local LRU
+ */
+ move_to_head( &(imesa->TexObjList), t );
+
+ /* Update the global LRU
+ */
+ for (i = start ; i <= end ; i++) {
+
+ list[i].in_use = 1;
+ list[i].age = imesa->texAge;
+
+ /* remove_from_list(i)
+ */
+ list[(unsigned)list[i].next].prev = list[i].prev;
+ list[(unsigned)list[i].prev].next = list[i].next;
+
+ /* insert_at_head(list, i)
+ */
+ list[i].prev = I810_NR_TEX_REGIONS;
+ list[i].next = list[I810_NR_TEX_REGIONS].next;
+ list[(unsigned)list[I810_NR_TEX_REGIONS].next].prev = i;
+ list[I810_NR_TEX_REGIONS].next = i;
+ }
+}
+
-static int i810UploadTexImages( i810ContextPtr ctx, i810TextureObjectPtr t )
+/* Called for every shared texture region which has increased in age
+ * since we last held the lock.
+ *
+ * Figures out which of our textures have been ejected by other clients,
+ * and pushes a placeholder texture onto the LRU list to represent
+ * the other client's textures.
+ */
+void i810TexturesGone( i810ContextPtr imesa,
+ GLuint offset,
+ GLuint size,
+ GLuint in_use )
+{
+ i810TextureObjectPtr t, tmp;
+
+ foreach_s ( t, tmp, &imesa->TexObjList ) {
+
+ if (t->MemBlock->ofs >= offset + size ||
+ t->MemBlock->ofs + t->MemBlock->size <= offset)
+ continue;
+
+ /* It overlaps - kick it off. Need to hold onto the currently bound
+ * objects, however.
+ */
+ if (t->bound)
+ i810SwapOutTexObj( imesa, t );
+ else
+ i810DestroyTexObj( imesa, t );
+ }
+
+
+ if (in_use) {
+ t = (i810TextureObjectPtr) calloc(1,sizeof(*t));
+ if (!t) return;
+
+ t->MemBlock = mmAllocMem( imesa->texHeap, size, 0, offset);
+ insert_at_head( &imesa->TexObjList, t );
+ }
+}
+
+
+
+
+
+/* This is called with the lock held. May have to eject our own and/or
+ * other client's texture objects to make room for the upload.
+ */
+int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t )
{
int i;
+ int ofs;
i810glx.c_textureSwaps++;
- if (!t->MemBlock)
- i810SwapInTexObj( ctx, t );
+ /* Do we need to eject LRU texture objects?
+ */
+ if (!t->MemBlock) {
+ while (1)
+ {
+ t->MemBlock = mmAllocMem( imesa->texHeap, t->totalSize, 12, 0 );
+ if (t->MemBlock)
+ break;
- if (t->age > i810glx.dma_buffer_age)
- i810WaitDrawingEngine();
+ if (imesa->TexObjList.prev->bound) {
+ fprintf(stderr, "Hit bound texture in upload\n");
+ i810PrintLocalLRU( imesa );
+ return -1;
+ }
- for (i = t->min_level ; i <= t->max_level ; i++)
- if (t->dirty_images & (1<<i)) {
- if (i810UploadTexLevel( t, i ) != 0)
+ if (imesa->TexObjList.prev == &(imesa->TexObjList)) {
+ fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
+ mmDumpMemInfo( imesa->texHeap );
return -1;
+ }
+
+ i810DestroyTexObj( imesa, imesa->TexObjList.prev );
}
+
+ ofs = t->MemBlock->ofs;
+ t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs;
+ t->BufAddr = i810glx.texVirtual + ofs;
+ imesa->dirty |= I810_UPLOAD_CTX;
+ }
+
+ /* Let the world know we've used this memory recently.
+ */
+ i810UpdateTexLRU( imesa, t );
+
+ if (I810_DEBUG & DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "dispatch age: %d age freed memory: %d\n",
+ GET_DISPATCH_AGE(imesa), imesa->dirtyAge);
+
+ if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa))
+ i810WaitAgeLocked( imesa, imesa->dirtyAge );
+
+
+ if (t->dirty_images) {
+ if (I810_DEBUG & DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "*");
+
+ for (i = t->min_level ; i <= t->max_level ; i++)
+ if (t->dirty_images & (1<<i))
+ i810UploadTexLevel( t, i );
+ }
+
t->dirty_images = 0;
return 0;
@@ -499,7 +661,6 @@ static void i810TexSetUnit( i810TextureObjectPtr t, GLuint unit )
t->Setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1);
t->Setup[I810_TEXREG_MF] ^= (MF_MAP_0 ^ MF_MAP_1);
- t->reg_dirty = ~0;
t->current_unit = unit;
}
@@ -519,30 +680,29 @@ static void i810UpdateTex0State( GLcontext *ctx )
if ( tObj != ctx->Texture.Unit[0].CurrentD[2] )
tObj = 0;
- if (!(ctx->Texture.Enabled & 0xf) || !tObj || !tObj->Complete) {
-
- imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
- MC_STAGE_0 |
- MC_UPDATE_DEST |
- MC_DEST_CURRENT |
- MC_UPDATE_ARG1 |
- MC_ARG1_ITERATED_COLOR |
- MC_UPDATE_ARG2 |
- MC_ARG2_ONE |
- MC_UPDATE_OP |
- MC_OP_ARG1 );
- imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
- MA_STAGE_0 |
- MA_UPDATE_ARG1 |
- MA_ARG1_ITERATED_ALPHA |
- MA_UPDATE_ARG2 |
- MA_ARG2_TEX0_ALPHA |
- MA_UPDATE_OP |
- MA_OP_ARG1 );
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ITERATED_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
+
+ imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_0 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_ITERATED_ALPHA |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_TEX0_ALPHA |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
- imesa->reg_dirty |= ((1<<I810_CTXREG_MA0) |
- (1<<I810_CTXREG_MC0));
+
+ if (!(ctx->Texture.Enabled & 0xf) || !tObj || !tObj->Complete) {
return;
}
@@ -557,30 +717,13 @@ static void i810UpdateTex0State( GLcontext *ctx )
i810TexSetUnit( t, 0 );
if (t->dirty_images)
- i810UploadTexImages(imesa, t);
-
- t->age = ++i810glx.current_texture_age;
- move_to_head(&imesa->TexObjList, t);
-
- imesa->CurrentTex0Obj = t;
-
- if (0)
- if (t->UsePalette == I810_USE_PALETTE) {
- if (ctx->Texture.SharedPalette) {
- if (imesa->GlobalPaletteUpdated)
- i810LoadTexturePalette(imesa->GlobalPalette,0,256);
- imesa->GlobalPaletteUpdated = 0;
- }
- else {
- i810LoadTexturePalette(t->Palette,0,256);
- imesa->GlobalPaletteUpdated = 1;
- }
- }
-
-
- if (t->reg_dirty)
- i810DmaExecute(t->Setup,I810_TEX_SETUP_SIZE);
+ imesa->dirty |= I810_UPLOAD_TEX0IMAGE;
+
+ imesa->CurrentTexObj[0] = t;
+ t->bound = 1;
+ if (t->MemBlock)
+ i810UpdateTexLRU( imesa, t );
switch (ctx->Texture.Unit[0].EnvMode) {
case GL_REPLACE:
@@ -730,15 +873,10 @@ static void i810UpdateTex0State( GLcontext *ctx )
break;
default:
- FatalError("unkown tex env mode");
+ fprintf(stderr, "unknown tex env mode");
+ exit(1);
break;
}
-
-
-
- imesa->reg_dirty |= ((1<<I810_CTXREG_MA0) |
- (1<<I810_CTXREG_MC0));
-
}
@@ -756,36 +894,34 @@ static void i810UpdateTex1State( GLcontext *ctx )
if ( tObj != ctx->Texture.Unit[1].CurrentD[2] )
tObj = 0;
- if (!(ctx->Texture.Enabled & 0xf0) || !tObj || !tObj->Complete) {
- imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
- MC_STAGE_1 |
- MC_UPDATE_DEST |
- MC_DEST_CURRENT |
- MC_UPDATE_ARG1 |
- MC_ARG1_ONE |
- MC_ARG1_DONT_REPLICATE_ALPHA |
- MC_ARG1_DONT_INVERT |
- MC_UPDATE_ARG2 |
- MC_ARG2_ONE |
- MC_ARG2_DONT_REPLICATE_ALPHA |
- MC_ARG2_DONT_INVERT |
- MC_UPDATE_OP |
- MC_OP_DISABLE );
+ imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_1 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_ONE |
+ MC_ARG1_DONT_REPLICATE_ALPHA |
+ MC_ARG1_DONT_INVERT |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_ARG2_DONT_REPLICATE_ALPHA |
+ MC_ARG2_DONT_INVERT |
+ MC_UPDATE_OP |
+ MC_OP_DISABLE );
+
+ imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
+ MA_STAGE_1 |
+ MA_UPDATE_ARG1 |
+ MA_ARG1_CURRENT_ALPHA |
+ MA_ARG1_DONT_INVERT |
+ MA_UPDATE_ARG2 |
+ MA_ARG2_CURRENT_ALPHA |
+ MA_ARG2_DONT_INVERT |
+ MA_UPDATE_OP |
+ MA_OP_ARG1 );
- imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
- MA_STAGE_1 |
- MA_UPDATE_ARG1 |
- MA_ARG1_CURRENT_ALPHA |
- MA_ARG1_DONT_INVERT |
- MA_UPDATE_ARG2 |
- MA_ARG2_CURRENT_ALPHA |
- MA_ARG2_DONT_INVERT |
- MA_UPDATE_OP |
- MA_OP_ARG1 );
-
- imesa->reg_dirty |= ((1<<I810_CTXREG_MA1) |
- (1<<I810_CTXREG_MC1));
+ if (!(ctx->Texture.Enabled & 0xf0) || !tObj || !tObj->Complete) {
return;
}
@@ -796,35 +932,18 @@ static void i810UpdateTex1State( GLcontext *ctx )
if (!t) return;
}
- if (t->dirty_images)
- i810UploadTexImages(imesa, t);
-
if (t->current_unit != 1)
i810TexSetUnit( t, 1 );
- t->age = ++i810glx.current_texture_age;
- move_to_head(&imesa->TexObjList, t);
- imesa->CurrentTex1Obj = t;
-
- if (0)
- if (t->UsePalette == I810_USE_PALETTE) {
- if (ctx->Texture.SharedPalette) {
- if (imesa->GlobalPaletteUpdated)
- i810LoadTexturePalette(imesa->GlobalPalette,0,256);
- imesa->GlobalPaletteUpdated = 0;
- }
- else {
- i810LoadTexturePalette(t->Palette,0,256);
- imesa->GlobalPaletteUpdated = 1;
- }
- }
-
+ if (t->dirty_images)
+ imesa->dirty |= I810_UPLOAD_TEX1IMAGE;
- if (t->reg_dirty)
- i810DmaExecute(t->Setup,I810_TEX_SETUP_SIZE);
+ imesa->CurrentTexObj[1] = t;
+ t->bound = 2;
+ if (t->MemBlock)
+ i810UpdateTexLRU( imesa, t );
-
switch (ctx->Texture.Unit[1].EnvMode) {
case GL_REPLACE:
imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
@@ -980,64 +1099,70 @@ static void i810UpdateTex1State( GLcontext *ctx )
break;
default:
- FatalError("unkown tex 1 env mode");
+ fprintf(stderr, "unkown tex 1 env mode\n");
+ exit(1);
break;
}
-
- imesa->reg_dirty |= ((1<<I810_CTXREG_MA1) |
- (1<<I810_CTXREG_MC1));
}
void i810UpdateTextureState( GLcontext *ctx )
{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound = 0;
+ if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0;
+ imesa->CurrentTexObj[0] = 0;
+ imesa->CurrentTexObj[1] = 0;
i810UpdateTex0State( ctx );
i810UpdateTex1State( ctx );
+ I810_CONTEXT( ctx )->dirty |= I810_UPLOAD_CTX;
}
/*****************************************
- * Driver functions
+ * DRIVER functions
*****************************************/
-void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+static void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
if (pname == GL_TEXTURE_ENV_MODE) {
+ FLUSH_BATCH(imesa);
imesa->new_state |= I810_NEW_TEXTURE;
} else if (pname == GL_TEXTURE_ENV_COLOR) {
struct gl_texture_unit *texUnit =
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- GLubyte c[4];
+ GLfloat *fc = texUnit->EnvColor;
GLuint col;
- FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
- col = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+ col = ((((GLubyte)fc[3])<<24) |
+ (((GLubyte)fc[0])<<16) |
+ (((GLubyte)fc[1])<<8) |
+ (((GLubyte)fc[2])<<0));
if (imesa->Setup[I810_CTXREG_CF1] != col) {
+ FLUSH_BATCH(imesa);
imesa->Setup[I810_CTXREG_CF1] = col;
- imesa->reg_dirty |= (1<<I810_CTXREG_CF1);
+ imesa->dirty |= I810_UPLOAD_CTX;
}
}
}
-void i810TexImage( GLcontext *ctx,
- GLenum target,
- struct gl_texture_object *tObj,
- GLint level,
- GLint internalFormat,
- const struct gl_texture_image *image )
+static void i810TexImage( GLcontext *ctx,
+ GLenum target,
+ struct gl_texture_object *tObj,
+ GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
i810TextureObjectPtr t;
- CHECK_CONTEXT( return; );
-
i810Msg(10,"i810TexImage(%d): level %d internalFormat %x\n",
tObj->Name, level, internalFormat);
@@ -1049,6 +1174,7 @@ void i810TexImage( GLcontext *ctx,
t = (i810TextureObjectPtr) tObj->DriverData;
if (t) {
+ if (t->bound) FLUSH_BATCH(imesa);
/* if this is the current object, it will force an update */
i810DestroyTexObj( imesa, t );
tObj->DriverData = 0;
@@ -1056,12 +1182,12 @@ void i810TexImage( GLcontext *ctx,
}
}
-void i810TexSubImage( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLint internalFormat,
- const struct gl_texture_image *image )
+static void i810TexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
i810TextureObjectPtr t;
@@ -1070,13 +1196,12 @@ void i810TexSubImage( GLcontext *ctx, GLenum target,
width, height, image->Width,image->Height,
level);
- CHECK_CONTEXT( return; );
-
if ( target != GL_TEXTURE_2D )
return;
t = (i810TextureObjectPtr) tObj->DriverData;
if (t) {
+ if (t->bound) FLUSH_BATCH( imesa );
i810DestroyTexObj( imesa, t );
tObj->DriverData = 0;
imesa->new_state |= I810_NEW_TEXTURE;
@@ -1084,9 +1209,9 @@ void i810TexSubImage( GLcontext *ctx, GLenum target,
}
}
-void i810TexParameter( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj,
- GLenum pname, const GLfloat *params )
+static void i810TexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
{
i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
i810ContextPtr imesa = I810_CONTEXT( ctx );
@@ -1097,97 +1222,82 @@ void i810TexParameter( GLcontext *ctx, GLenum target,
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) FLUSH_BATCH( imesa );
i810SetTexFilter(t,tObj->MinFilter,tObj->MagFilter);
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
+ if (t->bound) FLUSH_BATCH( imesa );
i810SetTexWrapping(t,tObj->WrapS,tObj->WrapT);
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) FLUSH_BATCH( imesa );
i810SetTexBorderColor(t,tObj->BorderColor);
break;
default:
return;
}
+
imesa->new_state |= I810_NEW_TEXTURE;
}
-void i810BindTexture( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj )
+static void i810BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
+
+ FLUSH_BATCH(imesa);
- if (target != GL_TEXTURE_2D)
- return;
+ if (imesa->CurrentTexObj[ctx->Texture.CurrentUnit]) {
+ imesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0;
+ imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0;
+ }
imesa->new_state |= I810_NEW_TEXTURE;
}
-void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
{
i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData;
i810ContextPtr imesa = I810_CONTEXT( ctx );
- i810DestroyTexObj(imesa,t);
- tObj->DriverData=0;
-}
-
-void i810UpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj )
-{
- i810ContextPtr imesa = I810_CONTEXT( ctx );
- i810TextureObjectPtr t;
- GLushort *dst;
- GLubyte *src;
- int i, size, next;
- GLenum format;
+ if (t) {
+ if (t->bound) {
+ FLUSH_BATCH(imesa);
+ imesa->CurrentTexObj[t->bound-1] = 0;
+ imesa->new_state |= I810_NEW_TEXTURE;
+ }
- return;
+ i810DestroyTexObj(imesa,t);
+ tObj->DriverData=0;
+ }
+}
- if (tObj)
- {
- i810Msg(8,"i810UpdateTexturePalette(): size %d\n", tObj->PaletteSize);
- t = (i810TextureObjectPtr) tObj->DriverData;;
- if (!t) return;
- size = tObj->PaletteSize;
- format = tObj->PaletteFormat;
- dst = t->Palette;
- src = (GLubyte *) tObj->Palette;
- }
- else
- {
- /* shared palette */
- imesa->GlobalPaletteUpdated = 1;
- size = ctx->Texture.PaletteSize;
- format = ctx->Texture.PaletteFormat;
- dst = imesa->GlobalPalette;
- src = (GLubyte *) ctx->Texture.Palette;
-
- i810Msg(8, "i810UpdateTexturePalette(): size %d intFormat %x format %x\n",
- size, ctx->Texture.PaletteIntFormat, ctx->Texture.PaletteFormat);
- }
+static GLboolean i810IsTextureResident( GLcontext *ctx,
+ struct gl_texture_object *t )
+{
+ i810TextureObjectPtr mt;
- if (size > 256) {
- i810Error("i810UpdateTexturePalette(): palette > 256 entries!\n");
- return;
- }
+/* LOCK_HARDWARE; */
+ mt = (i810TextureObjectPtr)t->DriverData;
+/* UNLOCK_HARDWARE; */
- switch (format)
- {
- case GL_RGB: next = 3; break;
- case GL_RGBA:next = 4; break;
- default :
- i810Error("i810UpdateTexturePalette(): unsupported palette format %x\n");
- next = 4;
- }
+ return mt && mt->MemBlock;
+}
- for (i=0; i < size; i++) {
- *dst = I810PACKCOLOR565(src[RCOMP],src[GCOMP],src[BCOMP]);
- dst++;
- src += next;
- }
+void i810DDInitTextureFuncs( GLcontext *ctx )
+{
+ ctx->Driver.TexEnv = i810TexEnv;
+ ctx->Driver.TexImage = i810TexImage;
+ ctx->Driver.TexSubImage = i810TexSubImage;
+ ctx->Driver.BindTexture = i810BindTexture;
+ ctx->Driver.DeleteTexture = i810DeleteTexture;
+ ctx->Driver.TexParameter = i810TexParameter;
+ ctx->Driver.UpdateTexturePalette = 0;
+ ctx->Driver.IsTextureResident = i810IsTextureResident;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.h b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
index ed9875be8..5261d0b1b 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tex.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
@@ -26,16 +26,31 @@
#ifndef I810TEX_INC
#define I810TEX_INC
-#include "mesaglx/types.h"
+#include "types.h"
#include "mmath.h"
+#include "mm.h"
-#include "i810common.h"
-#include "i810buf.h"
+#include "i810context.h"
+#include "i810_3d_reg.h"
#define VALID_I810_TEXTURE_OBJECT(tobj) (tobj)
#define I810_TEX_MAXLEVELS 10
+
+
+/* For shared texture space managment, these texture objects may also
+ * be used as proxies for regions of texture memory containing other
+ * client's textures. Such proxy textures (not to be confused with GL
+ * proxy textures) are subject to the same LRU aging we use for our
+ * own private textures, and thus we have a mechanism where we can
+ * fairly decide between kicking out our own textures and those of
+ * other clients.
+ *
+ * Non-local texture objects have a valid MemBlock to describe the
+ * region managed by the other client, and can be identified by
+ * 't->globj == 0'
+ */
struct i810_texture_object_t {
struct i810_texture_object_t *next, *prev;
@@ -46,11 +61,11 @@ struct i810_texture_object_t {
int Height;
int texelBytes;
int totalSize;
+ int bound;
- PMemBlock MemBlock;
-
+ PMemBlock MemBlock;
char *BufAddr;
-
+
GLuint min_level;
GLuint max_level;
GLuint dirty_images;
@@ -64,13 +79,8 @@ struct i810_texture_object_t {
/* Support for multitexture.
*/
- GLuint current_unit;
-
+ GLuint current_unit;
GLuint Setup[I810_TEX_SETUP_SIZE];
- GLuint reg_dirty;
-
- GLushort Palette[256];
- int UsePalette;
};
#define I810_NO_PALETTE 0x0
@@ -80,38 +90,20 @@ struct i810_texture_object_t {
typedef struct i810_texture_object_t *i810TextureObjectPtr;
-i810TextureObjectPtr i810CreateTexObj(i810ContextPtr ctx,
- struct gl_texture_object *tObj);
-int i810DestroyTexObj(i810ContextPtr ctx, i810TextureObjectPtr t);
-void i810UpdateTextureState(GLcontext *ctx);
-
-
-/* Driver functions */
-
-void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param );
-
-void i810TexImage( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj, GLint level,
- GLint internalFormat,
- const struct gl_texture_image *image );
+void i810UpdateTextureState( GLcontext *ctx );
+void i810DDInitTextureFuncs( GLcontext *ctx );
-void i810TexSubImage( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLint internalFormat,
- const struct gl_texture_image *image );
+void i810DestroyTexObj( i810ContextPtr imesa, i810TextureObjectPtr t);
+int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t );
-void i810TexParameter( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj,
- GLenum pname, const GLfloat *params );
+void i810ResetGlobalLRU( i810ContextPtr imesa );
+void i810TexturesGone( i810ContextPtr imesa,
+ GLuint start, GLuint end,
+ GLuint in_use );
-void i810BindTexture( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj );
+void i810PrintLocalLRU( i810ContextPtr imesa );
+void i810PrintGlobalLRU( i810ContextPtr imesa );
-void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj );
-void i810UpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj );
-void i810UseGlobalTexturePalette( GLcontext *ctx, GLboolean state );
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
index 1c81b9549..d970e3a36 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tris.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <math.h>
+#include "types.h"
#include "vb.h"
#include "pipeline.h"
@@ -34,28 +35,9 @@
#include "i810tris.h"
#include "i810vb.h"
#include "i810log.h"
-#include "xsmesaP.h"
-
-
-static void i810_null_quad( GLcontext *ctx, GLuint v0,
- GLuint v1, GLuint v2, GLuint v3, GLuint pv )
-{
-}
-
-static void i810_null_triangle( GLcontext *ctx, GLuint v0,
- GLuint v1, GLuint v2, GLuint pv )
-{
-}
-
-static void i810_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
-{
-}
-
-static void i810_null_points( GLcontext *ctx, GLuint first, GLuint last )
-{
-}
-
+/* Used in i810tritmp.h
+ */
#define I810_COLOR(to, from) { \
(to)[0] = (from)[2]; \
(to)[1] = (from)[1]; \
@@ -70,17 +52,6 @@ static quad_func quad_tab[0x20];
static line_func line_tab[0x20];
static points_func points_tab[0x20];
-void i810PrintRenderState( const char *msg, GLuint state )
-{
- fprintf(stderr, "%s: (%x) %s%s%s%s%s%s\n",
- msg, state,
- (state & I810_FLAT_BIT) ? "flat, " : "",
- (state & I810_OFFSET_BIT) ? "offset, " : "",
- (state & I810_TWOSIDE_BIT) ? "twoside, " : "",
- (state & I810_ANTIALIAS_BIT) ? "antialias, " : "",
- (state & I810_NODRAW_BIT) ? "no-draw, " : "",
- (state & I810_FALLBACK_BIT) ? "fallback" : "");
-}
#define IND (0)
#define TAG(x) x
@@ -90,33 +61,32 @@ void i810PrintRenderState( const char *msg, GLuint state )
#define TAG(x) x##_flat
#include "i810tritmp.h"
-#define IND (I810_OFFSET_BIT)
+#define IND (I810_OFFSET_BIT) /* wide */
#define TAG(x) x##_offset
#include "i810tritmp.h"
-#define IND (I810_OFFSET_BIT|I810_FLAT_BIT)
+#define IND (I810_OFFSET_BIT|I810_FLAT_BIT) /* wide|flat */
#define TAG(x) x##_offset_flat
#include "i810tritmp.h"
-#define IND (I810_TWOSIDE_BIT)
+#define IND (I810_TWOSIDE_BIT) /* stipple */
#define TAG(x) x##_twoside
#include "i810tritmp.h"
-#define IND (I810_TWOSIDE_BIT|I810_FLAT_BIT)
+#define IND (I810_TWOSIDE_BIT|I810_FLAT_BIT) /* stipple|flat */
#define TAG(x) x##_twoside_flat
#include "i810tritmp.h"
-#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT) /* stipple|wide */
#define TAG(x) x##_twoside_offset
#include "i810tritmp.h"
-#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FLAT_BIT)
+#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FLAT_BIT) /* stip|wide|flat*/
#define TAG(x) x##_twoside_offset_flat
#include "i810tritmp.h"
void i810DDTrifuncInit()
{
- int i;
init();
init_flat();
init_offset();
@@ -125,113 +95,9 @@ void i810DDTrifuncInit()
init_twoside_flat();
init_twoside_offset();
init_twoside_offset_flat();
-
- /* Hmmm...
- */
- for (i = 0 ; i < 0x20 ; i++) {
- if (i & ~I810_FLAT_BIT) {
- points_tab[i] = points_tab[i&I810_FLAT_BIT];
- line_tab[i] = line_tab[i&I810_FLAT_BIT];
- }
- }
-
- for (i = 0 ; i < 0x20 ; i++)
- if ((i & (I810_NODRAW_BIT|I810_FALLBACK_BIT)) == I810_NODRAW_BIT ||
- i810glx.nullprims)
- {
- quad_tab[i] = i810_null_quad;
- tri_tab[i] = i810_null_triangle;
- line_tab[i] = i810_null_line;
- points_tab[i] = i810_null_points;
- }
-
- if (i810glx.noFallback) {
- for (i = 0 ; i < 0x10 ; i++) {
- points_tab[i|I810_FALLBACK_BIT] = points_tab[i];
- line_tab[i|I810_FALLBACK_BIT] = line_tab[i];
- tri_tab[i|I810_FALLBACK_BIT] = tri_tab[i];
- quad_tab[i|I810_FALLBACK_BIT] = quad_tab[i];
- }
- }
-
}
-/* Everything is done via single triangle instructiopns at the moment;
- * this can change fairly easily.
- */
-#if I810_USE_BATCH
-
-GLuint *i810AllocPrimitiveVerts( int dwords )
-{
- GLuint orig_dwords = dwords;
-
- dwords+=2;
- dwords&=~1;
-
- while (1) {
- if (i810glx.dma_buffer->space < dwords * 4)
- {
- if (I810_DEBUG & DEBUG_VERBOSE_RING)
- fprintf(stderr, "i810AllocPrimitiveVerts: dma buffer overflow\n");
- i810DmaOverflow( dwords );
- }
- else
- {
- GLuint start = i810glx.dma_buffer->head;
- i810glx.dma_buffer->head += dwords * 4;
- i810glx.dma_buffer->space -= dwords * 4;
-
- if ((orig_dwords & 1) == 0) {
- *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) = 0;
- start += 4;
- }
-
- *(GLuint *)(i810glx.dma_buffer->virtual_start + start ) =
- GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1);
-
- return (GLuint *)(i810glx.dma_buffer->virtual_start + start + 4);
- }
- }
-}
-
-#else
-GLuint *i810AllocPrimitiveVerts( int dwords )
-{
- GLuint orig_dwords = dwords;
-
- dwords+=2;
- dwords&=~1;
-
- while (1)
- {
- BEGIN_LP_RING( dwords );
-
- if (outring + dwords * 4 != ((outring + dwords * 4) & ringmask))
- {
- int i;
-
- if (I810_DEBUG & DEBUG_VERBOSE_RING)
- fprintf(stderr, "\n\nwrap case in i810AllocPrimitiveVerts\n\n");
-
- for (i = 0 ; i < dwords ; i++)
- OUT_RING( 0 );
- ADVANCE_LP_RING();
- }
- else
- {
- I810LpRing.tail = outring + dwords * 4;
-
- if ((orig_dwords & 1) == 0)
- OUT_RING(0);
-
- OUT_RING( GFX_OP_PRIMITIVE | PR_TRIANGLES | (orig_dwords-1) );
- return (GLuint *)(virt + outring);
- }
- }
-}
-#endif
-
void i810DDChooseRenderState( GLcontext *ctx )
@@ -239,50 +105,41 @@ void i810DDChooseRenderState( GLcontext *ctx )
i810ContextPtr imesa = I810_CONTEXT( ctx );
GLuint flags = ctx->TriangleCaps;
- ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ imesa->IndirectTriangles = 0;
if (flags) {
GLuint ind = 0;
GLuint shared = 0;
- GLuint setup = imesa->setupindex;
- GLuint fallback = I810_FALLBACK_BIT;
-
- if (i810glx.noFallback) fallback = 0;
- if ((flags & DD_FLATSHADE) && (setup & I810_RGBA_BIT)) shared |= I810_FLAT_BIT;
- if (flags & DD_MULTIDRAW) shared |= fallback;
+ if (flags & DD_FLATSHADE) shared |= I810_FLAT_BIT;
+ if (flags & DD_MULTIDRAW) shared |= I810_FALLBACK_BIT;
if (flags & DD_SELECT) shared |= I810_FALLBACK_BIT;
if (flags & DD_FEEDBACK) shared |= I810_FALLBACK_BIT;
- ind = shared;
- if (flags & DD_POINT_SMOOTH) ind |= I810_ANTIALIAS_BIT;
- if (flags & DD_POINT_ATTEN) ind |= fallback;
-
- imesa->renderindex = ind;
- imesa->PointsFunc = points_tab[ind];
- if (ind & I810_FALLBACK_BIT)
- ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+ imesa->renderindex = shared;
+ imesa->PointsFunc = points_tab[shared];
ind = shared;
- if (flags & DD_LINE_SMOOTH) ind |= I810_ANTIALIAS_BIT;
- if (flags & DD_LINE_STIPPLE) ind |= fallback;
+ if (flags & DD_LINE_WIDTH) ind |= I810_WIDE_LINE_BIT;
+ if (flags & DD_LINE_STIPPLE) ind |= I810_FALLBACK_BIT;
imesa->renderindex |= ind;
imesa->LineFunc = line_tab[ind];
if (ind & I810_FALLBACK_BIT)
- ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+ imesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
ind = shared;
- if (flags & DD_TRI_SMOOTH) ind |= I810_ANTIALIAS_BIT;
if (flags & DD_TRI_OFFSET) ind |= I810_OFFSET_BIT;
if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= I810_TWOSIDE_BIT;
- if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback;
+ if (flags & DD_TRI_UNFILLED) ind |= I810_FALLBACK_BIT;
+ if ((flags & DD_TRI_STIPPLE) &&
+ (ctx->IndirectTriangles & DD_TRI_STIPPLE)) ind |= I810_FALLBACK_BIT;
imesa->renderindex |= ind;
imesa->TriangleFunc = tri_tab[ind];
imesa->QuadFunc = quad_tab[ind];
if (ind & I810_FALLBACK_BIT)
- ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE);
+ imesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE);
}
else if (imesa->renderindex)
{
@@ -293,9 +150,9 @@ void i810DDChooseRenderState( GLcontext *ctx )
imesa->QuadFunc = quad_tab[0];
}
- if (MESA_VERBOSE&VERBOSE_DRIVER) {
+
+ if (I810_DEBUG&DEBUG_VERBOSE_API) {
gl_print_tri_caps("tricaps", ctx->TriangleCaps);
- i810PrintRenderState("i810: Render state", imesa->renderindex);
}
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
index 12e0ec7fd..5b73b7676 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
@@ -23,107 +23,76 @@
*
*/
-#ifndef I810TIS_INC
-#define I810TIS_INC
+#ifndef I810TRIS_INC
+#define I810TRIS_INC
-#include "mesaglx/types.h"
+#include "types.h"
+#include "i810dma.h"
+#include "i810ioctl.h"
+extern void i810PrintRenderState( const char *msg, GLuint state );
extern void i810DDChooseRenderState(GLcontext *ctx);
-extern void i810DDTrifuncInit();
+extern void i810DDTrifuncInit( void );
-/* extern void i810FinishPrimitive( void ); */
-extern void i810NaughtyFinishPrimitive( void );
-extern GLuint *i810AllocPrimitiveVerts( int dwords );
+/* shared */
+#define I810_FLAT_BIT 0x1
+/* triangle */
+#define I810_OFFSET_BIT 0x2
+#define I810_TWOSIDE_BIT 0x4
-/* Todo:
- * - multidraw, ...
- * - Antialiasing (?)
- * - line and polygon stipple
- * - select and feedback
- * - stencil
- * - point parameters
- * -
- */
-#define I810_ANTIALIAS_BIT 0 /* ignored for now, no fallback */
-#define I810_FLAT_BIT 0x1
-#define I810_OFFSET_BIT 0x2 /* 3.1 only */
-#define I810_TWOSIDE_BIT 0x4 /* 3.1 only */
-#define I810_NODRAW_BIT 0x8
-#define I810_FALLBACK_BIT 0x10
-
-/* Not in use:
- */
-#define I810_FEEDBACK_BIT 0x20
-#define I810_SELECT_BIT 0x40
-#define I810_POINT_PARAM_BIT 0x80 /* not needed? */
+/* line */
+#define I810_WIDE_LINE_BIT 0x2
+#define I810_STIPPLE_LINE_BIT 0x4
+/* shared */
+#define I810_FALLBACK_BIT 0x8
-static inline void i810_draw_triangle( i810_vertex *v0,
- i810_vertex *v1,
- i810_vertex *v2 )
-{
-#if 0
- fprintf(stderr, "i810_draw_triangle( %p, %p, %p )\n", v0, v1, v2);
-#endif
+static i810_vertex __inline__ *i810AllocTriangles( i810ContextPtr imesa, int nr)
+{
+ GLuint *start = i810AllocDwords( imesa, 30*nr+1 );
+ *start++ = GFX_OP_PRIMITIVE | PR_TRIANGLES | (30*nr-1);
+ return (i810_vertex *)start;
+}
-#if 0
-#define WID 640
-#define HI 480
- {
- GLuint print = 1, draw = 1;
- GLfloat area = ((v0->x - v2->x) * (v1->y - v2->y) -
- (v0->y - v2->y) * (v1->x - v2->x));
-
- if (v0->x < -.501 || v0->x > WID || v0->y < -.501 || v0->y > HI ||
- v1->x < -.501 || v1->x > WID || v1->y < -.501 || v1->y > HI ||
- v2->x < -.501 || v2->x > WID || v2->y < -.501 || v2->y > HI) {
- fprintf(stderr, "not clipped\n");
- print = 1;
- }
-
- if (area == 0 && ((v0 == v1) || (v1 == v2))) {
- fprintf(stderr, "zero area %p %p %p\n", v0, v1, v2);
- draw = 0;
- }
-
- if (print) {
- fprintf(stderr," v0: %f %f %f %f tex: %f %f\n",
- v0->x, v0->y, v0->z, v0->oow, v0->tu0, v0->tv0);
- fprintf(stderr," v1: %f %f %f %f tex: %f %f\n",
- v1->x, v1->y, v1->z, v1->oow, v1->tu0, v1->tv0);
- fprintf(stderr," v2: %f %f %f %f tex: %f %f\n",
- v2->x, v2->y, v2->z, v2->oow, v2->tu0, v2->tv0);
- return;
- }
-
- if (!draw) return;
- }
-#endif
+static i810_vertex __inline__ *i810AllocLine( i810ContextPtr imesa )
+{
+ GLuint *start = i810AllocDwords( imesa, 21 );
+ *start++ = GFX_OP_PRIMITIVE | PR_LINESTRIP | (20-1);
+ return (i810_vertex *)start;
+}
- {
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 3 * 10 );
- wv[0] = *v0;
- wv[1] = *v1;
- wv[2] = *v2;
- FINISH_PRIM();
- }
+static i810_vertex __inline__ *i810AllocRect( i810ContextPtr imesa )
+{
+ GLuint *start = i810AllocDwords( imesa, 31 );
+ *start++ = GFX_OP_PRIMITIVE | PR_RECTS | (30-1);
+ return (i810_vertex *)start;
}
+static void __inline__ i810_draw_triangle( i810ContextPtr imesa,
+ i810_vertex *v0,
+ i810_vertex *v1,
+ i810_vertex *v2 )
+{
+ i810_vertex *wv = i810AllocTriangles( imesa, 1 );
+ wv[0] = *v0;
+ wv[1] = *v1;
+ wv[2] = *v2;
+ FINISH_PRIM();
+}
-/* These can go soon, but for the meantime we're using triangles for
- * everything.
- */
-static inline void i810_draw_point( i810_vertex *tmp, float sz )
+
+static __inline__ void i810_draw_point( i810ContextPtr imesa,
+ i810_vertex *tmp, float sz )
{
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts(6*10);
+ i810_vertex *wv = i810AllocTriangles( imesa, 2 );
wv[0] = *tmp;
wv[0].x = tmp->x - sz;
@@ -153,11 +122,23 @@ static inline void i810_draw_point( i810_vertex *tmp, float sz )
}
-static inline void i810_draw_line( i810_vertex *tmp0,
- i810_vertex *tmp1,
- float width )
+static __inline__ void i810_draw_line_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1 )
+{
+ i810_vertex *wv = i810AllocLine( imesa );
+ wv[0] = *tmp0;
+ wv[1] = *tmp1;
+ FINISH_PRIM();
+}
+
+static __inline__ void i810_draw_tri_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1,
+ float width )
{
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 6 * 10 );
+ i810_vertex *wv = i810AllocTriangles( imesa, 2 );
+
float dx, dy, ix, iy;
dx = tmp0->x - tmp1->x;
@@ -168,15 +149,6 @@ static inline void i810_draw_line( i810_vertex *tmp0,
iy = ix; ix = 0;
}
-#if 0
- fprintf(stderr,"tmp0: %f %f %f %f col: %x tex: %f %f\n",
- tmp0->x, tmp0->y, tmp0->z, tmp0->oow, *(GLuint*)&tmp0->color, tmp0->tu0, tmp0->tv0);
- fprintf(stderr,"tmp1: %f %f %f %f col: %x tex: %f %f\n",
- tmp1->x, tmp1->y, tmp1->z, tmp1->oow, *(GLuint*)&tmp1->color, tmp1->tu0, tmp1->tv0);
- fprintf(stderr, "ix: %f, iy: %f\n", ix, iy);
-#endif
-
-
wv[0] = *tmp0;
wv[0].x = tmp0->x - ix;
wv[0].y = tmp0->y - iy;
@@ -200,8 +172,16 @@ static inline void i810_draw_line( i810_vertex *tmp0,
wv[5] = *tmp1;
wv[5].x = tmp1->x + ix;
wv[5].y = tmp1->y + iy;
-
FINISH_PRIM();
}
+
+static __inline__ void i810_draw_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1,
+ float width )
+{
+ i810_draw_line_line( imesa, tmp0, tmp1 );
+}
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
index c8ec01d49..ebe1ef5ea 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
@@ -1,19 +1,20 @@
-static inline void TAG(triangle)( GLcontext *ctx, GLuint e0,
- GLuint e1, GLuint e2, GLuint pv )
+static __inline__ void TAG(triangle)( GLcontext *ctx, GLuint e0,
+ GLuint e1, GLuint e2, GLuint pv )
{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
struct vertex_buffer *VB = ctx->VB;
i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts;
- const i810_vertex *v0 = &i810VB[e0].v.v;
- const i810_vertex *v1 = &i810VB[e1].v.v;
- const i810_vertex *v2 = &i810VB[e2].v.v;
+ const i810_vertex *v0 = &i810VB[e0].v;
+ const i810_vertex *v1 = &i810VB[e1].v;
+ const i810_vertex *v2 = &i810VB[e2].v;
#if (IND & I810_OFFSET_BIT)
GLfloat offset = ctx->Polygon.OffsetUnits * 1.0/0x10000;
#endif
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- int c0 = *(int *)&i810VB[pv].v.v.color;
+ int c0 = *(int *)&i810VB[pv].v.color;
int c1 = c0;
int c2 = c0;
#endif
@@ -64,78 +65,39 @@ static inline void TAG(triangle)( GLcontext *ctx, GLuint e0,
i810glx.c_triangles++;
-#if 0
-#define WID 512
-#define HI 384
- {
- GLuint print = 0, draw = 1;
- GLfloat area = ((v0->x - v2->x) * (v1->y - v2->y) -
- (v0->y - v2->y) * (v1->x - v2->x));
-
- if (v0->x < -.501 || v0->x > WID || v0->y < -.501 || v0->y > HI ||
- v1->x < -.501 || v1->x > WID || v1->y < -.501 || v1->y > HI ||
- v2->x < -.501 || v2->x > WID || v2->y < -.501 || v2->y > HI) {
- fprintf(stderr, "not clipped\n");
- print = 1;
- }
-
- if (area == 0 && ((v0 == v1) || (v1 == v2))) {
- fprintf(stderr, "zero area %p %p %p\n", v0, v1, v2);
- draw = 0;
- }
-
- if (print) {
- fprintf(stderr,"v0: %f %f %f %f col: %x tex: %f %f\n",
- v0->x, v0->y, v0->z, v0->oow,
- *(GLuint*)&v0->color, v0->tu0, v0->tv0);
- fprintf(stderr,"v1: %f %f %f %f col: %x tex: %f %f\n",
- v1->x, v1->y, v1->z, v1->oow,
- *(GLuint*)&v1->color, v1->tu0, v1->tv0);
- fprintf(stderr,"v2: %f %f %f %f col: %x tex: %f %f\n",
- v2->x, v2->y, v2->z, v2->oow,
- *(GLuint*)&v2->color, v2->tu0, v2->tv0);
-/* return; */
- }
-
- if (!draw) return;
- }
-#endif
- BEGIN_CLIP_LOOP()
- {
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( 3 * 10 );
- wv[0] = *v0;
+ {
+ i810_vertex *wv = i810AllocTriangles( imesa, 1 );
+ wv[0] = *v0;
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- *((int *)(&wv[0].color)) = c0;
+ *((int *)(&wv[0].color)) = c0;
#endif
#if (IND & I810_OFFSET_BIT)
- wv[0].z = v0->z + offset;
+ wv[0].z = v0->z + offset;
#endif
- wv[1] = *v1;
+ wv[1] = *v1;
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- *((int *)(&wv[1].color)) = c1;
+ *((int *)(&wv[1].color)) = c1;
#endif
#if (IND & I810_OFFSET_BIT)
- wv[1].z = v1->z + offset;
+ wv[1].z = v1->z + offset;
#endif
- wv[2] = *v2;
+ wv[2] = *v2;
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- *((int *)(&wv[2].color)) = c2;
+ *((int *)(&wv[2].color)) = c2;
#endif
#if (IND & I810_OFFSET_BIT)
- wv[2].z = v2->z + offset;
+ wv[2].z = v2->z + offset;
#endif
- FINISH_PRIM();
- }
- END_CLIP_LOOP();
+ FINISH_PRIM();
+ }
}
-
static void TAG(quad)( GLcontext *ctx, GLuint v0,
GLuint v1, GLuint v2, GLuint v3,
GLuint pv )
@@ -144,60 +106,66 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0,
TAG(triangle)( ctx, v1, v2, v3, pv );
}
-
-#if ((IND & ~I810_FLAT_BIT) == 0)
-
static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
i810VertexPtr i810VB = I810_DRIVER_DATA(ctx->VB)->verts;
- i810_vertex tmp0 = i810VB[v0].v.v;
- i810_vertex tmp1 = i810VB[v1].v.v;
- float width = ctx->Line.Width;
+ int tmp0, tmp1;
+ (void) tmp0; (void) tmp1;
+
if (IND & I810_FLAT_BIT) {
- *(int *)&tmp1.color = *(int *)&tmp0.color =
- *(int *)&i810VB[pv].v.v.color;
- }
+ tmp0 = *(int *)&i810VB[v0].v.color;
+ tmp1 = *(int *)&i810VB[v1].v.color;
+ i810VB[v0].v.color = i810VB[pv].v.color;
+ i810VB[v1].v.color = i810VB[pv].v.color;
+ }
- BEGIN_CLIP_LOOP()
- i810_draw_line( &tmp0, &tmp1, width );
- END_CLIP_LOOP();
+ if (IND & I810_WIDE_LINE_BIT)
+ {
+ i810_draw_tri_line( imesa, &i810VB[v0].v, &i810VB[v1].v,
+ ctx->Line.Width );
+ }
+ else
+ {
+ i810_draw_line_line( imesa, &i810VB[v0].v, &i810VB[v1].v );
+ }
+
+ if (IND & I810_FLAT_BIT) {
+ *(int *)&i810VB[v0].v.color = tmp0;
+ *(int *)&i810VB[v1].v.color = tmp1;
+ }
}
static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
{
- int i;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
struct vertex_buffer *VB = ctx->VB;
i810VertexPtr i810VB = I810_DRIVER_DATA(VB)->verts;
GLfloat sz = ctx->Point.Size * .5;
+ int i;
/* Culling is disabled automatically via. the
* ctx->Driver.ReducedPrimitiveChange() callback.
*/
-
+
for(i=first;i<=last;i++) {
if(VB->ClipMask[i]==0) {
- i810_vertex *tmp = &i810VB[i].v.v;
- BEGIN_CLIP_LOOP()
- i810_draw_point( tmp, sz );
- END_CLIP_LOOP();
+ i810_vertex *tmp = &i810VB[i].v;
+ i810_draw_point( imesa, tmp, sz );
}
}
}
-#endif
-static void TAG(init)()
+static void TAG(init)( void )
{
tri_tab[IND] = TAG(triangle);
quad_tab[IND] = TAG(quad);
-
-#if ((IND & ~I810_FLAT_BIT) == 0)
line_tab[IND] = TAG(line);
points_tab[IND] = TAG(points);
-#endif
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
index b41ad0960..6ba7eb9a5 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
@@ -28,46 +28,43 @@
#include "i810vb.h"
#include "i810log.h"
#include "i810dma.h"
-#include "xsmesaP.h"
-#include "xsmesa.h"
#include "stages.h"
-#include "os.h"
#include <stdio.h>
#include <stdlib.h>
#define TEX0 { \
- v->v.v.tu0 = tc0[i][0]; \
- v->v.v.tv0 = tc0[i][1]; \
+ v->v.tu0 = tc0[i][0]; \
+ v->v.tv0 = tc0[i][1]; \
}
#define TEX1 { \
- v->v.v.tu1 = tc1[i][0]; \
- v->v.v.tv1 = tc1[i][1]; \
+ v->v.tu1 = tc1[i][0]; \
+ v->v.tv1 = tc1[i][1]; \
}
/* Doesn't seem to work very well (golly).
*/
#define SPC { \
GLubyte *spec = &(VB->Spec[0][i][0]); \
- v->v.v.specular.red = spec[0]; \
- v->v.v.specular.green = spec[1]; \
- v->v.v.specular.blue = spec[2]; \
+ v->v.specular.red = spec[0]; \
+ v->v.specular.green = spec[1]; \
+ v->v.specular.blue = spec[2]; \
}
#define FOG { \
GLubyte *spec = &(VB->Spec[0][i][0]); \
- v->v.v.specular.alpha = spec[3]; \
+ v->v.specular.alpha = spec[3]; \
}
#define COL { \
GLubyte *col = &(VB->Color[0]->data[i][0]); \
- v->v.v.color.blue = col[2]; \
- v->v.v.color.green = col[1]; \
- v->v.v.color.red = col[0]; \
- v->v.v.color.alpha = col[3]; \
+ v->v.color.blue = col[2]; \
+ v->v.color.green = col[1]; \
+ v->v.color.red = col[0]; \
+ v->v.color.alpha = col[3]; \
}
/* The vertex formats we have don't seem to support projective texturing
@@ -82,19 +79,19 @@
imesa->setupdone &= ~I810_WIN_BIT; \
for (i=start; i < end; i++, v++) { \
float oow = 1.0 / tc[i][3]; \
- v->v.v.oow *= tc[i][3]; \
- v->v.v.tu0 *= oow; \
- v->v.v.tv0 *= oow; \
+ v->v.oow *= tc[i][3]; \
+ v->v.tu0 *= oow; \
+ v->v.tv0 *= oow; \
} \
}
#define COORD \
GLfloat *win = VB->Win.data[i]; \
- v->v.v.x = win[0]; \
- v->v.v.y = i810height - win[1]; \
- v->v.v.z = (1.0/0x10000) * win[2]; \
- v->v.v.oow = win[3];
+ v->v.x = win[0]; \
+ v->v.y = i810height - win[1]; \
+ v->v.z = (1.0/0x10000) * win[2]; \
+ v->v.oow = win[3];
@@ -104,15 +101,15 @@
#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \
static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
{ \
- i810ContextPtr imesa = I810_CONTEXT( ctx ); \
+ i810ContextPtr imesa = I810_CONTEXT( VB->ctx ); \
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
i810VertexPtr v; \
GLfloat (*tc0)[4]; \
GLfloat (*tc1)[4]; \
- GLfloat i810height = i810DB->Height; \
+ GLfloat i810height = dPriv->h; \
int i; \
- (void) i810height; \
+ (void) i810height; (void) imesa; \
\
- CHECK_CONTEXT( return; ); \
\
gl_import_client_data( VB, VB->ctx->RenderFlags, \
(VB->ClipOrMask \
@@ -143,7 +140,7 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
tex1; \
} \
col; \
- } \
+ } \
tex0_4; \
}
@@ -155,11 +152,13 @@ SETUPFUNC(rs_wt0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,NOP)
SETUPFUNC(rs_wft0, COORD,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
SETUPFUNC(rs_wft0t1, COORD,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
SETUPFUNC(rs_wg, COORD,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_wgs, COORD,COL,NOP,NOP,NOP,SPC,NOP)
SETUPFUNC(rs_wgt0, COORD,COL,TEX0,NOP,TEX0_4,NOP,NOP)
SETUPFUNC(rs_wgt0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
SETUPFUNC(rs_wgst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,NOP)
SETUPFUNC(rs_wgst0t1, COORD,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
SETUPFUNC(rs_wgf, COORD,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_wgfs, COORD,COL,NOP,NOP,NOP,SPC,FOG)
SETUPFUNC(rs_wgft0, COORD,COL,TEX0,NOP,TEX0_4,NOP,FOG)
SETUPFUNC(rs_wgft0t1, COORD,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
SETUPFUNC(rs_wgfst0, COORD,COL,TEX0,NOP,TEX0_4,SPC,FOG)
@@ -171,11 +170,13 @@ SETUPFUNC(rs_f, NOP,NOP,NOP,NOP,NOP,NOP,FOG)
SETUPFUNC(rs_ft0, NOP,NOP,TEX0,NOP,TEX0_4,NOP,FOG)
SETUPFUNC(rs_ft0t1, NOP,NOP,TEX0,TEX1,TEX0_4,NOP,FOG)
SETUPFUNC(rs_g, NOP,COL,NOP,NOP,NOP,NOP,NOP)
+SETUPFUNC(rs_gs, NOP,COL,NOP,NOP,NOP,SPC,NOP)
SETUPFUNC(rs_gt0, NOP,COL,TEX0,NOP,TEX0_4,NOP,NOP)
SETUPFUNC(rs_gt0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,NOP)
SETUPFUNC(rs_gst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,NOP)
SETUPFUNC(rs_gst0t1, NOP,COL,TEX0,TEX1,TEX0_4,SPC,NOP)
SETUPFUNC(rs_gf, NOP,COL,NOP,NOP,NOP,NOP,FOG)
+SETUPFUNC(rs_gfs, NOP,COL,NOP,NOP,NOP,SPC,FOG)
SETUPFUNC(rs_gft0, NOP,COL,TEX0,NOP,TEX0_4,NOP,FOG)
SETUPFUNC(rs_gft0t1, NOP,COL,TEX0,TEX1,TEX0_4,NOP,FOG)
SETUPFUNC(rs_gfst0, NOP,COL,TEX0,NOP,TEX0_4,SPC,FOG)
@@ -206,11 +207,13 @@ void i810DDSetupInit( void )
setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wft0;
setup_func[I810_WIN_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wft0t1;
setup_func[I810_WIN_BIT|I810_RGBA_BIT] = rs_wg;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT] = rs_wgs;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT] = rs_wgt0;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgt0t1;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgst0;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgst0t1;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT] = rs_wgf;
+ setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT] = rs_wgfs;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_wgft0;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_wgft0t1;
setup_func[I810_WIN_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_wgfst0;
@@ -223,11 +226,13 @@ void i810DDSetupInit( void )
setup_func[I810_FOG_BIT|I810_TEX0_BIT] = rs_ft0;
setup_func[I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_ft0t1;
setup_func[I810_RGBA_BIT] = rs_g;
+ setup_func[I810_RGBA_BIT|I810_SPEC_BIT] = rs_gs;
setup_func[I810_RGBA_BIT|I810_TEX0_BIT] = rs_gt0;
setup_func[I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gt0t1;
setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gst0;
setup_func[I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gst0t1;
setup_func[I810_RGBA_BIT|I810_FOG_BIT] = rs_gf;
+ setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT] = rs_gfs;
setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT] = rs_gft0;
setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT] = rs_gft0t1;
setup_func[I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT] = rs_gfst0;
@@ -240,7 +245,7 @@ void i810PrintSetupFlags(char *msg, GLuint flags )
{
fprintf(stderr, "%s: %d %s%s%s%s%s%s%s\n",
msg,
- flags,
+ (int)flags,
(flags & I810_WIN_BIT) ? " xyzw," : "",
(flags & I810_RGBA_BIT) ? " rgba," : "",
(flags & I810_SPEC_BIT) ? " spec," : "",
@@ -274,7 +279,7 @@ void i810ChooseRasterSetupFunc(GLcontext *ctx)
if (ctx->FogMode == FOG_FRAGMENT)
funcindex |= I810_FOG_BIT;
- if (MESA_VERBOSE || I810_DEBUG)
+ if (MESA_VERBOSE)
i810PrintSetupFlags("xsmesa: full setup function", funcindex);
imesa->setupindex = funcindex;
@@ -312,6 +317,7 @@ void i810DDCheckPartialRasterSetup( GLcontext *ctx,
*/
void i810DDPartialRasterSetup( struct vertex_buffer *VB )
{
+ i810ContextPtr imesa = I810_CONTEXT( VB->ctx );
GLuint new = VB->pipeline->new_outputs;
GLuint available = VB->pipeline->outputs;
GLuint ind = 0;
@@ -337,7 +343,7 @@ void i810DDPartialRasterSetup( struct vertex_buffer *VB )
ind &= imesa->setupindex;
imesa->setupdone |= ind;
- i810PrintSetupFlags("xsmesa: partial setup function", ind);
+ if (0) i810PrintSetupFlags("xsmesa: partial setup function", ind);
if (ind)
setup_func[ind&~I810_ALPHA_BIT]( VB, VB->Start, VB->Count );
@@ -366,28 +372,37 @@ void i810DDResizeVB( struct vertex_buffer *VB, GLuint size )
free( mvb->vert_store );
mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31);
- if (!mvb->vert_store)
- FatalError("i810-glx: out of memory !\n");
+ if (!mvb->vert_store) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
gl_vector1ui_free( &mvb->clipped_elements );
gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
- if (!mvb->clipped_elements.start)
- FatalError("i810-glx: out of memory !\n");
+ if (!mvb->clipped_elements.start) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
free( VB->ClipMask );
VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
- if (!VB->ClipMask)
- FatalError("i810-glx: out of memory !\n");
+ if (!VB->ClipMask) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
if (VB->Type == VB_IMMEDIATE) {
free( mvb->primitive );
free( mvb->next_primitive );
mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
- if (!mvb->primitive || !mvb->next_primitive)
- FatalError("i810-glx: out of memory!");
+ if (!mvb->primitive || !mvb->next_primitive) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
}
}
@@ -398,31 +413,35 @@ void i810DDRegisterVB( struct vertex_buffer *VB )
mvb = (i810VertexBufferPtr)calloc( 1, sizeof(*mvb) );
- /* This looks like it allocates a lot of memory, but it basically
- * just sets an upper limit on how much can be used - nothing like
- * this amount will ever be turned into 'real' memory.
- */
- mvb->size = VB->Size * 5;
+ mvb->size = VB->Size * 2;
mvb->vert_store = malloc( sizeof(i810Vertex) * mvb->size + 31);
- if (!mvb->vert_store)
- FatalError("i810-glx: out of memory !\n");
+ if (!mvb->vert_store) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
mvb->verts = (i810VertexPtr)(((unsigned long)mvb->vert_store + 31) & ~31);
gl_vector1ui_alloc( &mvb->clipped_elements, VEC_WRITABLE, mvb->size, 32 );
- if (!mvb->clipped_elements.start)
- FatalError("i810-glx: out of memory !\n");
-
+ if (!mvb->clipped_elements.start) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
free( VB->ClipMask );
VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * mvb->size);
- if (!VB->ClipMask)
- FatalError("i810-glx: out of memory !\n");
+ if (!VB->ClipMask) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
mvb->primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
mvb->next_primitive = (GLuint *)malloc( sizeof(GLuint) * mvb->size );
- if (!mvb->primitive || !mvb->next_primitive)
- FatalError("i810-glx: out of memory!");
-
+ if (!mvb->primitive || !mvb->next_primitive) {
+ fprintf(stderr, "i810-glx: out of memory !\n");
+ exit(1);
+ }
+
VB->driver_data = mvb;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.h b/xc/lib/GL/mesa/src/drv/i810/i810vb.h
index 640afa678..23685f106 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810vb.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.h
@@ -26,7 +26,8 @@
#ifndef I810VB_INC
#define I810VB_INC
-#include "mesaglx/vb.h"
+#include "vb.h"
+#include "types.h"
/*
* color type for the vertex data
@@ -56,15 +57,13 @@ typedef struct {
/* Unfortunately only have assembly for 16-stride vertices.
*/
-struct i810_vertex_t {
- union {
- i810_vertex v;
- float f[16];
- } v;
+union i810_vertex_t {
+ i810_vertex v;
+ float f[16];
};
-typedef struct i810_vertex_t i810Vertex;
-typedef struct i810_vertex_t *i810VertexPtr;
+typedef union i810_vertex_t i810Vertex;
+typedef union i810_vertex_t *i810VertexPtr;
struct i810_vertex_buffer_t {
GLvector1ui clipped_elements;
@@ -79,7 +78,7 @@ struct i810_vertex_buffer_t {
typedef struct i810_vertex_buffer_t *i810VertexBufferPtr;
-#define I810_CONTEXT(ctx) ((i810ContextPtr)(((XSMesaContext)(ctx)->DriverCtx)->hw_ctx))
+#define I810_CONTEXT(ctx) ((i810ContextPtr)(ctx->DriverCtx))
#define I810_DRIVER_DATA(vb) ((i810VertexBufferPtr)((vb)->driver_data))
@@ -97,7 +96,7 @@ extern void i810PrintSetupFlags(char *msg, GLuint flags );
extern void i810DDDoRasterSetup( struct vertex_buffer *VB );
extern void i810DDPartialRasterSetup( struct vertex_buffer *VB );
extern void i810DDCheckPartialRasterSetup( GLcontext *ctx,
- struct gl_pipeline_stage *d );
+ struct gl_pipeline_stage *d );
extern void i810DDViewport( GLcontext *ctx,
GLint x, GLint y,
diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile
index e4e39b747..1ca3bde8a 100644
--- a/xc/lib/GL/mesa/src/drv/mga/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile
@@ -1,4 +1,6 @@
+#include <Threads.tmpl>
+
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
#define DoExtraLib SharedLibGlx
@@ -12,6 +14,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#if BuildXF86DRI
DRI_DEFINES = GlxDefines -DDRIVERTS
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
-I$(XF86DRIVERSRC)/mga \
@@ -24,23 +27,244 @@ MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
- DRISRCS = mgaclear.c mgacnvtex.c mgadd.c mgadepth.c \
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+#if 0
+ LOSRC = ../../../../lowpc.c
+ LOOBJ = ../../../../lowpc.o
+
+ HISRC = ../../../../highpc.c
+ HIOBJ = ../../../../highpc.o
+#endif
+
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o
+
+
+ MGASRCS = mgaclear.c mgacnvtex.c mgadd.c \
mgafastpath.c \
mgapipeline.c \
mgaspan.c mgastate.c mgatex.c \
- mgatris.c mgavb.c mgaioctl.c mga_xmesa.c
+ mgatris.c mgavb.c mgaioctl.c mga_xmesa.c mgabuffers.c
- DRIOBJS = mgaclear.o mgacnvtex.o mgadd.o mgadepth.o \
+ MGAOBJS = mgaclear.o mgacnvtex.o mgadd.o \
mgafastpath.o \
mgapipeline.o \
mgaspan.o mgastate.o mgatex.o \
- mgatris.o mgavb.o mgaioctl.o mga_xmesa.o
+ mgatris.o mgavb.o mgaioctl.o mga_xmesa.o mgabuffers.o
+
+ MESASRCS = ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.o \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ COMMONSRCS = ../common/mm.c ../common/hwlog.c
+ COMMONOBJS = ../common/mm.o ../common/hwlog.o
+ SRCS = $(LOWSRC) $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(COMMONSRCS) $(MGASRCS) $(HISRC)
+ OBJS = $(LOWOBJ) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(COMMONOBJS) $(MGAOBJS) $(HIOBJ)
- SRCS = $(DRISRCS)
- OBJS = $(DRIOBJS)
+REQUIREDLIBS += -lm
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -61,7 +285,7 @@ LIBNAME = mga_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
index 496c29a05..996dc3819 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
@@ -27,7 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
- * Daryll Strauss <daryll@precisioninsight.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
*
*/
@@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <X11/Xlibint.h>
#include <stdio.h>
+#include "drm.h"
#include "mga_xmesa.h"
#include "context.h"
#include "vbxform.h"
@@ -49,20 +50,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "mgadepth.h"
#include "mgatris.h"
#include "mgapipeline.h"
+#include "mgabuffers.h"
#include "xf86dri.h"
-#include "mga_dri.h"
-#include "mga_drm_public.h"
#include "mga_xmesa.h"
+#include "mga_dri.h"
+
#ifndef MGA_DEBUG
int MGA_DEBUG = (0
-/* | MGA_DEBUG_ALWAYS_SYNC */
-/* | MGA_DEBUG_VERBOSE_MSG */
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_MSG */
+/* | DEBUG_VERBOSE_LRU */
+/* | DEBUG_VERBOSE_DRI */
+/* | DEBUG_VERBOSE_IOCTL */
+/* | DEBUG_VERBOSE_2D */
);
#endif
@@ -107,7 +113,10 @@ static int count_bits(unsigned int n)
GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen;
- MGADRIPtr gDRIPriv = (MGADRIPtr)sPriv->pDevPriv;
+ MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;
+
+
+ fprintf(stderr, "XMesaInitDriver\n");
/* Allocate the private area */
mgaScreen = (mgaScreenPrivate *)Xmalloc(sizeof(mgaScreenPrivate));
@@ -116,20 +125,68 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
mgaScreen->sPriv = sPriv;
sPriv->private = (void *)mgaScreen;
- mgaScreen->chipset=gDRIPriv->chipset;
- mgaScreen->width=gDRIPriv->width;
- mgaScreen->height=gDRIPriv->height;
- mgaScreen->mem=gDRIPriv->mem;
- mgaScreen->cpp=gDRIPriv->cpp;
- mgaScreen->frontPitch=gDRIPriv->frontPitch;
- mgaScreen->frontOffset=gDRIPriv->frontOffset;
- mgaScreen->backOffset=gDRIPriv->backOffset;
- mgaScreen->backPitch = gDRIPriv->backPitch;
- mgaScreen->depthOffset=gDRIPriv->depthOffset;
- mgaScreen->depthPitch = gDRIPriv->depthPitch;
- mgaScreen->textureOffset=gDRIPriv->textureOffset;
- mgaScreen->textureSize=gDRIPriv->textureSize;
- mgaScreen->logTextureGranularity = gDRIPriv->logTextureGranularity;
+ fprintf(stderr, "serverInfo->chipset: %d\n", serverInfo->chipset);
+
+ if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
+ serverInfo->chipset != MGA_CARD_TYPE_G400)
+ return GL_FALSE;
+
+ mgaScreen->chipset = serverInfo->chipset;
+ mgaScreen->width = serverInfo->width;
+ mgaScreen->height = serverInfo->height;
+ mgaScreen->mem = serverInfo->mem;
+ mgaScreen->cpp = serverInfo->cpp;
+ mgaScreen->frontPitch = serverInfo->frontPitch;
+ mgaScreen->frontOffset = serverInfo->frontOffset;
+ mgaScreen->backOffset = serverInfo->backOffset;
+ mgaScreen->backPitch = serverInfo->backPitch;
+ mgaScreen->depthOffset = serverInfo->depthOffset;
+ mgaScreen->depthPitch = serverInfo->depthPitch;
+
+
+ mgaScreen->agp_tex.handle = serverInfo->agp;
+ mgaScreen->agp_tex.size = serverInfo->agpSize;
+
+ if (drmMap(sPriv->fd,
+ mgaScreen->agp_tex.handle,
+ mgaScreen->agp_tex.size,
+ (drmAddress *)&mgaScreen->agp_tex.map) != 0)
+ {
+ Xfree(mgaScreen);
+ return GL_FALSE;
+ }
+
+
+
+ mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
+ mgaScreen->textureOffset[MGA_AGP_HEAP] = (mgaScreen->agp_tex.handle |
+ PDEA_pagpxfer_enable | 1);
+
+ fprintf(stderr, "CARD texture size %x, granul %d --> %x\n",
+ serverInfo->textureSize, serverInfo->logTextureGranularity,
+ 1<<serverInfo->logTextureGranularity);
+
+ mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
+ mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;
+
+ mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
+ serverInfo->logTextureGranularity;
+ mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
+ serverInfo->logAgpTextureGranularity;
+
+ mgaScreen->texVirtual[MGA_CARD_HEAP] = (mgaScreen->sPriv->pFB +
+ mgaScreen->textureOffset[0]);
+ mgaScreen->texVirtual[MGA_AGP_HEAP] = mgaScreen->agp_tex.map;
+
+ mgaScreen->mAccess = serverInfo->mAccess;
+
+
+ fprintf(stderr, "\n\n\nbackOffset: %x pitch %x\n",
+ mgaScreen->backOffset,
+ mgaScreen->backPitch);
+
+
+ mgaScreen->Attrib = MGA_PF_565;
mgaScreen->bufs = drmMapBufs(sPriv->fd);
@@ -169,6 +226,8 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
{
XMesaVisual v;
+ fprintf(stderr, "XMesaCreateVisual\n");
+
/* Only RGB visuals are supported on the MGA boards */
if (!rgb_flag) return 0;
@@ -183,28 +242,19 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
memcpy(v->visinfo, visinfo, sizeof(*visinfo));
v->display = display;
- v->level = level;
-
- v->gl_visual = (GLvisual *)Xmalloc(sizeof(GLvisual));
+ v->level = level;
+ v->gl_visual = gl_create_visual(rgb_flag, GL_FALSE, db_flag, stereo_flag,
+ depth_size, stencil_size, accum_size, 0,
+ count_bits(visinfo->red_mask),
+ count_bits(visinfo->green_mask),
+ count_bits(visinfo->blue_mask),
+ GL_FALSE);
if (!v->gl_visual) {
Xfree(v->visinfo);
- XFree(v);
- return 0;
+ Xfree(v);
+ return NULL;
}
- v->gl_visual->RGBAflag = rgb_flag;
- v->gl_visual->DBflag = db_flag;
- v->gl_visual->StereoFlag = stereo_flag;
-
- v->gl_visual->RedBits = count_bits(visinfo->red_mask);
- v->gl_visual->GreenBits = count_bits(visinfo->green_mask);
- v->gl_visual->BlueBits = count_bits(visinfo->blue_mask);
- v->gl_visual->AlphaBits = 0; /* Not currently supported */
-
- v->gl_visual->AccumBits = accum_size;
- v->gl_visual->DepthBits = depth_size;
- v->gl_visual->StencilBits = stencil_size;
-
return v;
}
@@ -218,6 +268,7 @@ void XMesaDestroyVisual(XMesaVisual v)
XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
__DRIcontextPrivate *driContextPriv)
{
+ int i;
GLcontext *ctx;
XMesaContext c;
mgaContextPtr mmesa;
@@ -227,12 +278,15 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
sizeof(XF86DRISAREARec));
GLcontext *shareCtx = 0;
+ fprintf(stderr, "XMesaCreateContext\n");
+
+
c = (XMesaContext)Xmalloc(sizeof(struct xmesa_context));
if (!c) {
return 0;
}
- mmesa = (mgaContextPtr)Xmalloc(sizeof(mgaContext));
+ mmesa = (mgaContextPtr)Xcalloc(sizeof(mgaContext), 1);
if (!mmesa) {
Xfree(c);
return 0;
@@ -250,8 +304,6 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
ctx = mmesa->glCtx = gl_create_context(v->gl_visual, shareCtx,
(void*)mmesa, GL_TRUE);
- /* Dri stuff
- */
mmesa->display = v->display;
mmesa->hHWContext = driContextPriv->hHWContext;
mmesa->driFd = sPriv->fd;
@@ -261,40 +313,45 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
mmesa->driScreen = sPriv;
mmesa->sarea = saPriv;
- mmesa->glBuffer=gl_create_framebuffer(v->gl_visual);
+ mmesa->glBuffer=gl_create_framebuffer(v->gl_visual,
+ GL_FALSE, /* software depth buffer? */
+ v->gl_visual->StencilBits > 0,
+ v->gl_visual->AccumBits > 0,
+ v->gl_visual->AlphaBits > 0);
+
+ make_empty_list(&mmesa->SwappedOut);
- mmesa->needClip=1;
+ mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1;
- mmesa->texHeap = mmInit( 0, mgaScreen->textureSize );
+ for (i = 0 ; i < mmesa->lastTexHeap ; i++) {
+ mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]);
+ make_empty_list(&mmesa->TexObjList[i]);
+ }
- /* Utah stuff
- */
mmesa->renderindex = -1; /* impossible value */
mmesa->new_state = ~0;
mmesa->dirty = ~0;
-
- mmesa->warp_pipe = 0;
-
-
- make_empty_list(&mmesa->SwappedOut);
- make_empty_list(&mmesa->TexObjList);
-
+ mmesa->warp_pipe = 0;
mmesa->CurrentTexObj[0] = 0;
mmesa->CurrentTexObj[1] = 0;
+ mmesa->texAge[0] = 0;
+ mmesa->texAge[1] = 0;
+
+
mgaDDExtensionsInit( ctx );
mgaDDInitStateFuncs( ctx );
mgaDDInitTextureFuncs( ctx );
mgaDDInitSpanFuncs( ctx );
- mgaDDInitDepthFuncs( ctx );
mgaDDInitDriverFuncs( ctx );
mgaDDInitIoctlFuncs( ctx );
ctx->Driver.TriangleCaps = (DD_TRI_CULL|
DD_TRI_LIGHT_TWOSIDE|
+ DD_TRI_STIPPLE|
DD_TRI_OFFSET);
/* Ask mesa to clip fog coordinates for us.
@@ -312,6 +369,9 @@ XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
mgaDDRegisterPipelineStages(ctx->PipelineStage,
ctx->PipelineStage,
ctx->NrPipelineStages);
+
+ mgaInitState( mmesa );
+
return c;
}
@@ -364,59 +424,12 @@ void XMesaSwapBuffers(XMesaBuffer bogus_value_do_not_use)
-
-void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
+GLboolean XMesaUnbindContext(XMesaContext c)
{
- __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
-
- mmesa->numClipRects = dPriv->numClipRects;
- mmesa->pClipRects = dPriv->pClipRects;
- mmesa->drawX = dPriv->x;
- mmesa->drawY = dPriv->y;
-
- mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
-}
-
-
-void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
-{
- __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
-
- if (dPriv->numAuxClipRects == 0)
- {
- mmesa->numClipRects = dPriv->numClipRects;
- mmesa->pClipRects = dPriv->pClipRects;
- mmesa->drawX = dPriv->x;
- mmesa->drawY = dPriv->y;
- } else {
- mmesa->numClipRects = dPriv->numAuxClipRects;
- mmesa->pClipRects = dPriv->pAuxClipRects;
- mmesa->drawX = dPriv->auxX;
- mmesa->drawY = dPriv->auxY;
- }
-
- mmesa->drawOffset = mmesa->mgaScreen->backOffset;
-}
-
-
-static void mgaXMesaWindowMoved( mgaContextPtr mmesa )
-{
- /* Clear any contaminated CVA data.
- */
- mmesa->setupdone = 0;
-
- switch (mmesa->glCtx->Color.DriverDrawBuffer) {
- case GL_FRONT_LEFT:
- mgaXMesaSetFrontClipRects( mmesa );
- break;
- case GL_BACK_LEFT:
- mgaXMesaSetBackClipRects( mmesa );
- break;
- default:
- fprintf(stderr, "fallback buffer\n");
- break;
- }
+ if (c->private)
+ ((mgaContextPtr)c->private)->dirty = ~0;
+ return GL_TRUE;
}
@@ -439,9 +452,9 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
gl_make_current(mgaCtx->glCtx, mgaCtx->glBuffer);
- mgaXMesaWindowMoved( mgaCtx );
mgaCtx->driDrawable = dPriv;
mgaCtx->dirty = ~0;
+ mgaCtx->dirty_cliprects = (MGA_FRONT|MGA_BACK);
if (!mgaCtx->glCtx->Viewport.Width)
gl_Viewport(mgaCtx->glCtx, 0, 0, dPriv->w, dPriv->h);
@@ -455,54 +468,36 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
}
-void mgaXMesaUpdateState( mgaContextPtr mmesa )
+void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
{
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
- __DRIscreenPrivate *sPriv = mmesa->driScreen;
drm_mga_sarea_t *sarea = mmesa->sarea;
-
int me = mmesa->hHWContext;
- int stamp = dPriv->lastStamp;
+ int i;
- /* If the window moved, may need to set a new cliprect now.
- *
- * NOTE: This releases and regains the hw lock, so all state
- * checking must be done *after* this call:
- */
- XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display, sPriv, dPriv);
+ drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
- if (sarea->ctxOwner != me) {
- mmesa->dirty |= MGA_UPLOAD_CTX;
+ if (*(dPriv->pStamp) != dPriv->lastStamp) {
+ mmesa->setupdone = 0;
+ mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
+ mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) );
}
- if (sarea->texAge != mmesa->texAge) {
- int sz = 1 << (mmesa->mgaScreen->logTextureGranularity);
- int idx, nr = 0;
-
- /* Have to go right round from the back to ensure stuff ends up
- * LRU in our local list...
- */
- for (idx = sarea->texList[MGA_NR_TEX_REGIONS].prev ;
- idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ;
- idx = sarea->texList[idx].prev, nr++)
- {
- if (sarea->texList[idx].age > mmesa->texAge)
- mgaTexturesGone(mmesa, idx * sz, sz, 1);
- }
-
- if (nr == MGA_NR_TEX_REGIONS) {
- mgaTexturesGone(mmesa, 0, mmesa->mgaScreen->textureSize, 0);
- mgaResetGlobalLRU( mmesa );
- }
-
- mmesa->texAge = sarea->texAge;
- mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE;
+ mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_CLIPRECTS;
+
+ mmesa->sarea->dirty |= MGA_UPLOAD_CTX;
+
+ if (sarea->ctxOwner != me) {
+ mmesa->dirty |= (MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0 |
+ MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
+ sarea->ctxOwner=me;
}
- if (dPriv->lastStamp != stamp)
- mgaXMesaWindowMoved( mmesa );
+ for (i = 0 ; i < mmesa->lastTexHeap ; i++)
+ if (sarea->texAge[i] != mmesa->texAge[i])
+ mgaAgeTextures( mmesa, i );
- sarea->ctxOwner=me;
+ sarea->last_quiescent = -1; /* just kill it for now */
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
index d563bd429..1379f48d9 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
@@ -28,7 +28,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
* Keith Whitwell <keithw@precisioninsight.com>
- * Daryll Strauss <daryll@precisioninsight.com> (Origninal tdfx driver).
*
*/
@@ -43,6 +42,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri_mesa.h"
#include "types.h"
#include "xmesaP.h"
+#include "mgaregs.h"
+
+typedef struct {
+ drmHandle handle;
+ drmSize size;
+ char *map;
+} mgaRegion, *mgaRegionPtr;
typedef struct {
@@ -54,6 +60,7 @@ typedef struct {
int cpp; /* for front and back buffers */
int Attrib;
+ int mAccess;
int frontOffset;
int frontPitch;
@@ -64,43 +71,54 @@ typedef struct {
int depthPitch;
int depthCpp;
- int textureOffset;
- int textureSize;
- int logTextureGranularity;
+ int textureOffset[MGA_NR_TEX_HEAPS];
+ int textureSize[MGA_NR_TEX_HEAPS];
+ int logTextureGranularity[MGA_NR_TEX_HEAPS];
+ char *texVirtual[MGA_NR_TEX_HEAPS];
+
__DRIscreenPrivate *sPriv;
drmBufMapPtr bufs;
+ mgaRegion agp_tex;
+
} mgaScreenPrivate;
#include "mgalib.h"
-extern void mgaXMesaUpdateState( mgaContextPtr mmesa );
+extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags );
extern void mgaEmitHwStateLocked( mgaContextPtr mmesa );
extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit );
-extern void mgaXMesaSetBackClipRects( mgaContextPtr mmesa );
-extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa );
+
+#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue
/* Lock the hardware and validate our state.
*/
-#define LOCK_HARDWARE( mmesa ) \
- do { \
- char __ret=0; \
- DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \
- (DRM_LOCK_HELD|mmesa->hHWContext), __ret); \
- if (__ret) { \
- drmGetLock(mmesa->driFd, mmesa->hHWContext, 0); \
- mgaXMesaUpdateState( mmesa ); \
- } \
+#define LOCK_HARDWARE( mmesa ) \
+ do { \
+ char __ret=0; \
+ DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \
+ (DRM_LOCK_HELD|mmesa->hHWContext), __ret); \
+ if (__ret) \
+ mgaGetLock( mmesa, 0 ); \
} while (0)
+/*
+ */
+#define LOCK_HARDWARE_QUIESCENT( mmesa ) do { \
+ LOCK_HARDWARE( mmesa ); \
+ mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); \
+} while (0)
+
+
/* Unlock the hardware using the global current context
*/
-#define UNLOCK_HARDWARE(mmesa) \
+#define UNLOCK_HARDWARE(mmesa) \
DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
@@ -109,6 +127,8 @@ extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa );
#define REFRESH_DRAWABLE_INFO( mmesa ) \
do { \
LOCK_HARDWARE( mmesa ); \
+ mmesa->lastX = mmesa->drawX; \
+ mmesa->lastY = mmesa->drawY; \
UNLOCK_HARDWARE( mmesa ); \
} while (0)
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c
new file mode 100644
index 000000000..276c5df85
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c
@@ -0,0 +1,315 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@precisioninsight.com>
+ *
+ * $PI: $
+ */
+
+#include <stdio.h>
+#include "mgalib.h"
+#include "mgabuffers.h"
+#include "mgastate.h"
+
+static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+
+ mmesa->numClipRects = driDrawable->numClipRects;
+ mmesa->pClipRects = driDrawable->pClipRects;
+ mmesa->drawX = driDrawable->x;
+ mmesa->drawY = driDrawable->y;
+
+ mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->drawOffset;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+}
+
+
+static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+
+ if (driDrawable->numBackClipRects == 0)
+ {
+ mmesa->numClipRects = driDrawable->numClipRects;
+ mmesa->pClipRects = driDrawable->pClipRects;
+ mmesa->drawX = driDrawable->x;
+ mmesa->drawY = driDrawable->y;
+ } else {
+ mmesa->numClipRects = driDrawable->numBackClipRects;
+ mmesa->pClipRects = driDrawable->pBackClipRects;
+ mmesa->drawX = driDrawable->backX;
+ mmesa->drawY = driDrawable->backY;
+ }
+
+ mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->drawOffset;
+
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+}
+
+
+
+static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+ __DRIscreenPrivate *driScreen = mmesa->driScreen;
+ drm_mga_sarea_t *sarea = mmesa->sarea;
+ int i = 0, top = 0;
+
+
+ if (sarea->exported_buffers & MGA_BACK) {
+ XF86DRIClipRectPtr boxes =
+ (XF86DRIClipRectPtr)malloc( sarea->exported_nback * sizeof(*boxes) );
+
+ if (driDrawable->pBackClipRects)
+ free(driDrawable->pBackClipRects);
+
+ driDrawable->numBackClipRects = sarea->exported_nback;
+ driDrawable->pBackClipRects = boxes;
+
+ top = sarea->exported_nback;
+ for (i = 0 ; i < top ; i++)
+ boxes[i] = *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
+ }
+
+
+ if (sarea->exported_buffers & MGA_FRONT)
+ {
+ int start = top;
+ XF86DRIClipRectPtr boxes =
+ (XF86DRIClipRectPtr)malloc( sarea->exported_nfront * sizeof(*boxes) );
+
+ if (driDrawable->pClipRects)
+ free(driDrawable->pClipRects);
+
+ driDrawable->numClipRects = sarea->exported_nfront;
+ driDrawable->pClipRects = boxes;
+
+ top += sarea->exported_nfront;
+ for ( ; i < top ; i++)
+ boxes[i-start] = *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]);
+
+ }
+
+
+
+ driDrawable->index = sarea->exported_index;
+ driDrawable->lastStamp = sarea->exported_stamp;
+ driDrawable->x = sarea->exported_front_x;
+ driDrawable->y = sarea->exported_front_y;
+ driDrawable->backX = sarea->exported_back_x;
+ driDrawable->backY = sarea->exported_back_y;
+ driDrawable->w = sarea->exported_w;
+ driDrawable->h = sarea->exported_h;
+ driDrawable->pStamp =
+ &(driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
+
+ mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers);
+}
+
+
+
+static void printSareaRects( mgaContextPtr mmesa )
+{
+ __DRIscreenPrivate *driScreen = mmesa->driScreen;
+ drm_mga_sarea_t *sarea = mmesa->sarea;
+ int i;
+
+ fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable);
+ fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index);
+ fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp);
+ fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x);
+ fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y);
+ fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x);
+ fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y);
+ fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w);
+ fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h);
+ fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers);
+ fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront);
+ fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback);
+
+ i = 0;
+ if (sarea->exported_buffers & MGA_BACK)
+ for ( ; i < sarea->exported_nback ; i++)
+ fprintf(stderr, "back %d: %d,%d-%d,%d\n", i,
+ sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
+ sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
+
+ if (sarea->exported_buffers & MGA_FRONT) {
+ int start = i;
+ int top = i + sarea->exported_nfront;
+ for ( ; i < top ; i++)
+ fprintf(stderr, "front %d: %d,%d-%d,%d\n",
+ i - start,
+ sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1,
+ sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2);
+ }
+
+ fprintf(stderr, "drawableTable[%d].stamp: %d\n",
+ sarea->exported_index,
+ driScreen->pSAREA->drawableTable[sarea->exported_index].stamp);
+}
+
+static void printMmesaRects( mgaContextPtr mmesa )
+{
+ __DRIscreenPrivate *driScreen = mmesa->driScreen;
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+ int nr = mmesa->numClipRects;
+ int i;
+
+ fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw);
+ fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index);
+ fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp);
+ fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX);
+ fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY);
+ fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w);
+ fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h);
+
+ for (i = 0 ; i < nr ; i++)
+ fprintf(stderr, "box %d: %d,%d-%d,%d\n", i,
+ mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1,
+ mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2);
+
+ fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer);
+ fprintf(stderr, "drawableTable[%d].stamp: %d\n",
+ driDrawable->index,
+ driScreen->pSAREA->drawableTable[driDrawable->index].stamp);
+}
+
+
+
+void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+ drm_mga_sarea_t *sarea = mmesa->sarea;
+
+ /* The MGA X driver will try to push one set of cliprects (back or
+ * front, the last active) for one drawable (the last used) into
+ * the sarea. See if that window was ours, else retrieve both back
+ * and front rects from the X server via a protocol request.
+ *
+ * If there isn't room for the cliprects in the sarea, the X server
+ * clears the drawable value to indicate failure.
+ */
+ if (0) printSareaRects(mmesa);
+
+ if (sarea->exported_drawable == driDrawable->draw &&
+ (sarea->exported_buffers & buffers) == buffers)
+ {
+ mgaUpdateRectsFromSarea( mmesa );
+ }
+ else
+ {
+ if(MGA_DEBUG & DEBUG_VERBOSE_MSG)
+ fprintf(stderr, "^");
+ driDrawable->lastStamp = 0;
+
+ XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display,
+ mmesa->driScreen,
+ driDrawable);
+ mmesa->dirty_cliprects = 0;
+ }
+
+ if (mmesa->draw_buffer == MGA_FRONT)
+ mgaXMesaSetFrontClipRects( mmesa );
+ else
+ mgaXMesaSetBackClipRects( mmesa );
+
+
+ if (0) printMmesaRects(mmesa);
+
+ sarea->req_drawable = driDrawable->draw;
+ sarea->req_draw_buffer = mmesa->draw_buffer;
+
+
+ mgaUpdateClipping( mmesa->glCtx );
+
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+}
+
+
+
+GLboolean mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
+
+ mmesa->Fallback &= ~MGA_FALLBACK_BUFFER;
+
+ if (mode == GL_FRONT_LEFT)
+ {
+ mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->frontOffset;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->draw_buffer = MGA_FRONT;
+ mgaXMesaSetFrontClipRects( mmesa );
+ return GL_TRUE;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset;
+ mmesa->draw_buffer = MGA_BACK;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mgaXMesaSetBackClipRects( mmesa );
+ return GL_TRUE;
+ }
+ else
+ {
+ mmesa->Fallback |= MGA_FALLBACK_BUFFER;
+ return GL_FALSE;
+ }
+}
+
+GLboolean mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ if (mode == GL_FRONT_LEFT)
+ {
+ mmesa->readOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->read_buffer = MGA_FRONT;
+ return GL_TRUE;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ mmesa->readOffset = mmesa->mgaScreen->backOffset;
+ mmesa->read_buffer = MGA_BACK;
+ return GL_TRUE;
+ }
+ else
+ {
+ return GL_FALSE;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h
new file mode 100644
index 000000000..9345fd9c4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h
@@ -0,0 +1,9 @@
+#ifndef MGA_BUFFERS_H
+#define MGA_BUFFERS_H
+
+GLboolean mgaDDSetReadBuffer(GLcontext *ctx, GLenum mode );
+GLboolean mgaDDSetDrawBuffer(GLcontext *ctx, GLenum mode );
+
+void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c b/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c
index ae8d95037..428b65d06 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgacnvtex.c
@@ -46,205 +46,206 @@
*/
void mgaConvertTexture( mgaUI32 *destPtr, int texelBytes,
struct gl_texture_image *image,
- int x, int y, int width, int height ) {
+ int x, int y, int width, int height )
+{
register int i, j;
mgaUI8 *src;
int stride;
/* FIXME: g400 luminance_alpha internal format */
switch (texelBytes) {
- case 1:
- switch (image->Format) {
- case GL_COLOR_INDEX:
- case GL_INTENSITY:
- case GL_LUMINANCE:
- case GL_ALPHA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 2 ; j ; j-- ) {
+ case 1:
+ switch (image->Format) {
+ case GL_COLOR_INDEX:
+ case GL_INTENSITY:
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 2 ; j ; j-- ) {
- *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 );
- src += 4;
- }
- src += stride;
- }
- break;
- default:
- goto format_error;
- }
- break;
- case 2:
- switch (image->Format) {
- case GL_RGB:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3;
- stride = (image->Width - width) * 3;
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 1 ; j ; j-- ) {
+ *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 );
+ src += 4;
+ }
+ src += stride;
+ }
+ break;
+ default:
+ goto format_error;
+ }
+ break;
+ case 2:
+ switch (image->Format) {
+ case GL_RGB:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3;
+ stride = (image->Width - width) * 3;
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 1 ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) |
- ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 );
- src += 6;
- }
- src += stride;
- }
- break;
- case GL_RGBA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4;
- stride = (image->Width - width) * 4;
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 1 ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) |
+ ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 );
+ src += 6;
+ }
+ src += stride;
+ }
+ break;
+ case GL_RGBA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4;
+ stride = (image->Width - width) * 4;
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 1 ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) |
- ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 );
- src += 8;
- }
- src += stride;
- }
- break;
- case GL_LUMINANCE:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 1 ; j ; j-- ) {
- /* FIXME: should probably use 555 texture to get true grey */
- *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) |
- ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 );
- src += 2;
- }
- src += stride;
- }
- break;
- case GL_INTENSITY:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 1 ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) |
+ ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 );
+ src += 8;
+ }
+ src += stride;
+ }
+ break;
+ case GL_LUMINANCE:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 1 ; j ; j-- ) {
+ /* FIXME: should probably use 555 texture to get true grey */
+ *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) |
+ ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 );
+ src += 2;
+ }
+ src += stride;
+ }
+ break;
+ case GL_INTENSITY:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 1 ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) |
- ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 );
- src += 2;
- }
- src += stride;
- }
- break;
- case GL_ALPHA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 1 ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) |
+ ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 );
+ src += 2;
+ }
+ src += stride;
+ }
+ break;
+ case GL_ALPHA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 1 ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) |
- ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 );
- src += 2;
- }
- src += stride;
- }
- break;
- case GL_LUMINANCE_ALPHA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2;
- stride = (image->Width - width) * 2;
- for ( i = height ; i ; i-- ) {
- for ( j = width >> 1 ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) |
+ ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 );
+ src += 2;
+ }
+ src += stride;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2;
+ stride = (image->Width - width) * 2;
+ for ( i = height ; i ; i-- ) {
+ for ( j = width >> 1 ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) |
- ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 );
- src += 4;
- }
- src += stride;
- }
- break;
- default:
- goto format_error;
- }
- break;
- case 4:
- switch (image->Format) {
- case GL_RGB:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3;
- stride = (image->Width - width) * 3;
- for ( i = height ; i ; i-- ) {
- for ( j = width ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) |
+ ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 );
+ src += 4;
+ }
+ src += stride;
+ }
+ break;
+ default:
+ goto format_error;
+ }
+ break;
+ case 4:
+ switch (image->Format) {
+ case GL_RGB:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 3;
+ stride = (image->Width - width) * 3;
+ for ( i = height ; i ; i-- ) {
+ for ( j = width ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255);
- src += 3;
- }
- src += stride;
- }
- break;
- case GL_RGBA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4;
- stride = (image->Width - width) * 4;
- for ( i = height ; i ; i-- ) {
- for ( j = width ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255);
+ src += 3;
+ }
+ src += stride;
+ }
+ break;
+ case GL_RGBA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 4;
+ stride = (image->Width - width) * 4;
+ for ( i = height ; i ; i-- ) {
+ for ( j = width ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]);
- src += 4;
- }
- src += stride;
- }
- break;
- case GL_LUMINANCE:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]);
+ src += 4;
+ }
+ src += stride;
+ }
+ break;
+ case GL_LUMINANCE:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255);
- src += 1;
- }
- src += stride;
- }
- break;
- case GL_INTENSITY:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255);
+ src += 1;
+ }
+ src += stride;
+ }
+ break;
+ case GL_INTENSITY:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]);
- src += 1;
- }
- src += stride;
- }
- break;
- case GL_ALPHA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x );
- stride = (image->Width - width);
- for ( i = height ; i ; i-- ) {
- for ( j = width ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]);
+ src += 1;
+ }
+ src += stride;
+ }
+ break;
+ case GL_ALPHA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x );
+ stride = (image->Width - width);
+ for ( i = height ; i ; i-- ) {
+ for ( j = width ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]);
- src += 1;
- }
- src += stride;
- }
- break;
- case GL_LUMINANCE_ALPHA:
- src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2;
- stride = (image->Width - width) * 2;
- for ( i = height ; i ; i-- ) {
- for ( j = width ; j ; j-- ) {
+ *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]);
+ src += 1;
+ }
+ src += stride;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ src = (mgaUI8 *)image->Data + ( y * image->Width + x ) * 2;
+ stride = (image->Width - width) * 2;
+ for ( i = height ; i ; i-- ) {
+ for ( j = width ; j ; j-- ) {
- *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],
- src[0],src[1]);
- src += 2;
- }
- src += stride;
- }
- break;
- default:
- goto format_error;
- }
- break;
- default:
- goto format_error;
+ *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],
+ src[0],src[1]);
+ src += 2;
+ }
+ src += stride;
+ }
+ break;
+ default:
+ goto format_error;
+ }
+ break;
+ default:
+ goto format_error;
}
return;
-format_error:
+ format_error:
- mgaError( "Unsupported texelBytes %i, image->Format %i\n",
- texelBytes, image->Format );
+ mgaError( "Unsupported texelBytes %i, image->Format %i\n",
+ (int)texelBytes, (int)image->Format );
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c
index ad56cbbc3..bdae9a2bf 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c
@@ -61,11 +61,11 @@ static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name )
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
switch (name) {
case GL_VENDOR:
- return "Utah GLX";
+ return "Precision Insight";
case GL_RENDERER:
- if (MGA_IS_G200(mmesa)) return "GLX-MGA-G200";
- if (MGA_IS_G400(mmesa)) return "GLX-MGA-G400";
- return "GLX-MGA";
+ if (MGA_IS_G200(mmesa)) return "DRI-MGA-G200";
+ if (MGA_IS_G400(mmesa)) return "DRI-MGA-G400";
+ return "DRI-MGA";
default:
return 0;
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadepth.c b/xc/lib/GL/mesa/src/drv/mga/mgadepth.c
index 0d55137d1..2dfc3e00c 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgadepth.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgadepth.c
@@ -43,20 +43,24 @@
#include "mgalib.h"
#endif
-
+#define DEPTH_SCALE 65535.0F
/*
* Return the address of the Z-buffer value for window coordinate (x,y):
*/
-#define Z_SETUP \
- mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
- __DRIscreenPrivate *sPriv = mmesa->driScreen; \
- mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
- GLdepth *zbstart = (GLdepth *)(sPriv->pFB + mgaScreen->depthOffset);\
- GLint zbpitch = mgaScreen->depthPitch
+#define Z_SETUP \
+ __DRIscreenPrivate *sPriv = mmesa->driScreen; \
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
+ GLuint height = dPriv->h; \
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
+ GLint zbpitch = mgaScreen->depthPitch; \
+ char *zbstart = (char *)(sPriv->pFB + \
+ mgaScreen->depthOffset + \
+ dPriv->x * 2 + \
+ dPriv->y * zbpitch)
#define Z_ADDRESS( X, Y ) \
- (zbstart + zbpitch * (Y) + (X))
+ (GLdepth *)(zbstart + zbpitch * (height - (Y)) + (X) * 2)
/**********************************************************************/
@@ -84,16 +88,18 @@ static GLuint mga_depth_test_span_generic( GLcontext* ctx,
const GLdepth z[],
GLubyte mask[] )
{
- Z_SETUP;
- GLdepth *zptr = Z_ADDRESS( x, y );
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
GLubyte *m = mask;
GLuint i;
GLuint passed = 0;
- LOCK_HARDWARE(mmesa);
+ LOCK_HARDWARE_QUIESCENT(mmesa);
+ {
+ Z_SETUP;
+ GLdepth *zptr = Z_ADDRESS( x, y );
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
@@ -297,8 +303,8 @@ static GLuint mga_depth_test_span_generic( GLcontext* ctx,
}
break;
default:
+ }
}
-
UNLOCK_HARDWARE(mmesa);
return passed;
@@ -320,14 +326,16 @@ static void mga_depth_test_pixels_generic( GLcontext* ctx,
const GLint x[], const GLint y[],
const GLdepth z[], GLubyte mask[] )
{
- Z_SETUP;
- register GLdepth *zptr;
- register GLuint i;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ LOCK_HARDWARE_QUIESCENT(mmesa);
+ {
+ Z_SETUP;
+ register GLdepth *zptr;
+ register GLuint i;
- LOCK_HARDWARE(mmesa);
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
+ /* switch cases ordered from most frequent to less frequent */
+ switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
@@ -547,8 +555,8 @@ static void mga_depth_test_pixels_generic( GLcontext* ctx,
}
break;
default:
- }
-
+ }
+ }
UNLOCK_HARDWARE(mmesa);
}
@@ -570,27 +578,29 @@ static void mga_read_depth_span_float( GLcontext* ctx,
GLuint n, GLint x, GLint y,
GLfloat depth[] )
{
- Z_SETUP;
- GLdepth *zptr;
- GLfloat scale;
- GLuint i;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ LOCK_HARDWARE_QUIESCENT(mmesa);
+ {
- LOCK_HARDWARE(mmesa);
+ Z_SETUP;
+ GLdepth *zptr;
+ GLfloat scale;
+ GLuint i;
- scale = 1.0F / DEPTH_SCALE;
+ scale = 1.0F / DEPTH_SCALE;
- if (ctx->Buffer->Depth) {
- zptr = Z_ADDRESS( x, y );
- for (i=0;i<n;i++) {
- depth[i] = (GLfloat) zptr[i] * scale;
+ if (ctx->ReadBuffer->Depth) {
+ zptr = Z_ADDRESS( x, y );
+ for (i=0;i<n;i++) {
+ depth[i] = (GLfloat) zptr[i] * scale;
+ }
}
- }
- else {
- for (i=0;i<n;i++) {
- depth[i] = 0.0F;
+ else {
+ for (i=0;i<n;i++) {
+ depth[i] = 0.0F;
+ }
}
}
-
UNLOCK_HARDWARE(mmesa);
}
@@ -607,30 +617,32 @@ static void mga_read_depth_span_int( GLcontext* ctx,
GLuint n, GLint x, GLint y,
GLdepth depth[] )
{
- Z_SETUP;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ LOCK_HARDWARE_QUIESCENT(mmesa);
+ {
+ Z_SETUP;
- LOCK_HARDWARE(mmesa);
- if (ctx->Buffer->Depth) {
- GLdepth *zptr = Z_ADDRESS( x, y );
- MEMCPY( depth, zptr, n * sizeof(GLdepth) );
- }
- else {
- GLuint i;
- for (i=0;i<n;i++) {
- depth[i] = 0;
+ if (ctx->ReadBuffer->Depth) {
+ GLdepth *zptr = Z_ADDRESS( x, y );
+ MEMCPY( depth, zptr, n * sizeof(GLdepth) );
+ }
+ else {
+ GLuint i;
+ for (i=0;i<n;i++) {
+ depth[i] = 0;
+ }
}
}
-
UNLOCK_HARDWARE(mmesa);
}
void mgaDDInitDepthFuncs( GLcontext *ctx )
{
- ctx->Driver.ReadDepthSpanFloat = mga_read_depth_span_float;
- ctx->Driver.ReadDepthSpanInt = mga_read_depth_span_int;
- ctx->Driver.DepthTestSpan = mga_depth_test_span_generic;
- ctx->Driver.DepthTestPixels = mga_depth_test_pixels_generic;
+ ctx->Driver.ReadDepthSpan = mga_read_depth_span_float;
+ ctx->Driver.WriteDepthSpan = mga_read_depth_span_float;
+ ctx->Driver.ReadDepthPixels mga_read_depth_span_float;
+ ctx->Driver.WriteDepthPixels = mga_read_depth_span_float;
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
index 8017e7f02..5e237bb01 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
@@ -380,6 +380,8 @@ static void mga_project_vertices( struct vertex_buffer *VB )
GLmatrix *mat = &ctx->Viewport.WindowMap;
GLfloat m[16];
+ REFRESH_DRAWABLE_INFO(mmesa);
+
m[MAT_SX] = mat->m[MAT_SX];
m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX - .5;
m[MAT_SY] = (- mat->m[MAT_SY]);
@@ -401,6 +403,8 @@ static void mga_project_clipped_vertices( struct vertex_buffer *VB )
GLmatrix *mat = &ctx->Viewport.WindowMap;
GLfloat m[16];
+ REFRESH_DRAWABLE_INFO(mmesa);
+
m[MAT_SX] = mat->m[MAT_SX];
m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX - .5;
m[MAT_SY] = (- mat->m[MAT_SY]);
@@ -507,18 +511,12 @@ void mgaDDFastPath( struct vertex_buffer *VB )
ctx->CVA.elt_mode = gl_reduce_prim[prim];
VB->EltPtr = &(MGA_DRIVER_DATA(VB)->clipped_elements);
- LOCK_HARDWARE( mmesa );
mga_project_clipped_vertices( VB ); /* clip->device space */
mga_render_elements_direct( VB ); /* render using new list */
- mgaFlushVerticesLocked( mmesa );
- UNLOCK_HARDWARE( mmesa );
}
} else {
- LOCK_HARDWARE( mmesa );
mga_project_vertices( VB ); /* clip->device space */
mga_render_elements_direct( VB ); /* render using orig list */
- mgaFlushVerticesLocked( mmesa );
- UNLOCK_HARDWARE( mmesa );
}
/* This indicates that there is no cached data to reuse.
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
index 43caddcac..1fb177694 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
@@ -87,6 +87,8 @@ static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest )
STRIDE_F(tex0_data, tex0_stride);
}
if (TYPE & MGA_TEX1_BIT) {
+ /* Hits a second cache line.
+ */
f[CLIP_S1] = tex1_data[0];
f[CLIP_T1] = tex1_data[1];
STRIDE_F(tex1_data, tex1_stride);
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
index c1819924d..f9ef24310 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
@@ -14,114 +14,137 @@
#include "mgalog.h"
#include "mgavb.h"
#include "mgatris.h"
+#include "mgabuffers.h"
+
#include "drm.h"
#include <sys/ioctl.h>
+#define DEPTH_SCALE 65535.0F
+
static void mga_iload_dma_ioctl(mgaContextPtr mmesa,
- int x1, int y1, int x2, int y2,
- unsigned long dest, unsigned int maccess)
+ unsigned long dest,
+ int length)
{
int retcode;
drm_mga_iload_t iload;
- drmBufPtr buf = mmesa->dma_buffer;
+ drmBufPtr buf = mmesa->iload_buffer;
iload.idx = buf->idx;
iload.destOrg = dest;
- iload.mAccess = maccess;
- iload.texture.x1 = x1;
- iload.texture.y1 = y1;
- iload.texture.y2 = x2;
- iload.texture.x2 = y2;
+ iload.length = length;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n",
+ iload.idx, iload.destOrg, iload.length);
+
if ((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_ILOAD, &iload))) {
printf("send iload retcode = %d\n", retcode);
exit(1);
}
-}
+ mmesa->iload_buffer = 0;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished iload dma put\n");
-static void mga_vertex_dma_ioctl(mgaContextPtr mmesa)
+}
+
+int mgaUpdateLock( mgaContextPtr mmesa, drmLockFlags flags )
{
- int retcode;
- int size = MGA_DMA_BUF_SZ;
- drmDMAReq dma;
- drmBufPtr buf = mmesa->dma_buffer;
+ drm_lock_t lock;
+
+ lock.flags = 0;
- dma.context = mmesa->hHWContext;
- dma.send_count = 1;
- dma.send_list = &buf->idx;
- dma.send_sizes = &size;
- dma.flags = DRM_DMA_WAIT;
- dma.request_count = 0;
- dma.request_size = 0;
- dma.request_list = 0;
- dma.request_sizes = 0;
-
- if ((retcode = drmDMA(mmesa->driFd, &dma))) {
- printf("send iload retcode = %d\n", retcode);
- exit(1);
+ if (mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue &&
+ flags & DRM_LOCK_QUIESCENT) {
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaLockQuiescent\n");
+ lock.flags |= _DRM_LOCK_QUIESCENT;
+ }
+
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+
+ if (!lock.flags)
+ return 0;
+
+ if(ioctl(mmesa->driFd, DRM_IOCTL_MGA_FLUSH, &lock)) {
+ printf("Lockupdate failed\n");
+ return -1;
}
+
+ if(flags & DRM_LOCK_QUIESCENT)
+ mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue;
+
+ return 0;
}
-
-static void mga_get_buffer_ioctl( mgaContextPtr mmesa )
+static drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa )
{
int idx = 0;
int size = 0;
drmDMAReq dma;
int retcode;
+ drmBufPtr buf;
- fprintf(stderr, "Getting dma buffer\n");
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Getting dma buffer\n");
dma.context = mmesa->hHWContext;
dma.send_count = 0;
dma.send_list = NULL;
dma.send_sizes = NULL;
- dma.flags = DRM_DMA_WAIT;
+ dma.flags = 0;
dma.request_count = 1;
dma.request_size = MGA_DMA_BUF_SZ;
dma.request_list = &idx;
dma.request_sizes = &size;
-
- if ((retcode = drmDMA(mmesa->driFd, &dma))) {
- fprintf(stderr, "request drmDMA retcode = %d\n", retcode);
- exit(1);
- }
+ dma.granted_count = 0;
- mmesa->dma_buffer = &mmesa->mgaScreen->bufs->list[idx];
-}
-static void mga_swap_ioctl( mgaContextPtr mmesa )
-{
- int retcode;
- drm_mga_swap_t swap;
-
- if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) {
- printf("send swap retcode = %d\n", retcode);
- exit(1);
- }
-}
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
+ dma.context, dma.request_count,
+ dma.request_size);
+ while (1) {
+ retcode = drmDMA(mmesa->driFd, &dma);
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
+ retcode,
+ dma.request_sizes[0],
+ dma.request_list[0],
+ dma.granted_count);
-static void mga_clear_ioctl( mgaContextPtr mmesa, int flags, int col, int zval )
-{
- int retcode;
- drm_mga_clear_t clear;
-
- clear.flags = flags;
- clear.clear_color = col;
- clear.clear_depth = zval;
-
- if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear))) {
- printf("send clear retcode = %d\n", retcode);
- exit(1);
+ if (retcode == 0 &&
+ dma.request_sizes[0] &&
+ dma.granted_count)
+ break;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "\n\nflush");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
}
-}
+ buf = &(mmesa->mgaScreen->bufs->list[idx]);
+ buf->used = 0;
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr,
+ "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
+ "dma_buffer now: buf idx: %d size: %d used: %d\n",
+ dma.request_sizes[0], dma.request_list[0],
+ buf->idx, buf->total,
+ buf->used);
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished getbuffer\n");
+
+ return buf;
+}
@@ -130,52 +153,57 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLuint c = mmesa->ClearColor;
- mgaUI32 zval = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE);
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
- int flags = 0;
+ const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+ drm_mga_clear_t clear;
+ int retcode;
int i;
+ static int nrclears;
- mgaMsg( 10, "mgaClear( %i, %i, %i, %i, %i )\n",
- mask, x, y, width, height );
-
-
- mgaFlushVertices( mmesa );
+ clear.flags = 0;
+ clear.clear_color = mmesa->ClearColor;
+ clear.clear_depth = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE);
+ FLUSH_BATCH( mmesa );
+
+ if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
+ clear.flags |= MGA_FRONT;
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
- if (mask & GL_COLOR_BUFFER_BIT) {
- if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT) {
- flags |= MGA_CLEAR_FRONT;
- mask &= ~GL_COLOR_BUFFER_BIT;
- } else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
- flags |= MGA_CLEAR_BACK;
- mask &= ~GL_COLOR_BUFFER_BIT;
- }
+ if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
+ clear.flags |= MGA_BACK;
+ mask &= ~DD_BACK_LEFT_BIT;
}
- if ((flags & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask) {
- flags |= MGA_CLEAR_DEPTH;
- mask &= ~GL_DEPTH_BUFFER_BIT;
+ if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) {
+ clear.flags |= MGA_DEPTH;
+ mask &= ~DD_DEPTH_BIT;
}
- if (!flags)
+ if (!clear.flags)
return mask;
LOCK_HARDWARE( mmesa );
-
+
+ if (mmesa->dirty_cliprects)
+ mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK));
+
/* flip top to bottom */
cy = dPriv->h-cy-ch;
cx += mmesa->drawX;
cy += mmesa->drawY;
- for (i = 0 ; i < dPriv->numClipRects ; ) {
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Clear, bufs %x nbox %d\n",
+ (int)clear.flags, (int)mmesa->numClipRects);
- /* Use the cliprects for the current draw buffer
- */
+ for (i = 0 ; i < mmesa->numClipRects ; )
+ {
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
XF86DRIClipRectRec *box = mmesa->pClipRects;
- xf86drmClipRectRec *b = mmesa->sarea->boxes;
- mmesa->sarea->nbox = nr - i;
+ drm_clip_rect_t *b = mmesa->sarea->boxes;
+ int n = 0;
if (!all) {
for ( ; i < nr ; i++) {
@@ -196,16 +224,37 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
b->x2 = x + w;
b->y2 = y + h;
b++;
+ n++;
}
} else {
- for ( ; i < nr ; i++)
- *b++ = *(xf86drmClipRectRec *)&box[i];
+ for ( ; i < nr ; i++) {
+ *b++ = *(drm_clip_rect_t *)&box[i];
+ n++;
+ }
}
- mga_clear_ioctl( mmesa, mask, c, zval );
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr,
+ "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",
+ clear.flags, clear.clear_color,
+ clear.clear_depth, mmesa->sarea->nbox);
+
+
+ mmesa->sarea->nbox = n;
+
+ retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear);
+ if (retcode) {
+ printf("send clear retcode = %d\n", retcode);
+ exit(1);
+ }
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished clear %d\n", ++nrclears);
}
UNLOCK_HARDWARE( mmesa );
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
return mask;
}
@@ -218,50 +267,62 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
void mgaSwapBuffers( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+ XF86DRIClipRectPtr pbox;
+ int nbox;
+ drm_mga_swap_t swap;
+ static int nrswaps;
+ int retcode;
int i;
+ int tmp;
- mgaFlushVertices( mmesa );
- LOCK_HARDWARE( mmesa );
- {
- /* Use the frontbuffer cliprects
- */
- XF86DRIClipRectPtr pbox = dPriv->pClipRects;
- int nbox = dPriv->numClipRects;
+ FLUSH_BATCH( mmesa );
- for (i = 0 ; i < nbox ; )
- {
- int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
- XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
- mmesa->sarea->nbox = nr - i;
+ LOCK_HARDWARE( mmesa );
+
+ /* Use the frontbuffer cliprects
+ */
+ if (mmesa->dirty_cliprects & MGA_FRONT)
+ mgaUpdateRects( mmesa, MGA_FRONT );
+
- for ( ; i < nr ; i++)
- *b++ = pbox[i];
-
- mga_swap_ioctl( mmesa );
- }
- }
+ pbox = dPriv->pClipRects;
+ nbox = dPriv->numClipRects;
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "swap, nbox %d\n", nbox);
-#if 1
- UNLOCK_HARDWARE(mmesa);
-#else
+ for (i = 0 ; i < nbox ; )
{
- last_enqueue = mmesa->sarea->lastEnqueue;
- last_dispatch = mmesa->sarea->lastDispatch;
- UNLOCK_HARDWARE;
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+ XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
+
+ mmesa->sarea->nbox = nr - i;
+
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
- /* Throttle runaway apps - there should be an easier way to sleep
- * on dma without locking out the rest of the system!
- */
- if (mmesa->lastSwap > last_dispatch) {
- drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT);
- DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+ if (0)
+ fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");
+
+ if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) {
+ printf("send swap retcode = %d\n", retcode);
+ exit(1);
}
- mmesa->lastSwap = last_enqueue;
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished swap %d\n", ++nrswaps);
}
-#endif
+
+ tmp = GET_ENQUEUE_AGE(mmesa);
+
+ UNLOCK_HARDWARE( mmesa );
+
+ if (GET_DISPATCH_AGE(mmesa) < mmesa->lastSwap)
+ mgaWaitAge(mmesa, mmesa->lastSwap);
+
+ mmesa->lastSwap = tmp;
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}
@@ -269,53 +330,243 @@ void mgaSwapBuffers( mgaContextPtr mmesa )
*/
void mgaDDFinish( GLcontext *ctx )
{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT);
- DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ if (mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue) {
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaRegetLockQuiescent\n");
+
+ LOCK_HARDWARE( mmesa );
+ mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH);
+ UNLOCK_HARDWARE( mmesa );
+
+ mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue;
+ }
}
+void mgaWaitAgeLocked( mgaContextPtr mmesa, int age )
+{
+ if (GET_DISPATCH_AGE(mmesa) < age) {
+ if (0) fprintf(stderr, "\n\n\nmgaWaitAgeLocked\n");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
+ }
+}
+void mgaWaitAge( mgaContextPtr mmesa, int age )
+{
+ if (GET_DISPATCH_AGE(mmesa) < age) {
+ LOCK_HARDWARE(mmesa);
+ if (GET_DISPATCH_AGE(mmesa) < age) {
+ if (0) fprintf(stderr, "\n\n\nmgaWaitAge\n");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
+ }
+ UNLOCK_HARDWARE(mmesa);
+ }
+}
-void mgaFlushVertices( mgaContextPtr mmesa )
+
+static int intersect_rect( drm_clip_rect_t *out,
+ drm_clip_rect_t *a,
+ drm_clip_rect_t *b )
{
- LOCK_HARDWARE( mmesa );
- mgaFlushVerticesLocked( mmesa );
- UNLOCK_HARDWARE( mmesa );
+ *out = *a;
+ if (b->x1 > out->x1) out->x1 = b->x1;
+ if (b->y1 > out->y1) out->y1 = b->y1;
+ if (b->x2 < out->x2) out->x2 = b->x2;
+ if (b->y2 < out->y2) out->y2 = b->y2;
+ if (out->x1 >= out->x2) return 0;
+ if (out->y1 >= out->y2) return 0;
+ return 1;
}
+
+
+static void age_mmesa( mgaContextPtr mmesa, int age )
+{
+ if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age;
+ if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age;
+}
+
void mgaFlushVerticesLocked( mgaContextPtr mmesa )
{
- XF86DRIClipRectPtr pbox = mmesa->pClipRects;
+ drm_clip_rect_t *pbox = (drm_clip_rect_t *)mmesa->pClipRects;
int nbox = mmesa->numClipRects;
+ drmBufPtr buffer = mmesa->vertex_dma_buffer;
+ drm_mga_vertex_t vertex;
int i;
- if (mmesa->dirty)
+ if (!buffer)
+ return;
+
+ if (mmesa->dirty_cliprects & mmesa->draw_buffer)
+ mgaUpdateRects( mmesa, mmesa->draw_buffer );
+
+ if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
mgaEmitHwStateLocked( mmesa );
- for (i = 0 ; i < nbox ; )
+ /* FIXME: Workaround bug in kernel module.
+ */
+ mmesa->sarea->dirty |= MGA_UPLOAD_CTX;
+
+ /* FIXME: dstorg bug
+ */
+ if (0)
+ if (mmesa->lastX != mmesa->drawX || mmesa->lastY != mmesa->drawY)
+ fprintf(stderr, "****** last: %d,%d current: %d,%d\n",
+ mmesa->lastX, mmesa->lastY,
+ mmesa->drawX, mmesa->drawY);
+
+
+ mmesa->vertex_dma_buffer = 0;
+ vertex.idx = buffer->idx;
+ vertex.used = buffer->used;
+ vertex.discard = 0;
+
+ if (!nbox)
+ vertex.used = 0;
+
+ if (nbox >= MGA_NR_SAREA_CLIPRECTS)
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
+ if (!vertex.used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
{
- int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
- XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
- mmesa->sarea->nbox = nr - i;
+ if (nbox == 1)
+ mmesa->sarea->nbox = 0;
+ else
+ mmesa->sarea->nbox = nbox;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);
+
+ vertex.discard = 1;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex);
+ age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+ }
+ else
+ {
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
+ drm_clip_rect_t *b = mmesa->sarea->boxes;
+
+ if (mmesa->scissor) {
+ mmesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++) {
+ *b = pbox[i];
+ if (intersect_rect(b, b, &mmesa->scissor_rect)) {
+ mmesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if (!mmesa->sarea->nbox) {
+ if (nr < nbox) continue;
+ vertex.used = 0;
+ }
+ } else {
+ mmesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+ }
- for ( ; i < nr ; i++)
- *b++ = pbox[i];
-
- mga_vertex_dma_ioctl( mmesa );
+ /* Finished with the buffer?
+ */
+ if (nr == nbox)
+ vertex.discard = 1;
+
+ mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex);
+ age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+ }
+ }
+
+ mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
+}
+
+void mgaFlushVertices( mgaContextPtr mmesa )
+{
+ LOCK_HARDWARE( mmesa );
+ mgaFlushVerticesLocked( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+}
+
+
+mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords )
+{
+ int bytes = dwords * 4;
+ mgaUI32 *head;
+
+ if (!mmesa->vertex_dma_buffer) {
+ LOCK_HARDWARE( mmesa );
+ mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+ } else if (mmesa->vertex_dma_buffer->used + bytes >
+ mmesa->vertex_dma_buffer->total) {
+ LOCK_HARDWARE( mmesa );
+ mgaFlushVerticesLocked( mmesa );
+ mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+ }
+
+ head = (mgaUI32 *)((char *)mmesa->vertex_dma_buffer->address +
+ mmesa->vertex_dma_buffer->used);
+
+ mmesa->vertex_dma_buffer->used += bytes;
+ return head;
+}
- break; /* fix dma multiple dispatch */
+
+void mgaFireILoadLocked( mgaContextPtr mmesa,
+ GLuint offset, GLuint length )
+{
+ if (!mmesa->iload_buffer) {
+ fprintf(stderr, "mgaFireILoad: no buffer\n");
+ return;
}
- mga_get_buffer_ioctl( mmesa );
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n",
+ mmesa->iload_buffer->idx, (int)offset, (int)length );
+
+ mga_iload_dma_ioctl( mmesa, offset, length );
}
+void mgaGetILoadBufferLocked( mgaContextPtr mmesa )
+{
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n",
+ mmesa->iload_buffer);
+
+ mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa );
+}
+
+
+static void mgaDDFlush( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+ FLUSH_BATCH( mmesa );
+
+ /* This may be called redundantly - dispatch_age may trail what
+ * has actually been sent and processed by the hardware.
+ */
+ if (GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) {
+ LOCK_HARDWARE( mmesa );
+ if (0) fprintf(stderr, "mgaDDFlush\n");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
+ UNLOCK_HARDWARE( mmesa );
+ }
+}
void mgaDDInitIoctlFuncs( GLcontext *ctx )
{
ctx->Driver.Clear = mgaClear;
- ctx->Driver.Flush = 0;
+ ctx->Driver.Flush = mgaDDFlush;
ctx->Driver.Finish = mgaDDFinish;
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
index 22ca26e17..13cec59d7 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
@@ -9,6 +9,21 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
void mgaSwapBuffers( mgaContextPtr mmesa );
+
+
+mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords );
+
+
+void mgaGetILoadBufferLocked( mgaContextPtr mmesa );
+
+
+void mgaFireILoadLocked( mgaContextPtr mmesa,
+ GLuint offset, GLuint length );
+
+void mgaWaitAgeLocked( mgaContextPtr mmesa, int age );
+void mgaWaitAge( mgaContextPtr mmesa, int age );
+int mgaUpdateLock( mgaContextPtr mmesa, drmLockFlags flags );
+
void mgaFlushVertices( mgaContextPtr mmesa );
void mgaFlushVerticesLocked( mgaContextPtr mmesa );
@@ -19,5 +34,11 @@ void mgaDDFinish( GLcontext *ctx );
void mgaDDInitIoctlFuncs( GLcontext *ctx );
+#define FLUSH_BATCH(mmesa) do { \
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) \
+ fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \
+ if (mmesa->vertex_dma_buffer) mgaFlushVertices(mmesa); \
+} while (0)
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgalib.h b/xc/lib/GL/mesa/src/drv/mga/mgalib.h
index 4600a69a0..176c126bd 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgalib.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgalib.h
@@ -36,6 +36,7 @@
#include "types.h"
+#include "drm.h"
#include "mgacommon.h"
#include "mm.h"
#include "mgalog.h"
@@ -43,7 +44,6 @@
#include "mgatex.h"
#include "mgavb.h"
-#include "mga_drm_public.h"
#include "mga_xmesa.h"
@@ -51,11 +51,8 @@
#define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK))
#define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT))
-#define MGA_CHIP_MGAG200 0
-#define MGA_CHIP_MGAG400 1
-
-#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CHIP_MGAG200)
-#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CHIP_MGAG400)
+#define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200)
+#define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400)
/* SoftwareFallback
@@ -65,6 +62,7 @@
*/
#define MGA_FALLBACK_TEXTURE 0x1
#define MGA_FALLBACK_BUFFER 0x2
+#define MGA_FALLBACK_STIPPLE 0x3
/* For mgaCtx->new_state.
@@ -97,17 +95,30 @@ typedef void (*mga_interp_func)( GLfloat t,
#define MGA_PF_8888 (10 << 4)
#define MGA_PF_HASALPHA (8 << 4)
+
+
+/* Reasons why the GL_BLEND fallback mightn't work:
+ */
+#define MGA_BLEND_ENV_COLOR 0x1
+#define MGA_BLEND_MULTITEX 0x2
+
+
struct mga_context_t {
GLcontext *glCtx;
- /* Hardware state - moved from mgabuf.h
- */
- mgaUI32 Setup[MGA_CTX_SETUP_SIZE];
- /* Variable sized vertices
+ /* Bookkeeping for texturing
*/
- mgaUI32 vertsize;
+ int lastTexHeap;
+ struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS];
+ struct mga_texture_object_s SwappedOut;
+ struct mga_texture_object_s *CurrentTexObj[2];
+ memHeap_t *texHeap[MGA_NR_TEX_HEAPS];
+ int c_texupload;
+ int c_texusage;
+ int tex_thrash;
+
/* Map GL texture units onto hardware.
*/
@@ -116,68 +127,84 @@ struct mga_context_t {
mgaUI32 tex_dest[2];
+ /* Manage fallbacks
+ */
+ mgaUI32 IndirectTriangles;
+ int Fallback;
- /* bookkeeping for textureing */
- struct mga_texture_object_s TexObjList;
- struct mga_texture_object_s SwappedOut;
- struct mga_texture_object_s *CurrentTexObj[2];
-
-
- /* shared texture palette */
- mgaUI16 GlobalPalette[256];
-
- int Fallback; /* or'ed values of FALLBACK_* */
- /* Support for CVA and the fast paths */
+ /* Support for CVA and the fastpath
+ */
unsigned int setupdone;
unsigned int setupindex;
unsigned int renderindex;
unsigned int using_fast_path;
- unsigned int using_immediate_fast_path;
mga_interp_func interp;
- /* Shortcircuit some state changes */
+
+ /* Support for limited GL_BLEND fallback
+ */
+ unsigned int blend_flags;
+ unsigned int envcolor;
+
+
+ /* Shortcircuit some state changes
+ */
points_func PointsFunc;
line_func LineFunc;
triangle_func TriangleFunc;
quad_func QuadFunc;
- /* Manage our own state */
+
+ /* Manage driver and hardware state
+ */
GLuint new_state;
GLuint dirty;
-
- GLubyte clearcolor[4];
- GLushort MonoColor;
- GLushort ClearColor;
+ GLuint Setup[MGA_CTX_SETUP_SIZE];
+ GLuint warp_pipe;
+ GLuint vertsize;
+ GLushort MonoColor;
+ GLushort ClearColor;
+ GLuint poly_stipple;
- /* DRI stuff
+ /* Dma buffers
*/
- drmBufPtr dma_buffer;
+ drmBufPtr vertex_dma_buffer;
+ drmBufPtr iload_buffer;
- GLframebuffer *glBuffer;
- memHeap_t *texHeap;
+
+ /* Drawable, cliprect and scissor information
+ */
+ int dirty_cliprects; /* which sets of cliprects are uptodate? */
+ int draw_buffer; /* which buffer are we rendering to */
+ int drawOffset; /* draw buffer address in space */
+ int read_buffer;
+ int readOffset;
+ int drawX, drawY; /* origin of drawable in draw buffer */
+ int lastX, lastY; /* detect DSTORG bug */
+ GLuint numClipRects; /* cliprects for the draw buffer */
+ XF86DRIClipRectPtr pClipRects;
+ XF86DRIClipRectRec draw_rect;
+ drm_clip_rect_t scissor_rect;
+ int scissor;
- GLuint needClip;
- GLuint warp_pipe;
- /* These refer to the current draw (front vs. back) buffer:
+ /* Texture aging and DMA based aging.
*/
- int drawOffset; /* draw buffer address in agp space */
- int drawX; /* origin of drawable in draw buffer */
- int drawY;
- GLuint numClipRects; /* cliprects for that buffer */
- XF86DRIClipRectPtr pClipRects;
+ unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */
+ int dirtyAge; /* buffer age for synchronization */
+ int lastSwap; /* throttling runaway apps */
- int texAge;
- XF86DRIClipRectRec draw_rect;
+ /* Mirrors of some DRI state.
+ */
+ GLframebuffer *glBuffer;
drmContext hHWContext;
drmLock *driHwLock;
int driFd;
Display *display;
-
__DRIdrawablePrivate *driDrawable;
__DRIscreenPrivate *driScreen;
mgaScreenPrivate *mgaScreen;
@@ -191,16 +218,12 @@ typedef struct {
/* dma stuff */
mgaUI32 systemTexture;
- mgaUI32 noSetupDma;
mgaUI32 default32BitTextures;
- mgaUI32 swapBuffersCount;
/* options */
mgaUI32 nullprims; /* skip all primitive generation */
- mgaUI32 noFallback; /* don't fall back to software, do
- best-effort rendering */
- mgaUI32 skipDma; /* don't send anything to the hardware */
+ mgaUI32 noFallback;
/* performance counters */
mgaUI32 c_textureUtilization;
@@ -240,10 +263,12 @@ extern mgaGlx_t mgaglx;
extern int MGA_DEBUG;
#endif
-#define MGA_DEBUG_ALWAYS_SYNC 0x1
-#define MGA_DEBUG_VERBOSE_MSG 0x2
-#define MGA_DEBUG_VERBOSE_LRU 0x4
-#define MGA_DEBUG_VERBOSE_DRI 0x8
+#define DEBUG_ALWAYS_SYNC 0x1
+#define DEBUG_VERBOSE_MSG 0x2
+#define DEBUG_VERBOSE_LRU 0x4
+#define DEBUG_VERBOSE_DRI 0x8
+#define DEBUG_VERBOSE_IOCTL 0x10
+#define DEBUG_VERBOSE_2D 0x20
static __inline__ mgaUI32 mgaPackColor(mgaUI32 format,
mgaUI8 r, mgaUI8 g,
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c
index 38e3cdde8..9bf62391c 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c
@@ -5,70 +5,99 @@
#include "mgalog.h"
#include "mgaspan.h"
+#define DBG 0
+
#define LOCAL_VARS \
- mgaContextPtr mmesa = MGA_CONTEXT( ctx ); \
__DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
- __DRIscreenPrivate *sPriv = mmesa->driScreen; \
mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
- GLuint pitch = mgaScreen->backPitch; \
+ __DRIscreenPrivate *sPriv = mmesa->driScreen; \
+ GLuint pitch = mgaScreen->frontPitch; \
GLuint height = dPriv->h; \
+ char *read_buf = (char *)(sPriv->pFB + \
+ mmesa->readOffset + \
+ dPriv->x * 2 + \
+ dPriv->y * pitch); \
char *buf = (char *)(sPriv->pFB + \
mmesa->drawOffset + \
dPriv->x * 2 + \
+ dPriv->y * pitch); \
+ GLushort p = MGA_CONTEXT( ctx )->MonoColor; \
+ (void) read_buf; (void) buf; (void) p
+
+
+
+#define LOCAL_DEPTH_VARS \
+ __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
+ __DRIscreenPrivate *sPriv = mmesa->driScreen; \
+ GLuint pitch = mgaScreen->frontPitch; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(sPriv->pFB + \
+ mgaScreen->depthOffset + \
+ dPriv->x * 2 + \
dPriv->y * pitch)
-#define INIT_MONO_PIXEL(p) \
- GLushort p = MGA_CONTEXT( ctx )->MonoColor;
+#define INIT_MONO_PIXEL(p)
-#define CLIPPIXEL(_x,_y) (_x >= minx && _x <= maxx && \
- _y >= miny && _y <= maxy)
+#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
+ _y >= miny && _y < maxy)
-#define CLIPSPAN(_x,_y,_n,_x1,_n1) \
+#define CLIPSPAN(_x,_y,_n,_x1,_n1,_i) \
if (_y < miny || _y >= maxy) _n1 = 0, _x1 = x; \
else { \
_n1 = _n; \
_x1 = _x; \
- if (_x1 < minx) _n1 -= (minx - _x1), _x1 = minx; \
- if (_x1 + _n1 > maxx) n1 -= (_x1 + n1 - maxx); \
+ if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \
+ if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \
}
-
+#define HW_LOCK() \
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
+ LOCK_HARDWARE_QUIESCENT(mmesa);
#define HW_CLIPLOOP() \
do { \
int _nc = mmesa->numClipRects; \
- LOCK_HARDWARE_QUIESCENT(mmesa); \
while (_nc--) { \
- int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
- int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
- int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
+ int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
+ int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
+ int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
-
#define HW_ENDCLIPLOOP() \
} \
- UNLOCK_HARDWARE(mmesa); \
} while (0)
+#define HW_UNLOCK() \
+ UNLOCK_HARDWARE(mmesa);
+
+
+
-#define Y_FLIP(_y) (height - _y)
+
+
+
+/* 16 bit, 565 rgb color spanline and pixel functions
+ */
+#define Y_FLIP(_y) (height - _y - 1)
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
- *(GLushort *)(buf + _x*2 + _y*pitch) = ( ((r & 0x1f) << 11) | \
- ((g & 0x3f) << 5) | \
- ((b & 0x1f)))
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
+ (((int)g & 0xfc) << 3) | \
+ (((int)b & 0xf8) >> 3))
+
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
- GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
- rgba[0] = (p >> 11) & 0x1f; \
- rgba[1] = (p >> 5) & 0x3f; \
- rgba[2] = (p >> 0) & 0x1f; \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 8) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xfc; \
+ rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 0; /* or 255? */ \
} while(0)
@@ -78,21 +107,21 @@ do { \
-
-#define WRITE_RGBA( _x, _y, r, g, b, a ) \
- *(GLushort *)(buf + _x*2 + _y*pitch) = ( ((r & 0x1f) << 10) | \
- ((g & 0x1f) << 5) | \
- ((b & 0x1f)))
-
+/* 15 bit, 555 rgb color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
+ ((g & 0xf8) << 3) | \
+ ((b & 0xf8) >> 3))
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
- GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
- rgba[0] = (p >> 10) & 0x1f; \
- rgba[1] = (p >> 5) & 0x1f; \
- rgba[2] = (p >> 0) & 0x1f; \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 7) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xf8; \
+ rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 0; /* or 255? */ \
} while(0)
@@ -101,27 +130,19 @@ do { \
-#if 0
-#define WRITE_RGBA( _x, _y, r, g, b, a ) \
- *(GLuint *)(buf + _x*4 + _y*pitch) = ( ((r) << 16) | \
- ((g) << 8) | \
- ((b)))
+/* 16 bit depthbuffer functions.
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLdepth *)(buf + _x*2 + _y*pitch) = d;
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLdepth *)(buf + _x*2 + _y*pitch);
+
+#define TAG(x) mga##x##_16
+#include "depthtmp.h"
-#define WRITE_PIXEL( _x, _y, p ) \
- *(GLuint *)(buf + _x*4 + _y*pitch) = p
-#define READ_RGBA( rgba, _x, _y ) \
-do { \
- GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
- rgba[0] = (p >> 16) & 0xff; \
- rgba[1] = (p >> 8) & 0xff; \
- rgba[2] = (p >> 0) & 0xff; \
- rgba[3] = 0; /* or 255? */ \
-} while(0)
-#define TAG(x) mga##x##_888
-#include "spantmp.h"
-#endif
void mgaDDInitSpanFuncs( GLcontext *ctx )
{
@@ -143,6 +164,11 @@ void mgaDDInitSpanFuncs( GLcontext *ctx )
ctx->Driver.ReadRGBAPixels = mgaReadRGBAPixels_555;
}
+ ctx->Driver.ReadDepthSpan = mgaReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = mgaWriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = mgaReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = mgaWriteDepthPixels_16;
+
ctx->Driver.WriteCI8Span =NULL;
ctx->Driver.WriteCI32Span =NULL;
ctx->Driver.WriteMonoCISpan =NULL;
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c
index ff9063e0b..0dacd7646 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c
@@ -16,7 +16,7 @@
#include "mgavb.h"
#include "mgatris.h"
#include "mgaregs.h"
-#include "mga_drm_public.h"
+#include "mgabuffers.h"
static void mgaUpdateZMode(const GLcontext *ctx)
{
@@ -60,17 +60,20 @@ static void mgaUpdateZMode(const GLcontext *ctx)
static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
@@ -78,6 +81,7 @@ static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
GLenum dfactorRGB, GLenum sfactorA,
GLenum dfactorA )
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
@@ -87,6 +91,7 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
const GLfloat *param)
{
if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
}
@@ -95,6 +100,7 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
{
if (1) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
mgaMsg(8, "mgaDDShadeModel: %x\n", mode);
}
@@ -103,11 +109,13 @@ static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
}
static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
}
@@ -134,6 +142,7 @@ static void mgaUpdateFogAttrib( GLcontext *ctx )
static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG;
}
@@ -148,10 +157,11 @@ static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
static void mgaUpdateAlphaMode(GLcontext *ctx)
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
int a = 0;
/* determine source of alpha for blending and testing */
- if ( !ctx->Texture.Enabled || (mmesa->Fallback & MGA_FALLBACK_TEXTURE))
+ if ( !ctx->Texture.Enabled )
a |= AC_alphasel_diffused;
else {
switch (ctx->Texture.Unit[0].EnvMode) {
@@ -168,7 +178,7 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
}
- /* alpha test control - disabled by default.
+ /* alpha test control.
*/
if (ctx->Color.AlphaEnabled) {
GLubyte ref = ctx->Color.AlphaRef;
@@ -219,13 +229,13 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
case GL_ONE_MINUS_SRC_ALPHA:
a |= AC_src_om_src_alpha; break;
case GL_DST_ALPHA:
- if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_src_dst_alpha;
else
a |= AC_src_one;
break;
case GL_ONE_MINUS_DST_ALPHA:
- if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_src_om_dst_alpha;
else
a |= AC_src_zero;
@@ -250,13 +260,13 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
case GL_ONE_MINUS_SRC_COLOR:
a |= AC_dst_om_src_color; break;
case GL_DST_ALPHA:
- if (0) /*(mgaDB->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_dst_dst_alpha;
else
a |= AC_dst_one;
break;
case GL_ONE_MINUS_DST_ALPHA:
- if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_dst_om_dst_alpha;
else
a |= AC_dst_zero;
@@ -282,50 +292,44 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
* Hardware clipping
*/
-static void mgaUpdateClipping(const GLcontext *ctx)
+void mgaUpdateClipping(const GLcontext *ctx)
{
-#if 0
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
- int x1,x2,y1,y2;
-
- if ( ctx->Scissor.Enabled) {
- x1 = ctx->Scissor.X;
- x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
- y1 = dPriv->Height - ctx->Scissor.Y - ctx->Scissor.Height;
- y2 = dPriv->Height - ctx->Scissor.Y - 1;
- } else {
- x1 = 0;
- y1 = 0;
- x2 = mgaDB->Width-1;
- y2 = mgaDB->Height-1;
- }
-
- if (x1 < 0) x1 = 0;
- if (y1 < 0) y1 = 0;
- if (x2 >= mgaDB->Width) x2 = mgaDB->Width-1;
- if (y2 >= mgaDB->Height) y2 = mgaDB->Height-1;
-
- if (x1 > x2 || y1 > y2) {
- x1 = 0; x2 = 0;
- y2 = 0; y1 = 1;
- }
-
-
- mmesa->Setup[MGA_CTXREG_CXBNDRY] = (MGA_FIELD(CXB_cxright,x2) |
- MGA_FIELD(CXB_cxleft,x1));
- mmesa->Setup[MGA_CTXREG_YTOP] = y1*mgaDB->Pitch;
- mmesa->Setup[MGA_CTXREG_YBOT] = y2*mgaDB->Pitch;
-
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- mmesa->dirty |= MGA_UPLOAD_CTX;
-#endif
+ if (mmesa->driDrawable)
+ {
+ int x1 = mmesa->driDrawable->x + ctx->Scissor.X;
+ int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y+
+ ctx->Scissor.Height);
+ int x2 = mmesa->driDrawable->x + ctx->Scissor.X+ctx->Scissor.Width;
+ int y2 = mmesa->driDrawable->y + mmesa->driDrawable->h - ctx->Scissor.Y;
+
+ if (x1 < 0) x1 = 0;
+ if (y1 < 0) y1 = 0;
+ if (x2 < 0) x2 = 0;
+ if (y2 < 0) y2 = 0;
+
+ mmesa->scissor_rect.x1 = x1;
+ mmesa->scissor_rect.y1 = y1;
+ mmesa->scissor_rect.x2 = x2;
+ mmesa->scissor_rect.y2 = y2;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n",
+ mmesa->scissor_rect.x1,
+ mmesa->scissor_rect.y1,
+ mmesa->scissor_rect.x2,
+ mmesa->scissor_rect.y2);
+
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+ }
}
static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
GLsizei w, GLsizei h )
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
}
@@ -339,35 +343,6 @@ static void mgaDDDither(GLcontext *ctx, GLboolean enable)
}
-static GLboolean mgaDDSetBuffer(GLcontext *ctx, GLenum mode )
-{
- mgaContextPtr mmesa = MGA_CONTEXT(ctx);
-
- mmesa->Fallback &= ~MGA_FALLBACK_BUFFER;
-
- if (mode == GL_FRONT_LEFT)
- {
- mmesa->drawOffset = mmesa->mgaScreen->fbOffset;
- mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->fbOffset;
- mmesa->dirty |= MGA_UPLOAD_CTX;
- mgaXMesaSetFrontClipRects( mmesa );
- return GL_TRUE;
- }
- else if (mode == GL_BACK_LEFT)
- {
- mmesa->drawOffset = mmesa->mgaScreen->backOffset;
- mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset;
- mmesa->dirty |= MGA_UPLOAD_CTX;
- mgaXMesaSetBackClipRects( mmesa );
- return GL_TRUE;
- }
- else
- {
- mmesa->Fallback |= MGA_FALLBACK_BUFFER;
- return GL_FALSE;
- }
-}
-
static void mgaDDSetColor(GLcontext *ctx,
@@ -376,7 +351,7 @@ static void mgaDDSetColor(GLcontext *ctx,
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->fbFormat,
+ mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->Attrib,
r, g, b, a );
}
@@ -387,7 +362,7 @@ static void mgaDDClearColor(GLcontext *ctx,
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->fbFormat,
+ mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->Attrib,
r, g, b, a );
}
@@ -426,6 +401,7 @@ static void mgaUpdateCull( GLcontext *ctx )
static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
}
@@ -461,6 +437,7 @@ static GLboolean mgaDDColorMask(GLcontext *ctx,
}
if (mmesa->Setup[MGA_CTXREG_PLNWT] != mask) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
mmesa->Setup[MGA_CTXREG_PLNWT] = mask;
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_MASK;
mmesa->dirty |= MGA_UPLOAD_CTX;
@@ -470,6 +447,85 @@ static GLboolean mgaDDColorMask(GLcontext *ctx,
}
/* =============================================================
+ * Polygon stipple
+ *
+ * The mga supports a subset of possible 4x4 stipples natively, GL
+ * wants 32x32. Fortunately stipple is usually a repeating pattern.
+ * Could also consider using a multitexturing mechanism for this, but
+ * that has real issues, too.
+ */
+static int mgaStipples[16] = {
+ 0xffff,
+ 0xa5a5,
+ 0x5a5a,
+ 0xa0a0,
+ 0x5050,
+ 0x0a0a,
+ 0x0505,
+ 0x8020,
+ 0x0401,
+ 0x1040,
+ 0x0208,
+ 0x0802,
+ 0x4010,
+ 0x0104,
+ 0x2080,
+ 0x0000
+};
+
+static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ const GLubyte *m = mask;
+ GLubyte p[4];
+ int i,j,k;
+ int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON);
+ GLuint stipple;
+
+ FLUSH_BATCH(mmesa);
+ ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE;
+
+ if (active) {
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ }
+
+ p[0] = mask[0] & 0xf; p[0] |= p[0] << 4;
+ p[1] = mask[4] & 0xf; p[1] |= p[1] << 4;
+ p[2] = mask[8] & 0xf; p[2] |= p[2] << 4;
+ p[3] = mask[12] & 0xf; p[3] |= p[3] << 4;
+
+ for (k = 0 ; k < 8 ; k++)
+ for (j = 0 ; j < 4; j++)
+ for (i = 0 ; i < 4 ; i++)
+ if (*m++ != p[j]) {
+ ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE;
+ return;
+ }
+
+ stipple = ( ((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12) );
+
+ for (i = 0 ; i < 16 ; i++)
+ if (mgaStipples[i] == stipple) {
+ mmesa->poly_stipple = i<<20;
+ break;
+ }
+
+ if (i == 16) {
+ ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE;
+ return;
+ }
+
+ if (active) {
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple;
+ }
+}
+
+/* =============================================================
*/
@@ -477,15 +533,16 @@ static GLboolean mgaDDColorMask(GLcontext *ctx,
static void mgaDDPrintDirty( const char *msg, GLuint state )
{
- fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
msg,
(unsigned int) state,
- (state & MGA_REQUIRE_QUIESCENT) ? "req-quiescent, " : "",
+ (state & MGA_WAIT_AGE) ? "wait-age, " : "",
(state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img, " : "",
(state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img, " : "",
(state & MGA_UPLOAD_CTX) ? "upload-ctx, " : "",
(state & MGA_UPLOAD_TEX0) ? "upload-tex0, " : "",
- (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : ""
+ (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : "",
+ (state & MGA_UPLOAD_PIPE) ? "upload-pipe, " : ""
);
}
@@ -494,7 +551,7 @@ static void mgaDDPrintDirty( const char *msg, GLuint state )
*/
void mgaEmitHwStateLocked( mgaContextPtr mmesa )
{
- if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG)
+ if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty );
if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0])
@@ -503,27 +560,28 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1])
mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]);
- if (mmesa->dirty & MGA_UPLOAD_CTX) {
+ if (mmesa->dirty & MGA_UPLOAD_CTX)
memcpy( mmesa->sarea->ContextState,
mmesa->Setup,
sizeof(mmesa->Setup));
- if (mmesa->CurrentTexObj[0])
+ if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0])
memcpy(mmesa->sarea->TexState[0],
mmesa->CurrentTexObj[0]->Setup,
sizeof(mmesa->sarea->TexState[0]));
- if (mmesa->CurrentTexObj[1])
+ if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1])
memcpy(mmesa->sarea->TexState[1],
mmesa->CurrentTexObj[1]->Setup,
sizeof(mmesa->sarea->TexState[1]));
- }
- if (mmesa->dirty & MGA_UPLOAD_PIPE)
- mmesa->sarea->WarpPipe = mmesa->setupindex & MGA_WARP_T2GZSAF;
-
+ mmesa->sarea->WarpPipe = mmesa->setupindex & MGA_WARP_T2GZSAF;
mmesa->sarea->dirty |= mmesa->dirty;
- mmesa->dirty = 0;
+#if 0
+ fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n",
+ mmesa->sarea->dirty);
+#endif
+ mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE);
}
@@ -533,29 +591,50 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
switch(cap) {
case GL_ALPHA_TEST:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_ALPHA;
break;
case GL_BLEND:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_ALPHA;
break;
case GL_DEPTH_TEST:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_DEPTH;
break;
case GL_SCISSOR_TEST:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
+ FLUSH_BATCH( mmesa );
+ mmesa->scissor = state;
+ mmesa->new_state |= MGA_NEW_CLIP;
break;
case GL_FOG:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_FOG;
break;
case GL_CULL_FACE:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_CULL;
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ break;
+ case GL_POLYGON_STIPPLE:
+ if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) &&
+ ctx->PB->primitive == GL_POLYGON)
+ {
+ FLUSH_BATCH(mmesa);
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ if (state)
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple;
+ }
break;
default:
;
@@ -581,6 +660,7 @@ static void mgaWarpUpdateState( GLcontext *ctx )
{
mmesa->warp_pipe = index;
mmesa->new_state |= MGA_NEW_WARP;
+ mmesa->dirty |= MGA_UPLOAD_PIPE;
}
}
@@ -611,21 +691,15 @@ void mgaDDUpdateHwState( GLcontext *ctx )
if (new_state)
{
- mmesa->new_state = 0;
+ FLUSH_BATCH( mmesa );
- /* Emit any vertices for the current state. This will also
- * push the current state into the sarea.
- */
-/* mgaFlushVertices( mmesa ); */
+ mmesa->new_state = 0;
if (MESA_VERBOSE&VERBOSE_DRIVER)
mgaDDPrintState("UpdateHwState", new_state);
if (new_state & MGA_NEW_DEPTH)
- {
mgaUpdateZMode(ctx);
- mgaDDInitDepthFuncs(ctx);
- }
if (new_state & MGA_NEW_ALPHA)
mgaUpdateAlphaMode(ctx);
@@ -641,8 +715,6 @@ void mgaDDUpdateHwState( GLcontext *ctx )
if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE))
mgaUpdateTextureState(ctx);
-
- mmesa->new_state = 0; /* tex uploads scribble newstate */
}
}
@@ -654,8 +726,17 @@ void mgaDDUpdateHwState( GLcontext *ctx )
void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
{
- mgaFlushVertices( MGA_CONTEXT(ctx) );
- mgaUpdateCull(ctx);
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ FLUSH_BATCH( mmesa );
+ mgaUpdateCull(ctx);
+
+ if (ctx->Polygon.StippleFlag && (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE))
+ {
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ if (ctx->PB->primitive == GL_POLYGON)
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple;
+ }
}
@@ -677,10 +758,16 @@ void mgaDDUpdateState( GLcontext *ctx )
/* Have to do this here to detect texture fallbacks in time:
*/
- if (MGA_CONTEXT(ctx)->new_state & MGA_NEW_TEXTURE)
+ if (mmesa->new_state & MGA_NEW_TEXTURE)
mgaDDUpdateHwState( ctx );
- if (!mmesa->Fallback || mgaglx.noFallback) {
+ if (0) fprintf(stderr, "fallback %x indirect %x\n", mmesa->Fallback,
+ mmesa->IndirectTriangles);
+
+ if (!mmesa->Fallback) {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= mmesa->IndirectTriangles;
+
ctx->Driver.PointsFunc=mmesa->PointsFunc;
ctx->Driver.LineFunc=mmesa->LineFunc;
ctx->Driver.TriangleFunc=mmesa->TriangleFunc;
@@ -689,6 +776,60 @@ void mgaDDUpdateState( GLcontext *ctx )
}
+
+void mgaInitState( mgaContextPtr mmesa )
+{
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
+ GLcontext *ctx = mmesa->glCtx;
+
+ if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ mmesa->draw_buffer = MGA_BACK;
+ mmesa->read_buffer = MGA_BACK;
+ mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+ mmesa->readOffset = mmesa->mgaScreen->backOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->backOffset;
+ } else {
+ mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->readOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->draw_buffer = MGA_FRONT;
+ mmesa->read_buffer = MGA_FRONT;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->frontOffset;
+ }
+
+/* mmesa->Setup[MGA_CTXREG_MACCESS] = mgaScreen->mAccess; */
+/* mmesa->Setup[MGA_CTXREG_DWGCTL] = ( DC_clipdis_disable | */
+/* (0xC << DC_bop_SHIFT) | */
+/* DC_shftzero_enable | */
+/* DC_zmode_nozcmp | */
+/* DC_atype_zi ); */
+
+
+ mmesa->Setup[MGA_CTXREG_MACCESS] = 0x1;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] = 0xc4074;
+
+
+ mmesa->Setup[MGA_CTXREG_PLNWT] = ~0;
+ mmesa->Setup[MGA_CTXREG_ALPHACTRL] = ( AC_src_one |
+ AC_dst_zero |
+ AC_amode_FCOL |
+ AC_astipple_disable |
+ AC_aten_disable |
+ AC_atmode_noacmp |
+ AC_alphasel_fromtex );
+
+ mmesa->Setup[MGA_CTXREG_FOGCOLOR] =
+ MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
+ (GLubyte)(ctx->Fog.Color[1]*255.0F),
+ (GLubyte)(ctx->Fog.Color[2]*255.0F));
+
+ mmesa->Setup[MGA_CTXREG_WFLAG] = 0;
+ mmesa->Setup[MGA_CTXREG_TDUAL0] = 0;
+ mmesa->Setup[MGA_CTXREG_TDUAL1] = 0;
+ mmesa->Setup[MGA_CTXREG_FCOL] = 0;
+ mmesa->new_state = ~0;
+}
+
+
void mgaDDInitStateFuncs( GLcontext *ctx )
{
ctx->Driver.UpdateState = mgaDDUpdateState;
@@ -710,11 +851,14 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
ctx->Driver.RenderStart = mgaDDUpdateHwState;
ctx->Driver.RenderFinish = 0;
- ctx->Driver.SetBuffer = mgaDDSetBuffer;
+ ctx->Driver.SetDrawBuffer = mgaDDSetDrawBuffer;
+ ctx->Driver.SetReadBuffer = mgaDDSetReadBuffer;
ctx->Driver.Color = mgaDDSetColor;
ctx->Driver.ClearColor = mgaDDClearColor;
ctx->Driver.Dither = mgaDDDither;
+ ctx->Driver.PolygonStipple = mgaDDPolygonStipple;
+
ctx->Driver.Index = 0;
ctx->Driver.ClearIndex = 0;
ctx->Driver.IndexMask = 0;
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.h b/xc/lib/GL/mesa/src/drv/mga/mgastate.h
index 5ada1b23c..ac92cb0c2 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgastate.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.h
@@ -7,9 +7,10 @@ extern void mgaDDUpdateHwState( GLcontext *ctx );
extern void mgaDDUpdateState( GLcontext *ctx );
extern void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim );
-/* reprograms the current registers without updating them, used to
-reset state after a dma buffer overflow */
-void mgaUpdateRegs( GLuint regs );
+extern void mgaInitState( mgaContextPtr mmesa );
+
+extern void mgaUpdateClipping(const GLcontext *ctx);
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
index be7ad6018..3afb70bad 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
@@ -47,22 +47,25 @@
* to it.
*/
static void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) {
- int i;
if ( !t ) return;
/* free the texture memory */
- mmFreeMem( t->MemBlock );
+ if (t->MemBlock) {
+ mmFreeMem( t->MemBlock );
+ t->MemBlock = 0;
+
+ if (t->age > mmesa->dirtyAge)
+ mmesa->dirtyAge = t->age;
+ }
/* free mesa's link */
- t->tObj->DriverData = NULL;
+ if (t->tObj)
+ t->tObj->DriverData = NULL;
/* see if it was the driver's current object */
- for ( i = 0 ; i < 2 ; i++ ) {
- if ( mmesa->CurrentTexObj[i] == t ) {
- mmesa->CurrentTexObj[i] = NULL;
- }
- }
+ if (t->bound)
+ mmesa->CurrentTexObj[t->bound - 1] = 0;
remove_from_list(t);
free( t );
@@ -73,6 +76,9 @@ static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
if (t->MemBlock) {
mmFreeMem(t->MemBlock);
t->MemBlock = 0;
+
+ if (t->age > mmesa->dirtyAge)
+ mmesa->dirtyAge = t->age;
}
t->dirty_images = ~0;
@@ -80,22 +86,76 @@ static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
}
-void mgaResetGlobalLRU( mgaContextPtr mmesa )
+static void mgaPrintLocalLRU( mgaContextPtr mmesa, int heap )
+{
+ mgaTextureObjectPtr t;
+ int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
+
+ fprintf(stderr, "\nLocal LRU, heap %d:\n", heap);
+
+ foreach( t, &(mmesa->TexObjList[heap]) ) {
+ if (!t->tObj)
+ fprintf(stderr, "Placeholder %d at %x sz %x\n",
+ t->MemBlock->ofs / sz,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+ else
+ fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
+ t->bound,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+
+ }
+
+ fprintf(stderr, "\n\n");
+}
+
+static void mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap )
+{
+ int i, j;
+ drm_mga_tex_region_t *list = mmesa->sarea->texList[heap];
+
+ fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list);
+
+ for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev);
+ j = list[j].next;
+ if (j == MGA_NR_TEX_REGIONS) break;
+ }
+
+ if (j != MGA_NR_TEX_REGIONS) {
+ fprintf(stderr, "Loop detected in global LRU\n\n\n");
+ for (i = 0 ; i < MGA_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ i, list[i].age, list[i].next, list[i].prev);
+ }
+ }
+
+ fprintf(stderr, "\n\n");
+}
+
+
+static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap )
{
- mgaTexRegion *list = mmesa->sarea->texList;
- int sz = 1 << mmesa->mgaScreen->logTextureGranularity;
+ drm_mga_tex_region_t *list = mmesa->sarea->texList[heap];
+ int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap];
int i;
+ mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
+
+ if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap);
+
/* (Re)initialize the global circular LRU list. The last element
* in the array (MGA_NR_TEX_REGIONS) is the sentinal. Keeping it
* at the end of the array allows it to be addressed rationally
* when looking up objects at a particular location in texture
* memory.
*/
- for (i = 0 ; (i+1) * sz < mmesa->mgaScreen->textureSize ; i++) {
+ for (i = 0 ; (i+1) * sz <= mmesa->mgaScreen->textureSize[heap] ; i++) {
list[i].prev = i-1;
list[i].next = i+1;
- list[i].age = 0;
+ list[i].age = mmesa->sarea->texAge[heap];
}
i--;
@@ -104,30 +164,41 @@ void mgaResetGlobalLRU( mgaContextPtr mmesa )
list[i].next = MGA_NR_TEX_REGIONS;
list[MGA_NR_TEX_REGIONS].prev = i;
list[MGA_NR_TEX_REGIONS].next = 0;
- mmesa->sarea->texAge = 0;
+
}
static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
int i;
- int logsz = mmesa->mgaScreen->logTextureGranularity;
+ int heap = t->heap;
+ int logsz = mmesa->mgaScreen->logTextureGranularity[heap];
int start = t->MemBlock->ofs >> logsz;
int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
- mgaTexRegion *list = mmesa->sarea->texList;
+ drm_mga_tex_region_t *list = mmesa->sarea->texList[heap];
- mmesa->texAge = ++mmesa->sarea->texAge;
+ mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
+
+ if (!t->MemBlock) {
+ fprintf(stderr, "no memblock\n\n");
+ return;
+ }
/* Update our local LRU
*/
- move_to_head( &(mmesa->TexObjList), t );
+ move_to_head( &(mmesa->TexObjList[heap]), t );
+
+
+ if (0)
+ fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list);
+
/* Update the global LRU
*/
for (i = start ; i <= end ; i++) {
list[i].in_use = 1;
- list[i].age = mmesa->texAge;
+ list[i].age = mmesa->texAge[heap];
/* remove_from_list(i)
*/
@@ -141,8 +212,12 @@ static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i;
list[MGA_NR_TEX_REGIONS].next = i;
}
-}
+ if (0) {
+ mgaPrintGlobalLRU(mmesa, t->heap);
+ mgaPrintLocalLRU(mmesa, t->heap);
+ }
+}
/* Called for every shared texture region which has increased in age
* since we last held the lock.
@@ -151,23 +226,29 @@ static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
* and pushes a placeholder texture onto the LRU list to represent
* the other client's textures.
*/
-void mgaTexturesGone( mgaContextPtr mmesa,
- GLuint offset,
- GLuint size,
- GLuint in_use )
+static void mgaTexturesGone( mgaContextPtr mmesa,
+ GLuint heap,
+ GLuint offset,
+ GLuint size,
+ GLuint in_use )
{
mgaTextureObjectPtr t, tmp;
-
- foreach_s ( t, tmp, &mmesa->TexObjList ) {
+
+
+
+ foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) {
if (t->MemBlock->ofs >= offset + size ||
t->MemBlock->ofs + t->MemBlock->size <= offset)
continue;
+
+
+
/* It overlaps - kick it off. Need to hold onto the currently bound
* objects, however.
*/
- if (t == mmesa->CurrentTexObj[0] || t == mmesa->CurrentTexObj[1])
+ if (t->bound)
mgaSwapOutTexObj( mmesa, t );
else
mgaDestroyTexObj( mmesa, t );
@@ -178,12 +259,54 @@ void mgaTexturesGone( mgaContextPtr mmesa,
t = (mgaTextureObjectPtr) calloc(1,sizeof(*t));
if (!t) return;
- t->MemBlock = mmAllocMem( mmesa->texHeap, size, 0, offset);
- insert_at_head( &mmesa->TexObjList, t );
+ t->heap = heap;
+ t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset);
+ if (!t->MemBlock) {
+ fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
+ (int)size, (int)offset);
+ mmDumpMemInfo( mmesa->texHeap[heap]);
+ return;
+ }
+ insert_at_head( &(mmesa->TexObjList[heap]), t );
}
}
+void mgaAgeTextures( mgaContextPtr mmesa, int heap )
+{
+ drm_mga_sarea_t *sarea = mmesa->sarea;
+ int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
+ int idx, nr = 0;
+
+ /* Have to go right round from the back to ensure stuff ends up
+ * LRU in our local list... Fix with a cursor pointer.
+ */
+ for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ;
+ idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ;
+ idx = sarea->texList[heap][idx].prev, nr++)
+ {
+ if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) {
+ mgaTexturesGone(mmesa, heap, idx * sz, sz, 1);
+ }
+ }
+
+ if (nr == MGA_NR_TEX_REGIONS) {
+ mgaTexturesGone(mmesa, heap, 0,
+ mmesa->mgaScreen->textureSize[heap], 0);
+ mgaResetGlobalLRU( mmesa, heap );
+ }
+
+
+ if (0) {
+ mgaPrintGlobalLRU( mmesa, heap );
+ mgaPrintLocalLRU( mmesa, heap );
+ }
+
+ mmesa->texAge[heap] = sarea->texAge[heap];
+ mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE;
+}
+
+
/*
* mgaSetTexWrappings
*/
@@ -281,22 +404,22 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) {
/*
- * mgaUploadSubImage
+ * mgaUploadSubImageLocked
*
* Perform an iload based update of a resident buffer. This is used for
* both initial loading of the entire image, and texSubImage updates.
*
* Performed with the hardware lock held.
*/
-static void mgaUploadSubImage( mgaContextPtr mmesa,
- mgaTextureObjectPtr t,
- int level,
- int x, int y, int width, int height ) {
+static void mgaUploadSubImageLocked( mgaContextPtr mmesa,
+ mgaTextureObjectPtr t,
+ int level,
+ int x, int y, int width, int height ) {
int x2;
int dwords;
- int dstorg;
+ int offset;
struct gl_texture_image *image;
- int texelBytes, texelsPerDword, texelMaccess;
+ int texelBytes, texelsPerDword, texelMaccess, length;
if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) {
mgaMsg( 1, "mgaUploadSubImage: bad level: %i\n", level );
@@ -310,15 +433,9 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
}
/* find the proper destination offset for this level */
- dstorg = (mmesa->mgaScreen->textureOffset + t->MemBlock->ofs +
+ offset = (t->MemBlock->ofs +
t->offsets[level]);
- /* turn on PCI/AGP if needed
- if ( textureHeapPhysical ) {
- dstorg |= 1 | mgaglx.use_agp;
- }
- */
-
texelBytes = t->texelBytes;
switch( texelBytes ) {
case 1:
@@ -363,7 +480,7 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1);
width = x2 - x;
}
-
+
/* we may not be able to upload the entire texture in one
batch due to register limits or dma buffer limits.
Recursively split it up. */
@@ -374,7 +491,8 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
}
mgaMsg(10, "mgaUploadSubImage: recursively subdividing\n" );
- mgaUploadSubImage( mmesa, t, level, x, y, width, height >> 1 );
+ mgaUploadSubImageLocked( mmesa, t, level, x, y,
+ width, height >> 1 );
y += ( height >> 1 );
height -= ( height >> 1 );
}
@@ -385,31 +503,50 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
/* bump the performance counter */
mgaglx.c_textureSwaps += ( dwords << 2 );
-
-#if 0
-
- /* fill in the secondary buffer with properly converted texels
- from the mesa buffer */
- mgaConvertTexture( dest, texelBytes, image, x, y, width, height );
-
- /* send the secondary data */
- mgaSecondaryDma( TT_BLIT, dest, dwords );
-#endif
-
+ length = dwords * 4;
+
+ /* Fill in the secondary buffer with properly converted texels
+ * from the mesa buffer. */
+ if(t->heap == MGA_CARD_HEAP) {
+ mgaGetILoadBufferLocked( mmesa );
+ mgaConvertTexture( (mgaUI32 *)mmesa->iload_buffer->address,
+ texelBytes, image, x, y, width, height );
+ if(length < 64) length = 64;
+ mgaMsg(10, "TexelBytes : %d, offset: %d, length : %d\n",
+ texelBytes,
+ mmesa->mgaScreen->textureOffset[t->heap] +
+ offset +
+ y * width * 4/texelsPerDword,
+ length);
+
+ mgaFireILoadLocked( mmesa,
+ mmesa->mgaScreen->textureOffset[t->heap] +
+ offset +
+ y * width * 4/texelsPerDword,
+ length);
+ } else {
+ /* This works, is slower for uploads to card space and needs
+ * additional synchronization with the dma stream.
+ */
+ mgaConvertTexture( (mgaUI32 *)
+ (mmesa->mgaScreen->texVirtual[t->heap] +
+ offset +
+ y * width * 4/texelsPerDword),
+ texelBytes, image, x, y, width, height );
+ }
}
-
static void mgaUploadTexLevel( mgaContextPtr mmesa,
- mgaTextureObjectPtr t,
- int l )
+ mgaTextureObjectPtr t,
+ int l )
{
- mgaUploadSubImage( mmesa,
- t,
- l,
- 0, 0,
- t->tObj->Image[l]->Width,
- t->tObj->Image[l]->Height);
+ mgaUploadSubImageLocked( mmesa,
+ t,
+ l,
+ 0, 0,
+ t->tObj->Image[l]->Width,
+ t->tObj->Image[l]->Height);
}
@@ -527,9 +664,11 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj)
/* fill in our mga texture object */
t->tObj = tObj;
t->ctx = mmesa;
+ t->age = 0;
+ t->bound = 0;
- insert_at_tail(&(mmesa->TexObjList), t);
+ insert_at_tail(&(mmesa->SwappedOut), t);
t->MemBlock = 0;
@@ -596,34 +735,61 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj)
tObj->DriverData = t;
}
+static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+ /* NOT DONE */
+}
-int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
+ return 0;
+}
+
+int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+ int heap;
int i;
int ofs;
mgaglx.c_textureSwaps++;
+ heap = t->heap = mgaChooseTexHeap( mmesa, t );
+
/* Do we need to eject LRU texture objects?
*/
if (!t->MemBlock) {
while (1)
{
- t->MemBlock = mmAllocMem( mmesa->texHeap, t->totalSize, 12, 0 );
+ mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev;
+
+ t->MemBlock = mmAllocMem( mmesa->texHeap[heap],
+ t->totalSize,
+ 6, 0 );
if (t->MemBlock)
break;
- if (mmesa->TexObjList.prev == &(mmesa->TexObjList)) {
- fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
- mmDumpMemInfo( mmesa->texHeap );
+ if (mmesa->TexObjList[heap].prev->bound) {
+ fprintf(stderr,
+ "Hit bound texture in upload\n");
return -1;
}
- mgaDestroyTexObj( mmesa, mmesa->TexObjList.prev );
+ if (mmesa->TexObjList[heap].prev ==
+ &(mmesa->TexObjList[heap]))
+ {
+ fprintf(stderr, "Failed to upload texture, "
+ "sz %d\n", t->totalSize);
+ mmDumpMemInfo( mmesa->texHeap[heap] );
+ return -1;
+ }
+
+ mgaDestroyTexObj( mmesa, tmp );
}
- ofs = t->MemBlock->ofs;
+ ofs = t->MemBlock->ofs
+ + mmesa->mgaScreen->textureOffset[heap]
+ ;
t->Setup[MGA_TEXREG_ORG] = ofs;
t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1];
@@ -638,8 +804,16 @@ int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
*/
mgaUpdateTexLRU( mmesa, t );
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "dispatch age: %d age freed memory: %d\n",
+ GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge);
+
+ if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa))
+ mgaWaitAgeLocked( mmesa, mmesa->dirtyAge );
+
if (t->dirty_images) {
- if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG)
+ if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
fprintf(stderr, "*");
for (i = 0 ; i <= t->lastLevel ; i++)
@@ -692,12 +866,10 @@ static void mgaUpdateTextureEnvG200( GLcontext *ctx )
}
}
-/* I don't have the alpha values correct yet:
- */
static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- mgaUI32 *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit];
+ GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit];
GLuint source = mmesa->tmu_source[unit];
struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current;
@@ -725,13 +897,13 @@ static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_mul);
else
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_mul);
break;
case GL_DECAL:
*reg = (TD0_color_arg2_fcol |
@@ -751,20 +923,49 @@ static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_add);
else
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_add);
break;
case GL_BLEND:
- /* Use a multipass mechanism to do this:
+ if (0)
+ fprintf(stderr, "GL_BLEND unit %d flags %x\n", unit,
+ mmesa->blend_flags);
+
+ if (mmesa->blend_flags)
+ mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ return;
+
+ /* Do singletexture GL_BLEND with 'all ones' env-color
+ * by using both texture units. Multitexture gl_blend
+ * is a fallback.
*/
- mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ if (unit == 0) {
+ /* Part 1: R1 = Rf ( 1 - Rt )
+ * A1 = Af At
+ */
+ *reg = ( TD0_color_arg2_diffuse |
+ TD0_color_arg1_inv_enable |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg1);
+ } else {
+ /* Part 2: R2 = R1 + Rt
+ * A2 = A1
+ */
+ *reg = ( TD0_color_arg2_prevstage |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ }
+
break;
default:
}
@@ -782,9 +983,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
mgaMsg(15,"mgaUpdateTextureState %d\n", unit);
/* disable texturing until it is known to be good */
- mmesa->Setup[MGA_CTXREG_DWGCTL] =
- (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) |
- DC_opcod_trap);
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_trap;
enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY;
if (enabled != TEXTURE0_2D) {
@@ -804,7 +1004,6 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
if ( !tObj->DriverData ) {
/* clear the current pointer so that texture object can be
swapped out if necessary to make room */
- mmesa->CurrentTexObj[source] = NULL;
mgaCreateTexObj( mmesa, tObj );
if ( !tObj->DriverData ) {
@@ -815,9 +1014,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
}
/* we definately have a valid texture now */
- mmesa->Setup[MGA_CTXREG_DWGCTL] =
- (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) |
- DC_opcod_texture_trap);
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_texture_trap;
t = (mgaTextureObjectPtr)tObj->DriverData;
@@ -825,6 +1023,11 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit);
mmesa->CurrentTexObj[unit] = t;
+ t->bound = unit+1;
+
+ if (t->MemBlock)
+ mgaUpdateTexLRU( mmesa, t );
+
t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable;
if (ctx->Texture.Enabled == (TEXTURE0_2D|TEXTURE1_2D))
@@ -848,23 +1051,31 @@ void mgaUpdateTextureState( GLcontext *ctx )
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE;
+ if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->bound = 0;
+ if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->bound = 0;
+ mmesa->CurrentTexObj[0] = 0;
+ mmesa->CurrentTexObj[1] = 0;
+
if (MGA_IS_G400(mmesa)) {
mgaUpdateTextureObject( ctx, 0 );
mgaUpdateTextureStage( ctx, 0 );
- mmesa->Setup[MGA_CTXREG_TDUAL1] = mmesa->Setup[MGA_CTXREG_TDUAL0];
+ mmesa->Setup[MGA_CTXREG_TDUAL1] =
+ mmesa->Setup[MGA_CTXREG_TDUAL0];
if (mmesa->multitex) {
mgaUpdateTextureObject( ctx, 1 );
mgaUpdateTextureStage( ctx, 1 );
}
+
+ mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1;
} else {
mgaUpdateTextureObject( ctx, 0 );
- mgaUpdateTextureEnvG200( ctx );
+ mgaUpdateTextureEnvG200( ctx );
}
/* schedule the register writes */
- mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0;
}
@@ -880,14 +1091,57 @@ Driver functions called directly from mesa
/*
* mgaTexEnv
*/
-void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) {
+void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
mgaMsg( 10, "mgaTexEnv( %i )\n", pname );
+
if (pname == GL_TEXTURE_ENV_MODE) {
/* force the texture state to be updated */
- MGA_CONTEXT(ctx)->CurrentTexObj[0] = 0;
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
+ else if (pname == GL_TEXTURE_ENV_COLOR)
+ {
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GLfloat *fc = texUnit->EnvColor;
+ GLubyte c[4];
+ GLuint col;
+
+
+ c[0] = fc[0];
+ c[1] = fc[1];
+ c[2] = fc[2];
+ c[3] = fc[3];
+
+ /* No alpha at 16bpp?
+ */
+ col = mgaPackColor( mmesa->mgaScreen->Attrib,
+ c[0], c[1], c[2], c[3] );
+
+ mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+
+ if (mmesa->Setup[MGA_CTXREG_FCOL] != col) {
+ FLUSH_BATCH(mmesa);
+ mmesa->Setup[MGA_CTXREG_FCOL] = col;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+
+ mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;
+
+ /* Actually just require all four components to be
+ * equal. This permits a single-pass GL_BLEND.
+ *
+ * More complex multitexture/multipass fallbacks
+ * for blend can be done later.
+ */
+ if (mmesa->envcolor != 0x0 &&
+ mmesa->envcolor != 0xffffffff)
+ mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
+ }
+ }
+
}
/*
@@ -907,6 +1161,7 @@ void mgaTexImage( GLcontext *ctx, GLenum target,
mgaUpdateTextureState time. */
t = (mgaTextureObjectPtr) tObj->DriverData;
if ( t ) {
+ if (t->bound) FLUSH_BATCH(mmesa);
/* if this is the current object, it will force an update */
mgaDestroyTexObj( mmesa, t );
mmesa->new_state |= MGA_NEW_TEXTURE;
@@ -936,6 +1191,7 @@ void mgaTexSubImage( GLcontext *ctx, GLenum target,
mgaUpdateTextureState time. */
t = (mgaTextureObjectPtr) tObj->DriverData;
if ( t ) {
+ if (t->bound) FLUSH_BATCH(mmesa);
/* if this is the current object, it will force an update */
mgaDestroyTexObj( mmesa, t );
mmesa->new_state |= MGA_NEW_TEXTURE;
@@ -956,7 +1212,9 @@ void mgaTexSubImage( GLcontext *ctx, GLenum target,
*/
void mgaTexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
- GLenum pname, const GLfloat *params ) {
+ GLenum pname, const GLfloat *params )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t;
mgaMsg( 10, "mgaTexParameter( %p, %i )\n", tObj, pname );
@@ -973,52 +1231,68 @@ void mgaTexParameter( GLcontext *ctx, GLenum target,
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) FLUSH_BATCH(mmesa);
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
+ if (t->bound) FLUSH_BATCH(mmesa);
mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) FLUSH_BATCH(mmesa);
mgaSetTexBorderColor(t,tObj->BorderColor);
break;
default:
return;
}
- /* force the texture state to be updated */
- MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL;
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+
+ mmesa->new_state |= MGA_NEW_TEXTURE;
}
/*
* mgaBindTexture
*/
void mgaBindTexture( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj ) {
+ struct gl_texture_object *tObj )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaMsg( 10, "mgaBindTexture( %p )\n", tObj );
-
+
+ FLUSH_BATCH(mmesa);
+
+ if (mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]) {
+ mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0;
+ mmesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0;
+ }
+
/* force the texture state to be updated
*/
- MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL;
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
/*
* mgaDeleteTexture
*/
-void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) {
+void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData;
mgaMsg( 10, "mgaDeleteTexture( %p )\n", tObj );
- /* delete our driver data */
- if ( tObj->DriverData ) {
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- mgaDestroyTexObj( mmesa,
- (mgaTextureObjectPtr)(tObj->DriverData) );
+ if ( t ) {
+ if (t->bound) {
+ FLUSH_BATCH(mmesa);
+ mmesa->CurrentTexObj[t->bound-1] = 0;
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ }
+
+ mgaDestroyTexObj( mmesa, t );
mmesa->new_state |= MGA_NEW_TEXTURE;
}
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h
index 1e8e7e86f..7873146c0 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatex.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h
@@ -28,7 +28,6 @@
#ifndef MGATEX_INC
#define MGATEX_INC
-#include "mga_drm_public.h"
#include "types.h"
#include "mgacommon.h"
#include "mm.h"
@@ -48,7 +47,9 @@ typedef struct mga_texture_object_s {
mgaUI32 dirty_images;
mgaUI32 totalSize;
int texelBytes;
- mgaUI32 age;
+ mgaUI32 age;
+ int bound;
+ int heap; /* agp or card */
mgaUI32 Setup[MGA_TEX_SETUP_SIZE];
} mgaTextureObject_t;
@@ -96,7 +97,7 @@ void mgaUpdateTexturePalette( GLcontext *ctx, struct gl_texture_object *tObj );
GLboolean mgaIsTextureResident( GLcontext *ctx, struct gl_texture_object *t );
-void mgaConvertTexture( mgaUI32 *destPtr, int texelBytes,
+void mgaConvertTexture( mgaUI32 *dest, int texelBytes,
struct gl_texture_image *image,
int x, int y, int width, int height );
@@ -107,9 +108,7 @@ int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t );
-void mgaResetGlobalLRU( mgaContextPtr mmesa );
-void mgaTexturesGone( mgaContextPtr mmesa, GLuint offset,
- GLuint size, GLuint in_use );
+void mgaAgeTextures( mgaContextPtr mmesa, int heap );
void mgaDDInitTextureFuncs( GLcontext *ctx );
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c
index bd8ef083f..b83aaf2ea 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <math.h>
+#include "types.h"
#include "vb.h"
#include "pipeline.h"
@@ -122,34 +123,14 @@ void mgaDDTrifuncInit()
init_twoside_offset();
init_twoside_offset_flat();
- /* Hmmm...
- */
- for (i = 0 ; i < 0x20 ; i++) {
- if (i & ~MGA_FLAT_BIT) {
- points_tab[i] = points_tab[i&MGA_FLAT_BIT];
- line_tab[i] = line_tab[i&MGA_FLAT_BIT];
- }
- }
-
for (i = 0 ; i < 0x20 ; i++)
- if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT ||
- mgaglx.nullprims)
+ if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT)
{
quad_tab[i] = mga_null_quad;
tri_tab[i] = mga_null_triangle;
line_tab[i] = mga_null_line;
points_tab[i] = mga_null_points;
}
-
- if (mgaglx.noFallback) {
- for (i = 0 ; i < 0x10 ; i++) {
- points_tab[i|MGA_FALLBACK_BIT] = points_tab[i];
- line_tab[i|MGA_FALLBACK_BIT] = line_tab[i];
- tri_tab[i|MGA_FALLBACK_BIT] = tri_tab[i];
- quad_tab[i|MGA_FALLBACK_BIT] = quad_tab[i];
- }
- }
-
}
@@ -162,50 +143,53 @@ void mgaDDChooseRenderState( GLcontext *ctx )
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint flags = ctx->TriangleCaps;
- ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ if (mmesa->Fallback)
+ return;
+
+ mmesa->IndirectTriangles &= ~DD_SW_RASTERIZE;
if (flags) {
GLuint ind = 0;
GLuint shared = 0;
- GLuint fallback = MGA_FALLBACK_BIT;
-
- if (mgaglx.noFallback) fallback = 0;
if (flags & DD_Z_NEVER) shared |= MGA_NODRAW_BIT;
if (flags & DD_FLATSHADE) shared |= MGA_FLAT_BIT;
- if (flags & DD_MULTIDRAW) shared |= fallback;
- if (flags & (DD_SELECT|DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT;
+ if (flags & (DD_MULTIDRAW|
+ DD_SELECT|
+ DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT;
if (flags & DD_STENCIL) shared |= MGA_FALLBACK_BIT;
ind = shared;
if (flags & DD_POINT_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
- if (flags & DD_POINT_ATTEN) ind |= fallback;
mmesa->renderindex = ind;
mmesa->PointsFunc = points_tab[ind];
if (ind & MGA_FALLBACK_BIT)
- ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+ mmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
ind = shared;
if (flags & DD_LINE_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
- if (flags & DD_LINE_STIPPLE) ind |= fallback;
+ if (flags & DD_LINE_STIPPLE) ind |= MGA_FALLBACK_BIT;
mmesa->renderindex |= ind;
mmesa->LineFunc = line_tab[ind];
if (ind & MGA_FALLBACK_BIT)
- ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+ mmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
ind = shared;
if (flags & DD_TRI_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
if (flags & DD_TRI_OFFSET) ind |= MGA_OFFSET_BIT;
if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= MGA_TWOSIDE_BIT;
- if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback;
+ if (flags & DD_TRI_UNFILLED) ind |= MGA_FALLBACK_BIT;
+ if ((flags & DD_TRI_STIPPLE) &&
+ (ctx->IndirectTriangles & DD_TRI_STIPPLE)) ind |= MGA_FALLBACK_BIT;
mmesa->renderindex |= ind;
mmesa->TriangleFunc = tri_tab[ind];
mmesa->QuadFunc = quad_tab[ind];
if (ind & MGA_FALLBACK_BIT)
- ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE);
+ mmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE |
+ DD_QUAD_SW_RASTERIZE);
}
else if (mmesa->renderindex)
{
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h
index 3b41900f1..dcf697409 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h
@@ -34,26 +34,16 @@ extern void mgaDDTrifuncInit( void );
/* Todo:
- * - multidraw, ...
* - Antialiasing (?)
* - line and polygon stipple
- * - select and feedback
* - stencil
- * - point parameters
- * -
*/
#define MGA_ANTIALIAS_BIT 0 /* ignored for now, no fallback */
-#define MGA_FLAT_BIT 0x1
-#define MGA_OFFSET_BIT 0x2 /* 3.1 only */
-#define MGA_TWOSIDE_BIT 0x4 /* 3.1 only */
-#define MGA_NODRAW_BIT 0x8
-#define MGA_FALLBACK_BIT 0x10
-
-/* Not in use:
- */
-#define MGA_FEEDBACK_BIT 0x20
-#define MGA_SELECT_BIT 0x40
-#define MGA_POINT_PARAM_BIT 0x80 /* not needed? */
+#define MGA_FLAT_BIT 0x1
+#define MGA_OFFSET_BIT 0x2
+#define MGA_TWOSIDE_BIT 0x4
+#define MGA_NODRAW_BIT 0x8
+#define MGA_FALLBACK_BIT 0x10
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
index ac5a545d2..ba2410914 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
@@ -98,8 +98,6 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0,
}
-#if ((IND & ~MGA_FLAT_BIT) == 0)
-
static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
@@ -131,7 +129,6 @@ static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
mga_draw_point( mmesa, &mgaVB[i], sz );
}
-#endif
static void TAG(init)( void )
@@ -139,10 +136,9 @@ static void TAG(init)( void )
tri_tab[IND] = TAG(triangle);
quad_tab[IND] = TAG(quad);
-#if ((IND & ~MGA_FLAT_BIT) == 0)
line_tab[IND] = TAG(line);
points_tab[IND] = TAG(points);
-#endif
+
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c
index f78c542c8..0b703a184 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c
@@ -260,11 +260,21 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx)
mmesa->tex_dest[0] = MGA_TEX0_BIT;
mmesa->tex_dest[1] = MGA_TEX1_BIT;
mmesa->multitex = 0;
+ mmesa->blend_flags &= ~MGA_BLEND_MULTITEX;
if (ctx->Texture.Enabled & 0xf) {
if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
funcindex &= ~MGA_RGBA_BIT;
+ if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
+ mmesa->envcolor)
+ {
+ mmesa->multitex = 1;
+ mmesa->vertsize = 10;
+ mmesa->tmu_source[1] = 0;
+ funcindex |= MGA_TEX1_BIT;
+ }
+
funcindex |= MGA_TEX0_BIT;
}
@@ -272,7 +282,8 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx)
if (ctx->Texture.Enabled & 0xf) {
mmesa->multitex = 1;
mmesa->vertsize = 10;
- funcindex |= MGA_TEX1_BIT;
+ mmesa->blend_flags |= MGA_BLEND_MULTITEX;
+ funcindex |= MGA_TEX1_BIT;
} else {
/* Just a funny way of doing single texturing
*/
@@ -281,11 +292,25 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx)
if (ctx->Texture.Unit[1].EnvMode == GL_REPLACE)
funcindex &= ~MGA_RGBA_BIT;
+
+ if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
+ mmesa->envcolor)
+ {
+ mmesa->multitex = 1;
+ mmesa->vertsize = 10;
+ mmesa->tmu_source[1] = 1;
+ funcindex |= MGA_TEX1_BIT;
+ }
funcindex |= MGA_TEX0_BIT;
}
}
+ /* Not really a good place to do this - need to make the mga state
+ * management code more event-driven so this can be calculated for
+ * free.
+ */
+
if (ctx->Color.BlendEnabled)
funcindex |= MGA_ALPHA_BIT;
@@ -298,6 +323,7 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx)
if (0)
mgaPrintSetupFlags("xsmesa: full setup function", funcindex);
+ mmesa->dirty |= MGA_UPLOAD_PIPE;
mmesa->setupindex = funcindex;
/* Called by mesa's clip functons:
@@ -477,17 +503,3 @@ void mgaDDUnregisterVB( struct vertex_buffer *VB )
}
-mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords )
-{
- int bytes = dwords * 4;
- mgaUI32 *head;
-
- if (mmesa->dma_buffer->used + bytes > mmesa->dma_buffer->total)
- mgaFlushVertices( mmesa );
-
- head = (mgaUI32 *)((char *)mmesa->dma_buffer->address +
- mmesa->dma_buffer->used);
-
- mmesa->dma_buffer->used += bytes;
- return head;
-}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.h b/xc/lib/GL/mesa/src/drv/mga/mgavb.h
index 8d7c65207..675c1779c 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgavb.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.h
@@ -27,6 +27,7 @@
#ifndef MGAVB_INC
#define MGAVB_INC
+#include "types.h"
#include "vb.h"
#include "mgacommon.h"
@@ -126,7 +127,4 @@ extern void mgaDDResizeVB( struct vertex_buffer *VB, GLuint size );
extern void mgaDDSetupInit( void );
-extern mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords );
-
-
#endif
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
index 982ca93e8..a8fe76fe7 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
@@ -278,7 +278,7 @@ XCOMM Disabling 3Dnow code for the time being.
SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS)
OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS)
-REQUIREDLIBS += -lglide3x
+REQUIREDLIBS += -lglide3x -lm
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c
index 68e638f27..22780d753 100644
--- a/xc/programs/Xserver/GL/dri/dri.c
+++ b/xc/programs/Xserver/GL/dri/dri.c
@@ -120,6 +120,7 @@ DRIScreenInit(
pDRIPriv->directRenderingSupport = TRUE;
pDRIPriv->pDriverInfo = pDRIInfo;
+ pDRIPriv->nrWindows = 0;
/* setup device independent direct rendering memory maps */
@@ -334,8 +335,9 @@ DRIFinishScreenInit(ScreenPtr pScreen)
pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
}
- miClipNotify(DRIClipNotify);
-
+ if (pDRIInfo->wrap.ClipNotify)
+ miClipNotify(pDRIInfo->wrap.ClipNotify);
+
DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n");
return TRUE;
@@ -492,8 +494,6 @@ DRICloseConnection(
ScreenPtr pScreen
)
{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
return TRUE;
}
@@ -652,7 +652,7 @@ DRICreateContext(
visual,
*pHWContext,
*pVisualConfigPriv,
- contextStore))) {
+ (int)contextStore))) {
DRIDestroyContextPriv(pDRIContextPriv);
return FALSE;
}
@@ -689,12 +689,72 @@ DRIContextPrivDelete(
if (pDRIPriv->pDriverInfo->DestroyContext) {
contextStore=DRIGetContextStore(pDRIContextPriv);
(pDRIPriv->pDriverInfo->DestroyContext)(pDRIContextPriv->pScreen,
- pDRIContextPriv->hwContext,
- contextStore);
+ pDRIContextPriv->hwContext,
+ (int)contextStore);
}
return DRIDestroyContextPriv(pDRIContextPriv);
}
+
+/* This walks the drawable timestamp array and invalidates all of them
+ * in the case of transition from private to shared backbuffers. It's
+ * not necessary for correctness, because DRIClipNotify gets called in
+ * time to prevent any conflict, but the transition from
+ * shared->private is sometimes missed if we don't do this.
+ */
+static void
+DRIClipNotifyAllDrawables( ScreenPtr pScreen )
+{
+ int i;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
+ pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++;
+ }
+}
+
+
+static void
+DRITransitionToSharedBuffers( ScreenPtr pScreen )
+{
+/* ErrorF("DRITransitionToSharedBuffers\n"); */
+ DRIClipNotifyAllDrawables( pScreen );
+}
+
+
+static void
+DRITransitionToPrivateBuffers( ScreenPtr pScreen )
+{
+/* ErrorF("DRITransitionToPrivateBuffers\n"); */
+ DRIClipNotifyAllDrawables( pScreen );
+}
+
+
+static void
+DRITransitionTo3d( ScreenPtr pScreen )
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+/* ErrorF("DRITransitionTo3d\n"); */
+
+ if (pDRIInfo->TransitionTo3d)
+ pDRIInfo->TransitionTo3d( pScreen );
+}
+
+static void
+DRITransitionTo2d( ScreenPtr pScreen )
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+/* ErrorF("DRITransitionTo2d\n"); */
+
+ if (pDRIInfo->TransitionTo2d)
+ pDRIInfo->TransitionTo2d( pScreen );
+}
+
+
Bool
DRICreateDrawable(
ScreenPtr pScreen,
@@ -734,6 +794,17 @@ DRICreateDrawable(
pWin->devPrivates[DRIWindowPrivIndex].ptr =
(pointer)pDRIDrawablePriv;
+ switch (++pDRIPriv->nrWindows) {
+ case 1:
+ DRITransitionTo3d( pScreen );
+ break;
+ case 2:
+ DRITransitionToSharedBuffers( pScreen );
+ break;
+ default:
+ break;
+ }
+
/* track this in case this window is destroyed */
AddResource(id, DRIDrawablePrivResType, (pointer)pWin);
}
@@ -756,13 +827,14 @@ DRIDestroyDrawable(
DRIDrawablePrivPtr pDRIDrawablePriv;
WindowPtr pWin;
+
if (pDrawable->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr)pDrawable;
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
pDRIDrawablePriv->refCount--;
if (pDRIDrawablePriv->refCount <= 0) {
/* This calls back DRIDrawablePrivDelete which frees private area */
- FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
}
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
@@ -798,6 +870,17 @@ DRIDrawablePrivDelete(
}
xfree(pDRIDrawablePriv);
pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
+
+ switch (--pDRIPriv->nrWindows) {
+ case 0:
+ DRITransitionTo2d( pDrawable->pScreen );
+ break;
+ case 1:
+ DRITransitionToPrivateBuffers( pDrawable->pScreen );
+ break;
+ default:
+ break;
+ }
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
@@ -818,7 +901,11 @@ DRIGetDrawableInfo(
int* W,
int* H,
int* numClipRects,
- XF86DRIClipRectPtr* pClipRects
+ XF86DRIClipRectPtr* pClipRects,
+ int* backX,
+ int* backY,
+ int* numBackClipRects,
+ XF86DRIClipRectPtr* pBackClipRects
)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
@@ -907,6 +994,35 @@ DRIGetDrawableInfo(
*H = (int)(pWin->drawable.height);
*numClipRects = REGION_NUM_RECTS(&pWin->clipList);
*pClipRects = (XF86DRIClipRectPtr)REGION_RECTS(&pWin->clipList);
+
+ *backX = *X;
+ *backY = *Y;
+
+ if (pDRIPriv->nrWindows == 1 && *numClipRects) {
+ /* Use a single cliprect. */
+
+ int x0 = *X;
+ int y0 = *Y;
+ int x1 = x0 + *W;
+ int y1 = y0 + *H;
+
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 > pScreen->width-1) x1 = pScreen->width-1;
+ if (y1 > pScreen->height-1) y1 = pScreen->height-1;
+
+ pDRIPriv->private_buffer_rect.x1 = x0;
+ pDRIPriv->private_buffer_rect.y1 = y0;
+ pDRIPriv->private_buffer_rect.x2 = x1;
+ pDRIPriv->private_buffer_rect.y2 = y1;
+
+ *numBackClipRects = 1;
+ *pBackClipRects = &(pDRIPriv->private_buffer_rect);
+ } else {
+ /* Use the frontbuffer cliprects for back buffers. */
+ *numBackClipRects = 0;
+ *pBackClipRects = 0;
+ }
}
else {
/* Not a DRIDrawable */
@@ -961,6 +1077,10 @@ DRICreateInfoRec(void)
inforec->wrap.CopyWindow = DRICopyWindow;
inforec->wrap.ValidateTree = DRIValidateTree;
inforec->wrap.PostValidateTree = DRIPostValidateTree;
+ inforec->wrap.ClipNotify = DRIClipNotify;
+
+ inforec->TransitionTo2d = 0;
+ inforec->TransitionTo3d = 0;
return inforec;
}
@@ -972,6 +1092,7 @@ DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
xfree((char*)DRIInfo);
}
+
void
DRIWakeupHandler(
pointer wakeupData,
@@ -1502,10 +1623,27 @@ DRIGetDrawableIndex(
return index;
}
+unsigned int
+DRIGetDrawableStamp(
+ ScreenPtr pScreen,
+ CARD32 drawable_index)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp;
+}
+
+
+void DRIPrintDrawableLock(ScreenPtr pScreen, char *msg)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock);
+}
+
void
DRILock(ScreenPtr pScreen, int flags) {
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
+
if (!lockRefCount)
DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext, flags);
lockRefCount++;
@@ -1532,7 +1670,7 @@ void *DRIGetSAREAPrivate(ScreenPtr pScreen)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
if (!pDRIPriv) return 0;
- return ((void*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec);
+ return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec));
}
drmContext DRIGetContext(ScreenPtr pScreen)
@@ -1542,3 +1680,11 @@ drmContext DRIGetContext(ScreenPtr pScreen)
return pDRIPriv->myContext;
}
+/* This lets get at the unwrapped functions so that they can correctly
+ * call the lowerlevel functions, and choose whether they will be
+ * called at every level of recursion (eg in validatetree).
+ */
+DRIWrappedFuncsRec *DRIGetWrappedFuncs( ScreenPtr pScreen )
+{
+ return &(DRI_SCREEN_PRIV(pScreen)->wrap);
+}
diff --git a/xc/programs/Xserver/GL/dri/dri.h b/xc/programs/Xserver/GL/dri/dri.h
index d82ec5359..367351836 100644
--- a/xc/programs/Xserver/GL/dri/dri.h
+++ b/xc/programs/Xserver/GL/dri/dri.h
@@ -69,6 +69,10 @@ typedef int DRIWindowRequests;
#define DRI_3D_WINDOWS_ONLY 1
#define DRI_ALL_WINDOWS 2
+
+typedef void (*ClipNotifyPtr)( WindowPtr, int, int );
+
+
/*
* These functions can be wrapped by the DRI. Each of these have
* generic default funcs (initialized in DRICreateInfoRec) and can be
@@ -82,8 +86,12 @@ typedef struct {
CopyWindowProcPtr CopyWindow;
ValidateTreeProcPtr ValidateTree;
PostValidateTreeProcPtr PostValidateTree;
+ ClipNotifyPtr ClipNotify;
} DRIWrappedFuncsRec, *DRIWrappedFuncsPtr;
+
+
+
typedef struct {
/* driver call back functions */
Bool (*CreateContext)(ScreenPtr pScreen,
@@ -107,6 +115,8 @@ typedef struct {
DDXPointRec ptOldOrg,
RegionPtr prgnSrc,
CARD32 index);
+ void (*TransitionTo3d)(ScreenPtr pScreen);
+ void (*TransitionTo2d)(ScreenPtr pScreen);
/* wrapped functions */
DRIWrappedFuncsRec wrap;
@@ -185,7 +195,11 @@ Bool DRIGetDrawableInfo(
int* W,
int* H,
int* numClipRects,
- XF86DRIClipRectPtr* pClipRects
+ XF86DRIClipRectPtr* pClipRects,
+ int* backX,
+ int* backY,
+ int* numBackClipRects,
+ XF86DRIClipRectPtr* pBackClipRects
);
Bool DRIGetDeviceInfo(
ScreenPtr pScreen,
@@ -199,6 +213,7 @@ Bool DRIGetDeviceInfo(
DRIInfoPtr DRICreateInfoRec(void);
void DRIDestroyInfoRec(DRIInfoPtr DRIInfo);
Bool DRIFinishScreenInit(ScreenPtr pScreen);
+
void DRIWakeupHandler(
pointer wakeupData,
int result,
@@ -246,7 +261,13 @@ CARD32 DRIGetDrawableIndex(
WindowPtr pWin);
void DRILock(ScreenPtr pScreen, int flags);
void DRIUnlock(ScreenPtr pScreen);
+
+DRIWrappedFuncsRec *DRIGetWrappedFuncs( ScreenPtr pScreen );
+
void *DRIGetSAREAPrivate(ScreenPtr pScreen);
+
+unsigned int DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index);
+
DRIContextPrivPtr
DRICreateContextPriv(ScreenPtr pScreen,
drmContextPtr pHWContext,
@@ -256,6 +277,7 @@ DRICreateContextPrivFromHandle(ScreenPtr pScreen,
drmContext hHWContext,
DRIContextFlags flags);
Bool DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv);
+drmContext DRIGetContext(ScreenPtr pScreen);
#define _DRI_H_
diff --git a/xc/programs/Xserver/GL/dri/dristruct.h b/xc/programs/Xserver/GL/dri/dristruct.h
index 392be3d97..d576f40af 100644
--- a/xc/programs/Xserver/GL/dri/dristruct.h
+++ b/xc/programs/Xserver/GL/dri/dristruct.h
@@ -87,6 +87,8 @@ typedef struct _DRIScreenPrivRec
void** hiddenContextStore; /* hidden X context */
void** partial3DContextStore; /* parital 3D context */
DRIInfoPtr pDriverInfo;
+ int nrWindows;
+ XF86DRIClipRectRec private_buffer_rect; /* management of private buffers */
DRIWrappedFuncsRec wrap;
DrawablePtr DRIDrawables[SAREA_MAX_DRAWABLES];
} DRIScreenPrivRec, *DRIScreenPrivPtr;
diff --git a/xc/programs/Xserver/GL/dri/xf86dri.c b/xc/programs/Xserver/GL/dri/xf86dri.c
index 77f74e0a8..2619fba87 100644
--- a/xc/programs/Xserver/GL/dri/xf86dri.c
+++ b/xc/programs/Xserver/GL/dri/xf86dri.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.2 1999/06/27 14:07:39 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.6 2000/02/23 04:46:52 martin Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -31,7 +31,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Kevin E. Martin <kevin@precisioninsight.com>
* Jens Owen <jens@precisioninsight.com>
*
- * $PI: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.20 1999/06/24 19:10:40 faith Exp $
*/
#if XFree86LOADER
@@ -389,6 +388,8 @@ ProcXF86DRIGetDrawableInfo(
DrawablePtr pDrawable;
int X, Y, W, H;
XF86DRIClipRectPtr pClipRects;
+ XF86DRIClipRectPtr pBackClipRects;
+ int backX, backY;
REQUEST(xXF86DRIGetDrawableInfoReq);
REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
@@ -412,7 +413,11 @@ ProcXF86DRIGetDrawableInfo(
(int*)&W,
(int*)&H,
(int*)&rep.numClipRects,
- &pClipRects)) {
+ &pClipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &pBackClipRects)) {
return BadValue;
}
@@ -420,18 +425,32 @@ ProcXF86DRIGetDrawableInfo(
rep.drawableY = Y;
rep.drawableWidth = W;
rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+ if (rep.numBackClipRects)
+ rep.length += sizeof(XF86DRIClipRectRec) * rep.numBackClipRects;
+
+ if (rep.numClipRects)
+ rep.length += sizeof(XF86DRIClipRectRec) * rep.numClipRects;
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
- rep.length = 0;
if (rep.numClipRects) {
- rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply) +
- sizeof(XF86DRIClipRectRec) * rep.numClipRects);
+ WriteToClient(client,
+ sizeof(XF86DRIClipRectRec) * rep.numClipRects,
+ (char *)pClipRects);
}
- WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
- if (rep.length) {
- WriteToClient(client, rep.length, (char *)pClipRects);
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(XF86DRIClipRectRec) * rep.numBackClipRects,
+ (char *)pBackClipRects);
}
+
return (client->noClientException);
}
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml
index 5306e50a9..895ce09a7 100644
--- a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml
@@ -7,11 +7,11 @@
<article>
- <title>DRI User Guide
+ <title>DRI Users Guide
<author><htmlurl url="http://www.precisioninsight.com/"
name="Precision Insight, Inc.">
- <date>20 March 2000
-
+ <date>6 March 2000
+
<ident>
$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml,v 1.3 2000/03/08 05:38:41 dawes Exp $
</ident>
@@ -25,7 +25,7 @@
<bf>Copyright &copy; 2000 by Precision Insight, Inc.,
Cedar Park, Texas.
All Rights Reserved.</bf>
-<p>
+ <p>
<bf>Permission is granted to make and distribute verbatim copies
of this document provided the copyright notice and this permission
notice are preserved on all copies.</bf>
@@ -60,13 +60,9 @@
software downloads.
<p>
This document does not cover compilation or installation of
- XFree86 4.0.
- It is assumed that you've already installed a Linux distribution which
- includes XFree86 4.0 or that you're an experienced Linux developer
- who has compiled the DRI for himself.
- DRI download, compilation and installation instructions can be found
- at <htmlurl url="http://dri.sourceforge.net/DRIcompile.html"
- name="http://dri.sourceforge.net/DRIcompile.html">
+ XFree86 4.0;
+ it is assumed that you've already installed a Linux distribution which
+ includes XFree86 4.0.
<sect>Supported Hardware
<p>
@@ -108,13 +104,8 @@
<p>
<itemize>
<item>XFree86 4.0
- <item>Linux kernel 2.2.x.
- Later kernels will be supported in the near future, and may be
- required for some chipsets.
- The DRI modules currently in the 2.3.x kernel tree will not
- currently work.
- DRI updates for the 2.3.x kernel series are under development
- at the time of writing.
+ <item>Linux kernel 2.2.x (later kernels will be supported in
+ the near future, and may be required for some chipsets)
</itemize>
<p>
Mesa 3.3 (beta) is included with XFree86 4.0; there is no need to
@@ -130,8 +121,6 @@
<p>
Before starting the X server you must install the correct kernel
module for your hardware.
- In the future, this should be automatically done by the system.
- But until then, it must be installed manually.
<p>
This can be done by executing the following as root:
<verb>
@@ -140,17 +129,7 @@
<p>
For example, on 3dfx hardware, the kernel module is called tdfx.o
so you you would type insmod XXX/tdfx.o
- <p>
- Replace XXX with the location of DRI modules on your system.
- This may vary between distributions or depend on where you
- have your DRI build tree if you compiled it yourself.
- <p>
- If you compiled the XFree86 source tree yourself, the kernel
- modules should be in
- <tt>$BUILDROOT/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/</tt>.
- Another place to look is
- <tt>/lib/modules/</tt><em>kernel-version</em><tt>/misc/</tt> or
- <tt>/lib/modules/</tt><em>kernel-version</em><tt>/dri/</tt>.
+
<p>
Verify that the kernel module was installed by checking that
/proc/dri/0 exists.
@@ -269,19 +248,6 @@
The documentation included with your card should have information
about maximum screen size when using 3D.
- <sect1>Start-up
-<p>
- Start your X server in the normal way (typically startx).
- If the DRM kernel module loaded correctly there will be a
- message to indicate so:
- <verb>
- (0): [DRI] installation complete
- </verb>
- When the X server is running, you can use <tt>xdpyinfo</tt> to
- check that the GLX, SGI-GLX and XFree86-DRI extensions have loaded.
- <p>
- Go to the troubleshooting section if this fails.
-
<sect>Using 3D Acceleration
<p>
@@ -538,13 +504,14 @@
<item>
Older Linux OpenGL applications may have been linked against
- Mesa's GL library and will not automatically use the new libGL.so.
- In some cases, making symbolic links will solve the problem:
+ Mesa's GL library and will not automatically use libGL.so.
+ In some cases, making symbolic links from the Mesa GL library
+ to libGL.so.1 will solve the problem:
<verb>
ln -s libGL.so.1 libMesaGL.so.3
</verb>
In other cases, the application will have to be relinked
- against the new libGL.so from XFree86.
+ against the new XFree86 libGL.so.
<P>
It is reported that part of the problem is that running
<tt/ldconfig/ will silently rewrite symbolic links based
@@ -564,42 +531,6 @@
<sect1>3dfx Voodoo3
<p>
- <sect2>Configuration
-<p>
- Your XF86Config file's device section must specify the
- <tt>tdfx</tt> device:
- <verb>
- Section "Device"
- Identifier "Voodoo3"
- VendorName "3dfx"
- Driver "tdfx"
- EndSection
- </verb>
- The Screen section should then reference the Voodoo3 device:
- <verb>
- Section "Screen"
- Identifier "Screen 1"
- Device "Voodoo3"
- Monitor "High Res Monitor"
- DefaultDepth 16
- Subsection "Display"
- Depth 16
- Modes "1280x1024" "1024x768" "800x600" "640x480"
- ViewPort 0 0
- EndSubsection
- EndSection
- </verb>
- <p>
- The kernel module for the Voodoo3 is named <tt>tdfx.o</tt> and
- must be installed with:
- <verb>
- insmod tdfx.o
- </verb>
- <p>
- The DRI 3D driver for the Voodoo3 should be in
- <tt>/usr/X11R6/lib/modules/dri/tdfx_dri.so</tt>.
- This will be automatically loaded by libGL.so.
-
<sect2>Troubleshooting
<p>
<itemize>
@@ -608,9 +539,6 @@
bit/pixel screen mode.
Use <tt/xdpyinfo/ to verify that all your visuals are depth 16.
Edit your XF86Config file if needed.
- <item>
- The <tt>/dev/3dfx</tt> device is not used for DRI; it's only for
- Glide on older 3dfx hardware.
</itemize>
<sect2>Performance
@@ -633,14 +561,10 @@
demo, may become sluggish when falling back to software
rendering to render in that mode.
</itemize>
-
<sect2>Known Problems
<p>
<itemize>
<item>
- Glide cannot be used directly; only OpenGL-based programs are
- supported on the Voodoo3.
- <item>
SSystem has problems because of poorly set near and far
clipping planes.
The office.unc Performer model also suffers from this problem.
@@ -649,16 +573,10 @@
<sect1>Intel i810
<p>
- Information to be added in the future.
-
<sect1>Matrox G400
<p>
- Information to be added in the future.
-
<sect1>ATI Rage 128
<p>
- Information to be added in the future.
-
<sect1>3DLabs Oxygen GMX 2000
<p>
The driver for this hardware was experimental and is no longer being
@@ -736,9 +654,6 @@
<item>Visit the <htmlurl url="http://dri.sourceforge.net"
name="DRI project on SourceForge.net"> for the latest development
news about the DRI and 3D drivers.
- <item>The <htmlurl url="http://dri.sourceforge.net/DRIcompile.html"
- name="DRI Compilation Guide"> explains how to download, compile
- and install the DRI for yourself.
</itemize>
<sect1>Support
@@ -749,8 +664,9 @@
<htmlurl url="http://sourceforge.net/mail/?group_id=387"
name="SourceForge"> is a forum for people to discuss DRI problems.
<item>
- In the future there may be IHV and Linux vendor support resources
- for the DRI.
+ XXX IHV support?
+ <item>
+ XXX Linux distro support?
</itemize>
</article>
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
index 9acce4b54..b90ed5511 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
@@ -510,7 +510,8 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
if ((bufs = drmAddBufs(pGlint->drmSubFD,
xf86ConfigDRI.bufs[i].count,
xf86ConfigDRI.bufs[i].size,
- 0 /* flags */)) <= 0) {
+ 0, /* flags */
+ 0 /* offset */)) <= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failure adding %d %d byte DMA buffers\n",
xf86ConfigDRI.bufs[i].count,
@@ -530,7 +531,8 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
if ((bufs = drmAddBufs(pGlint->drmSubFD,
GLINT_DRI_BUF_COUNT,
GLINT_DRI_BUF_SIZE,
- 0 /* flags */)) <= 0) {
+ 0, /* flags */
+ 0 /* offset */)) <= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] failure adding %d %d byte DMA buffers\n",
GLINT_DRI_BUF_COUNT,
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile
index 331396f38..1a960e964 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile
@@ -11,8 +11,8 @@ XCOMM
#
#undef BuildXF86DRI
#if BuildXF86DRI
-DRISRCS = i810_dri.c i810_drm.c
-DRIOBJS = i810_dri.o i810_drm.o
+DRISRCS = i810_dri.c
+DRIOBJS = i810_dri.o
DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \
-I$(XF86OSSRC)/linux/drm/kernel
DRIDEFINES = $(GLX_DEFINES)
@@ -63,7 +63,6 @@ InstallDriverSDKNonExecFile(i810_cursor.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_driver.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_dri.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_dri.h,$(DRIVERSDKDIR)/drivers/i810)
-InstallDriverSDKNonExecFile(i810_dripriv.h,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_io.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_memory.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_wmark.c,$(DRIVERSDKDIR)/drivers/i810)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h
index 6aceea540..6bb176f9f 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h
@@ -36,7 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _I810_H_
#define _I810_H_
-
+#include "compiler.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "i810_reg.h"
@@ -211,8 +211,8 @@ typedef struct _I810Rec {
extern Bool I810DRIScreenInit(ScreenPtr pScreen);
extern void I810DRICloseScreen(ScreenPtr pScreen);
extern Bool I810DRIFinishScreenInit(ScreenPtr pScreen);
-extern Bool I810drmInitDma(ScrnInfoPtr pScrn);
-extern Bool I810drmCleanupDma(ScrnInfoPtr pScrn);
+extern Bool I810InitDma(ScrnInfoPtr pScrn);
+extern Bool I810CleanupDma(ScrnInfoPtr pScrn);
#define I810PTR(p) ((I810Ptr)((p)->driverPrivate))
#define I810REGPTR(p) (&(I810PTR(p)->ModeReg))
@@ -312,7 +312,7 @@ extern void I810EmitInvarientState(ScrnInfoPtr pScrn);
/* To remove all debugging, make sure I810_DEBUG is defined as a
* preprocessor symbol, and equal to zero.
*/
-#define I810_DEBUG 0
+#define I810_DEBUG 0
#ifndef I810_DEBUG
#warning "Debugging enabled - expect reduced performance"
extern int I810_DEBUG;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c
index 0f67180d2..5c90fc88a 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c
@@ -301,13 +301,9 @@ I810Sync( ScrnInfoPtr pScrn )
#ifdef XF86DRI
/* VT switching tries to do this.
*/
- if (!pI810->LockHeld) {
+ if (!pI810->LockHeld && pI810->directRenderingEnabled) {
return;
}
-
-
-/* if (pI810->directRenderingEnabled) */
-/* DRIUnlockLockQueiscent( pScrn->pScreen ); */
#endif
/* Send a flush instruction and then wait till the ring is empty.
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
index 5bb1b3191..48adc170a 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
@@ -20,10 +20,6 @@
#include "i810.h"
#include "i810_dri.h"
-#include "xf86drm.h"
-#include "dristruct.h"
-
-
static char I810KernelDriverName[] = "i810";
static char I810ClientDriverName[] = "i810";
@@ -62,6 +58,29 @@ static int i810_pitch_flags[] = {
0
};
+Bool I810CleanupDma(ScrnInfoPtr pScrn)
+{
+ I810Ptr pI810 = I810PTR(pScrn);
+ Bool ret_val;
+
+ ret_val = drmI810CleanupDma(pI810->drmSubFD);
+ if(ret_val == FALSE) ErrorF("I810 Dma Cleanup Failed\n");
+ return ret_val;
+}
+
+Bool I810InitDma(ScrnInfoPtr pScrn)
+{
+ I810Ptr pI810 = I810PTR(pScrn);
+ I810RingBuffer *ring = &(pI810->LpRing);
+ Bool ret_val;
+
+ ret_val = drmI810InitDma(pI810->drmSubFD, ring->mem.Start,
+ ring->mem.End, ring->mem.Size,
+ 6, 5, sizeof(XF86DRISAREARec));
+ if(ret_val == FALSE) ErrorF("I810 Dma Initialization Failed\n");
+ return ret_val;
+}
+
static Bool
I810InitVisualConfigs(ScreenPtr pScreen)
{
@@ -260,8 +279,13 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
int width = pScrn->displayWidth * pI810->cpp;
int i;
- /* ToDo : save agpHandles? */
-
+#if XFree86LOADER
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ * for canonical symbols in each module. */
+ if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE;
+ if (!LoaderSymbol("DRIScreenInit")) return FALSE;
+ if (!LoaderSymbol("drmAvailable")) return FALSE;
+#endif
pDRIInfo = DRICreateInfoRec();
if (!pDRIInfo) {
@@ -302,7 +326,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
/* For now the mapping works by using a fixed size defined
* in the SAREA header
*/
- if (sizeof(XF86DRISAREARec)+sizeof(drm_i810_sarea_t)>SAREA_MAX) {
+ if (sizeof(XF86DRISAREARec)+sizeof(I810SAREARec)>SAREA_MAX) {
ErrorF("Data does not fit in SAREA\n");
return FALSE;
}
@@ -378,9 +402,10 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
* under the DRI.
*/
- dcacheHandle = drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL);
+ drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, &dcacheHandle);
pI810->dcacheHandle = dcacheHandle;
+ ErrorF("dcacheHandle : %p\n", dcacheHandle);
#define Elements(x) sizeof(x)/sizeof(*x)
for (pitch_idx = 0 ; pitch_idx < Elements(i810_pitches) ; pitch_idx++)
@@ -392,10 +417,12 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
"Couldn't find depth/back buffer pitch");
DRICloseScreen(pScreen);
return FALSE;
- }
- else {
- back_size = i810_pitches[pitch_idx] * pScrn->virtualY;
+ } else {
+ back_size = i810_pitches[pitch_idx] * (pScrn->virtualY + 4);
+ ErrorF("back_size: %d\n", back_size);
+ /* Round to 4k */
back_size = ((back_size + 4096 - 1) / 4096) * 4096;
+ ErrorF("back_size 2 : %d\n", back_size);
}
sysmem_size = pScrn->videoRam * 1024;
@@ -411,6 +438,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
} else {
sysmem_size = sysmem_size - 2*back_size;
}
+ ErrorF("sysmem_size : %d\n", sysmem_size);
sysmem_size -= 4096;
if(sysmem_size > ((48*1024*1024) - 1) ) {
@@ -428,6 +456,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
if (dcacheHandle != 0) {
/* The Z buffer is always aligned to the 48 mb mark in the aperture */
+ ErrorF("dcacheHandle : %p, aligned to : %lx\n",
+ dcacheHandle, 48*1024*1024);
if(drmAgpBind(pI810->drmSubFD, dcacheHandle, 48*1024*1024) == 0) {
xf86memset (&pI810->DcacheMem, 0, sizeof(I810MemRange));
@@ -454,11 +484,12 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: no dcache memory found\n");
}
- agpHandle = drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL);
+ drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, &agpHandle);
pI810->backHandle = agpHandle;
if(agpHandle != 0) {
/* The backbuffer is always aligned to the 56 mb mark in the aperture */
+ ErrorF("agpHandle : %p, aligned to : %lx\n", agpHandle, 56*1024*1024);
if(drmAgpBind(pI810->drmSubFD, agpHandle, 56*1024*1024) == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Bound backbuffer memory\n");
@@ -481,11 +512,14 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
if(dcacheHandle == 0) {
/* The Z buffer is always aligned to the 48 mb mark in the aperture */
- agpHandle = drmAgpAlloc(pI810->drmSubFD, back_size, 0,
- NULL);
+ drmAgpAlloc(pI810->drmSubFD, back_size, 0,
+ NULL, &agpHandle);
pI810->zHandle = agpHandle;
if(agpHandle != 0) {
+ ErrorF("agpHandle : %p, aligned to : %lx\n", dcacheHandle,
+ 48*1024*1024);
+
if(drmAgpBind(pI810->drmSubFD, agpHandle, 48*1024*1024) == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bound depthbuffer memory\n");
pI810->DepthBuffer.Start = 48*1024*1024;
@@ -510,7 +544,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
* regular framebuffer as well as texture memory.
*/
- agpHandle = drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL);
+ drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, &agpHandle);
if(agpHandle == 0) {
ErrorF("drmAgpAlloc failed\n");
DRICloseScreen(pScreen);
@@ -524,8 +558,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
- agpHandle = drmAgpAlloc(pI810->drmSubFD, 4096, 2,
- (unsigned long *)&pI810->CursorPhysical);
+ drmAgpAlloc(pI810->drmSubFD, 4096, 2,
+ (unsigned long *)&pI810->CursorPhysical, &agpHandle);
pI810->cursorHandle = agpHandle;
if (agpHandle != 0) {
@@ -536,6 +570,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
"GART: Allocated 4K for mouse cursor image\n");
pI810->CursorStart = tom;
tom += 4096;
+ ErrorF("tom : %lx\n", tom);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: cursor bind failed\n");
pI810->CursorPhysical = 0;
@@ -545,16 +580,19 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810->CursorPhysical = 0;
}
+ ErrorF("i : %d pI810->DepthBuffer %x\n", pitch_idx, pI810->DepthBuffer);
I810SetTiledMemory(pScrn, 1,
pI810->DepthBuffer.Start,
i810_pitches[pitch_idx],
8*1024*1024);
+ ErrorF("i : %d\n", pitch_idx);
I810SetTiledMemory(pScrn, 2,
pI810->BackBuffer.Start,
i810_pitches[pitch_idx],
8*1024*1024);
+ ErrorF("i : %d\n", pitch_idx);
pI810->auxPitch = i810_pitches[pitch_idx];
pI810->auxPitchBits = i810_pitch_flags[pitch_idx];
@@ -562,6 +600,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810->SavedDcacheMem = pI810->DcacheMem;
pI810DRI->backbufferSize = pI810->BackBuffer.Size;
+ ErrorF("Backbuffer map : %lx\n", pI810->BackBuffer.Start);
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->BackBuffer.Start,
pI810->BackBuffer.Size, DRM_AGP, 0,
&pI810DRI->backbuffer) < 0) {
@@ -570,6 +609,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
+ ErrorF("Depth map : %lx\n", pI810->DepthBuffer.Start);
pI810DRI->depthbufferSize = pI810->DepthBuffer.Size;
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->DepthBuffer.Start,
pI810->DepthBuffer.Size, DRM_AGP, 0,
@@ -586,6 +626,15 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
I810AllocHigh( &(pI810->BufferMem), &(pI810->SysMem),
I810_DMA_BUF_NR * I810_DMA_BUF_SZ);
+ ErrorF("Buffer map : %lx\n", pI810->BufferMem.Start);
+
+ if(pI810->BufferMem.Start == 0 ||
+ pI810->BufferMem.End - pI810->BufferMem.Start >
+ I810_DMA_BUF_NR * I810_DMA_BUF_SZ) {
+ ErrorF("Not enough memory for dma buffers\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
if(drmAddMap(pI810->drmSubFD, (drmHandle)pI810->BufferMem.Start,
pI810->BufferMem.Size, DRM_AGP, 0,
&pI810->buffer_map) < 0) {
@@ -597,6 +646,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->agp_buffers = pI810->buffer_map;
pI810DRI->agp_buf_size = pI810->BufferMem.Size;
+ ErrorF("Ring map : %lx\n", pI810->LpRing.mem.Start);
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->LpRing.mem.Start,
pI810->LpRing.mem.Size, DRM_AGP, 0,
&pI810->ring_map) < 0) {
@@ -608,6 +658,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
/* Use the rest of memory for textures. */
pI810DRI->textureSize = pI810->SysMem.Size;
+ ErrorF("INITIAL texsize: %x\n", pI810DRI->textureSize);
i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS);
@@ -617,6 +668,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->logTextureGranularity = i;
pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */
+ ErrorF("REDUCED texsize: %x (i: %d)\n", pI810DRI->textureSize, i);
if(pI810DRI->textureSize < 512*1024) {
ErrorF("Less then 512k for textures\n");
@@ -625,8 +677,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
I810AllocLow( &(pI810->TexMem), &(pI810->SysMem),
pI810DRI->textureSize);
-
+ ErrorF("Texture map : %lx\n", pI810->TexMem.Start);
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->TexMem.Start,
pI810->TexMem.Size, DRM_AGP, 0,
&pI810DRI->textures) < 0) {
@@ -635,6 +687,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
+ ErrorF("pI810->BufferMem.Start : %lx\n", pI810->BufferMem.Start);
if((bufs = drmAddBufs(pI810->drmSubFD,
I810_DMA_BUF_NR,
I810_DMA_BUF_SZ,
@@ -650,7 +703,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] added %d %d byte DMA buffers\n",
bufs, I810_DMA_BUF_SZ);
- I810drmInitDma(pScrn);
+ I810InitDma(pScrn);
/* Okay now initialize the dma engine */
@@ -718,7 +771,7 @@ I810DRICloseScreen(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I810Ptr pI810 = I810PTR(pScrn);
- I810drmCleanupDma(pScrn);
+ I810CleanupDma(pScrn);
if(pI810->dcacheHandle) drmAgpFree(pI810->drmSubFD, pI810->dcacheHandle);
if(pI810->backHandle) drmAgpFree(pI810->drmSubFD, pI810->backHandle);
@@ -768,7 +821,7 @@ I810DestroyContext(ScreenPtr pScreen, drmContext hwContext,
Bool
I810DRIFinishScreenInit(ScreenPtr pScreen)
{
- drm_i810_sarea_t *sPriv = (drm_i810_sarea_t *)DRIGetSAREAPrivate(pScreen);
+ I810SAREARec *sPriv = (I810SAREARec *)DRIGetSAREAPrivate(pScreen);
xf86memset( sPriv, 0, sizeof(sPriv) );
return DRIFinishScreenInit(pScreen);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h
index e593f36b2..506227222 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h
@@ -4,7 +4,7 @@
#define _I810_DRI_
#include <xf86drm.h>
-#include "i810_drm_public.h"
+#include <xf86drmI810.h>
#define I810_MAX_DRAWABLES 256
@@ -53,6 +53,45 @@ typedef struct {
} I810DRIRec, *I810DRIPtr;
+/* WARNING: Do not change the SAREA structure without changing the kernel
+ * as well */
+
+typedef struct {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} I810TexRegionRec, *I810TexRegionPtr;
+
+typedef struct {
+ unsigned int nbox;
+ XF86DRIClipRectRec boxes[I810_NR_SAREA_CLIPRECTS];
+
+ /* Maintain an LRU of contiguous regions of texture space. If
+ * you think you own a region of texture memory, and it has an
+ * age different to the one you set, then you are mistaken and
+ * it has been stolen by another client. If global texAge
+ * hasn't changed, there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained
+ * texture information of other clients - by maintaining them
+ * in the same lru which is used to age their own textures,
+ * clients have an approximate lru for the whole of global
+ * texture space, and can make informed decisions as to which
+ * areas to kick out. There is no need to choose whether to
+ * kick out your own texture or someone else's - simply eject
+ * them all in LRU order.
+ */
+ I810TexRegionRec texList[I810_NR_TEX_REGIONS+1]; /* Last elt is sentinal */
+
+ int texAge; /* last time texture was uploaded */
+
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+
+ int ctxOwner; /* last context to upload state */
+} I810SAREARec, *I810SAREAPtr;
+
typedef struct {
/* Nothing here yet */
int dummy;
@@ -63,5 +102,4 @@ typedef struct {
int dummy;
} I810DRIContextRec, *I810DRIContextPtr;
-
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h
deleted file mode 100644
index b4bbab133..000000000
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dripriv.h,v 1.1 2000/03/02 16:07:50 martin Exp $ */
-
-#ifndef _I810_DRIPRIV_H_
-#define _I810_DRIPRIV_H_
-
-#define I810_MAX_DRAWABLES 256
-
-extern void GlxSetVisualConfigs(
- int nconfigs,
- __GLXvisualConfig *configs,
- void **configprivs
-);
-
-typedef struct {
- /* Nothing here yet */
- int dummy;
-} I810ConfigPrivRec, *I810ConfigPrivPtr;
-
-typedef struct {
- /* Nothing here yet */
- int dummy;
-} I810DRIContextRec, *I810DRIContextPtr;
-
-#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
index e489d17c9..e43685559 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
@@ -207,31 +207,19 @@ static const char *ramdacSymbols[] = {
#ifdef XF86DRI
static const char *drmSymbols[] = {
+ "drmAvailable",
"drmAddBufs",
"drmAddMap",
- "drmAvailable",
- "drmCtlAddCommand",
"drmCtlInstHandler",
"drmGetInterruptFromBusID",
- "drmMapBufs",
- "drmMarkBufs",
- "drmUnmapBufs",
"drmAgpAcquire",
"drmAgpRelease",
"drmAgpEnable",
"drmAgpAlloc",
"drmAgpFree",
"drmAgpBind",
- "drmAgpUnbind",
- "drmAgpVersionMajor",
- "drmAgpVersionMinor",
- "drmAgpGetMode",
- "drmAgpBase",
- "drmAgpSize",
- "drmAgpMemoryUsed",
- "drmAgpMemoryAvail",
- "drmAgpVendorId",
- "drmAgpDeviceId",
+ "drmI810CleanupDma",
+ "drmI810InitDma",
NULL
};
@@ -1551,9 +1539,16 @@ I810AllocateFront(ScrnInfoPtr pScrn) {
pI810->FbMemBox.y2 *
pI810->cpp) + 4095) & ~4095);
+ fprintf(stderr, "Framebuffer %x, size %x\n",
+ pI810->FrontBuffer.Start,
+ pI810->FrontBuffer.Size);
+
+ fprintf(stderr, "DisplayWidth %x, virtualX %x\n",
+ pScrn->displayWidth,
+ pScrn->virtualX);
+
xf86memset( &(pI810->LpRing), 0, sizeof( I810RingBuffer ) );
if(I810AllocLow( &(pI810->LpRing.mem), &(pI810->SysMem), 16*4096 )) {
-
if (I810_DEBUG & DEBUG_VERBOSE_MEMORY)
ErrorF( "ring buffer at local %lx\n",
pI810->LpRing.mem.Start);
@@ -1607,6 +1602,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
/* Have to init the DRM earlier than in other drivers to get agp
* memory. Wonder if this is going to be a problem...
*/
+
#ifdef XF86DRI
/*
* Setup DRI after visuals have been established, but before cfbScreenInit
@@ -1625,7 +1621,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
return FALSE;
I810AllocateFront(pScrn);
#endif
-
+
if (!I810MapMem(pScrn)) return FALSE;
pScrn->memPhysBase = (int)pI810->FbBase;
@@ -1729,6 +1725,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
}
}
#endif
+
#ifdef XF86DRI
if (!pI810->directRenderingEnabled) {
pI810->DoneFrontAlloc = FALSE;
@@ -1738,6 +1735,14 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
}
#endif
+ ErrorF("InitFB box: %d,%d-%d,%d virt: %d,%d\n",
+ pI810->FbMemBox.x1,
+ pI810->FbMemBox.y1,
+ pI810->FbMemBox.x2,
+ pI810->FbMemBox.y2,
+ pScrn->virtualX,
+ pScrn->virtualY);
+
if (!xf86InitFBManager(pScreen, &(pI810->FbMemBox))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
@@ -1762,7 +1767,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
}
}
-#if XF86DRI
+#ifdef XF86DRI
if (pI810->LpRing.mem.Start == 0) {
pI810->directRenderingEnabled = 0;
I810DRICloseScreen(pScreen);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h
deleted file mode 100644
index 0f70d3535..000000000
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_sarea.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef I810_SAPRIV_H
-#define I810_SAPRIV_H
-
-#include "i810_drm_public.h"
-
-#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile
index e9a42442d..c11f6a457 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile
@@ -1,4 +1,4 @@
-XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.26 1999/08/21 13:48:34 dawes Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.32 2000/02/28 19:53:12 alanh Exp $
XCOMM
XCOMM This is an Imakefile for the MGA driver.
XCOMM
@@ -6,26 +6,37 @@ XCOMM
#define IHaveModules
#include <Server.tmpl>
+#if BuildXF86DRI
+DRISRCS = mga_dri.c mga_warp.c mga_wrap.c
+DRIOBJS = mga_dri.o mga_warp.o mga_wrap.o
+DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \
+ -I$(XF86OSSRC)/linux/drm/kernel
+DRIDEFINES = $(GLX_DEFINES)
+#endif
+
SRCS = mga_driver.c mga_hwcurs.c /* mga_cmap.c */ mga_dac3026.c mga_dacG.c \
mga_storm8.c mga_storm16.c mga_storm24.c mga_storm32.c mga_arc.c \
- mga_dga.c mga_shadow.c
+ mga_dga.c mga_shadow.c mga_video.c $(DRISRCS)
OBJS = mga_driver.o mga_hwcurs.o /* mga_cmap.o */ mga_dac3026.o mga_dacG.o \
mga_storm8.o mga_storm16.o mga_storm24.o mga_storm32.o mga_arc.o \
- mga_dga.o mga_shadow.o
+ mga_dga.o mga_shadow.o mga_video.o $(DRIOBJS)
#if defined(XF86DriverSDK)
INCLUDES = -I. -I../../include
#else
INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
- -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(XF86SRC)/int10 \
-I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \
-I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \
-I$(XF86SRC)/ramdac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
-I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\
-I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
- -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC)
+ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) \
+ -I$(XF86OSSRC)/vbe $(DRIINCLUDES)
#endif
+DEFINES = $(DRIDEFINES)
+
#if MakeHasPosixVariableSubstitutions
SubdirLibraryRule($(OBJS))
#endif
@@ -62,6 +73,7 @@ InstallDriverSDKNonExecFile(mga_map.h,$(DRIVERSDKDIR)/drivers/mga)
InstallDriverSDKNonExecFile(mga_reg.h,$(DRIVERSDKDIR)/drivers/mga)
InstallDriverSDKNonExecFile(mga_shadow.c,$(DRIVERSDKDIR)/drivers/mga)
InstallDriverSDKNonExecFile(mga_storm.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_video.c,$(DRIVERSDKDIR)/drivers/mga)
InstallDriverSDKObjectModule(mga,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h
index bc927c8a4..5e0430616 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.47 1999/08/22 05:57:33 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.57 2000/02/27 02:50:47 mvojkovi Exp $ */
/*
* MGA Millennium (MGA2064W) functions
*
@@ -14,21 +14,32 @@
#ifndef MGA_H
#define MGA_H
+#include "compiler.h"
#include "xaa.h"
#include "xf86Cursor.h"
#include "vgaHW.h"
#include "colormapst.h"
#include "xf86DDC.h"
+#include "xf86xv.h"
-#if defined(__alpha__)
-#define INREG8(addr) xf86ReadSparse8(pMga->IOBase, (addr))
-#define INREG16(addr) xf86ReadSparse16(pMga->IOBase, (addr))
-#define INREG(addr) xf86ReadSparse32(pMga->IOBase, (addr))
-#define OUTREG8(addr,val) xf86WriteSparse8((val),pMga->IOBase,(addr))
-#define OUTREG16(addr,val) xf86WriteSparse16((val),pMga->IOBase,(addr))
-#define OUTREG(addr, val) xf86WriteSparse32((val),pMga->IOBase,(addr))
-#else /* __alpha__ */
-#if defined(EXTRADEBUG)
+#ifdef XF86DRI
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#include "mga_dri.h"
+#endif
+
+#if !defined(EXTRADEBUG)
+#define INREG8(addr) MMIO_IN8(pMga->IOBase, addr)
+#define INREG16(addr) MMIO_IN16(pMga->IOBase, addr)
+#define INREG(addr) MMIO_IN32(pMga->IOBase, addr)
+#define OUTREG8(addr, val) MMIO_OUT8(pMga->IOBase, addr, val)
+#define OUTREG16(addr, val) MMIO_OUT16(pMga->IOBase, addr, val)
+#define OUTREG(addr, val) MMIO_OUT32(pMga->IOBase, addr, val)
+#else /* !EXTRADEBUG */
CARD8 dbg_inreg8(ScrnInfoPtr,int,int);
CARD16 dbg_inreg16(ScrnInfoPtr,int,int);
CARD32 dbg_inreg32(ScrnInfoPtr,int,int);
@@ -41,15 +52,7 @@ void dbg_outreg32(ScrnInfoPtr,int,int);
#define OUTREG8(addr,val) dbg_outreg8(pScrn,addr,val)
#define OUTREG16(addr,val) dbg_outreg16(pScrn,addr,val)
#define OUTREG(addr,val) dbg_outreg32(pScrn,addr,val)
-#else /* EXTRADEBUG */
-#define INREG8(addr) *(volatile CARD8 *)(pMga->IOBase + (addr))
-#define INREG16(addr) *(volatile CARD16 *)(pMga->IOBase + (addr))
-#define INREG(addr) *(volatile CARD32 *)(pMga->IOBase + (addr))
-#define OUTREG8(addr, val) *(volatile CARD8 *)(pMga->IOBase + (addr)) = (val)
-#define OUTREG16(addr, val) *(volatile CARD16 *)(pMga->IOBase + (addr)) = (val)
-#define OUTREG(addr, val) *(volatile CARD32 *)(pMga->IOBase + (addr)) = (val)
#endif /* EXTRADEBUG */
-#endif /* __alpha__ */
#define PORT_OFFSET (0x1F00 - 0x300)
@@ -62,6 +65,7 @@ typedef struct {
CARD32 Option3;
} MGARegRec, *MGARegPtr;
+
typedef struct {
Bool isHwCursor;
int CursorMaxWidth;
@@ -93,6 +97,7 @@ typedef struct {
int displayWidth;
rgb weight;
Bool Overlay8Plus24;
+ DisplayModePtr mode;
} MGAFBLayout;
@@ -133,9 +138,7 @@ typedef struct {
CARD32 BiosAddress;
MessageType BiosFrom;
unsigned char * IOBase;
-#ifdef __alpha__
unsigned char * IOBaseDense;
-#endif
unsigned char * FbBase;
unsigned char * ILOADBase;
unsigned char * FbStart;
@@ -170,6 +173,8 @@ typedef struct {
CARD32 PlaneMask;
CARD32 FgColor;
CARD32 BgColor;
+ CARD32 MAccess;
+ int FifoSize;
int StyleLen;
XAAInfoRecPtr AccelInfoRec;
xf86CursorInfoPtr CursorInfoRec;
@@ -185,19 +190,43 @@ typedef struct {
Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
void (*PointerMoved)(int index, int x, int y);
CloseScreenProcPtr CloseScreen;
+ ScreenBlockHandlerProcPtr BlockHandler;
unsigned int (*ddc1Read)(ScrnInfoPtr);
void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed);
Bool (*i2cInit)(ScrnInfoPtr);
I2CBusPtr I2C;
Bool FBDev;
int colorKey;
+ int videoKey;
int fifoCount;
int Rotate;
MGAFBLayout CurrentLayout;
Bool DrawTransparent;
int MaxBlitDWORDS;
+
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmSubFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ MGAConfigPrivPtr pVisualConfigsPriv;
+ MGARegRec DRContextRegs;
+ MGADRIServerPrivatePtr DRIServerInfo;
+ Bool have_quiescense;
+#endif
+
+ XF86VideoAdaptorPtr adaptor;
} MGARec, *MGAPtr;
+#ifdef XF86DRI
+extern void GlxSetVisualConfigs(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs
+);
+#endif
+
extern CARD32 MGAAtype[16];
extern CARD32 MGAAtypeNoBLK[16];
@@ -211,11 +240,17 @@ extern CARD32 MGAAtypeNoBLK[16];
#define MGA_NO_PLANEMASK 0x00000080
#define USE_LINEAR_EXPANSION 0x00000100
#define LARGE_ADDRESSES 0x00000200
-
+#define MGAIOMAPSIZE 0x00004000
+#define MGAILOADMAPSIZE 0x00400000
#define TRANSPARENCY_KEY 255
#define KEY_COLOR 0
+#define MGA_FRONT 0x1
+#define MGA_BACK 0x2
+#define MGA_DEPTH 0x4
+
+
/* Prototypes */
void MGAAdjustFrame(int scrnIndex, int x, int y, int flags);
@@ -238,6 +273,18 @@ void MGAPolyArcThinSolid(DrawablePtr, GCPtr, int, xArc*);
Bool MGADGAInit(ScreenPtr pScreen);
+Bool MGADRIScreenInit(ScreenPtr pScreen);
+void MGADRICloseScreen(ScreenPtr pScreen);
+Bool MGADRIFinishScreenInit(ScreenPtr pScreen);
+void MGASwapContext(ScreenPtr pScreen);
+void MGASelectBuffer(ScrnInfoPtr pScrn, int which);
+Bool mgaConfigureWarp(ScrnInfoPtr pScrn);
+unsigned int mgaInstallMicrocode(ScreenPtr pScreen, int agp_offset);
+unsigned int mgaGetMicrocodeSize(ScreenPtr pScreen);
+Bool MgaCleanupDma(ScrnInfoPtr pScrn);
+Bool MgaInitDma(ScrnInfoPtr pScrn, int prim_size);
+Bool MgaLockUpdate(ScrnInfoPtr pScrn, drmLockFlags flags);
+
void MGARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void MGARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void MGARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
@@ -268,4 +315,7 @@ void Mga32SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
void MGAPointerMoved(int index, int x, int y);
+void MGAInitVideo(ScreenPtr pScreen);
+void MGAResetVideo(ScrnInfoPtr pScrn);
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c
index 2844302ff..993d763a8 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c
@@ -69,6 +69,8 @@ MGAZeroArc(
Bool do360;
DDXPointRec org, orgo;
+ CHECK_DMA_QUIESCENT( pMga, infoRec->pScrn );
+
(*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel,
pGC->alu, pGC->planemask);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c
index f9a07ade3..fb7952211 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.48 1999/08/21 13:48:35 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.52 2000/01/21 01:12:20 dawes Exp $ */
/*
* Copyright 1994 by Robin Cutshaw <robin@XFree86.org>
*
@@ -49,6 +49,7 @@
#include "mga_bios.h"
#include "mga_reg.h"
+#include "mga_macros.h"
#include "mga.h"
#include "xf86DDC.h"
@@ -85,17 +86,33 @@ const static unsigned char MGADACregs[] = {
0x06
};
+/* note: to fix a cursor hw glitch, register 0x37 (blue color key) needs
+ to be set to magic numbers, even though they are "never" used because
+ blue keying disabled in 0x38.
+
+ Matrox sez:
+
+ ...The more precise statement of the software workaround is to insure
+ that bits 7-5 of register 0x37 (Blue Color Key High) and bits 7-5 of
+ register 0x38 (HZOOM)are the same...
+*/
+
+/* also note: the values of the MUX control register 0x19 (index [2]) can be
+ found in table 2-17 of the 3026 manual. If interlace is set, the values
+ listed here are incremented by one.
+*/
+
#define DACREGSIZE sizeof(MGADACregs)
/*
* initial values of ti3026 registers
*/
const static unsigned char MGADACbpp8[DACREGSIZE] = {
- 0x06, 0x80, 0x48, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF,
+ 0x06, 0x80, 0x4b, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0, 0x00,
0x00
};
const static unsigned char MGADACbpp16[DACREGSIZE] = {
- 0x07, 0x45, 0x50, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
+ 0x07, 0x45, 0x53, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00,
0x00
};
@@ -103,18 +120,29 @@ const static unsigned char MGADACbpp16[DACREGSIZE] = {
* [0] value was 0x07, but changed to 0x06 by Doug Merrit to fix high res
* stripe glitches and clock glitches at 24bpp.
*/
+/* [0] value is now set inside of MGA3026Init, based on the silicon revision
+ It is still set to 7 or 6 based on the revision, though, since setting to
+ 8 as in the documentation makes (some?) revB chips get the colors wrong...
+ maybe BGR instead of RGB? This only applies to 24bpp, since it is the only
+ one documented as depending on revision.
+ */
+
const static unsigned char MGADACbpp24[DACREGSIZE] = {
- 0x06, 0x56, 0x58, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
+ 0x06, 0x56, 0x5b, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00,
0x00
};
const static unsigned char MGADACbpp32[DACREGSIZE] = {
- 0x07, 0x46, 0x58, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
+ 0x07, 0x46, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00,
0x00
};
+
+/* on at least some 2064Ws, the PSEL line flips at 4MB or so, so PSEL keying
+ has to be off in register 0x1e -> bit4 clear */
+
const static unsigned char MGADACbpp8plus24[DACREGSIZE] = {
- 0x07, 0x06, 0x58, 0x05, 0x00, 0x00, 0x3C, 0x00, 0x1E, 0xFF,
+ 0x07, 0x06, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00,
0x00
};
@@ -523,7 +551,31 @@ MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
&& (pLayout->weight.green == 5) && (pLayout->weight.blue == 5) ) {
pReg->DacRegs[1] &= ~0x01;
}
- pReg->DacRegs[2] |= pMga->Interleave? 0x04 : 0x03;
+ if (pMga->Interleave ) pReg->DacRegs[2] += 1;
+
+
+ if ( pLayout->bitsPerPixel == 24 ) {
+ int silicon_rev;
+ /* we need to set DacRegs[0] differently based on the silicon
+ * revision of the 3026 RAMDAC, as per page 2-14 of tvp3026.pdf.
+ * If we have rev A silicon, we want 0x07; rev B silicon wants
+ * 0x06.
+ */
+ silicon_rev = inTi3026(TVP3026_SILICON_REV);
+
+#ifdef DEBUG
+ ErrorF("TVP3026 revision 0x%x (rev %s)\n",
+ silicon_rev, (silicon_rev <= 0x20) ? "A" : "B");
+#endif
+
+ if(silicon_rev <= 0x20) {
+ /* rev A */
+ pReg->DacRegs[0] = 0x07;
+ } else {
+ /* rev B */
+ pReg->DacRegs[0] = 0x06;
+ }
+ }
/*
* This will initialize all of the generic VGA registers.
@@ -652,10 +704,9 @@ MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
else
pReg->Option &= ~0x1000;
- if(pMga->UsePCIRetry)
- pReg->Option &= ~0x20000000;
- else
- pReg->Option |= 0x20000000;
+ /* must always have the pci retries on but rely on
+ polling to keep them from occuring */
+ pReg->Option &= ~0x20000000;
pVga->MiscOutReg |= 0x0C;
/* XXX Need to check the first argument */
@@ -694,6 +745,8 @@ MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
int i;
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT( pMga, pScrn );
+
/*
* Code is needed to get things back to bank zero.
*/
@@ -771,6 +824,8 @@ MGA3026Save(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
int i;
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT( pMga, pScrn );
+
/* Allocate the DacRegs space if not done already */
if (mgaReg->DacRegs == NULL) {
mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
@@ -1034,14 +1089,29 @@ MGA3026RamdacInit(ScrnInfoPtr pScrn)
break;
}
/* Set MCLK based on amount of memory */
- if ( pScrn->videoRam < 4096 )
+ if(pMga->OverclockMem) {
+ if ( pScrn->videoRam < 4096 )
+ MGAdac->MemoryClock = pMga->Bios.ClkBase * 12;
+ else if ( pScrn->videoRam < 8192 )
+ MGAdac->MemoryClock = pMga->Bios.Clk4MB * 12;
+ else
+ MGAdac->MemoryClock = pMga->Bios.Clk8MB * 12;
+ MGAdac->MemClkFrom = X_CONFIG;
+ MGAdac->SetMemClk = TRUE;
+#if 0
+ ErrorF("BIOS Memory clock settings: 2Mb %d, 4Mb %d, 8MB %d\n",
+ pMga->Bios.ClkBase, pMga->Bios.Clk4MB, pMga->Bios.Clk8MB);
+#endif
+ } else {
+ if ( pScrn->videoRam < 4096 )
MGAdac->MemoryClock = pMga->Bios.ClkBase * 10;
- else if ( pScrn->videoRam < 8192 )
+ else if ( pScrn->videoRam < 8192 )
MGAdac->MemoryClock = pMga->Bios.Clk4MB * 10;
- else
+ else
MGAdac->MemoryClock = pMga->Bios.Clk8MB * 10;
- MGAdac->MemClkFrom = X_PROBED;
- MGAdac->SetMemClk = TRUE;
+ MGAdac->MemClkFrom = X_PROBED;
+ MGAdac->SetMemClk = TRUE;
+ }
}
else
{
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c
index 1cfa03f31..d81d12b3a 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c
@@ -2,7 +2,7 @@
* MGA-1064, MGA-G100, MGA-G200, MGA-G400 RAMDAC driver
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.30 1999/08/22 05:57:33 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.33 1999/12/03 04:03:52 mvojkovi Exp $ */
/*
* This is a first cut at a non-accelerated version to work with the
@@ -24,6 +24,7 @@
#include "mga_bios.h"
#include "mga_reg.h"
+#include "mga_macros.h"
#include "mga.h"
#include "xf86DDC.h"
@@ -330,24 +331,40 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
pReg->Option2 = 0x0000007;
break;
case PCI_CHIP_MGAG400:
- if(pMga->OverclockMem) {
- /* 166 Mhz but faster graphics engine clock */
- pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13;
- pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A;
- pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08;
- pReg->Option3 = 0x0190a421;
+ if(pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */
+ if(pMga->OverclockMem) {
+ /* 150/200 */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x05;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x42;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
+ pReg->Option3 = 0x019B8419;
+ pReg->Option = 0x50574120;
+ } else {
+ /* 125/166 */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
+ pReg->Option3 = 0x019B8419;
+ pReg->Option = 0x5053C120;
+ }
} else {
- /* 165 Mhz */
- pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x09;
- pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x3C;
- pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10;
- pReg->Option3 = 0x0190a419;
- }
+ if(pMga->OverclockMem) {
+ /* 125/166 */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
+ pReg->Option3 = 0x019B8419;
+ pReg->Option = 0x5053C120;
+ } else {
+ /* 110/166 */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08;
+ pReg->Option3 = 0x0190a421;
+ pReg->Option = 0x50044120;
+ }
+ }
pReg->Option2 = 0x01003000;
- if(pMga->HasSDRAM)
- pReg->Option = 0x50040120;
- else
- pReg->Option = 0x50044120;
break;
case PCI_CHIP_MGAG200:
case PCI_CHIP_MGAG200_PCI:
@@ -371,10 +388,9 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
break;
}
- if(pMga->UsePCIRetry)
- pReg->Option &= ~0x20000000;
- else
- pReg->Option |= 0x20000000;
+ /* must always have the pci retries on but rely on
+ polling to keep them from occuring */
+ pReg->Option &= ~0x20000000;
switch(pLayout->bitsPerPixel)
{
@@ -579,6 +595,8 @@ MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
int i;
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT( pMga, pScrn );
+
/*
* Code is needed to get things back to bank zero.
*/
@@ -656,6 +674,8 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
int i;
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT( pMga, pScrn );
+
/* Allocate the DacRegs space if not done already */
if (mgaReg->DacRegs == NULL) {
mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
@@ -749,6 +769,9 @@ MGAGSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
x += 64;
y += 64;
+ /* This doesn't require DMA quiescence (what about flush?)
+ */
+
/* cursor update must never occurs during a retrace period (pp 4-160) */
while( INREG( MGAREG_Status ) & 0x08 );
@@ -915,7 +938,12 @@ MGAGRamdacInit(ScrnInfoPtr pScrn)
MGAdac->maxPixelClock = 220000;
break;
case PCI_CHIP_MGAG400:
- MGAdac->maxPixelClock = 300000;
+ /* We don't know the new pins format but we know that
+ the maxclock / 4 is where the RamdacType was in the
+ old pins format */
+ MGAdac->maxPixelClock = pMga->Bios2.RamdacType * 4000;
+ if(MGAdac->maxPixelClock < 300000)
+ MGAdac->maxPixelClock = 300000;
break;
default:
MGAdac->maxPixelClock = 250000;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
index df23db4f6..ca69d37c1 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
@@ -22,7 +22,7 @@
#include "mga.h"
#include "mga_macros.h"
#include "mga_dri.h"
-#include "mga_dripriv.h"
+#include "mga_wrap.h"
static char MGAKernelDriverName[] = "mga";
static char MGAClientDriverName[] = "mga";
@@ -51,172 +51,252 @@ extern void Mga32DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
extern void Mga32DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
RegionPtr prgnSrc, CARD32 index);
-static Bool
-MGAInitVisualConfigs(ScreenPtr pScreen)
+Bool MgaCleanupDma(ScrnInfoPtr pScrn)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- MGAPtr pMGA = MGAPTR(pScrn);
- int numConfigs = 0;
- __GLXvisualConfig *pConfigs = 0;
- MGAConfigPrivPtr pMGAConfigs = 0;
- MGAConfigPrivPtr *pMGAConfigPtrs = 0;
- int i;
+ MGAPtr pMGA = MGAPTR(pScrn);
+ Bool ret_val;
+
+ ret_val = drmMgaCleanupDma(pMGA->drmSubFD);
+ if(ret_val == FALSE) ErrorF("Mga Dma Cleanup Failed\n");
+
+ return ret_val;
+}
- switch (pScrn->bitsPerPixel) {
- case 8:
- case 24:
- case 32:
- break;
- case 16:
- numConfigs = 4;
+Bool MgaLockUpdate(ScrnInfoPtr pScrn, drmLockFlags flags)
+{
+ MGAPtr pMGA = MGAPTR(pScrn);
+ Bool ret_val;
+
+ ret_val = drmMgaLockUpdate(pMGA->drmSubFD, flags);
+ if(ret_val == FALSE) ErrorF("LockUpdate failed\n");
+
+ return ret_val;
+}
- if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
- numConfigs))) {
+Bool MgaInitDma(ScrnInfoPtr pScrn, int prim_size)
+{
+ MGAPtr pMGA = MGAPTR(pScrn);
+ MGADRIPtr pMGADRI = (MGADRIPtr)pMGA->pDRIInfo->devPrivate;
+ MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo;
+ drmMgaInit init;
+ Bool ret_val;
+
+ memset(&init, 0, sizeof(drmMgaInit));
+ init.reserved_map_agpstart = 0;
+ init.reserved_map_idx = 3;
+ init.buffer_map_idx = 4;
+ init.sarea_priv_offset = sizeof(XF86DRISAREARec);
+ init.primary_size = prim_size;
+ init.warp_ucode_size = pMGADRIServer->warp_ucode_size;
+
+ switch(pMGA->Chipset) {
+ case PCI_CHIP_MGAG400:
+ init.chipset = MGA_CARD_TYPE_G400;
+ break;
+ case PCI_CHIP_MGAG200:
+ init.chipset = MGA_CARD_TYPE_G200;
+ break;
+ case PCI_CHIP_MGAG200_PCI:
+ default:
+ ErrorF("Direct rendering not supported on this card/chipset\n");
return FALSE;
- }
- if (!(pMGAConfigs = (MGAConfigPrivPtr)xnfcalloc(sizeof(MGAConfigPrivRec),
+ }
+
+ init.frontOffset = pMGADRI->frontOffset;
+ init.backOffset = pMGADRI->backOffset;
+ init.depthOffset = pMGADRI->depthOffset;
+ init.textureOffset = pMGADRI->textureOffset;
+ init.textureSize = pMGADRI->textureSize;
+ init.agpTextureSize = pMGADRI->agpTextureSize;
+ init.cpp = pMGADRI->cpp;
+ init.stride = pMGADRI->frontPitch;
+ init.mAccess = pMGA->MAccess;
+ init.sgram = !pMGA->HasSDRAM;
+
+ memcpy(&init.WarpIndex, &pMGADRIServer->WarpIndex,
+ sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES);
+
+ ErrorF("Mga Dma Initialization start\n");
+
+ ret_val = drmMgaInitDma(pMGA->drmSubFD, &init);
+ if(ret_val == FALSE) ErrorF("Mga Dma Initialization Failed\n");
+ else ErrorF("Mga Dma Initialization done\n");
+ return ret_val;
+}
+
+static Bool
+MGAInitVisualConfigs(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMGA = MGAPTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = 0;
+ MGAConfigPrivPtr pMGAConfigs = 0;
+ MGAConfigPrivPtr *pMGAConfigPtrs = 0;
+ int i;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 24:
+ case 32:
+ break;
+ case 16:
+ numConfigs = 4;
+
+ if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
numConfigs))) {
- xfree(pConfigs);
- return FALSE;
- }
- if (!(pMGAConfigPtrs = (MGAConfigPrivPtr*)xnfcalloc(sizeof(MGAConfigPrivPtr),
- numConfigs))) {
- xfree(pConfigs);
- xfree(pMGAConfigs);
- return FALSE;
- }
- for (i=0; i<numConfigs; i++)
- pMGAConfigPtrs[i] = &pMGAConfigs[i];
+ return FALSE;
+ }
+ if (!(pMGAConfigs = (MGAConfigPrivPtr)xnfcalloc(sizeof(MGAConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pMGAConfigPtrs = (MGAConfigPrivPtr*)xnfcalloc(sizeof(MGAConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pMGAConfigs);
+ return FALSE;
+ }
+ for (i=0; i<numConfigs; i++)
+ pMGAConfigPtrs[i] = &pMGAConfigs[i];
+
+ /* config 0: db=FALSE, depth=0
+ config 1: db=FALSE, depth=16
+ config 2: db=TRUE, depth=0;
+ config 3: db=TRUE, depth=16
+ */
+ pConfigs[0].vid = -1;
+ pConfigs[0].class = -1;
+ pConfigs[0].rgba = TRUE;
+ pConfigs[0].redSize = 5;
+ pConfigs[0].greenSize = 6;
+ pConfigs[0].blueSize = 5;
+ pConfigs[0].redMask = 0x0000F800;
+ pConfigs[0].greenMask = 0x000007E0;
+ pConfigs[0].blueMask = 0x0000001F;
+ pConfigs[0].alphaMask = 0;
+ pConfigs[0].accumRedSize = 0;
+ pConfigs[0].accumGreenSize = 0;
+ pConfigs[0].accumBlueSize = 0;
+ pConfigs[0].accumAlphaSize = 0;
+ pConfigs[0].doubleBuffer = FALSE;
+ pConfigs[0].stereo = FALSE;
+ pConfigs[0].bufferSize = 16;
+ pConfigs[0].depthSize = 16;
+ pConfigs[0].stencilSize = 0;
+ pConfigs[0].auxBuffers = 0;
+ pConfigs[0].level = 0;
+ pConfigs[0].visualRating = 0;
+ pConfigs[0].transparentPixel = 0;
+ pConfigs[0].transparentRed = 0;
+ pConfigs[0].transparentGreen = 0;
+ pConfigs[0].transparentBlue = 0;
+ pConfigs[0].transparentAlpha = 0;
+ pConfigs[0].transparentIndex = 0;
+
+ pConfigs[1].vid = -1;
+ pConfigs[1].class = -1;
+ pConfigs[1].rgba = TRUE;
+ pConfigs[1].redSize = 5;
+ pConfigs[1].greenSize = 6;
+ pConfigs[1].blueSize = 5;
+ pConfigs[1].redMask = 0x0000F800;
+ pConfigs[1].greenMask = 0x000007E0;
+ pConfigs[1].blueMask = 0x0000001F;
+ pConfigs[1].alphaMask = 0;
+ pConfigs[1].accumRedSize = 0;
+ pConfigs[1].accumGreenSize = 0;
+ pConfigs[1].accumBlueSize = 0;
+ pConfigs[1].accumAlphaSize = 0;
+ pConfigs[1].doubleBuffer = FALSE;
+ pConfigs[1].stereo = FALSE;
+ pConfigs[1].bufferSize = 16;
+ pConfigs[1].depthSize = 16;
+ pConfigs[1].stencilSize = 0;
+ pConfigs[1].auxBuffers = 0;
+ pConfigs[1].level = 0;
+ pConfigs[1].visualRating = 0;
+ pConfigs[1].transparentPixel = 0;
+ pConfigs[1].transparentRed = 0;
+ pConfigs[1].transparentGreen = 0;
+ pConfigs[1].transparentBlue = 0;
+ pConfigs[1].transparentAlpha = 0;
+ pConfigs[1].transparentIndex = 0;
+
+ pConfigs[2].vid = -1;
+ pConfigs[2].class = -1;
+ pConfigs[2].rgba = TRUE;
+ pConfigs[2].redSize = 5;
+ pConfigs[2].greenSize = 6;
+ pConfigs[2].blueSize = 5;
+ pConfigs[2].redMask = 0x0000F800;
+ pConfigs[2].greenMask = 0x000007E0;
+ pConfigs[2].blueMask = 0x0000001F;
+ pConfigs[2].alphaMask = 0;
+ pConfigs[2].accumRedSize = 0;
+ pConfigs[2].accumGreenSize = 0;
+ pConfigs[2].accumBlueSize = 0;
+ pConfigs[2].accumAlphaSize = 0;
+ pConfigs[2].doubleBuffer = TRUE;
+ pConfigs[2].stereo = FALSE;
+ pConfigs[2].bufferSize = 16;
+ pConfigs[2].depthSize = 16;
+ pConfigs[2].stencilSize = 0;
+ pConfigs[2].auxBuffers = 0;
+ pConfigs[2].level = 0;
+ pConfigs[2].visualRating = 0;
+ pConfigs[2].transparentPixel = 0;
+ pConfigs[2].transparentRed = 0;
+ pConfigs[2].transparentGreen = 0;
+ pConfigs[2].transparentBlue = 0;
+ pConfigs[2].transparentAlpha = 0;
+ pConfigs[2].transparentIndex = 0;
+
+ pConfigs[3].vid = -1;
+ pConfigs[3].class = -1;
+ pConfigs[3].rgba = TRUE;
+ pConfigs[3].redSize = 5;
+ pConfigs[3].greenSize = 6;
+ pConfigs[3].blueSize = 5;
+ pConfigs[3].redMask = 0x0000F800;
+ pConfigs[3].greenMask = 0x000007E0;
+ pConfigs[3].blueMask = 0x0000001F;
+ pConfigs[3].alphaMask = 0;
+ pConfigs[3].accumRedSize = 0;
+ pConfigs[3].accumGreenSize = 0;
+ pConfigs[3].accumBlueSize = 0;
+ pConfigs[3].accumAlphaSize = 0;
+ pConfigs[3].doubleBuffer = TRUE;
+ pConfigs[3].stereo = FALSE;
+ pConfigs[3].bufferSize = 16;
+ pConfigs[3].depthSize = 16;
+ pConfigs[3].stencilSize = 0;
+ pConfigs[3].auxBuffers = 0;
+ pConfigs[3].level = 0;
+ pConfigs[3].visualRating = 0;
+ pConfigs[3].transparentPixel = 0;
+ pConfigs[3].transparentRed = 0;
+ pConfigs[3].transparentGreen = 0;
+ pConfigs[3].transparentBlue = 0;
+ pConfigs[3].transparentAlpha = 0;
+ pConfigs[3].transparentIndex = 0;
+ }
+ pMGA->numVisualConfigs = numConfigs;
+ pMGA->pVisualConfigs = pConfigs;
+ pMGA->pVisualConfigsPriv = pMGAConfigs;
+ GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pMGAConfigPtrs);
+ return TRUE;
+}
- /* config 0: db=FALSE, depth=0
- config 1: db=FALSE, depth=16
- config 2: db=TRUE, depth=0;
- config 3: db=TRUE, depth=16
- */
- pConfigs[0].vid = -1;
- pConfigs[0].class = -1;
- pConfigs[0].rgba = TRUE;
- pConfigs[0].redSize = 8;
- pConfigs[0].greenSize = 8;
- pConfigs[0].blueSize = 8;
- pConfigs[0].redMask = 0x00FF0000;
- pConfigs[0].greenMask = 0x0000FF00;
- pConfigs[0].blueMask = 0x000000FF;
- pConfigs[0].alphaMask = 0;
- pConfigs[0].accumRedSize = 0;
- pConfigs[0].accumGreenSize = 0;
- pConfigs[0].accumBlueSize = 0;
- pConfigs[0].accumAlphaSize = 0;
- pConfigs[0].doubleBuffer = FALSE;
- pConfigs[0].stereo = FALSE;
- pConfigs[0].bufferSize = 16;
- pConfigs[0].depthSize = 0;
- pConfigs[0].stencilSize = 0;
- pConfigs[0].auxBuffers = 0;
- pConfigs[0].level = 0;
- pConfigs[0].visualRating = 0;
- pConfigs[0].transparentPixel = 0;
- pConfigs[0].transparentRed = 0;
- pConfigs[0].transparentGreen = 0;
- pConfigs[0].transparentBlue = 0;
- pConfigs[0].transparentAlpha = 0;
- pConfigs[0].transparentIndex = 0;
-
- pConfigs[1].vid = -1;
- pConfigs[1].class = -1;
- pConfigs[1].rgba = TRUE;
- pConfigs[1].redSize = 8;
- pConfigs[1].greenSize = 8;
- pConfigs[1].blueSize = 8;
- pConfigs[1].redMask = 0x00FF0000;
- pConfigs[1].greenMask = 0x0000FF00;
- pConfigs[1].blueMask = 0x000000FF;
- pConfigs[1].alphaMask = 0;
- pConfigs[1].accumRedSize = 0;
- pConfigs[1].accumGreenSize = 0;
- pConfigs[1].accumBlueSize = 0;
- pConfigs[1].accumAlphaSize = 0;
- pConfigs[1].doubleBuffer = FALSE;
- pConfigs[1].stereo = FALSE;
- pConfigs[1].bufferSize = 16;
- pConfigs[1].depthSize = 16;
- pConfigs[1].stencilSize = 0;
- pConfigs[1].auxBuffers = 0;
- pConfigs[1].level = 0;
- pConfigs[1].visualRating = 0;
- pConfigs[1].transparentPixel = 0;
- pConfigs[1].transparentRed = 0;
- pConfigs[1].transparentGreen = 0;
- pConfigs[1].transparentBlue = 0;
- pConfigs[1].transparentAlpha = 0;
- pConfigs[1].transparentIndex = 0;
-
- pConfigs[2].vid = -1;
- pConfigs[2].class = -1;
- pConfigs[2].rgba = TRUE;
- pConfigs[2].redSize = 8;
- pConfigs[2].greenSize = 8;
- pConfigs[2].blueSize = 8;
- pConfigs[2].redMask = 0x00FF0000;
- pConfigs[2].greenMask = 0x0000FF00;
- pConfigs[2].blueMask = 0x000000FF;
- pConfigs[2].alphaMask = 0;
- pConfigs[2].accumRedSize = 0;
- pConfigs[2].accumGreenSize = 0;
- pConfigs[2].accumBlueSize = 0;
- pConfigs[2].accumAlphaSize = 0;
- pConfigs[2].doubleBuffer = TRUE;
- pConfigs[2].stereo = FALSE;
- pConfigs[2].bufferSize = 16;
- pConfigs[2].depthSize = 0;
- pConfigs[2].stencilSize = 0;
- pConfigs[2].auxBuffers = 0;
- pConfigs[2].level = 0;
- pConfigs[2].visualRating = 0;
- pConfigs[2].transparentPixel = 0;
- pConfigs[2].transparentRed = 0;
- pConfigs[2].transparentGreen = 0;
- pConfigs[2].transparentBlue = 0;
- pConfigs[2].transparentAlpha = 0;
- pConfigs[2].transparentIndex = 0;
-
- pConfigs[3].vid = -1;
- pConfigs[3].class = -1;
- pConfigs[3].rgba = TRUE;
- pConfigs[3].redSize = 8;
- pConfigs[3].greenSize = 8;
- pConfigs[3].blueSize = 8;
- pConfigs[3].redMask = 0x00FF0000;
- pConfigs[3].greenMask = 0x0000FF00;
- pConfigs[3].blueMask = 0x000000FF;
- pConfigs[3].alphaMask = 0;
- pConfigs[3].accumRedSize = 0;
- pConfigs[3].accumGreenSize = 0;
- pConfigs[3].accumBlueSize = 0;
- pConfigs[3].accumAlphaSize = 0;
- pConfigs[3].doubleBuffer = TRUE;
- pConfigs[3].stereo = FALSE;
- pConfigs[3].bufferSize = 16;
- pConfigs[3].depthSize = 16;
- pConfigs[3].stencilSize = 0;
- pConfigs[3].auxBuffers = 0;
- pConfigs[3].level = 0;
- pConfigs[3].visualRating = 0;
- pConfigs[3].transparentPixel = 0;
- pConfigs[3].transparentRed = 0;
- pConfigs[3].transparentGreen = 0;
- pConfigs[3].transparentBlue = 0;
- pConfigs[3].transparentAlpha = 0;
- pConfigs[3].transparentIndex = 0;
- break;
- }
- pMGA->numVisualConfigs = numConfigs;
- pMGA->pVisualConfigs = pConfigs;
- pMGA->pVisualConfigsPriv = pMGAConfigs;
- GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pMGAConfigPtrs);
- return TRUE;
+static unsigned int mylog2(unsigned int n)
+{
+ unsigned int log2 = 1;
+ while (n>1) n >>= 1, log2++;
+ return log2;
}
+
Bool MGADRIScreenInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -224,10 +304,24 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
DRIInfoPtr pDRIInfo;
MGADRIPtr pMGADRI;
MGADRIServerPrivatePtr pMGADRIServer;
- int bufs;
- int prim_size;
- int init_offset;
+ int bufs, size;
+ int prim_size;
+ int init_offset;
+ int i;
+#if XFree86LOADER
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ * for canonical symbols in each module. */
+ if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE;
+ if (!LoaderSymbol("DRIScreenInit")) return FALSE;
+ if (!LoaderSymbol("drmAvailable")) return FALSE;
+#endif
+
+ if((pScrn->bitsPerPixel / 8) != 2) {
+ ErrorF("Direct Rendering only supported in 16 bpp mode\n");
+ return FALSE;
+ }
+
pDRIInfo = DRICreateInfoRec();
if (!pDRIInfo) return FALSE;
pMGA->pDRIInfo = pDRIInfo;
@@ -247,28 +341,25 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8);
pDRIInfo->ddxDrawableTableEntry = MGA_MAX_DRAWABLES;
+ MGADRIWrapFunctions( pScreen, pDRIInfo );
+
if (SAREA_MAX_DRAWABLES < MGA_MAX_DRAWABLES)
pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
else
pDRIInfo->maxDrawableTableEntry = MGA_MAX_DRAWABLES;
-#ifdef NOT_DONE
- /* FIXME need to extend DRI protocol to pass this size back to client
- * for SAREA mapping that includes a device private record
- */
- pDRIInfo->SAREASize =
- ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
- /* + shared memory device private rec */
-#else
/* For now the mapping works by using a fixed size defined
* in the SAREA header
*/
- if (sizeof(XF86DRISAREARec)+sizeof(drm_mga_sarea_t)>SAREA_MAX) {
+ if (sizeof(XF86DRISAREARec)+sizeof(MGASAREARec)>SAREA_MAX) {
ErrorF("Data does not fit in SAREA\n");
return FALSE;
}
+
+ ErrorF("\n\n\nSarea %d+%d: %d\n", sizeof(XF86DRISAREARec),
+ sizeof(MGASAREARec), sizeof(XF86DRISAREARec) + sizeof(MGASAREARec));
+
pDRIInfo->SAREASize = SAREA_MAX;
-#endif
if (!(pMGADRI = (MGADRIPtr)xnfcalloc(sizeof(MGADRIRec),1))) {
DRIDestroyInfoRec(pMGA->pDRIInfo);
@@ -277,7 +368,7 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
if (!(pMGADRIServer = (MGADRIServerPrivatePtr)
- xnfcalloc(sizeof(MGADRIServerPrivate),1))) {
+ xnfcalloc(sizeof(MGADRIServerPrivateRec),1))) {
xfree(pMGADRI);
DRIDestroyInfoRec(pMGA->pDRIInfo);
pMGA->pDRIInfo=0;
@@ -334,25 +425,44 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
pMGADRIServer->regs);
/* Agp Support */
+ pMGADRIServer->agpAcquired = FALSE;
+ pMGADRIServer->agpHandle = 0;
+ pMGADRIServer->agpSizep = 0;
+ pMGADRIServer->agp_map = 0;
+
if(drmAgpAcquire(pMGA->drmSubFD) < 0) {
DRICloseScreen(pScreen);
ErrorF("drmAgpAcquire failed\n");
return FALSE;
}
+ pMGADRIServer->agpAcquired = TRUE;
+
pMGADRIServer->warp_ucode_size = mgaGetMicrocodeSize(pScreen);
if(pMGADRIServer->warp_ucode_size == 0) {
ErrorF("microcodeSize is zero\n");
DRICloseScreen(pScreen);
return FALSE;
}
+
+ pMGADRIServer->agpMode = drmAgpGetMode(pMGA->drmSubFD);
+ /* Default to 1X agp mode */
+ pMGADRIServer->agpMode &= ~0x00000002;
+ if (drmAgpEnable(pMGA->drmSubFD, pMGADRIServer->agpMode) < 0) {
+ ErrorF("drmAgpEnable failed\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ ErrorF("drmAgpEnabled succeeded\n");
prim_size = 65536;
init_offset = ((prim_size + pMGADRIServer->warp_ucode_size +
4096 - 1) / 4096) * 4096;
- pMGADRIServer->agpSizep = drmAgpSize(pMGA->drmSubFD);
- pMGADRIServer->agpBase = drmAgpBase(pMGA->drmSubFD);
- if (drmAddMap(pMGA->drmSubFD, (drmHandle)pMGADRIServer->agpBase,
+ pMGADRIServer->agpSizep = init_offset;
+ pMGADRI->agpSize = (drmAgpSize(pMGA->drmSubFD)) - init_offset;
+
+ pMGADRIServer->agpBase = (drmAddress) drmAgpBase(pMGA->drmSubFD);
+ if (drmAddMap(pMGA->drmSubFD, 0,
init_offset, DRM_AGP, 0,
&pMGADRIServer->agp_private) < 0) {
DRICloseScreen(pScreen);
@@ -370,12 +480,15 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
/* Now allocate and bind a default of 8 megs */
- pMGADRIServer->agpHandle = drmAgpAlloc(pMGA->drmSubFD, 0x00800000, 0, 0);
+ drmAgpAlloc(pMGA->drmSubFD, 0x00800000, 0, 0,
+ &pMGADRIServer->agpHandle);
+
if(pMGADRIServer->agpHandle == 0) {
ErrorF("drmAgpAlloc failed\n");
DRICloseScreen(pScreen);
return FALSE;
}
+
if(drmAgpBind(pMGA->drmSubFD, pMGADRIServer->agpHandle, 0) < 0) {
DRICloseScreen(pScreen);
ErrorF("drmAgpBind failed\n");
@@ -384,72 +497,115 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
mgaInstallMicrocode(pScreen, prim_size);
- ErrorF("init_offset: %x\n", init_offset);
- pMGADRI->agpSize = pMGADRIServer->agpSizep - init_offset;
- ErrorF("pMGADRI->agpSize: %x\n", pMGADRI->agpSize);
-
- if(drmAddMap(pMGA->drmSubFD, (drmHandle)pMGADRIServer->agpBase + init_offset,
+ if(drmAddMap(pMGA->drmSubFD, (drmHandle)init_offset,
pMGADRI->agpSize, DRM_AGP, 0,
&pMGADRI->agp) < 0) {
ErrorF("Failed to map public agp area\n");
DRICloseScreen(pScreen);
return FALSE;
}
- ErrorF("Mapped public agp area\n");
+
+
+ switch(pMGA->Chipset) {
+ case PCI_CHIP_MGAG400:
+ pMGADRI->chipset = MGA_CARD_TYPE_G400;
+ break;
+ case PCI_CHIP_MGAG200:
+#if 0
+ pMGADRI->chipset = MGA_CARD_TYPE_G200;
+ break;
+#endif
+ case PCI_CHIP_MGAG200_PCI:
+ default:
+ ErrorF("Direct rendering not supported on this card/chipset\n");
+ return FALSE;
+ }
+
+
+ pMGADRI->width = pScrn->virtualX;
+ pMGADRI->height = pScrn->virtualY;
+ pMGADRI->mem = pScrn->videoRam * 1024;
+ pMGADRI->cpp = pScrn->bitsPerPixel / 8;
+ pMGADRI->frontPitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
+
+
+ pMGADRI->frontOffset = 0; /* pMGA->YDstOrg * (pScrn->bitsPerPixel / 8) */
+ pMGADRI->backOffset = ((pScrn->virtualY+129) * pScrn->displayWidth *
+ (pScrn->bitsPerPixel / 8) + 4095) & ~0xFFF;
+
+
+ fprintf(stderr, "calced backoffset: 0x%x\n",
+ pMGADRI->backOffset);
+
+
+#if 0
+ size = 2 * pScrn->virtualX * pScrn->virtualY;
+ pMGADRI->depthOffset = (pMGADRI->backOffset + size + 4095) & ~0xFFF;
+ pMGADRI->textureOffset = pMGADRI->depthOffset + size;
+ pMGADRI->textureSize = pMGA->FbUsableSize - pMGADRI->textureOffset;
+#else
+ size = 2 * pScrn->virtualX * pScrn->virtualY;
+ size += 4095;
+ size &= ~4095;
+ pMGADRI->depthOffset = pMGA->FbUsableSize - size;
+ pMGADRI->depthOffset &= ~4095;
+ pMGADRI->textureOffset = pMGADRI->backOffset + size;
+ pMGADRI->textureSize = pMGADRI->depthOffset - pMGADRI->textureOffset;
+
+ if (pMGADRI->depthOffset < pMGADRI->textureOffset + 512*1024) {
+ ErrorF("Insufficient memory for direct rendering\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+#endif
+
+ pMGADRI->mAccess = pMGA->MAccess;
+
+ i = mylog2(pMGADRI->textureSize / MGA_NR_TEX_REGIONS);
+ if (i < MGA_LOG_MIN_TEX_REGION_SIZE)
+ i = MGA_LOG_MIN_TEX_REGION_SIZE;
+
+ pMGADRI->logTextureGranularity = i;
+ pMGADRI->textureSize = (pMGADRI->textureSize >> i) << i; /* truncate */
+
+
+ /* Calculate similar constants for AGP texture space
+ */
+ i = mylog2(pMGADRI->agpSize / MGA_NR_TEX_REGIONS);
+ if (i < MGA_LOG_MIN_TEX_REGION_SIZE)
+ i = MGA_LOG_MIN_TEX_REGION_SIZE;
+
+ pMGADRI->logAgpTextureGranularity = i;
+ pMGADRI->agpTextureSize = (pMGADRI->agpSize >> i) << i;
+
+
/* Here is where we need to do initialization of the dma engine */
-
- pMGADRIServer->agpMode = drmAgpGetMode(pMGA->drmSubFD);
- /* Default to 1X agp mode */
- pMGADRIServer->agpMode &= ~0x00000002;
- if (drmAgpEnable(pMGA->drmSubFD, pMGADRIServer->agpMode) < 0) {
- ErrorF("drmAgpEnable failed\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- ErrorF("drmAgpEnabled succeeded\n");
- if((bufs = drmAddBufs(pMGA->drmSubFD,
- /*63*/ 15,
- /* 65536 */ 524288,
+ if((bufs = drmAddBufs(pMGA->drmSubFD,
+ MGA_DMA_BUF_NR,
+ MGA_DMA_BUF_SZ,
DRM_AGP_BUFFER,
init_offset)) <= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] failure adding %d %d byte DMA buffers\n",
- /* 63 */ 15,
- /* 65536 */ 524288);
+ MGA_DMA_BUF_NR,
+ MGA_DMA_BUF_SZ);
DRICloseScreen(pScreen);
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] added %d %d byte DMA buffers\n",
- bufs, /* 65536 */ 524288);
+ bufs, MGA_DMA_BUF_SZ);
- if((mgadrmInitDma(pScrn, prim_size)) != TRUE) {
+ if((MgaInitDma(pScrn, prim_size)) != TRUE) {
ErrorF("Failed to initialize dma engine\n");
DRICloseScreen(pScreen);
return FALSE;
}
-
- ErrorF("Initialized Dma Engine\n");
+ ErrorF("Initialized Dma Engine\n");
- if(drmMarkBufs(pMGA->drmSubFD, 0.133333, 0.266666) != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] failure marking DMA buffers\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- if (!(pMGADRIServer->drmBufs = drmMapBufs(pMGA->drmSubFD))) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] failure mapping DMA buffers\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] buffers mapped with %p\n",
- pMGADRIServer->drmBufs);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] %d DMA buffers mapped\n",
- pMGADRIServer->drmBufs->count);
if (!pMGADRIServer->irq) {
pMGADRIServer->irq = drmGetInterruptFromBusID(pMGA->drmSubFD,
((pciConfigPtr)pMGA->PciInfo
@@ -481,16 +637,26 @@ MGADRICloseScreen(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
MGAPtr pMGA = MGAPTR(pScrn);
MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] unmapping %d buffers\n",
- pMGADRIServer->drmBufs->count);
- if (drmUnmapBufs(pMGADRIServer->drmBufs)) {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] unable to unmap DMA buffers\n");
+
+ MgaCleanupDma(pScrn);
+
+ if(pMGADRIServer->agp_map) {
+ ErrorF("Unmapped agp region\n");
+ drmUnmap(pMGADRIServer->agp_map, pMGADRIServer->agpSizep);
+ pMGADRIServer->agp_map = 0;
}
- mgadrmCleanupDma(pScrn);
-
+ if(pMGADRIServer->agpHandle) {
+ ErrorF("Freeing agp memory\n");
+ drmAgpFree(pMGA->drmSubFD, pMGADRIServer->agpHandle);
+ pMGADRIServer->agpHandle = 0;
+ pMGADRIServer->agpSizep = 0;
+ }
+ if(pMGADRIServer->agpAcquired == TRUE) {
+ ErrorF("releasing agp module\n");
+ drmAgpRelease(pMGA->drmSubFD);
+ pMGADRIServer->agpAcquired = FALSE;
+ }
+
DRICloseScreen(pScreen);
if (pMGA->pDRIInfo) {
@@ -518,9 +684,6 @@ MGACreateContext(ScreenPtr pScreen, VisualPtr visual,
drmContext hwContext, void *pVisualConfigPriv,
DRIContextType contextStore)
{
- MGADRIContextPtr ctx;
-
- ctx = (MGADRIContextPtr)contextStore;
return TRUE;
}
@@ -528,106 +691,120 @@ static void
MGADestroyContext(ScreenPtr pScreen, drmContext hwContext,
DRIContextType contextStore)
{
- MGADRIContextPtr ctx;
- ctx = (MGADRIContextPtr)contextStore;
}
Bool
MGADRIFinishScreenInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGASAREAPtr sPriv;
MGAPtr pMGA = MGAPTR(pScrn);
- MGADRIPtr pMGADRI;
- int size;
+ if (!pMGA->pDRIInfo) return FALSE;
+
+ sPriv = (MGASAREAPtr)DRIGetSAREAPrivate(pScreen);
pMGA->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
- /* pMGA->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */
- pMGADRI = (MGADRIPtr)pMGA->pDRIInfo->devPrivate;
- pMGADRI->deviceID = pMGA->PciInfo->chipType;
- pMGADRI->width = pScrn->virtualX;
- pMGADRI->height = pScrn->virtualY;
- pMGADRI->mem = pScrn->videoRam * 1024;
- pMGADRI->cpp = pScrn->bitsPerPixel / 8;
- pMGADRI->stride = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
- pMGADRI->backOffset = ((pScrn->virtualY+129) * pScrn->displayWidth *
- (pScrn->bitsPerPixel / 8) + 4095) & ~0xFFF;
- size = 2 * pScrn->virtualX * pScrn->virtualY;
- pMGADRI->depthOffset = (pMGADRI->backOffset + size + 4095) & ~0xFFF;
- pMGADRI->textureOffset = pMGADRI->depthOffset + size;
- /*
- * The rest of the framebuffer is for textures except for the
- * memory for the hardware cursor.
- */
- pMGADRI->textureSize = pMGA->FbUsableSize - pMGADRI->textureOffset;
- pMGADRI->fbOffset = pMGA->YDstOrg * (pScrn->bitsPerPixel / 8);
+ xf86memset( sPriv, 0, sizeof(MGASAREARec) );
return DRIFinishScreenInit(pScreen);
}
-void MGASwapContext(ScreenPtr pScreen)
+
+void mgaGetQuiescence( ScrnInfoPtr pScrn )
{
-#if 0
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- MGAPtr pMga = MGAPTR(pScrn);
- MGAFBLayout *pLayout = &pMga->CurrentLayout;
-
- usleep(500);
- ErrorF("Syncing : swap\n");
- MGABUSYWAIT();
- ErrorF("Sync : swap 1\n");
- MGAStormSync(pScrn);
- ErrorF("Syncing done\n");
- pMga->AccelInfoRec->NeedToSync = TRUE;
-
- WAITFIFO(12);
- OUTREG(MGAREG_MACCESS, pMga->MAccess);
- OUTREG(MGAREG_PITCH, pLayout->displayWidth);
- OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
- OUTREG(MGAREG_PLNWT, pMga->PlaneMask);
- OUTREG(MGAREG_BCOL, pMga->BgColor);
- OUTREG(MGAREG_FCOL, pMga->FgColor);
- OUTREG(MGAREG_SRCORG, pMga->SrcOrg);
- OUTREG(MGAREG_DSTORG, pMga->DstOrg);
- OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
- OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
- OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
- OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
- pMga->AccelFlags &= ~CLIPPER_ON;
-#endif
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ pMga->have_quiescense = 1;
+
+ if (pMga->directRenderingEnabled) {
+ MGAFBLayout *pLayout = &pMga->CurrentLayout;
+
+ MgaLockUpdate(pScrn, (DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH));
+
+ WAITFIFO(12);
+ OUTREG(MGAREG_MACCESS, pMga->MAccess);
+ OUTREG(MGAREG_PITCH, pLayout->displayWidth);
+ OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
+ OUTREG(MGAREG_PLNWT, pMga->PlaneMask);
+ OUTREG(MGAREG_BCOL, pMga->BgColor);
+ OUTREG(MGAREG_FCOL, pMga->FgColor);
+ OUTREG(MGAREG_SRCORG, pMga->SrcOrg);
+ OUTREG(MGAREG_DSTORG, pMga->DstOrg);
+ OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
+ OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
+ OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
+ pMga->AccelFlags &= ~CLIPPER_ON;
+ }
}
-void MGALostContext(ScreenPtr pScreen)
+
+
+void MGASwapContext(ScreenPtr pScreen)
{
-#if 0
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- MGAPtr pMga = MGAPTR(pScrn);
- MGAFBLayout *pLayout = &pMga->CurrentLayout;
-
- ErrorF("Syncing : lost\n");
- MGAStormSync(pScrn);
- ErrorF("Sync : lost 1\n");
- MGABUSYWAIT();
- ErrorF("Syncing done\n");
-#endif
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Arrange for dma_quiescence and xaa sync to be called as
+ * appropriate.
+ */
+ pMga->have_quiescense = 0;
+ pMga->AccelInfoRec->NeedToSync = TRUE;
}
+
+
+/* This is really only called from validate/postvalidate as we
+ * override the dri lock/unlock. Want to remove validate/postvalidate
+ * processing, but need to remove all client-side use of drawable lock
+ * first (otherwise there is noone recover when a client dies holding
+ * the drawable lock).
+ *
+ * What does this mean?
+ *
+ * - The above code gets executed every time a
+ * window changes shape or the focus changes, which isn't really
+ * optimal.
+ * - The X server therefore believes it needs to do an XAA sync
+ * *and* a dma quiescense ioctl each time that happens.
+ *
+ * We don't wrap wakeuphandler any longer, so at least we can say that
+ * this doesn't happen *every time the mouse moves*...
+ */
static void
MGADRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
DRIContextType oldContextType, void *oldContext,
DRIContextType newContextType, void *newContext)
{
- if ((syncType == DRI_3D_SYNC) && (oldContextType == DRI_2D_CONTEXT) &&
- (newContextType == DRI_2D_CONTEXT)) { /* Entering from Wakeup */
- MGASwapContext(pScreen);
- }
- if ((syncType == DRI_2D_SYNC) && (oldContextType == DRI_NO_CONTEXT) &&
- (newContextType == DRI_2D_CONTEXT)) { /* Exiting from Block Handler */
- MGALostContext(pScreen);
- }
+ if (syncType == DRI_3D_SYNC &&
+ oldContextType == DRI_2D_CONTEXT &&
+ newContextType == DRI_2D_CONTEXT)
+ {
+ MGASwapContext(pScreen);
+ }
}
-/* Needs to be written */
-void MGASelectBuffer(MGAPtr pMGA, int which)
+
+void
+MGASelectBuffer(ScrnInfoPtr pScrn, int which)
{
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGADRIPtr pMGADRI = (MGADRIPtr)pMga->pDRIInfo->devPrivate;
+
+ switch (which) {
+ case MGA_BACK:
+ OUTREG(MGAREG_DSTORG, pMGADRI->backOffset);
+ OUTREG(MGAREG_SRCORG, pMGADRI->backOffset);
+ break;
+ case MGA_DEPTH:
+ OUTREG(MGAREG_DSTORG, pMGADRI->depthOffset);
+ OUTREG(MGAREG_SRCORG, pMGADRI->depthOffset);
+ break;
+ default:
+ case MGA_FRONT:
+ OUTREG(MGAREG_DSTORG, pMGADRI->frontOffset);
+ OUTREG(MGAREG_SRCORG, pMGADRI->frontOffset);
+ break;
+ }
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
index 7196bc954..2d35a6a89 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
@@ -4,9 +4,11 @@
#define _MGA_DRI_
#include <xf86drm.h>
-#include "mga_drm_public.h"
+#include <xf86drmMga.h>
-typedef struct _mga_dri_server_private {
+#define MGA_MAX_DRAWABLES 256
+
+typedef struct {
int reserved_map_agpstart;
int reserved_map_idx;
int buffer_map_idx;
@@ -17,6 +19,7 @@ typedef struct _mga_dri_server_private {
int sgram;
unsigned long agpMode;
unsigned long agpHandle;
+ Bool agpAcquired;
drmHandle agp_private;
drmSize agpSizep;
drmAddress agpBase;
@@ -24,27 +27,110 @@ typedef struct _mga_dri_server_private {
drmHandle regs;
drmSize regsSize;
drmAddress regsMap;
- mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
+ drmMgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
drmBufMapPtr drmBufs;
CARD8 *agp_map;
-} MGADRIServerPrivate, *MGADRIServerPrivatePtr;
+} MGADRIServerPrivateRec, *MGADRIServerPrivatePtr;
typedef struct {
- int deviceID;
- int width;
- int height;
- int mem;
- int cpp;
- int stride;
- int fbOffset;
- int backOffset;
- int depthOffset;
- int textureOffset;
- int textureSize;
- drmHandle agp;
- drmSize agpSize;
+ int chipset;
+ int width;
+ int height;
+ int mem;
+ int cpp;
+ int frontOffset;
+ int frontPitch;
+
+ int backOffset;
+ int backPitch;
+
+ int depthOffset;
+ int depthPitch;
+
+ int textureOffset;
+ int textureSize;
+ int logTextureGranularity;
+
+ int agpTextureSize;
+ int logAgpTextureGranularity;
+
+ /* Redundant?
+ */
+ unsigned int frontOrg;
+ unsigned int backOrg;
+ unsigned int depthOrg;
+
+ unsigned int mAccess;
+
+ drmHandle agp;
+ drmSize agpSize;
} MGADRIRec, *MGADRIPtr;
+/* WARNING: Do not change the SAREA structure without changing the kernel
+ * as well */
+typedef struct {
+ unsigned char next, prev;
+ unsigned char in_use;
+ int age;
+} MGATexRegionRec, *MGATexRegionPtr;
+
+typedef struct {
+ /* The channel for communication of state information to the kernel
+ * on firing a vertex dma buffer.
+ */
+ unsigned int ContextState[MGA_CTX_SETUP_SIZE];
+ unsigned int ServerState[MGA_2D_SETUP_SIZE];
+ unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
+ unsigned int WarpPipe;
+ unsigned int dirty;
+
+ unsigned int nbox;
+ XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
+
+ /* Information about the most recently used 3d drawable. The
+ * client fills in the req_* fields, the server fills in the
+ * exported_ fields and puts the cliprects into boxes, above.
+ *
+ * The client clears the exported_drawable field before
+ * clobbering the boxes data.
+ */
+ unsigned int req_drawable; /* the X drawable id */
+ unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
+
+ unsigned int exported_drawable;
+ unsigned int exported_index;
+ unsigned int exported_stamp;
+ unsigned int exported_buffers;
+ unsigned int exported_nfront;
+ unsigned int exported_nback;
+ int exported_back_x, exported_front_x, exported_w;
+ int exported_back_y, exported_front_y, exported_h;
+ XF86DRIClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+
+ /* Counters for aging textures and for client-side throttling.
+ */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+
+ /* LRU lists for texture memory in agp space and on the card */
+
+ MGATexRegionRec texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+ unsigned int texAge[MGA_NR_TEX_HEAPS];
+ /* Mechanism to validate card state.
+ */
+ int ctxOwner;
+} MGASAREARec, *MGASAREAPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} MGAConfigPrivRec, *MGAConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} MGADRIContextRec, *MGADRIContextPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h
deleted file mode 100644
index 841c17cb9..000000000
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dripriv.h,v 1.1 2000/02/11 17:25:55 dawes Exp $ */
-
-#ifndef _MGA_DRIPRIV_H_
-#define _MGA_DRIPRIV_H_
-
-#define MGA_MAX_DRAWABLES 256
-
-extern void GlxSetVisualConfigs(
- int nconfigs,
- __GLXvisualConfig *configs,
- void **configprivs
-);
-
-typedef struct {
- /* Nothing here yet */
- int dummy;
-} MGAConfigPrivRec, *MGAConfigPrivPtr;
-
-typedef struct {
- /* Nothing here yet */
- int dummy;
-} MGADRIContextRec, *MGADRIContextPtr;
-
-#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
index 85a529068..6f95b8d87 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
@@ -15,8 +15,8 @@
* to be based on Radoslaw's original source
*
* Contributors:
- * Andrew Vanderstock, Melbourne, Australia
- * vanderaj@mail2.svhm.org.au
+ * Andrew van der Stock
+ * ajv@greebo.net
* additions, corrections, cleanups
*
* Dirk Hohndel
@@ -43,7 +43,7 @@
* Fixed 32bpp hires 8MB horizontal line glitch at middle right
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.114 1999/08/28 14:32:47 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.149 2000/03/07 01:37:49 dawes Exp $ */
/*
* This is a first cut at a non-accelerated version to work with the
@@ -76,8 +76,9 @@
#include "micmap.h"
#include "xf86DDC.h"
-
#include "xf86RAC.h"
+#include "vbe.h"
+
/*
* If using cfb, cfb.h is required. Select the others for the bpp values
@@ -102,8 +103,9 @@
#include "shadowfb.h"
#include "fbdevhw.h"
-#include "xf86xv.h"
-#include "Xv.h"
+#ifdef XF86DRI
+#include "dri.h"
+#endif
/*
@@ -111,6 +113,7 @@
*/
/* Mandatory functions */
+static OptionInfoPtr MGAAvailableOptions(int chipid, int busid);
static void MGAIdentify(int flags);
static Bool MGAProbe(DriverPtr drv, int flags);
static Bool MGAPreInit(ScrnInfoPtr pScrn, int flags);
@@ -120,7 +123,7 @@ static Bool MGAEnterVT(int scrnIndex, int flags);
static Bool MGAEnterVTFBDev(int scrnIndex, int flags);
static void MGALeaveVT(int scrnIndex, int flags);
static Bool MGACloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool MGASaveScreen(ScreenPtr pScreen, Bool unblank);
+static Bool MGASaveScreen(ScreenPtr pScreen, int mode);
/* This shouldn't be needed since RAC will disable all I/O for MGA cards. */
#ifdef DISABLE_VGA_IO
@@ -162,9 +165,13 @@ static Bool MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
DriverRec MGA = {
VERSION,
+ MGA_DRIVER_NAME,
+#if 0
"accelerated driver for Matrox Millennium and Mystique cards",
+#endif
MGAIdentify,
MGAProbe,
+ MGAAvailableOptions,
NULL,
0
};
@@ -208,6 +215,7 @@ typedef enum {
OPTION_COLOR_KEY,
OPTION_SET_MCLK,
OPTION_OVERCLOCK_MEM,
+ OPTION_VIDEO_KEY,
OPTION_ROTATE
} MGAOpts;
@@ -225,6 +233,7 @@ static OptionInfoRec MGAOptions[] = {
{ OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE },
{ OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE },
{ OPTION_OVERCLOCK_MEM, "OverclockMem", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE },
{ OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -287,6 +296,46 @@ static const char *ramdacSymbols[] = {
NULL
};
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAvailable",
+ "drmAddBufs",
+ "drmAddMap",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmAgpAcquire",
+ "drmAgpRelease",
+ "drmAgpEnable",
+ "drmAgpAlloc",
+ "drmAgpFree",
+ "drmAgpBind",
+ "drmAgpGetMode",
+ "drmAgpBase",
+ "drmAgpSize",
+ "drmMgaCleanupDma",
+ "drmMgaLockUpdate",
+ "drmMgaInitDma",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRIGetDrawableIndex",
+ "DRIFinishScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICloseScreen",
+ "DRIDestroyInfoRec",
+ "DRIScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICreateInfoRec",
+ "DRILock",
+ "DRIUnlock",
+ "DRIGetSAREAPrivate",
+ "DRIGetContext",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
#define MGAuseI2C 1
static const char *ddcSymbols[] = {
@@ -309,6 +358,12 @@ static const char *shadowSymbols[] = {
NULL
};
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ NULL
+};
+
static const char *fbdevHWSymbols[] = {
"fbdevHWInit",
"fbdevHWUseBuildinMode",
@@ -381,7 +436,12 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
xf8_32bppSymbols, ramdacSymbols,
ddcSymbols, i2cSymbols, shadowSymbols,
- fbdevHWSymbols, NULL);
+ fbdevHWSymbols, vbeSymbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
+
+ NULL);
/*
* The return value must be non-NULL on success even though there
@@ -439,6 +499,12 @@ MGAFreeRec(ScrnInfoPtr pScrn)
pScrn->driverPrivate = NULL;
}
+static
+OptionInfoPtr
+MGAAvailableOptions(int chipid, int busid)
+{
+ return MGAOptions;
+}
/* Mandatory */
static void
@@ -453,7 +519,7 @@ static Bool
MGAProbe(DriverPtr drv, int flags)
{
int i;
- GDevPtr *devSections;
+ GDevPtr *devSections = NULL;
int *usedChips;
int numDevSections;
int numUsed;
@@ -509,12 +575,15 @@ MGAProbe(DriverPtr drv, int flags)
MGAChipsets, MGAPciChipsets, devSections,
numDevSections, drv, &usedChips);
/* Free it since we don't need that list after this */
- xfree(devSections);
+ if (devSections)
+ xfree(devSections);
devSections = NULL;
if (numUsed <= 0)
return FALSE;
- for (i = 0; i < numUsed; i++) {
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn;
#ifdef DISABLE_VGA_IO
MgaSavePtr smga;
@@ -694,8 +763,6 @@ MGAReadBios(ScrnInfoPtr pScrn)
ErrorF("Pins[0x%02x] is 0x%02x\n", i,
((unsigned char *)pBios2)[i]);
#endif
- ErrorF("0x20 of Pins[0x34] is %s\n",
- (pBios2->VidCtrl & 0x20) ? "set" : "cleared");
return;
} else {
/* Set default MCLK values (scaled by 10 kHz) */
@@ -719,7 +786,7 @@ static void
MGASoftReset(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
- int i;
+/* int i; */
pMga->FbMapSize = 8192 * 1024;
MGAMapMem(pScrn);
@@ -733,6 +800,9 @@ MGASoftReset(ScrnInfoPtr pScrn)
OUTREG(MGAREG_MACCESS, 1<<15);
usleep(10);
+#if 0
+ /* This will hang if the PLLs aren't on */
+
/* wait until drawing engine is ready */
while ( MGAISBUSY() )
usleep(1000);
@@ -742,6 +812,7 @@ MGASoftReset(ScrnInfoPtr pScrn)
WAITFIFO(i);
while ( i-- )
OUTREG(MGAREG_SHIFT, 0);
+#endif
MGAUnmapMem(pScrn);
}
@@ -754,86 +825,99 @@ MGASoftReset(ScrnInfoPtr pScrn)
static int
MGACountRam(ScrnInfoPtr pScrn)
{
- MGAPtr pMga = MGAPTR(pScrn);
-
- if (pMga->FbAddress)
- {
- volatile unsigned char* base;
- unsigned char tmp, tmp3, tmp5;
-
- pMga->FbMapSize = 8192 * 1024;
- MGAMapMem(pScrn);
- base = pMga->FbBase;
-
- /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */
- OUTREG8(0x1FDE, 3);
- tmp = INREG8(0x1FDF);
- OUTREG8(0x1FDF, tmp | 0x80);
-
- /* write, read and compare method */
- base[0x500000] = 0x55;
- base[0x300000] = 0x33;
- base[0x100000] = 0x11;
- tmp5 = base[0x500000];
- tmp3 = base[0x300000];
-
- /* restore CRTCEXT3 state */
- OUTREG8(0x1FDE, 3);
- OUTREG8(0x1FDF, tmp);
-
- MGAUnmapMem(pScrn);
-
- if(tmp5 == 0x55)
- return 8192;
- if(tmp3 == 0x33)
- return 4096;
- }
- return 2048;
-}
+ MGAPtr pMga = MGAPTR(pScrn);
+ int ProbeSize = 8192;
+ int SizeFound = 2048;
+ CARD32 biosInfo = 0;
-/*
- * GetAccelPitchValues -
- *
- * This function returns a list of display width (pitch) values that can
- * be used in accelerated mode.
- */
#if 0
-static int *
-GetAccelPitchValues(ScrnInfoPtr pScrn)
-{
- int *linePitches = NULL;
- int i, n = 0;
- MGAPtr pMga = MGAPTR(pScrn);
-
- /* XXX ajv - 512, 576, and 1536 may not be supported
- line pitches. see sdk pp 4-59 for more
- details. Why anyone would want less than 640 is
- bizarre. (maybe lots of pixels tall?) */
-
- /* The only line pitches the accelerator supports */
-#if 0
- int accelWidths[] = { 512, 576, 640, 768, 800, 960,
- 1024, 1152, 1280, 1536, 1600, 1920, 2048, 0 };
-#else
- int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280,
- 1600, 1920, 2048, 0 };
+ /* This isn't correct. It looks like this can have arbitrary
+ data for the memconfig even when the bios has initialized
+ it. At least, my cards don't advertise the documented
+ values (my 8 and 16 Meg G200s have the same values) */
+ if(pMga->Primary) /* can only trust this for primary cards */
+ biosInfo = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
#endif
- for (i = 0; accelWidths[i] != 0; i++) {
- if (accelWidths[i] % pMga->Rounding == 0) {
- n++;
- linePitches = xnfrealloc(linePitches, n * sizeof(int));
- linePitches[n - 1] = accelWidths[i];
+ switch(pMga->Chipset) {
+ case PCI_CHIP_MGA2164:
+ case PCI_CHIP_MGA2164_AGP:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unable to probe memory amount due to hardware bug. "
+ "Assuming 4096 KB\n");
+ return 4096;
+ case PCI_CHIP_MGAG400:
+ if(biosInfo) {
+ switch((biosInfo >> 10) & 0x07) {
+ case 0:
+ return (biosInfo & (1 << 14)) ? 32768 : 16384;
+ case 1:
+ case 2:
+ return 16384;
+ case 3:
+ case 5:
+ return 65536;
+ case 4:
+ return 32768;
+ }
}
+ ProbeSize = 32768;
+ break;
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ if(biosInfo) {
+ switch((biosInfo >> 11) & 0x03) {
+ case 0:
+ return 8192;
+ default:
+ return 16384;
+ }
+ }
+ ProbeSize = 16384;
+ break;
+ case PCI_CHIP_MGAG100:
+ if(biosInfo) /* I'm not sure if the docs are correct */
+ return (biosInfo & (1 << 12)) ? 16384 : 8192;
+ case PCI_CHIP_MGA1064:
+ case PCI_CHIP_MGA2064:
+ ProbeSize = 8192;
+ break;
+ default:
+ break;
}
- /* Mark the end of the list */
- if (n > 0) {
- linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
- linePitches[n] = 0;
- }
- return linePitches;
+
+ if (pMga->FbAddress) {
+ volatile unsigned char* base;
+ unsigned char tmp;
+ int i;
+
+ pMga->FbMapSize = ProbeSize * 1024;
+ MGAMapMem(pScrn);
+ base = pMga->FbBase;
+
+ /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */
+ OUTREG8(0x1FDE, 3);
+ tmp = INREG8(0x1FDF);
+ OUTREG8(0x1FDF, tmp | 0x80);
+
+ /* write, read and compare method */
+ for(i = ProbeSize; i > 2048; i -= 2048) {
+ base[(i * 1024) - 1] = 0xAA;
+ OUTREG8(MGAREG_CRTC_INDEX, 0); /* flush the cache */
+ if(base[(i * 1024) - 1] == 0xAA) {
+ SizeFound = i;
+ break;
+ }
+ }
+
+ /* restore CRTCEXT3 state */
+ OUTREG8(0x1FDE, 3);
+ OUTREG8(0x1FDF, tmp);
+
+ MGAUnmapMem(pScrn);
+ }
+ return SizeFound;
}
-#endif
static xf86MonPtr
MGAdoDDC(ScrnInfoPtr pScrn)
@@ -878,7 +962,6 @@ MGAdoDDC(ScrnInfoPtr pScrn)
/* Initialize I2C bus - used by DDC if available */
if (pMga->i2cInit) {
pMga->i2cInit(pScrn);
-ErrorF("I2C initialized on %p\n",pMga->I2C);
}
/* Read and output monitor info using DDC2 over I2C bus */
if (pMga->I2C) {
@@ -908,6 +991,8 @@ ErrorF("I2C initialized on %p\n",pMga->I2C);
vgaHWUnmapMem(pScrn);
}
+ xf86SetDDCproperties(pScrn, MonInfo);
+
return MonInfo;
}
@@ -970,6 +1055,18 @@ VgaIOEnable(void *arg)
}
#endif /* DISABLE_VGA_IO */
+extern xf86MonPtr ConfiguredMonitor;
+
+void
+MGAProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe);
+ }
+}
+
/* Mandatory */
static Bool
MGAPreInit(ScrnInfoPtr pScrn, int flags)
@@ -1002,6 +1099,23 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
if (pScrn->numEntities != 1)
return FALSE;
+ /* Allocate the MGARec driverPrivate */
+ if (!MGAGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pMga = MGAPTR(pScrn);
+
+ /* Get the entity, and make sure it is PCI. */
+ pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pMga->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ if (flags & PROBE_DETECT) {
+ MGAProbeDDC(pScrn, pMga->pEnt->index);
+ return TRUE;
+ }
+
/* The vgahw module should be loaded here when needed */
if (!xf86LoadSubModule(pScrn, "vgahw"))
return FALSE;
@@ -1014,16 +1128,19 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
if (!vgaHWGetHWRec(pScrn))
return FALSE;
- /* Allocate the MGARec driverPrivate */
- if (!MGAGetRec(pScrn)) {
- return FALSE;
- }
- pMga = MGAPTR(pScrn);
+#if 0
+ /* This is causing problems with restoring the card to it's
+ original state. If this is to be done, it needs to happen
+ after we've saved the original state */
+ /* Initialize the card through int10 interface if needed */
+ if ( xf86LoadSubModule(pScrn, "int10")){
+ xf86Int10InfoPtr pInt;
- /* Get the entity, and make sure it is PCI. */
- pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
- if (pMga->pEnt->location.type != BUS_PCI)
- return FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
+ pInt = xf86InitInt10(pMga->pEnt->index);
+ xf86FreeInt10(pInt);
+ }
+#endif
/* Find the PCI info for this screen */
pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index);
@@ -1060,8 +1177,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
xf86SetAccessFuncs(pMga->pEnt, &pMga->Access, &pMga->Access,
&pMga->Access, NULL);
#endif
-
- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
/* Set pScrn->monitor */
pScrn->monitor = pScrn->confScreen->monitor;
@@ -1120,17 +1235,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
}
}
- if (!xf86SetDefaultVisual(pScrn, -1)) {
+ if (!xf86SetDefaultVisual(pScrn, -1))
return FALSE;
- } else {
- /* We don't currently support DirectColor at > 8bpp */
- if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
- " (%s) is not supported at depth %d\n",
- xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
- return FALSE;
- }
- }
bytesPerPixel = pScrn->bitsPerPixel / 8;
@@ -1144,20 +1250,52 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, MGAOptions);
/* Set the bits per RGB for 8bpp mode */
- if (pScrn->depth == 8) {
- /* XXX This is here just to test options. */
- /* Default to 8 */
+ if (pScrn->depth == 8)
pScrn->rgbBits = 8;
-#if 0
- if (xf86GetOptValInteger(MGAOptions, OPTION_RGB_BITS,
- &pScrn->rgbBits)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
- pScrn->rgbBits);
- }
-#endif
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pMga->pEnt->device->chipset && *pMga->pEnt->device->chipset) {
+ pScrn->chipset = pMga->pEnt->device->chipset;
+ pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pMga->pEnt->device->chipID >= 0) {
+ pMga->Chipset = pMga->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pMga->Chipset);
+ } else {
+ from = X_PROBED;
+ pMga->Chipset = pMga->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
+ }
+ if (pMga->pEnt->device->chipRev >= 0) {
+ pMga->ChipRev = pMga->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pMga->ChipRev);
+ } else {
+ pMga->ChipRev = pMga->PciInfo->chipRev;
}
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * MGAProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pMga->Chipset);
+ return FALSE;
+ }
+ if (pMga->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
from = X_DEFAULT;
pMga->HWCursor = TRUE;
/*
@@ -1199,10 +1337,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
}
if ((s = xf86GetOptValString(MGAOptions, OPTION_OVERLAY))) {
if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) {
- if(pMga->Chipset == PCI_CHIP_MGAG100) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Option \"Overlay\" is not supported by the G100\n");
- } else if(pScrn->bitsPerPixel == 32) {
+ if(pScrn->bitsPerPixel == 32) {
pMga->Overlay8Plus24 = TRUE;
if(!xf86GetOptValInteger(
MGAOptions, OPTION_COLOR_KEY,&(pMga->colorKey)))
@@ -1213,13 +1348,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
"PseudoColor overlay enabled\n");
} else {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Option \"Overlay\" is not supported in this configuration\n");
+ "Option \"Overlay\" is only supported in 32 bits per pixel\n");
}
} else {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"\"%s\" is not a valid value for Option \"Overlay\"\n", s);
}
- }
+ }
+ if(xf86GetOptValInteger(MGAOptions, OPTION_VIDEO_KEY, &(pMga->videoKey))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
+ pMga->videoKey);
+ } else {
+ pMga->videoKey = (1 << pScrn->offset.red) |
+ (1 << pScrn->offset.green) |
+ (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
+ }
if (xf86ReturnOptValBool(MGAOptions, OPTION_SHADOW_FB, FALSE)) {
pMga->ShadowFB = TRUE;
pMga->NoAccel = TRUE;
@@ -1273,57 +1416,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
}
}
-
- /*
- * Set the Chipset and ChipRev, allowing config file entries to
- * override.
- */
- if (pMga->pEnt->device->chipset && *pMga->pEnt->device->chipset) {
- pScrn->chipset = pMga->pEnt->device->chipset;
- pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset);
- from = X_CONFIG;
- } else if (pMga->pEnt->device->chipID >= 0) {
- pMga->Chipset = pMga->pEnt->device->chipID;
- pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
- from = X_CONFIG;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
- pMga->Chipset);
- } else {
- from = X_PROBED;
- pMga->Chipset = pMga->PciInfo->chipType;
- pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
- }
- if (pMga->pEnt->device->chipRev >= 0) {
- pMga->ChipRev = pMga->pEnt->device->chipRev;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
- pMga->ChipRev);
- } else {
- pMga->ChipRev = pMga->PciInfo->chipRev;
- }
-
- /*
- * This shouldn't happen because such problems should be caught in
- * MGAProbe(), but check it just in case.
- */
- if (pScrn->chipset == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ChipID 0x%04X is not recognised\n", pMga->Chipset);
- return FALSE;
- }
- if (pMga->Chipset < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Chipset \"%s\" is not recognised\n", pScrn->chipset);
- return FALSE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
-
- if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) ||
+ if(pMga->HasSDRAM) { /* don't bother checking */ }
+ else if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) ||
(pMga->PciInfo->subsysCard == PCI_CARD_MARV_G200_SD) ||
(pMga->PciInfo->subsysCard == PCI_CARD_MYST_G200_SD) ||
(pMga->PciInfo->subsysCard == PCI_CARD_PROD_G100_SD)) {
pMga->HasSDRAM = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");
+ }
+ else if (pMga->Primary && (pMga->Chipset != PCI_CHIP_MGA2064) &&
+ (pMga->Chipset != PCI_CHIP_MGA2164) &&
+ (pMga->Chipset != PCI_CHIP_MGA2164_AGP)) {
+ if(!(pciReadLong(pMga->PciTag, PCI_OPTION_REG) & (1 << 14))) {
+ pMga->HasSDRAM = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");
+ }
}
switch (pMga->Chipset) {
@@ -1464,28 +1571,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
/*
* Reset card if it isn't primary one
*/
- if (!pMga->Primary && !pMga->FBDev)
+ if ( (!pMga->Primary && !pMga->FBDev) || xf86IsPc98() )
MGASoftReset(pScrn);
+
/*
* If the user has specified the amount of memory in the XF86Config
* file, we respect that setting.
*/
+ from = X_PROBED;
if (pMga->pEnt->device->videoRam != 0) {
pScrn->videoRam = pMga->pEnt->device->videoRam;
from = X_CONFIG;
- } else if((pMga->Chipset == PCI_CHIP_MGA2164) ||
- (pMga->Chipset == PCI_CHIP_MGA2164_AGP)){
- pScrn->videoRam = 4096;
- from = X_DEFAULT;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Skipping memory probe due to hardware bug. Assuming 4096 kBytes\n");
+ } else if (pMga->FBDev) {
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
} else {
- if (pMga->FBDev) {
- pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
- } else {
- pScrn->videoRam = MGACountRam(pScrn);
- }
- from = X_PROBED;
+ pScrn->videoRam = MGACountRam(pScrn);
}
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
pScrn->videoRam);
@@ -1847,6 +1947,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pMga->CurrentLayout.weight.green = pScrn->weight.green;
pMga->CurrentLayout.weight.blue = pScrn->weight.blue;
pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24;
+ pMga->CurrentLayout.mode = pScrn->currentMode;
return TRUE;
}
@@ -1860,37 +1961,30 @@ static Bool
MGAMapMem(ScrnInfoPtr pScrn)
{
MGAPtr pMga;
- int mmioFlags;
pMga = MGAPTR(pScrn);
/*
* Map IO registers to virtual address space
*/
-#if !defined(__alpha__)
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
-#else
/*
* For Alpha, we need to map SPARSE memory, since we need
- * byte/short access.
+ * byte/short access. This is taken care of automatically by the
+ * os-support layer.
*/
- mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
-#endif
- pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pMga->PciTag,
- pMga->IOAddress, 0x4000);
+ pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ pMga->PciTag, pMga->IOAddress, 0x4000);
if (pMga->IOBase == NULL)
return FALSE;
#ifdef __alpha__
- /*
- * for Alpha, we need to map DENSE memory as well, for
- * setting CPUToScreenColorExpandBase.
- */
- pMga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pMga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
pMga->PciTag, pMga->IOAddress, 0x4000);
if (pMga->IOBaseDense == NULL)
return FALSE;
-#endif /* __alpha__ */
+#endif
pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
pMga->PciTag, pMga->FbAddress,
@@ -1905,7 +1999,8 @@ MGAMapMem(ScrnInfoPtr pScrn)
DWORD access on DWORD boundaries to this window */
if (pMga->ILOADAddress) {
pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex,
- VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ VIDMEM_MMIO | VIDMEM_MMIO_32BIT |
+ VIDMEM_READSIDEEFFECT,
pMga->PciTag, pMga->ILOADAddress, 0x800000);
} else
pMga->ILOADBase = NULL;
@@ -1961,11 +2056,6 @@ MGAUnmapMem(ScrnInfoPtr pScrn)
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000);
pMga->IOBase = NULL;
-#ifdef __alpha__
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBaseDense, 0x4000);
- pMga->IOBaseDense = NULL;
-#endif /* __alpha__ */
-
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize);
pMga->FbBase = NULL;
pMga->FbStart = NULL;
@@ -2039,9 +2129,16 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
vgaReg = &hwp->ModeReg;
mgaReg = &pMga->ModeReg;
+#ifdef XF86DRI
+ if (pMga->directRenderingEnabled) {
+ DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
+/* MGADRISwapContext(screenInfo.screens[pScrn->scrnIndex]); */
+ }
+#endif
+
(*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE);
-
- MGAStormSync(pScrn);
+
+ MGAStormSync(pScrn); /* JEFF - Check */
MGAStormEngineInit(pScrn);
vgaHWProtect(pScrn, FALSE);
@@ -2052,6 +2149,13 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
outb(0xfac, 0x02);
}
+ pMga->CurrentLayout.mode = mode;
+
+#ifdef XF86DRI
+ if (pMga->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+#endif
+
return TRUE;
}
@@ -2129,7 +2233,6 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000);
if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
return FALSE;
- MGAStormSync(pScrn);
MGAStormEngineInit(pScrn);
} else {
/* Save the current state */
@@ -2141,7 +2244,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* Darken the screen for aesthetic reasons and set the viewport */
- MGASaveScreen(pScreen, FALSE);
+ MGASaveScreen(pScreen, SCREEN_SAVER_ON);
pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
/*
@@ -2195,7 +2298,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if(pMga->ShadowFB) {
pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
- pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height);
+ pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height);
displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3);
FBStart = pMga->ShadowPtr;
} else {
@@ -2203,6 +2306,19 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
FBStart = pMga->FbStart;
}
+#ifdef XF86DRI
+ /*
+ * Setup DRI after visuals have been established, but before cfbScreenInit
+ * is called. cfbScreenInit will eventually call into the drivers
+ * InitGLXVisuals call back.
+ */
+ if (!pMga->NoAccel)
+ pMga->directRenderingEnabled = MGADRIScreenInit(pScreen);
+ else
+ pMga->directRenderingEnabled = FALSE;
+#endif
+
+
switch (pScrn->bitsPerPixel) {
case 8:
ret = cfbScreenInit(pScreen, FBStart,
@@ -2276,6 +2392,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
/* Initialize software cursor.
Must precede creation of the default colormap */
@@ -2309,9 +2426,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
RefreshAreaFuncPtr refreshArea = MGARefreshArea;
if(pMga->Rotate) {
- pMga->PointerMoved = pScrn->PointerMoved;
- pScrn->PointerMoved = MGAPointerMoved;
-
+ if (!pMga->PointerMoved) {
+ pMga->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = MGAPointerMoved;
+ }
+
switch(pScrn->bitsPerPixel) {
case 8: refreshArea = MGARefreshArea8; break;
case 16: refreshArea = MGARefreshArea16; break;
@@ -2326,21 +2445,29 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#ifdef DPMSExtension
xf86DPMSInit(pScreen, MGADisplayPowerManagementSet, 0);
#endif
-
+
+#ifdef XF86DRI
+ /* Initialize the Warp engine */
+ if (pMga->directRenderingEnabled) {
+ pMga->directRenderingEnabled = mgaConfigureWarp(pScrn);
+ }
+ if (pMga->directRenderingEnabled) {
+ /* Now that mi, cfb, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pMga->directRenderingEnabled = MGADRIFinishScreenInit(pScreen);
+ }
+ if (pMga->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n");
+ }
+#endif
+
pScrn->memPhysBase = pMga->FbAddress;
pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
-#ifdef XvExtension
- {
- XF86VideoAdaptorPtr *ptr;
- int n;
-
- n = xf86XVListGenericAdaptors(&ptr);
- if (n) {
- xf86XVScreenInit(pScreen, ptr, n);
- }
- }
-#endif
+ MGAInitVideo(pScreen);
pScreen->SaveScreen = MGASaveScreen;
@@ -2384,14 +2511,8 @@ MGAAdjustFrame(int scrnIndex, int x, int y, int flags)
pLayout = &pMga->CurrentLayout;
- if(pMga->ShowCache && y && pScrn->vtSema) {
- int lastline = pMga->FbUsableSize /
- (pScrn->displayWidth * pScrn->bitsPerPixel/8);
-
- lastline -= pScrn->currentMode->VDisplay;
+ if(pMga->ShowCache && y && pScrn->vtSema)
y += pScrn->virtualY - 1;
- if(y > lastline) y = lastline;
- }
Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >>
(3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]);
@@ -2430,7 +2551,17 @@ static Bool
MGAEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+ MGAPtr pMGA;
+ pMGA = MGAPTR(pScrn);
+ if (pMGA->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRIUnlock(pScreen);
+ }
+#endif
+
if (!MGAModeInit(pScrn, pScrn->currentMode))
return FALSE;
MGAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
@@ -2441,9 +2572,18 @@ static Bool
MGAEnterVTFBDev(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+ MGAPtr pMGA;
+
+ pMGA = MGAPTR(pScrn);
+ if (pMGA->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRIUnlock(pScreen);
+ }
+#endif
fbdevHWEnterVT(scrnIndex,flags);
- MGAStormSync(pScrn);
MGAStormEngineInit(pScrn);
return TRUE;
}
@@ -2461,12 +2601,24 @@ MGALeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(pScrn);
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+ MGAPtr pMGA;
+#endif
MGARestore(pScrn);
vgaHWLock(hwp);
if (xf86IsPc98())
outb(0xfac, 0x00);
+#ifdef XF86DRI
+ pMGA = MGAPTR(pScrn);
+ if (pMGA->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRILock(pScreen, 0);
+ }
+#endif
+
}
@@ -2496,6 +2648,13 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
vgaHWUnmapMem(pScrn);
}
}
+#ifdef XF86DRI
+ if (pMga->directRenderingEnabled) {
+ MGADRICloseScreen(pScreen);
+ pMga->directRenderingEnabled=FALSE;
+ }
+#endif
+
if (pMga->AccelInfoRec)
XAADestroyInfoRec(pMga->AccelInfoRec);
if (pMga->CursorInfoRec)
@@ -2504,11 +2663,17 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
xfree(pMga->ShadowPtr);
if (pMga->DGAModes)
xfree(pMga->DGAModes);
+ if (pMga->adaptor)
+ xfree(pMga->adaptor);
+
pScrn->vtSema = FALSE;
if (xf86IsPc98())
outb(0xfac, 0x00);
+ if(pMga->BlockHandler)
+ pScreen->BlockHandler = pMga->BlockHandler;
+
pScreen->CloseScreen = pMga->CloseScreen;
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
@@ -2524,7 +2689,8 @@ MGAFreeScreen(int scrnIndex, int flags)
* This only gets called when a screen is being deleted. It does not
* get called routinely at the end of a server generation.
*/
- vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
MGAFreeRec(xf86Screens[scrnIndex]);
}
@@ -2558,9 +2724,9 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
/* Mandatory */
static Bool
-MGASaveScreen(ScreenPtr pScreen, Bool unblank)
+MGASaveScreen(ScreenPtr pScreen, int mode)
{
- return vgaHWSaveScreen(pScreen, unblank);
+ return vgaHWSaveScreen(pScreen, mode);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c
deleted file mode 100644
index 6dbebb162..000000000
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_drm.c
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86Resources.h"
-#include "xf86_ansic.h"
-#include "compiler.h"
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-#include "xf86Priv.h"
-#include "mga_bios.h"
-#include "mga_reg.h"
-#include "mga.h"
-#include "mga_macros.h"
-#include "mga_dri.h"
-
-#ifndef XFree86LOADER
-#include <sys/stat.h>
-#include <sys/mman.h>
-#endif
-
-#include "xf86drm.h"
-#include "drm.h"
-#include "mga_drm_public.h"
-
-Bool mgadrmCleanupDma(ScrnInfoPtr pScrn)
-{
- MGAPtr pMGA = MGAPTR(pScrn);
- drm_mga_init_t init;
-
- memset(&init, 0, sizeof(drm_mga_init_t));
- init.func = MGA_CLEANUP_DMA;
-
- if(ioctl(pMGA->drmSubFD, DRM_IOCTL_MGA_INIT, &init)) {
- ErrorF("Mga Dma Cleanup Failed\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-int mgadrmInitDma(ScrnInfoPtr pScrn, int prim_size)
-{
- MGAPtr pMGA = MGAPTR(pScrn);
- MGADRIPtr pMGADRI = (MGADRIPtr)pMGA->pDRIInfo->devPrivate;
- MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo;
- drm_mga_init_t init;
-
- memset(&init, 0, sizeof(drm_mga_init_t));
- init.func = MGA_INIT_DMA;
- init.reserved_map_agpstart = 0;
- init.reserved_map_idx = 3;
- init.buffer_map_idx = 4;
- init.sarea_priv_offset = sizeof(XF86DRISAREARec);
- init.primary_size = prim_size;
- init.warp_ucode_size = pMGADRIServer->warp_ucode_size;
-
- switch(pMGA->Chipset) {
- case PCI_CHIP_MGAG400:
- init.chipset = MGA_CARD_TYPE_G400;
- break;
- case PCI_CHIP_MGAG200:
- init.chipset = MGA_CARD_TYPE_G200;
- break;
- case PCI_CHIP_MGAG200_PCI:
- default:
- ErrorF("Direct rendering not supported on this card/chipset\n");
- return FALSE;
- }
-
- init.fbOffset = pMGADRI->fbOffset;
- init.backOffset = pMGADRI->backOffset;
- init.depthOffset = pMGADRI->depthOffset;
- init.textureOffset = pMGADRI->textureOffset;
- init.textureSize = pMGADRI->textureSize;
- init.cpp = pMGADRI->cpp;
- init.stride = pMGADRI->stride;
-
- init.frontOrg = pMGA->DstOrg;
- init.backOrg = pMGADRI->backOffset; /* */
- init.depthOrg = pMGADRI->textureOffset;
- init.mAccess = pMGA->MAccess;
-
- if (pMGA->HasSDRAM)
- init.sgram = 0;
- else
- init.sgram = 1;
-
- memcpy(&init.WarpIndex, &pMGADRIServer->WarpIndex,
- sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES);
-
-
-
- ErrorF("Mga Dma Initialization start\n");
-
- if(ioctl(pMGA->drmSubFD, DRM_IOCTL_MGA_INIT, &init)) {
- ErrorF("Mga Dma Initialization Failed\n");
- return FALSE;
- }
- ErrorF("Mga Dma Initialization done\n");
- return TRUE;
-}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h
index 15d57b287..19b137740 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.10 1999/08/14 10:49:48 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.12 2000/02/11 17:25:57 dawes Exp $ */
#ifndef _MGA_MACROS_H_
#define _MGA_MACROS_H_
@@ -19,10 +19,23 @@
#define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
+#ifdef XF86DRI
+#define MGAREG_DWGSYNC 0x2c4c
+#define MGA_SYNC_XTAG 0x275f4200
+
+#define MGABUSYWAIT() do { \
+OUTREG(MGAREG_DWGSYNC, MGA_SYNC_XTAG); \
+while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \
+}while(0);
+
+#endif
+
#define MGAISBUSY() (INREG8(MGAREG_Status + 2) & 0x01)
-#define WAITFIFO(n) \
+#define WAITFIFO(cnt) \
if(!pMga->UsePCIRetry) {\
+ register int n = cnt; \
+ if(n > pMga->FifoSize) n = pMga->FifoSize; \
while(pMga->fifoCount < (n))\
pMga->fifoCount = INREG8(MGAREG_FIFOSTATUS);\
pMga->fifoCount -= n;\
@@ -71,4 +84,18 @@
WAITFIFO(1); \
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); }
+
+#ifdef XF86DRI
+extern void mgaGetQuiescence( ScrnInfoPtr pScrn );
+
+#define CHECK_DMA_QUIESCENT(pMGA, pScrn) { \
+ if (!pMGA->have_quiescense) { \
+ mgaGetQuiescence( pScrn ); \
+ } \
+}
+#else
+#define CHECK_DMA_QUIESCENT(pMGA, pScrn)
+#endif
+
+
#endif /* _MGA_MACROS_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c
index e97030796..903f6d279 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.59 1999/08/29 12:21:01 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.64 2000/02/12 20:45:24 dawes Exp $ */
/* All drivers should typically include these */
@@ -22,12 +22,21 @@
#include "miline.h"
#include "servermd.h"
+#ifdef XF86DRI
+#include "cfb.h"
+#include "GL/glxtokens.h"
+#endif
+
#include "mga_bios.h"
#include "mga.h"
#include "mga_reg.h"
#include "mga_map.h"
#include "mga_macros.h"
+#ifdef XF86DRI
+#include "mga_dri.h"
+#endif
+
static void MGANAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn,
int srcX, int srcY, int dstX, int dstY,
int w, int h);
@@ -87,6 +96,14 @@ static void MGANAME(SubsequentDashedTwoPointLine)(ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2,
int flags, int phase);
+#ifdef XF86DRI
+void MGANAME(DRIInitBuffers)(WindowPtr pWin,
+ RegionPtr prgn, CARD32 index);
+void MGANAME(DRIMoveBuffers)(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index);
+
+#endif
+
extern void MGAWriteBitmapColorExpand(ScrnInfoPtr pScrn, int x, int y,
int w, int h, unsigned char *src, int srcwidth,
int skipleft, int fg, int bg, int rop,
@@ -113,6 +130,9 @@ extern void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr);
extern void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr);
extern void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr,
int, int, XAACacheInfoPtr);
+extern void MGATEGlyphRenderer(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned int **glyphs, int, int, int, int,
+ unsigned planemask);
Bool
MGANAME(AccelInit)(ScreenPtr pScreen)
@@ -122,6 +142,9 @@ MGANAME(AccelInit)(ScreenPtr pScreen)
MGAPtr pMga = MGAPTR(pScrn);
int maxFastBlitMem;
BoxRec AvailFBArea;
+#ifdef XF86DRI
+ RegionRec MemRegion;
+#endif
pMga->AccelInfoRec = infoPtr = XAACreateInfoRec();
if(!infoPtr) return FALSE;
@@ -209,12 +232,10 @@ MGANAME(AccelInit)(ScreenPtr pScreen)
/* clipping */
infoPtr->SetClippingRectangle = MGASetClippingRectangle;
infoPtr->DisableClipping = MGADisableClipping;
- infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
HARDWARE_CLIP_DASHED_LINE |
- HARDWARE_CLIP_SOLID_FILL |
- HARDWARE_CLIP_MONO_8x8_FILL |
- HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
- HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND;
+ HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_MONO_8x8_FILL;
/* dashed lines */
infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
@@ -247,7 +268,11 @@ MGANAME(AccelInit)(ScreenPtr pScreen)
infoPtr->ColorExpandBase = pMga->ILOADBase;
} else {
infoPtr->ColorExpandRange = 0x1C00;
+#ifdef __alpha__
+ infoPtr->ColorExpandBase = pMga->IOBaseDense;
+#else
infoPtr->ColorExpandBase = pMga->IOBase;
+#endif
}
infoPtr->SetupForCPUToScreenColorExpandFill =
MGANAME(SetupForCPUToScreenColorExpandFill);
@@ -305,6 +330,7 @@ MGANAME(AccelInit)(ScreenPtr pScreen)
infoPtr->SubsequentCPUToScreenColorExpandFill) {
infoPtr->FillColorExpandRects = MGAFillColorExpandRects;
infoPtr->WriteBitmap = MGAWriteBitmapColorExpand;
+ infoPtr->TEGlyphRenderer = MGATEGlyphRenderer;
if(BITMAP_SCANLINE_PAD == 32)
infoPtr->NonTEGlyphRenderer = MGANonTEGlyphRenderer;
}
@@ -343,6 +369,7 @@ MGANAME(AccelInit)(ScreenPtr pScreen)
infoPtr->FillSolidSpansFlags |= NO_PLANEMASK;
infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK;
infoPtr->NonTEGlyphRendererFlags |= NO_PLANEMASK;
+ infoPtr->TEGlyphRendererFlags |= NO_PLANEMASK;
infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK;
}
@@ -355,10 +382,23 @@ MGANAME(AccelInit)(ScreenPtr pScreen)
AvailFBArea.x1 = 0;
- AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
- AvailFBArea.y2 = pMga->FbUsableSize / (pScrn->displayWidth * PSZ / 8);
+
+#ifndef XF86DRI
+ AvailFBArea.y1 = 0;
+ AvailFBArea.y2 = (min(pMga->FbUsableSize, 16*1024*1024)) /
+ (pScrn->displayWidth * PSZ / 8);
+
xf86InitFBManager(pScreen, &AvailFBArea);
+#else
+ AvailFBArea.y1 = pScrn->virtualY;
+ AvailFBArea.y2 = pScrn->virtualY+128;
+
+ REGION_INIT(pScreen, &MemRegion, &AvailFBArea, 1);
+ xf86InitFBManagerRegion(pScreen, &MemRegion);
+ REGION_UNINIT(pScreen, &MemRegion);
+#endif
+
return(XAAInit(pScreen, infoPtr));
}
@@ -414,6 +454,8 @@ void
MGAStormSync(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
+
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
while(MGAISBUSY());
/* flush cache before a read (mga-1064g 5.1.6) */
@@ -430,6 +472,8 @@ void MGAStormEngineInit(ScrnInfoPtr pScrn)
MGAPtr pMga = MGAPTR(pScrn);
MGAFBLayout *pLayout = &pMga->CurrentLayout;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
if (pMga->Chipset == PCI_CHIP_MGAG100)
maccess = 1 << 14;
@@ -451,10 +495,18 @@ void MGAStormEngineInit(ScrnInfoPtr pScrn)
pMga->fifoCount = 0;
- WAITFIFO(12);
+ while(MGAISBUSY());
+
+ if(!pMga->FifoSize) {
+ pMga->FifoSize = INREG8(MGAREG_FIFOSTATUS);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%i DWORD fifo\n",
+ pMga->FifoSize);
+ }
+
OUTREG(MGAREG_PITCH, pLayout->displayWidth);
OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
OUTREG(MGAREG_MACCESS, maccess);
+ pMga->MAccess = maccess;
pMga->PlaneMask = ~0;
if(pMga->Chipset != PCI_CHIP_MGAG100)
OUTREG(MGAREG_PLNWT, pMga->PlaneMask);
@@ -490,6 +542,8 @@ void MGASetClippingRectangle(
){
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
WAITFIFO(3);
OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1);
OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg);
@@ -501,6 +555,8 @@ void MGADisableClipping(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
WAITFIFO(3);
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
@@ -531,6 +587,9 @@ MGANAME(SetupForScreenToScreenCopy)(
CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO |
MGADWG_BITBLT | MGADWG_BFCOL;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
+
pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
MGANAME(SubsequentScreenToScreenCopy);
@@ -718,6 +777,8 @@ MGANAME(SetupForSolidFill)(
{
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
#if PSZ == 24
if(!RGBEQUAL(color))
pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
@@ -843,6 +904,8 @@ MGANAME(SetupForMono8x8PatternFill)(
MGAPtr pMga = MGAPTR(pScrn);
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
pMga->PatternRectCMD = MGADWG_TRAP | MGADWG_ARZERO | MGADWG_SGNZERO |
MGADWG_BMONOLEF;
@@ -957,6 +1020,8 @@ MGANAME(SetupForCPUToScreenColorExpandFill)(
CARD32 mgaCMD = MGADWG_ILOAD | MGADWG_LINEAR | MGADWG_SGNZERO |
MGADWG_SHIFTZERO | MGADWG_BMONOLEF;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
if(bg == -1) {
#if PSZ == 24
if(!RGBEQUAL(fg))
@@ -1017,6 +1082,8 @@ static void MGANAME(SetupForImageWrite)(
){
MGAPtr pMga = MGAPTR(pScrn);
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
WAITFIFO(3);
OUTREG(MGAREG_AR5, 0);
SET_PLANEMASK(planemask);
@@ -1061,6 +1128,8 @@ MGANAME(SetupForDashedLine)(
CARD32 NiceDashPattern = DashPattern[0];
int dwords = (length + 31) >> 5;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop];
pMga->StyleLen = length - 1;
@@ -1168,6 +1237,8 @@ MGANAME(SetupForPlanarScreenToScreenColorExpandFill)(
CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT |
MGADWG_SGNZERO | MGADWG_BPLAN;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
if(bg == -1) {
mgaCMD |= MGADWG_TRANSC;
WAITFIFO(4);
@@ -1218,6 +1289,8 @@ MGANAME(SetupForScreenToScreenColorExpandFill)(
){
MGAPtr pMga = MGAPTR(pScrn);
CARD32 mgaCMD = MGADWG_BITBLT | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
+
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
if(bg == -1) {
#if PSZ == 24
@@ -1259,32 +1332,35 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)(
MGAPtr pMga = MGAPTR(pScrn);
int pitch = pScrn->displayWidth * PSZ;
int start, end, next, num;
- int SrcOrg = 0, DstOrg = 0;
+ Bool resetDstOrg = FALSE;
if (pMga->AccelFlags & LARGE_ADDRESSES) {
- DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9;
- SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9;
+ int DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9;
+ int SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9;
+
y &= 1023;
+ srcy &= 1023;
WAITFIFO(2);
- if(DstOrg)
+ if(DstOrg) {
OUTREG(MGAREG_DSTORG, DstOrg << 6);
+ resetDstOrg = TRUE;
+ }
if(SrcOrg != pMga->SrcOrg) {
pMga->SrcOrg = SrcOrg;
OUTREG(MGAREG_SRCORG, SrcOrg << 6);
}
- SrcOrg <<= 9;
}
w--;
start = (XYADDRESS(srcx, srcy) * PSZ) + skipleft;
end = start + w + (pitch * (h - 1));
- /* src cannot split a 2 Meg boundary */
+ /* src cannot split a 2 Meg boundary from SrcOrg */
if(!((start ^ end) & 0xff000000)) {
WAITFIFO(4);
- OUTREG(MGAREG_AR3, start - SrcOrg);
- OUTREG(MGAREG_AR0, start + w - SrcOrg);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_AR0, start + w);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
} else {
@@ -1294,13 +1370,13 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)(
num = next - start - 1;
WAITFIFO(7);
- OUTREG(MGAREG_AR3, start - SrcOrg);
- OUTREG(MGAREG_AR0, start + num - SrcOrg);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_AR0, start + num);
OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff));
- OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1);
- OUTREG(MGAREG_AR3, next - SrcOrg);
- OUTREG(MGAREG_AR0, start + w - SrcOrg);
+ OUTREG(MGAREG_AR3, next);
+ OUTREG(MGAREG_AR0, start + w );
OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) |
((x + num + 1) & 0xffff));
start += pitch;
@@ -1310,8 +1386,8 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)(
if(num > h) num = h;
WAITFIFO(4);
- OUTREG(MGAREG_AR3, start - SrcOrg);
- OUTREG(MGAREG_AR0, start + w - SrcOrg);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_AR0, start + w);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num);
@@ -1321,7 +1397,7 @@ MGANAME(SubsequentScreenToScreenColorExpandFill)(
}
}
- if(DstOrg) {
+ if(resetDstOrg) {
WAITFIFO(1);
OUTREG(MGAREG_DSTORG, 0);
}
@@ -1375,6 +1451,8 @@ MGAWriteBitmapColorExpand(
CARD32* maxptr;
int dwords, maxlines, count;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
(*infoRec->SetupForCPUToScreenColorExpandFill)(
pScrn, fg, bg, rop, planemask);
@@ -1389,6 +1467,7 @@ MGAWriteBitmapColorExpand(
(pScrn, x, y, w, maxlines, skipleft);
count = maxlines;
while(count--) {
+ WAITFIFO(dwords);
destptr = MoveDWORDS(destptr, (CARD32*)src, dwords);
src += srcwidth;
if(destptr > maxptr)
@@ -1402,13 +1481,14 @@ MGAWriteBitmapColorExpand(
pScrn, x, y, w, h, skipleft);
while(h--) {
+ WAITFIFO(dwords);
destptr = MoveDWORDS(destptr, (CARD32*)src, dwords);
src += srcwidth;
if(destptr > maxptr)
destptr = (CARD32*)infoRec->ColorExpandBase;
}
- MGAStormSync(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
+ DISABLE_CLIP();
+ SET_SYNC_FLAG(infoRec);
}
@@ -1441,6 +1521,8 @@ MGAFillColorExpandRects(
} else
StippleFunc = XAAStippleScanlineFuncLSBFirst[2];
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
(*infoRec->SetupForCPUToScreenColorExpandFill)(
pScrn, fg, bg, rop, planemask);
@@ -1464,6 +1546,7 @@ MGAFillColorExpandRects(
pBox->x1, y, pBox->x2 - pBox->x1, maxlines, 0);
count = maxlines;
while(count--) {
+ WAITFIFO(dwords);
destptr = (*StippleFunc)(
destptr, (CARD32*)srcp, srcx, stipplewidth, dwords);
if(destptr > maxptr)
@@ -1483,6 +1566,7 @@ MGAFillColorExpandRects(
pBox->x1, y , pBox->x2 - pBox->x1, h, 0);
while(h--) {
+ WAITFIFO(dwords);
destptr = (*StippleFunc)(
destptr, (CARD32*)srcp, srcx, stipplewidth, dwords);
if(destptr > maxptr)
@@ -1497,8 +1581,8 @@ MGAFillColorExpandRects(
pBox++;
}
- MGAStormSync(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
+ DISABLE_CLIP();
+ SET_SYNC_FLAG(infoRec);
}
@@ -1514,6 +1598,8 @@ MGAFillSolidRectsDMA(
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
CARD32 *base = (CARD32*)pMga->ILOADBase;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
SET_SYNC_FLAG(infoRec);
(*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
@@ -1554,6 +1640,8 @@ MGAFillSolidSpansDMA(
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
CARD32 *base = (CARD32*)pMga->ILOADBase;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
SET_SYNC_FLAG(infoRec);
if(infoRec->ClipBox) {
@@ -1614,6 +1702,8 @@ MGAFillMono8x8PatternRectsTwoPass(
int nBox, SecondPassColor;
BoxPtr pBox;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
if((rop == GXcopy) && (bg != -1)) {
SecondPassColor = bg;
bg = -1;
@@ -1662,6 +1752,8 @@ void MGANonTEGlyphRenderer(
int x1, x2, y1, y2, i, h, skiptop, dwords, maxlines;
unsigned char *src;
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
(*infoRec->SetupForCPUToScreenColorExpandFill)(
pScrn, fg, -1, rop, planemask);
WAITFIFO(1);
@@ -1697,6 +1789,7 @@ void MGANonTEGlyphRenderer(
OUTREG(MGAREG_AR3, 0);
OUTREG(MGAREG_FXBNDRY, ((x2 - 1) << 16) | (x1 & 0xFFFF));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | h);
+ WAITFIFO(dwords * maxlines);
MoveDWORDS((CARD32*)infoRec->ColorExpandBase,
(CARD32*)src, dwords * maxlines);
src += dwords * maxlines << 2;
@@ -1710,12 +1803,12 @@ void MGANonTEGlyphRenderer(
OUTREG(MGAREG_AR3, 0);
OUTREG(MGAREG_FXBNDRY, ((x2 - 1) << 16) | (x1 & 0xFFFF));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | h);
-
+ WAITFIFO(dwords);
MoveDWORDS((CARD32*)infoRec->ColorExpandBase, (CARD32*)src, dwords);
}
- MGAStormSync(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
+ DISABLE_CLIP();
+ SET_SYNC_FLAG(infoRec);
}
void
@@ -1767,6 +1860,8 @@ MGAPolyPoint (
pbox = REGION_RECTS(pGC->pCompositeClip);
+ CHECK_DMA_QUIESCENT(pMga, infoRec->pScrn);
+
(*infoRec->SetClippingRectangle)(infoRec->pScrn,
pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
(*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
@@ -1831,6 +1926,8 @@ MGAFillCacheBltRects(
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start;
+ CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
+
(*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
pCache->trans_color);
@@ -1909,14 +2006,223 @@ MGAFillCacheBltRects(
SET_SYNC_FLAG(infoRec);
}
+void
+MGATEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GlyphScanlineFuncPtr GlyphFunc =
+ XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32* base;
+ int dwords;
-#endif
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+ w += skipleft;
+ x -= skipleft;
+ dwords = (w + 31) >> 5;
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+ base = (CARD32*)infoRec->ColorExpandBase;
+ if((dwords * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ WAITFIFO(dwords);
+ base = (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+ else
+ while(h--) {
+ WAITFIFO(dwords);
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+ DISABLE_CLIP();
+ SET_SYNC_FLAG(infoRec);
+}
+#endif
+#ifdef XF86DRI
+void
+MGANAME(DRIInitBuffers)(WindowPtr pWin, RegionPtr prgn, CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMGA = MGAPTR(pScrn);
+ BoxPtr pbox = REGION_RECTS(prgn);
+ int nbox = REGION_NUM_RECTS(prgn);
+
+ CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
+
+ MGANAME(SetupForSolidFill)(pScrn, 0, GXcopy, -1);
+ while (nbox--) {
+ MGASelectBuffer(pScrn, MGA_BACK);
+ MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1,
+ pbox->x2-pbox->x1, pbox->y2-pbox->y1);
+ MGASelectBuffer(pScrn, MGA_DEPTH);
+ MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1,
+ pbox->x2-pbox->x1, pbox->y2-pbox->y1);
+ pbox++;
+ }
+ MGASelectBuffer(pScrn, MGA_FRONT);
+
+ pMGA->AccelInfoRec->NeedToSync = TRUE;
+}
+/*
+ This routine is a modified form of XAADoBitBlt with the calls to
+ ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
+ instead of destination. My origin is upside down so the ydir cases
+ are reversed.
+*/
+
+void
+MGANAME(DRIMoveBuffers)(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMGA = MGAPTR(pScrn);
+ int nbox;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ int dx, dy;
+ DDXPointPtr pptSrc;
+
+ int screenwidth = pScrn->virtualX;
+ int screenheight = pScrn->virtualY;
+
+ CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
+
+ pbox = REGION_RECTS(prgnSrc);
+ nbox = REGION_NUM_RECTS(prgnSrc);
+ pboxNew1 = 0;
+ pptNew1 = 0;
+ pboxNew2 = 0;
+ pboxNew2 = 0;
+ pptSrc = &ptOldOrg;
+
+ dx = pParent->drawable.x - ptOldOrg.x;
+ dy = pParent->drawable.y - ptOldOrg.y;
+
+ /* If the copy will overlap in Y, reverse the order */
+ if (dy>0) {
+ ydir = -1;
+
+ if (nbox>1) {
+ /* Keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ if (!pboxNew1) return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* No changes required */
+ ydir = 1;
+ }
+
+ /* If the regions will overlap in X, reverse the order */
+ if (dx>0) {
+ xdir = -1;
+
+ if (nbox > 1) {
+ /*reverse orderof rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) && (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* No changes are needed */
+ xdir = 1;
+ }
+
+ MGANAME(SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, -1, -1);
+ for ( ; nbox-- ; pbox++)
+ {
+ int x1 = pbox->x1;
+ int y1 = pbox->y1;
+ int destx = x1 + dx;
+ int desty = y1 + dy;
+ int w = pbox->x2 - x1 + 1;
+ int h = pbox->y2 - y1 + 1;
+
+ if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
+ if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
+ if ( destx + w > screenwidth ) w = screenwidth - destx;
+ if ( desty + h > screenheight ) h = screenheight - desty;
+ if ( w <= 0 ) continue;
+ if ( h <= 0 ) continue;
+
+ MGASelectBuffer(pScrn, MGA_BACK);
+ MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1,y1, destx,desty, w, h);
+ MGASelectBuffer(pScrn, MGA_DEPTH);
+ MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1,y1, destx,desty, w, h);
+ }
+ MGASelectBuffer(pScrn, MGA_FRONT);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+ pMGA->AccelInfoRec->NeedToSync = TRUE;
+}
+
+#endif /* XF86DRI */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c
index 9bd43318a..f7c81968c 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c
@@ -18,6 +18,8 @@ Bool mgaConfigureWarp(ScrnInfoPtr pScrn)
MGAPtr pMga = MGAPTR(pScrn);
int wmisc;
+ CHECK_DMA_QUIESCENT( pMga, pScrn );
+
WAITFIFO(3);
switch(pMga->Chipset) {
@@ -108,7 +110,7 @@ static unsigned int mgaG400InstallMicrocode(MGAPtr pMGA, int agp_offset)
unsigned int microcode_size = 0;
memset(pMGADRIServer->WarpIndex, 0,
- sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES);
+ sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES);
microcode_size = mgaG400GetMicrocodeSize(pMGA);
mgaWarpInstallCode(tgz, MGA_WARP_TGZ);
@@ -150,7 +152,7 @@ static unsigned int mgaG200InstallMicrocode(MGAPtr pMGA, int agp_offset)
unsigned int microcode_size = 0;
memset(pMGADRIServer->WarpIndex, 0,
- sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES);
+ sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES);
microcode_size = mgaG400GetMicrocodeSize(pMGA);
mgaWarpInstallCode(tgz, MGA_WARP_TGZ);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c
new file mode 100644
index 000000000..d812149e1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.c
@@ -0,0 +1,198 @@
+/* $XFree86: xc/programs/Xserver/GL/dri/dri.c,v 1.4 1999/09/25 14:36:41 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@precisioninsight.com>
+ *
+ */
+
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Priv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "miline.h"
+
+#include "GL/glxtokens.h"
+
+#include "mga_bios.h"
+#include "mga_reg.h"
+#include "mga.h"
+#include "mga_macros.h"
+#include "mga_dri.h"
+#include "mga_wrap.h"
+
+
+
+static void MGAWakeupHandler(int screenNum,
+ pointer wakeupData,
+ unsigned long result,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ DRIWrappedFuncsRec *pDRIWrap = DRIGetWrappedFuncs(pScreen);
+
+ if (0) ErrorF("MGAWakeupHandler (in)\n");
+
+ /* Disabled: Check contention like the 3d clients do before trying
+ * to restore state.
+ */
+ DRILock(pScreen, 0);
+ MGASwapContext( pScreen );
+
+}
+
+static void MGABlockHandler(int screenNum,
+ pointer blockData,
+ pointer pTimeout,
+ pointer pReadmask)
+
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ DRIWrappedFuncsRec *pDRIWrap = DRIGetWrappedFuncs(pScreen);
+ MGASAREAPtr sa = (MGASAREAPtr)DRIGetSAREAPrivate( pScreen );
+
+ if (0) ErrorF("MGABlockHandler (out)\n");
+
+
+ /* Examine the cliprects for the most recently used 3d drawable.
+ * If they've changed, attempt to push the updated values into the
+ * sarea.
+ *
+ * This avoids the protocol round trip in all single-client
+ * frontbuffer rendering cases providing the cliprects fit into the
+ * sarea, and in all single-client backbuffer rendering with arbitary
+ * numbers of cliprects, for all operations except swapbuffers.
+ *
+ * Thus the number of round trips in the cases where comparison is
+ * possible is reduced to no more (and usually fewer) than the number
+ * Utah requires.
+ */
+
+ if (sa->req_drawable != sa->exported_drawable ||
+ sa->exported_stamp != DRIGetDrawableStamp( pScreen, sa->exported_index ))
+ {
+ int i;
+ XF86DRIClipRectPtr frontboxes, backboxes;
+ XF86DRIClipRectPtr boxes = (XF86DRIClipRectPtr)sa->exported_boxes;
+ WindowPtr window = LookupIDByType( sa->req_drawable, RT_WINDOW );
+
+ if (0)
+ ErrorF("Trying to update req_drawable: %d (exp %d), stamp %d/%d\n",
+ sa->req_drawable, sa->exported_drawable);
+
+ sa->exported_drawable = 0;
+
+ if (!window) {
+ if (0)
+ ErrorF("Couldn't retreive window\n");
+ sa->req_drawable = 0;
+ goto finished;
+ }
+
+ if (!DRIGetDrawableInfo( pScreen, &(window->drawable),
+ &sa->exported_index,
+ &sa->exported_stamp,
+ &sa->exported_front_x,
+ &sa->exported_front_y,
+ &sa->exported_w,
+ &sa->exported_h,
+ &sa->exported_nfront,
+ &frontboxes,
+ &sa->exported_back_x,
+ &sa->exported_back_y,
+ &sa->exported_nback,
+ &backboxes ))
+ {
+ if (0)
+ ErrorF("Couldn't get DRI info\n");
+ sa->req_drawable = 0;
+ goto finished;
+ }
+
+ /* If we can't fit both sets of cliprects into the sarea, try to
+ * fit the current draw buffer. Otherwise return.
+ */
+
+ sa->exported_buffers = MGA_FRONT | MGA_BACK;
+
+ if (sa->exported_nback + sa->exported_nfront >= MGA_NR_SAREA_CLIPRECTS) {
+ if (sa->req_draw_buffer == MGA_FRONT) {
+ sa->exported_buffers = MGA_FRONT;
+ if (sa->exported_nfront >= MGA_NR_SAREA_CLIPRECTS)
+ goto finished;
+ } else {
+ sa->exported_buffers = MGA_BACK;
+ if (sa->exported_nback >= MGA_NR_SAREA_CLIPRECTS)
+ goto finished;
+ }
+ }
+
+ if (sa->exported_buffers & MGA_BACK) {
+ for (i = 0 ; i < sa->exported_nback ; i++)
+ *boxes++ = backboxes[i];
+ }
+
+ if (sa->exported_buffers & MGA_FRONT) {
+ for (i = 0 ; i < sa->exported_nfront ; i++)
+ *boxes++ = frontboxes[i];
+ }
+
+ sa->exported_drawable = sa->req_drawable;
+ }
+
+ finished:
+ DRIUnlock(pScreen);
+}
+
+
+
+
+/* Just wrap validate tree for now to remove the quiescense hack.
+ * This is more of a win for the i810 than the mga, but should be useful
+ * here too.
+ */
+void MGADRIWrapFunctions(ScreenPtr pScreen, DRIInfoPtr pDRIInfo)
+{
+ pDRIInfo->wrap.BlockHandler = MGABlockHandler;
+ pDRIInfo->wrap.WakeupHandler = MGAWakeupHandler;
+/* pDRIInfo->wrap.ValidateTree = NULL; */
+/* pDRIInfo->wrap.PostValidateTree = NULL; */
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h
new file mode 100644
index 000000000..df65ad731
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_wrap.h
@@ -0,0 +1,6 @@
+#ifndef MGA_WRAP_H
+#define MGA_WRAP_H
+
+void MGADRIWrapFunctions(ScreenPtr pScreen, DRIInfoPtr pDRIInfo);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
index 96388450b..2c0ce97db 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
@@ -13,9 +13,8 @@ MOBJ = drmmodule.o
MTRR_DEFINES = -DHAS_MTRR_SUPPORT
#endif
-SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c $(MSRC)
-OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o $(MOBJ)
-
+SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c xf86drmI810.c xf86drmMga.c $(MSRC)
+OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o xf86drmI810.o xf86drmMga.o $(MOBJ)
INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
-I$(XINCLUDESRC) -I$(EXTINCSRC) -I../.. -Ikernel
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel
index 44d75c487..2ea6c7215 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel
@@ -14,7 +14,8 @@
L_TARGET := libdrm.a
L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
- lists.o lock.o ioctl.o fops.o vm.o dma.o
+ lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o \
+ agpsupport.o
M_OBJS :=
@@ -26,6 +27,14 @@ ifdef CONFIG_DRM_TDFX
M_OBJS += tdfx.o
endif
+ifdef CONFIG_DRM_MGA
+M_OBJS += mga.o
+endif
+
+ifdef CONFIG_DRM_R128
+M_OBJS += r128.o
+endif
+
include $(TOPDIR)/Rules.make
gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
@@ -33,3 +42,10 @@ gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET)
$(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm
+
+i810.o: i810_drv.o i810_context.o $(L_TARGET)
+ $(LD) $(LD_RFLAG) -r -o $@ i810_drv.o i810_bufs.o i810_dma.o i810_context.o -L. -ldrm
+
+mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET)
+ $(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_bufs.o mga_dma.o mga_context.o mga_state.o -L. -ldrm
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
index 8a41f880b..1db7a81fa 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
@@ -31,12 +31,14 @@
# *** Setup
+# **** End of SMP/MODVERSIONS detection
+
MODS= gamma.o tdfx.o
LIBS= libdrm.a
PROGS= drmstat
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
- lists.o lock.o ioctl.o fops.o vm.o dma.o
+ lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
DRMHEADERS= drm.h drmP.h
GAMMAOBJS= gamma_drv.o gamma_dma.o
@@ -48,6 +50,8 @@ TDFXHEADERS= tdfx_drv.h $(DRMHEADERS)
PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po
PROGHEADERS= xf86drm.h $(DRMHEADERS)
+INC= /usr/include
+
CFLAGS= -O2 $(WARNINGS)
WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \
-Wstrict-prototypes -Wshadow -Wnested-externs \
@@ -102,7 +106,27 @@ SMP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \
| grep -s 'SMP = ' | cut -d' ' -f3)
MODVERSIONS := $(shell gcc -E -I $(TREE) picker.c 2>/dev/null \
| grep -s 'MODVERSIONS = ' | cut -d' ' -f3)
-all::;@echo KERNEL HEADERS IN $(TREE): SMP=${SMP} MODVERSIONS=${MODVERSIONS}
+AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \
+ | grep -s 'AGP = ' | cut -d' ' -f3)
+ifeq ($(AGP),0)
+AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \
+ | grep -s 'AGP_MODULE = ' | cut -d' ' -f3)
+endif
+
+ifeq ($(AGP),1)
+MODCFLAGS += -DDRM_AGP
+DRMOBJS += agpsupport.o
+MODS += mga.o i810.o
+
+MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o
+MGAHEADERS= mga_drv.h $(DRMHEADERS)
+
+I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o
+I810HEADERS= i810_drv.h $(DRMHEADERS)
+endif
+
+all::;@echo KERNEL HEADERS IN $(TREE): SMP=${SMP} MODVERSIONS=${MODVERSIONS} \
+ AGP=${AGP}
all:: $(LIBS) $(MODS) $(PROGS)
endif
@@ -116,6 +140,7 @@ ifeq ($(MODVERSIONS),1)
MODCFLAGS += -DMODVERSIONS -include $(TREE)/linux/modversions.h
endif
+
# **** End of configuration
libdrm.a: $(DRMOBJS)
@@ -128,6 +153,14 @@ gamma.o: $(GAMMAOBJS) $(LIBS)
tdfx.o: $(TDFXOBJS) $(LIBS)
$(LD) -r $^ -o $@
+ifeq ($(AGP),1)
+mga.o: $(MGAOBJS) $(LIBS)
+ $(LD) -r $^ -o $@
+
+i810.o: $(I810OBJS) $(LIBS)
+ $(LD) -r $^ -o $@
+endif
+
drmstat: $(PROGOBJS)
$(CC) $(PRGCFLAGS) $^ $(PRGLIBS) -o $@
@@ -149,8 +182,11 @@ ChangeLog:
$(DRMOBJS): $(DRMHEADERS)
$(GAMMAOBJS): $(GAMMAHEADERS)
$(TDFXOBJS): $(TDFXHEADERS)
+ifeq ($(AGP),1)
+$(MGAOBJS): $(MGAHEADERS)
+$(I810OBJS): $(I810HEADERS)
+endif
$(PROGOBJS): $(PROGHEADERS)
clean:
- rm -f *.o *.po *~ core $(PROGS)
-
+ rm -f *.o *.a *.po *~ core $(PROGS)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c
index fb58154d6..c2da9ec7e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c
@@ -159,6 +159,8 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
-EFAULT);
if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
return -ENOMEM;
+
+ memset(entry, 0, sizeof(*entry));
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
type = (u32) request.type;
@@ -254,8 +256,10 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
return -EINVAL;
if (entry->bound) drm_unbind_agp(entry->memory);
- entry->prev->next = entry->next;
- entry->next->prev = entry->prev;
+
+ if (entry->prev) entry->prev->next = entry->next;
+ else dev->agp->memory = entry->next;
+ if (entry->next) entry->next->prev = entry->prev;
drm_free_agp(entry->memory, entry->pages);
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
@@ -269,15 +273,12 @@ drm_agp_head_t *drm_agp_init(void)
for (fill = &drm_agp_fill[0]; fill->name; fill++) {
char *n = (char *)fill->name;
-#if 0
- *fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
-#endif
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
- printk("%s resolves to 0x%08lx\n", n, (*fill->f).address);
+ DRM_DEBUG("%s resolves to 0x%08lx\n", n, (*fill->f).address);
if (!(*fill->f).address) agp_available = 0;
}
- printk("agp_available = %d\n", agp_available);
+ DRM_DEBUG("agp_available = %d\n", agp_available);
if (agp_available) {
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c
index 85244c7dc..7902f0ccf 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c
@@ -102,6 +102,11 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
dev->lock.hw_lock = map->handle; /* Pointer to lock */
}
break;
+#ifdef DRM_AGP
+ case _DRM_AGP:
+ map->offset = map->offset + dev->agp->base;
+ break;
+#endif
default:
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
@@ -172,7 +177,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
if (dev->queue_count) return -EBUSY; /* Not while in use */
- alignment = (request.flags & DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
+ alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c
index f67209d44..781984f11 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ctxbitmap.c
@@ -53,7 +53,7 @@ int drm_ctxbitmap_next(drm_device_t *dev)
bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
if (bit < DRM_MAX_CTXBITMAP) {
set_bit(bit, dev->ctx_bitmap);
- printk("drm_ctxbitmap_next bit : %d\n", bit);
+ DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
return bit;
}
return -1;
@@ -64,15 +64,15 @@ int drm_ctxbitmap_init(drm_device_t *dev)
int i;
int temp;
- dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE * 4,
+ dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE,
DRM_MEM_CTXBITMAP);
if(dev->ctx_bitmap == NULL) {
return -ENOMEM;
}
- memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE * 4);
+ memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE);
for(i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
temp = drm_ctxbitmap_next(dev);
- printk("drm_ctxbitmap_init : %d\n", temp);
+ DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp);
}
return 0;
@@ -80,7 +80,7 @@ int drm_ctxbitmap_init(drm_device_t *dev)
void drm_ctxbitmap_cleanup(drm_device_t *dev)
{
- drm_free((void *)dev->ctx_bitmap, PAGE_SIZE * 4,
+ drm_free((void *)dev->ctx_bitmap, PAGE_SIZE,
DRM_MEM_CTXBITMAP);
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c
index 8291e52e4..37ab674f8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c
@@ -63,15 +63,24 @@ void drm_dma_takedown(drm_device_t *dev)
dma->bufs[i].page_order,
DRM_MEM_DMA);
}
- drm_free(dma->bufs[i].buflist,
- dma->buf_count
- * sizeof(*dma->bufs[0].buflist),
- DRM_MEM_BUFS);
drm_free(dma->bufs[i].seglist,
- dma->buf_count
+ dma->bufs[i].seg_count
* sizeof(*dma->bufs[0].seglist),
DRM_MEM_SEGS);
- drm_freelist_destroy(&dma->bufs[i].freelist);
+ }
+ if(dma->bufs[i].buf_count) {
+ for(j = 0; j < dma->bufs[i].buf_count; j++) {
+ if(dma->bufs[i].buflist[j].dev_private) {
+ drm_free(dma->bufs[i].buflist[j].dev_private,
+ dma->bufs[i].buflist[j].dev_priv_size,
+ DRM_MEM_BUFS);
+ }
+ }
+ drm_free(dma->bufs[i].buflist,
+ dma->bufs[i].buf_count *
+ sizeof(*dma->bufs[0].buflist),
+ DRM_MEM_BUFS);
+ drm_freelist_destroy(&dma->bufs[i].freelist);
}
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index 7b8e88265..ae4c65ca3 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -61,6 +61,19 @@ typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
+/* Warning: If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well */
+
+typedef struct drm_clip_rect {
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
+} drm_clip_rect_t;
+
+/* Seperate include files for the i810/mga specific structures */
+#include "mga_drm.h"
+#include "i810_drm.h"
typedef struct drm_version {
int version_major; /* Major version */
@@ -101,7 +114,8 @@ typedef struct drm_control {
typedef enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
_DRM_REGISTERS = 1, /* no caching, no core dump */
- _DRM_SHM = 2 /* shared, cached */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3 /* AGP/GART */
} drm_map_type_t;
typedef enum drm_map_flags {
@@ -165,8 +179,11 @@ typedef struct drm_buf_desc {
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
enum {
- DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */
+ _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
} flags;
+ unsigned long agp_start; /* Start address of where the agp buffers
+ * are in the agp aperture */
} drm_buf_desc_t;
typedef struct drm_buf_info {
@@ -237,6 +254,38 @@ typedef struct drm_irq_busid {
int funcnum;
} drm_irq_busid_t;
+typedef struct drm_agp_mode {
+ unsigned long mode;
+} drm_agp_mode_t;
+
+ /* For drm_agp_alloc -- allocated a buffer */
+typedef struct drm_agp_buffer {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for BIND/UNBIND ioctls */
+ unsigned long type; /* Type of memory to allocate */
+ unsigned long physical; /* Physical used by i810 */
+} drm_agp_buffer_t;
+
+ /* For drm_agp_bind */
+typedef struct drm_agp_binding {
+ unsigned long handle; /* From drm_agp_buffer */
+ unsigned long offset; /* In bytes -- will round to page boundary */
+} drm_agp_binding_t;
+
+typedef struct drm_agp_info {
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
+ unsigned short id_vendor;
+ unsigned short id_device;
+} drm_agp_info_t;
+
#define DRM_IOCTL_BASE 'd'
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
@@ -276,4 +325,28 @@ typedef struct drm_irq_busid {
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOR( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOW( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+
+/* Mga specific ioctls */
+#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
+#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
+#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
+#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
+#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+
+/* I810 specific ioctls */
+#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t)
+#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
+#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
index 312fba36f..f8e78eabd 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
@@ -48,8 +48,12 @@
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
+#ifdef DRM_AGP
+#include <linux/types.h>
+#include <linux/agp_backend.h>
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-#include <asm/spinlock.h>
+#include <linux/tqueue.h>
#include <linux/poll.h>
#endif
#include "drm.h"
@@ -69,21 +73,27 @@
#define DRM_FLAG_DEBUG 0x01
#define DRM_FLAG_NOCTX 0x02
-#define DRM_MEM_DMA 0
-#define DRM_MEM_SAREA 1
-#define DRM_MEM_DRIVER 2
-#define DRM_MEM_MAGIC 3
-#define DRM_MEM_IOCTLS 4
-#define DRM_MEM_MAPS 5
-#define DRM_MEM_VMAS 6
-#define DRM_MEM_BUFS 7
-#define DRM_MEM_SEGS 8
-#define DRM_MEM_PAGES 9
-#define DRM_MEM_FILES 10
-#define DRM_MEM_QUEUES 11
-#define DRM_MEM_CMDS 12
-#define DRM_MEM_MAPPINGS 13
-#define DRM_MEM_BUFLISTS 14
+#define DRM_MEM_DMA 0
+#define DRM_MEM_SAREA 1
+#define DRM_MEM_DRIVER 2
+#define DRM_MEM_MAGIC 3
+#define DRM_MEM_IOCTLS 4
+#define DRM_MEM_MAPS 5
+#define DRM_MEM_VMAS 6
+#define DRM_MEM_BUFS 7
+#define DRM_MEM_SEGS 8
+#define DRM_MEM_PAGES 9
+#define DRM_MEM_FILES 10
+#define DRM_MEM_QUEUES 11
+#define DRM_MEM_CMDS 12
+#define DRM_MEM_MAPPINGS 13
+#define DRM_MEM_BUFLISTS 14
+#define DRM_MEM_AGPLISTS 15
+#define DRM_MEM_TOTALAGP 16
+#define DRM_MEM_BOUNDAGP 17
+#define DRM_MEM_CTXBITMAP 18
+
+#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
/* Backward compatibility section */
/* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
@@ -235,6 +245,7 @@ typedef struct drm_buf {
int used; /* Amount of buffer in use (for DMA) */
unsigned long offset; /* Byte offset (used internally) */
void *address; /* Address of buffer */
+ unsigned long bus_address; /* Bus address of buffer */
struct drm_buf *next; /* Kernel-only: used for free list */
__volatile__ int waiting; /* On kernel DMA queue */
__volatile__ int pending; /* On hardware DMA queue */
@@ -250,6 +261,11 @@ typedef struct drm_buf {
DRM_LIST_PRIO = 4,
DRM_LIST_RECLAIM = 5
} list; /* Which list we're on */
+
+
+ void *dev_private;
+ int dev_priv_size;
+
#if DRM_DMA_HISTOGRAM
cycles_t time_queued; /* Queued to kernel DMA queue */
cycles_t time_dispatched; /* Dispatched to hardware */
@@ -376,6 +392,9 @@ typedef struct drm_device_dma {
int page_count;
unsigned long *pagelist;
unsigned long byte_count;
+ enum {
+ _DRM_DMA_USE_AGP = 0x01
+ } flags;
/* DMA support */
drm_buf_t *this_buffer; /* Buffer being sent */
@@ -384,6 +403,41 @@ typedef struct drm_device_dma {
wait_queue_head_t waiting; /* Processes waiting on free bufs */
} drm_device_dma_t;
+#ifdef DRM_AGP
+typedef struct drm_agp_mem {
+ unsigned long handle;
+ agp_memory *memory;
+ unsigned long bound; /* address */
+ int pages;
+ struct drm_agp_mem *prev;
+ struct drm_agp_mem *next;
+} drm_agp_mem_t;
+
+typedef struct drm_agp_head {
+ agp_kern_info agp_info;
+ const char *chipset;
+ drm_agp_mem_t *memory;
+ unsigned long mode;
+ int enabled;
+ int acquired;
+ unsigned long base;
+ int agp_mtrr;
+} drm_agp_head_t;
+
+typedef struct {
+ void (*free_memory)(agp_memory *);
+ agp_memory *(*allocate_memory)(size_t, u32);
+ int (*bind_memory)(agp_memory *, off_t);
+ int (*unbind_memory)(agp_memory *);
+ void (*enable)(u32);
+ int (*acquire)(void);
+ void (*release)(void);
+ void (*copy_info)(agp_kern_info *);
+} drm_agp_func_t;
+
+extern drm_agp_func_t drm_agp;
+#endif
+
typedef struct drm_device {
const char *name; /* Simple driver name */
char *unique; /* Unique identifier: e.g., busid */
@@ -462,6 +516,12 @@ typedef struct drm_device {
struct fasync_struct *buf_async;/* Processes waiting for SIGIO */
wait_queue_head_t buf_readers; /* Processes waiting to read */
wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */
+
+#ifdef DRM_AGP
+ drm_agp_head_t *agp;
+#endif
+ unsigned long *ctx_bitmap;
+ void *dev_private;
} drm_device_t;
@@ -533,6 +593,14 @@ extern void drm_free_pages(unsigned long address, int order,
extern void *drm_ioremap(unsigned long offset, unsigned long size);
extern void drm_ioremapfree(void *pt, unsigned long size);
+#ifdef DRM_AGP
+extern agp_memory *drm_alloc_agp(int pages, u32 type);
+extern int drm_free_agp(agp_memory *handle, int pages);
+extern int drm_bind_agp(agp_memory *handle, unsigned int start);
+extern int drm_unbind_agp(agp_memory *handle);
+#endif
+
+
/* Buffer management support (bufs.c) */
extern int drm_order(unsigned long size);
extern int drm_addmap(struct inode *inode, struct file *filp,
@@ -642,5 +710,32 @@ extern int drm_flush_unblock(drm_device_t *dev, int context,
drm_lock_flags_t flags);
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
drm_lock_flags_t flags);
+
+ /* Context Bitmap support (ctxbitmap.c) */
+extern int drm_ctxbitmap_init(drm_device_t *dev);
+extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
+extern int drm_ctxbitmap_next(drm_device_t *dev);
+extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
+
+#ifdef DRM_AGP
+ /* AGP/GART support (agpsupport.c) */
+extern drm_agp_head_t *drm_agp_init(void);
+extern int drm_agp_acquire(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_release(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_enable(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_info(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_alloc(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_free(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_unbind(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_agp_bind(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+#endif
#endif
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c
index 8fe6f7072..a96a38b26 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c
@@ -187,7 +187,7 @@ int main(int argc, char **argv)
case 'b':
count = strtoul(optarg, &pt, 0);
size = strtoul(pt+1, NULL, 0);
- if ((r = drmAddBufs(fd, count, size, 0)) < 0) {
+ if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) {
drmError(r, argv[0]);
return 1;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c
index ce970835a..a3c2bd4a0 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c
@@ -271,6 +271,10 @@ static int gamma_takedown(drm_device_t *dev)
- PAGE_SHIFT,
DRM_MEM_SAREA);
break;
+ case _DRM_AGP:
+ /* Do nothing here, because this is all
+ handled in the AGP/GART driver. */
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c
index 49455b434..c025e400b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c
@@ -32,152 +32,28 @@
#define __NO_VERSION__
#include "drmP.h"
+#include "i810_drv.h"
#include "linux/un.h"
int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_desc_t request;
- drm_buf_entry_t *entry;
- drm_buf_t *buf;
- unsigned long offset;
- unsigned long agp_offset;
- int count;
- int order;
- int size;
- int alignment;
- int page_order;
- int total;
- int byte_count;
- int i;
-
- if (!dma) return -EINVAL;
-
- copy_from_user_ret(&request,
- (drm_buf_desc_t *)arg,
- sizeof(request),
- -EFAULT);
-
- count = request.count;
- order = drm_order(request.size);
- size = 1 << order;
- agp_offset = request.agp_start;
- alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
- page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
- total = PAGE_SIZE << page_order;
- byte_count = 0;
-
- if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
- if (dev->queue_count) return -EBUSY; /* Not while in use */
- spin_lock(&dev->count_lock);
- if (dev->buf_use) {
- spin_unlock(&dev->count_lock);
- return -EBUSY;
- }
- atomic_inc(&dev->buf_alloc);
- spin_unlock(&dev->count_lock);
-
- down(&dev->struct_sem);
- entry = &dma->bufs[order];
- if (entry->buf_count) {
- up(&dev->struct_sem);
- atomic_dec(&dev->buf_alloc);
- return -ENOMEM; /* May only call once for each order */
- }
-
- entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
- DRM_MEM_BUFS);
- if (!entry->buflist) {
- up(&dev->struct_sem);
- atomic_dec(&dev->buf_alloc);
- return -ENOMEM;
- }
- memset(entry->buflist, 0, count * sizeof(*entry->buflist));
-
- entry->buf_size = size;
- entry->page_order = page_order;
-
- while(entry->buf_count < count) {
- for(offset = 0; offset + size <= total && entry->buf_count < count;
- offset += alignment, ++entry->buf_count) {
- buf = &entry->buflist[entry->buf_count];
- buf->idx = dma->buf_count + entry->buf_count;
- buf->total = alignment;
- buf->order = order;
- buf->used = 0;
- buf->offset = agp_offset - dev->agp->base + offset;/* ?? */
- buf->bus_address = agp_offset + offset;
- buf->address = agp_offset + offset + dev->agp->base;
- buf->next = NULL;
- buf->waiting = 0;
- buf->pending = 0;
- init_waitqueue_head(&buf->dma_wait);
- buf->pid = 0;
-#if DRM_DMA_HISTOGRAM
- buf->time_queued = 0;
- buf->time_dispatched = 0;
- buf->time_completed = 0;
- buf->time_freed = 0;
-#endif
- DRM_DEBUG("buffer %d @ %p\n",
- entry->buf_count, buf->address);
- }
- byte_count += PAGE_SIZE << page_order;
- }
-
- dma->buflist = drm_realloc(dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- (dma->buf_count + entry->buf_count)
- * sizeof(*dma->buflist),
- DRM_MEM_BUFS);
- for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
- dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-
- dma->buf_count += entry->buf_count;
- dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-
- drm_freelist_create(&entry->freelist, entry->buf_count);
- for (i = 0; i < entry->buf_count; i++) {
- drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
- }
-
- up(&dev->struct_sem);
-
- request.count = entry->buf_count;
- request.size = size;
-
- copy_to_user_ret((drm_buf_desc_t *)arg,
- &request,
- sizeof(request),
- -EFAULT);
-
- atomic_dec(&dev->buf_alloc);
- return 0;
-}
-
-int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_desc_t request;
- int count;
- int order;
- int size;
- int total;
- int page_order;
- drm_buf_entry_t *entry;
- unsigned long page;
- drm_buf_t *buf;
- int alignment;
- unsigned long offset;
- int i;
- int byte_count;
- int page_count;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_desc_t request;
+ drm_buf_entry_t *entry;
+ drm_buf_t *buf;
+ unsigned long offset;
+ unsigned long agp_offset;
+ int count;
+ int order;
+ int size;
+ int alignment;
+ int page_order;
+ int total;
+ int byte_count;
+ int i;
if (!dma) return -EINVAL;
@@ -186,20 +62,17 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
sizeof(request),
-EFAULT);
- count = request.count;
- order = drm_order(request.size);
- size = 1 << order;
-
- DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
- request.count, request.size, size, order, dev->queue_count);
-
- if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
- if (dev->queue_count) return -EBUSY; /* Not while in use */
-
+ count = request.count;
+ order = drm_order(request.size);
+ size = 1 << order;
+ agp_offset = request.agp_start;
alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
- total = PAGE_SIZE << page_order;
-
+ total = PAGE_SIZE << page_order;
+ byte_count = 0;
+
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
+ if (dev->queue_count) return -EBUSY; /* Not while in use */
spin_lock(&dev->count_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
@@ -207,15 +80,15 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
-
+
down(&dev->struct_sem);
entry = &dma->bufs[order];
if (entry->buf_count) {
up(&dev->struct_sem);
atomic_dec(&dev->buf_alloc);
- return -ENOMEM; /* May only call once for each order */
+ return -ENOMEM; /* May only call once for each order */
}
-
+
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
DRM_MEM_BUFS);
if (!entry->buflist) {
@@ -224,69 +97,44 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
return -ENOMEM;
}
memset(entry->buflist, 0, count * sizeof(*entry->buflist));
-
- entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
- DRM_MEM_SEGS);
- if (!entry->seglist) {
- drm_free(entry->buflist,
- count * sizeof(*entry->buflist),
- DRM_MEM_BUFS);
- up(&dev->struct_sem);
- atomic_dec(&dev->buf_alloc);
- return -ENOMEM;
- }
- memset(entry->seglist, 0, count * sizeof(*entry->seglist));
-
- dma->pagelist = drm_realloc(dma->pagelist,
- dma->page_count * sizeof(*dma->pagelist),
- (dma->page_count + (count << page_order))
- * sizeof(*dma->pagelist),
- DRM_MEM_PAGES);
- DRM_DEBUG("pagelist: %d entries\n",
- dma->page_count + (count << page_order));
-
-
- entry->buf_size = size;
+
+ entry->buf_size = size;
entry->page_order = page_order;
- byte_count = 0;
- page_count = 0;
- while (entry->buf_count < count) {
- if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break;
- entry->seglist[entry->seg_count++] = page;
- for (i = 0; i < (1 << page_order); i++) {
- DRM_DEBUG("page %d @ 0x%08lx\n",
- dma->page_count + page_count,
- page + PAGE_SIZE * i);
- dma->pagelist[dma->page_count + page_count++]
- = page + PAGE_SIZE * i;
- }
- for (offset = 0;
- offset + size <= total && entry->buf_count < count;
- offset += alignment, ++entry->buf_count) {
- buf = &entry->buflist[entry->buf_count];
- buf->idx = dma->buf_count + entry->buf_count;
- buf->total = alignment;
- buf->order = order;
- buf->used = 0;
- buf->offset = (dma->byte_count + byte_count + offset);
- buf->address = (void *)(page + offset);
- buf->next = NULL;
- buf->waiting = 0;
- buf->pending = 0;
- init_waitqueue_head(&buf->dma_wait);
- buf->pid = 0;
+ offset = 0;
+
+ while(entry->buf_count < count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+ buf->offset = offset;
+ buf->bus_address = dev->agp->base + agp_offset + offset;
+ buf->address = (void *)(agp_offset + offset + dev->agp->base);
+ buf->next = NULL;
+ buf->waiting = 0;
+ buf->pending = 0;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->pid = 0;
+
+ buf->dev_private = drm_alloc(sizeof(drm_i810_buf_priv_t),
+ DRM_MEM_BUFS);
+ buf->dev_priv_size = sizeof(drm_i810_buf_priv_t);
+
#if DRM_DMA_HISTOGRAM
- buf->time_queued = 0;
- buf->time_dispatched = 0;
- buf->time_completed = 0;
- buf->time_freed = 0;
+ buf->time_queued = 0;
+ buf->time_dispatched = 0;
+ buf->time_completed = 0;
+ buf->time_freed = 0;
#endif
- DRM_DEBUG("buffer %d @ %p\n",
- entry->buf_count, buf->address);
- }
+ offset = offset + alignment;
+ entry->buf_count++;
byte_count += PAGE_SIZE << page_order;
+
+ DRM_DEBUG("buffer %d @ %p\n",
+ entry->buf_count, buf->address);
}
-
+
dma->buflist = drm_realloc(dma->buflist,
dma->buf_count * sizeof(*dma->buflist),
(dma->buf_count + entry->buf_count)
@@ -294,45 +142,43 @@ int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
DRM_MEM_BUFS);
for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-
- dma->buf_count += entry->buf_count;
- dma->seg_count += entry->seg_count;
- dma->page_count += entry->seg_count << page_order;
- dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-
+
+ dma->buf_count += entry->buf_count;
+ dma->byte_count += byte_count;
drm_freelist_create(&entry->freelist, entry->buf_count);
for (i = 0; i < entry->buf_count; i++) {
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
}
-
+
up(&dev->struct_sem);
-
+
request.count = entry->buf_count;
request.size = size;
-
+
copy_to_user_ret((drm_buf_desc_t *)arg,
&request,
sizeof(request),
-EFAULT);
-
+
atomic_dec(&dev->buf_alloc);
+ dma->flags = _DRM_DMA_USE_AGP;
return 0;
}
int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
- drm_buf_desc_t request;
+ drm_buf_desc_t request;
- copy_from_user_ret(&request,
- (drm_buf_desc_t *)arg,
- sizeof(request),
- -EFAULT);
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
- if(request.flags & _DRM_AGP_BUFFER)
- return i810_addbufs_agp(inode, filp, cmd, arg);
- else
- return i810_addbufs_pci(inode, filp, cmd, arg);
+ if(request.flags & _DRM_AGP_BUFFER)
+ return i810_addbufs_agp(inode, filp, cmd, arg);
+ else
+ return -EINVAL;
}
int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -487,7 +333,7 @@ int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
}
int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
@@ -506,6 +352,7 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
spin_lock(&dev->count_lock);
if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock);
+ DRM_DEBUG("Busy\n");
return -EBUSY;
}
++dev->buf_use; /* Can't allocate more after this call */
@@ -515,34 +362,46 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
(drm_buf_map_t *)arg,
sizeof(request),
-EFAULT);
-
- if (request.count >= dma->buf_count) {
- if(dma->flags & _DRM_DMA_USE_AGP) {
- /* This is an ugly vicious hack */
- drm_map_t *map = NULL;
- for(i = 0; i < dev->map_count; i++) {
- map = dev->maplist[i];
- if(map->type == _DRM_AGP) break;
- }
- if (i >= dev->map_count || !map) {
- retcode = -EINVAL;
- goto done;
- }
+ DRM_DEBUG("dma->flags : %lx\n", dma->flags);
+ if (request.count >= dma->buf_count) {
+ if(dma->flags & _DRM_DMA_USE_AGP) {
+ drm_i810_private_t *dev_priv =
+ (drm_i810_private_t *)dev->dev_private;
+ drm_map_t *map = NULL;
- virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE,
- MAP_SHARED, (unsigned long)map->handle);
- }
- else {
- virtual = do_mmap(filp, 0, dma->byte_count,
- PROT_READ|PROT_WRITE, MAP_SHARED, 0);
- }
+ map = dev->maplist[dev_priv->buffer_map_idx];
+ if (!map) {
+ DRM_DEBUG("map is null\n");
+ retcode = -EINVAL;
+ goto done;
+ }
+ DRM_DEBUG("map->offset : %lx\n", map->offset);
+ DRM_DEBUG("map->size : %lx\n", map->size);
+ DRM_DEBUG("map->type : %d\n", map->type);
+ DRM_DEBUG("map->flags : %x\n", map->flags);
+ DRM_DEBUG("map->handle : %lx\n", map->handle);
+ DRM_DEBUG("map->mtrr : %d\n", map->mtrr);
+ down(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, map->size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ (unsigned long)map->offset);
+
+ up(&current->mm->mmap_sem);
+ } else {
+ down(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, dma->byte_count,
+ PROT_READ|PROT_WRITE, MAP_SHARED, 0);
+ up(&current->mm->mmap_sem);
+ }
if (virtual > -1024UL) {
- /* Real error */
+ /* Real error */
+ DRM_DEBUG("mmap error\n");
retcode = (signed long)virtual;
goto done;
}
request.virtual = (void *)virtual;
-
+
for (i = 0; i < dma->buf_count; i++) {
if (copy_to_user(&request.list[i].idx,
&dma->buflist[i]->idx,
@@ -571,14 +430,15 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
}
}
}
-done:
+ done:
request.count = dma->buf_count;
DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
-
+
copy_to_user_ret((drm_buf_map_t *)arg,
&request,
sizeof(request),
-EFAULT);
+ DRM_DEBUG("retcode : %d\n", retcode);
return retcode;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c
new file mode 100644
index 000000000..5503edf24
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_context.c
@@ -0,0 +1,205 @@
+/* i810_context.c -- IOCTLs for i810 contexts -*- linux-c -*-
+ * Created: Mon Dec 13 09:51:35 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, 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, 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
+ * PRECISION INSIGHT 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.
+ *
+ * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#include <linux/sched.h>
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "i810_drv.h"
+
+static int i810_alloc_queue(drm_device_t *dev)
+{
+ int temp = drm_ctxbitmap_next(dev);
+ DRM_DEBUG("i810_alloc_queue: %d\n", temp);
+ return temp;
+}
+
+int i810_context_switch(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+
+ atomic_inc(&dev->total_ctx);
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ dev->ctx_start = get_cycles();
+#endif
+
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ if (drm_flags & DRM_FLAG_NOCTX) {
+ i810_context_switch_complete(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ drm_write_string(dev, buf);
+ }
+
+ return 0;
+}
+
+int i810_context_switch_complete(drm_device_t *dev, int new)
+{
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = jiffies;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+
+ /* If a context switch is ever initiated
+ when the kernel holds the lock, release
+ that lock here. */
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
+ - dev->ctx_start)]);
+
+#endif
+ clear_bit(0, &dev->context_flag);
+ wake_up(&dev->context_wait);
+
+ return 0;
+}
+
+int i810_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
+
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+ copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ copy_to_user_ret(&res.contexts[i],
+ &i,
+ sizeof(i),
+ -EFAULT);
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+ return 0;
+}
+
+int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ if ((ctx.handle = i810_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Skip kernel's context and get a new one. */
+ ctx.handle = i810_alloc_queue(dev);
+ }
+ if (ctx.handle == -1) {
+ DRM_DEBUG("Not enough free contexts.\n");
+ /* Should this return -EBUSY instead? */
+ return -ENOMEM;
+ }
+ DRM_DEBUG("%d\n", ctx.handle);
+ copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+ return 0;
+}
+
+int i810_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ /* This does nothing for the i810 */
+ return 0;
+}
+
+int i810_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+ /* This is 0, because we don't hanlde any context flags */
+ ctx.flags = 0;
+ copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+ return 0;
+}
+
+int i810_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+ return i810_context_switch(dev, dev->last_context, ctx.handle);
+}
+
+int i810_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+ i810_context_switch_complete(dev, ctx.handle);
+
+ return 0;
+}
+
+int i810_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+ if(ctx.handle != DRM_KERNEL_CONTEXT) {
+ drm_ctxbitmap_free(dev, ctx.handle);
+ }
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
index 09959b657..30fda5b8b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
@@ -25,8 +25,9 @@
*
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
* Jeff Hartmann <jhartmann@precisioninsight.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
*
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c,v 1.1 2000/02/11 17:26:04 dawes Exp $
+ * $XFree86$
*
*/
@@ -36,6 +37,9 @@
#include <linux/interrupt.h> /* For task queue support */
+#define I810_BUF_FREE 1
+#define I810_BUF_USED 0
+
#define I810_REG(reg) 2
#define I810_BASE(reg) ((unsigned long) \
dev->maplist[I810_REG(reg)]->handle)
@@ -43,544 +47,457 @@
#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
#define I810_READ(reg) I810_DEREF(reg)
#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0)
-
-void i810_dma_init(drm_device_t *dev)
+#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg)
+#define I810_READ16(reg) I810_DEREF16(reg)
+#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
+
+#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
+
+#define BEGIN_LP_RING(n) do { \
+ if (I810_VERBOSE) \
+ DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
+ n, __FUNCTION__); \
+ if (dev_priv->ring.space < n*4) \
+ i810_wait_ring(dev, n*4); \
+ dev_priv->ring.space -= n*4; \
+ outring = dev_priv->ring.tail; \
+ ringmask = dev_priv->ring.tail_mask; \
+ virt = dev_priv->ring.virtual_start; \
+} while (0)
+
+#define ADVANCE_LP_RING() do { \
+ if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
+ dev_priv->ring.tail = outring; \
+ I810_WRITE(LP_RING + RING_TAIL, outring); \
+} while(0)
+
+#define OUT_RING(n) do { \
+ if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
+ *(volatile unsigned int *)(virt + outring) = n; \
+ outring += 4; \
+ outring &= ringmask; \
+} while (0);
+
+static inline void i810_print_status_page(drm_device_t *dev)
{
- printk(KERN_INFO "i810_dma_init\n");
+ drm_device_dma_t *dma = dev->dma;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ u32 *temp = (u32 *)dev_priv->hw_status_page;
+ int i;
+
+ DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]);
+ DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]);
+ DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]);
+ DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]);
+ DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]);
+ for(i = 6; i < dma->buf_count + 6; i++) {
+ DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
+ }
}
-void i810_dma_cleanup(drm_device_t *dev)
+static drm_buf_t *i810_freelist_get(drm_device_t *dev)
{
- printk(KERN_INFO "i810_dma_cleanup\n");
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+ int used;
+
+ /* Linear search might not be the best solution */
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[ i ];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ /* In use is already a pointer */
+ used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
+ I810_BUF_USED);
+ if(used == I810_BUF_FREE) {
+ return buf;
+ }
+ }
+ return NULL;
}
-static inline void i810_dma_dispatch(drm_device_t *dev, unsigned long address,
- unsigned long length)
+/* This should only be called if the buffer is not sent to the hardware
+ * yet, the hardware updates in use for us once its on the ring buffer.
+ */
+
+static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
{
- printk(KERN_INFO "i810_dma_dispatch\n");
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ int used;
+
+ /* In use is already a pointer */
+ used = cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE);
+ if(used != I810_BUF_USED) {
+ DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
+ return -EINVAL;
+ }
+
+ return 0;
}
-static inline void i810_dma_quiescent(drm_device_t *dev)
+static int i810_dma_get_buffers(drm_device_t *dev, drm_dma_t *d)
{
+ int i;
+ drm_buf_t *buf;
+
+ for (i = d->granted_count; i < d->request_count; i++) {
+ buf = i810_freelist_get(dev);
+ if (!buf) break;
+ buf->pid = current->pid;
+ copy_to_user_ret(&d->request_indices[i],
+ &buf->idx,
+ sizeof(buf->idx),
+ -EFAULT);
+ copy_to_user_ret(&d->request_sizes[i],
+ &buf->total,
+ sizeof(buf->total),
+ -EFAULT);
+ ++d->granted_count;
+ }
+ return 0;
}
-static inline void i810_dma_ready(drm_device_t *dev)
+static unsigned long i810_alloc_page(drm_device_t *dev)
{
- i810_dma_quiescent(dev);
- printk(KERN_INFO "i810_dma_ready\n");
+ unsigned long address;
+
+ address = __get_free_page(GFP_KERNEL);
+ if(address == 0UL)
+ return 0;
+
+ atomic_inc(&mem_map[MAP_NR((void *) address)].count);
+ set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags);
+
+ return address;
}
-static inline int i810_dma_is_ready(drm_device_t *dev)
+static void i810_free_page(drm_device_t *dev, unsigned long page)
{
-
- i810_dma_quiescent(dev);
-
- printk(KERN_INFO "i810_dma_is_ready\n");
- return 1;
+ if(page == 0UL)
+ return;
+
+ atomic_dec(&mem_map[MAP_NR((void *) page)].count);
+ clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags);
+ wake_up(&mem_map[MAP_NR((void *) page)].wait);
+ free_page(page);
+ return;
}
-
-static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
+static int i810_dma_cleanup(drm_device_t *dev)
{
- drm_device_t *dev = (drm_device_t *)device;
- drm_device_dma_t *dma = dev->dma;
-
- atomic_inc(&dev->total_irq);
- if (i810_dma_is_ready(dev)) {
- /* Free previous buffer */
- if (test_and_set_bit(0, &dev->dma_flag)) {
- atomic_inc(&dma->total_missed_free);
- return;
+ if(dev->dev_private) {
+ drm_i810_private_t *dev_priv =
+ (drm_i810_private_t *) dev->dev_private;
+
+ if(dev_priv->ring.virtual_start) {
+ drm_ioremapfree((void *) dev_priv->ring.virtual_start,
+ dev_priv->ring.Size);
}
- if (dma->this_buffer) {
- drm_free_buffer(dev, dma->this_buffer);
- dma->this_buffer = NULL;
+ if(dev_priv->hw_status_page != 0UL) {
+ i810_free_page(dev, dev_priv->hw_status_page);
+ /* Need to rewrite hardware status page */
+ I810_WRITE(0x02080, 0x1ffff000);
}
- clear_bit(0, &dev->dma_flag);
-
- /* Dispatch new buffer */
- queue_task(&dev->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ drm_free(dev->dev_private, sizeof(drm_i810_private_t),
+ DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
}
+ return 0;
}
-/* Only called by i810_dma_schedule. */
-static int i810_do_dma(drm_device_t *dev, int locked)
+static int i810_wait_ring(drm_device_t *dev, int n)
{
- unsigned long address;
- unsigned long length;
- drm_buf_t *buf;
- int retcode = 0;
- drm_device_dma_t *dma = dev->dma;
-#if DRM_DMA_HISTOGRAM
- cycles_t dma_start, dma_stop;
-#endif
-
- if (test_and_set_bit(0, &dev->dma_flag)) {
- atomic_inc(&dma->total_missed_dma);
- return -EBUSY;
- }
-
-#if DRM_DMA_HISTOGRAM
- dma_start = get_cycles();
-#endif
-
- if (!dma->next_buffer) {
- DRM_ERROR("No next_buffer\n");
- clear_bit(0, &dev->dma_flag);
- return -EINVAL;
- }
-
- buf = dma->next_buffer;
- address = (unsigned long)buf->bus_address;
- length = buf->used;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
+ int iters = 0;
+ unsigned long end;
+
+ end = jiffies + (HZ*3);
+ while (ring->space < n) {
+ int i;
-
- DRM_DEBUG("context %d, buffer %d (%ld bytes)\n",
- buf->context, buf->idx, length);
-
- if (buf->list == DRM_LIST_RECLAIM) {
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
- clear_bit(0, &dev->dma_flag);
- return -EINVAL;
- }
-
- if (!length) {
- DRM_ERROR("0 length buffer\n");
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
- clear_bit(0, &dev->dma_flag);
- return 0;
- }
-
- if (!i810_dma_is_ready(dev)) {
- clear_bit(0, &dev->dma_flag);
- return -EBUSY;
- }
-
- if (buf->while_locked) {
- if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("Dispatching buffer %d from pid %d"
- " \"while locked\", but no lock held\n",
- buf->idx, buf->pid);
- }
- } else {
- if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- atomic_inc(&dma->total_missed_lock);
- clear_bit(0, &dev->dma_flag);
- return -EBUSY;
+ ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->space = ring->head - (ring->tail+8);
+
+ if (ring->space < 0) ring->space += ring->Size;
+
+ iters++;
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("space: %d wanted %d\n", ring->space, n);
+ DRM_ERROR("lockup\n");
+ goto out_wait_ring;
}
- }
-
- if (dev->last_context != buf->context
- && !(dev->queuelist[buf->context]->flags
- & _DRM_CONTEXT_PRESERVED)) {
- /* PRE: dev->last_context != buf->context */
- if (drm_context_switch(dev, dev->last_context, buf->context)) {
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
- }
- retcode = -EBUSY;
- goto cleanup;
-
- /* POST: we will wait for the context
- switch and will dispatch on a later call
- when dev->last_context == buf->context.
- NOTE WE HOLD THE LOCK THROUGHOUT THIS
- TIME! */
- }
-
- drm_clear_next_buffer(dev);
- buf->pending = 1;
- buf->waiting = 0;
- buf->list = DRM_LIST_PEND;
-#if DRM_DMA_HISTOGRAM
- buf->time_dispatched = get_cycles();
-#endif
- i810_dma_dispatch(dev, address, length);
- drm_free_buffer(dev, dma->this_buffer);
- dma->this_buffer = buf;
-
- atomic_add(length, &dma->total_bytes);
- atomic_inc(&dma->total_dmas);
-
- if (!buf->while_locked && !dev->context_flag && !locked) {
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
- }
+ for (i = 0 ; i < 2000 ; i++) ;
}
-cleanup:
-
- clear_bit(0, &dev->dma_flag);
-#if DRM_DMA_HISTOGRAM
- dma_stop = get_cycles();
- atomic_inc(&dev->histo.dma[drm_histogram_slot(dma_stop - dma_start)]);
-#endif
-
- return retcode;
-}
-
-static void i810_dma_schedule_timer_wrapper(unsigned long dev)
-{
- i810_dma_schedule((drm_device_t *)dev, 0);
+out_wait_ring:
+ return iters;
}
-static void i810_dma_schedule_tq_wrapper(void *dev)
+static void i810_kernel_lost_context(drm_device_t *dev)
{
- i810_dma_schedule(dev, 0);
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
+
+ ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ ring->tail = I810_READ(LP_RING + RING_TAIL);
+ ring->space = ring->head - (ring->tail+8);
+ if (ring->space < 0) ring->space += ring->Size;
}
-int i810_dma_schedule(drm_device_t *dev, int locked)
+static int i810_freelist_init(drm_device_t *dev)
{
- int next;
- drm_queue_t *q;
- drm_buf_t *buf;
- int retcode = 0;
- int processed = 0;
- int missed;
- int expire = 20;
- drm_device_dma_t *dma = dev->dma;
-#if DRM_DMA_HISTOGRAM
- cycles_t schedule_start;
-#endif
-
- if (test_and_set_bit(0, &dev->interrupt_flag)) {
- /* Not reentrant */
- atomic_inc(&dma->total_missed_sched);
- return -EBUSY;
- }
- missed = atomic_read(&dma->total_missed_sched);
-
-#if DRM_DMA_HISTOGRAM
- schedule_start = get_cycles();
-#endif
-
-again:
- if (dev->context_flag) {
- clear_bit(0, &dev->interrupt_flag);
- return -EBUSY;
- }
- if (dma->next_buffer) {
- /* Unsent buffer that was previously
- selected, but that couldn't be sent
- because the lock could not be obtained
- or the DMA engine wasn't ready. Try
- again. */
- atomic_inc(&dma->total_tried);
- if (!(retcode = i810_do_dma(dev, locked))) {
- atomic_inc(&dma->total_hit);
- ++processed;
- }
- } else {
- do {
- next = drm_select_queue(dev,
- i810_dma_schedule_timer_wrapper);
- if (next >= 0) {
- q = dev->queuelist[next];
- buf = drm_waitlist_get(&q->waitlist);
- dma->next_buffer = buf;
- dma->next_queue = q;
- if (buf && buf->list == DRM_LIST_RECLAIM) {
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
- }
- }
- } while (next >= 0 && !dma->next_buffer);
- if (dma->next_buffer) {
- if (!(retcode = i810_do_dma(dev, locked))) {
- ++processed;
- }
- }
+ drm_device_dma_t *dma = dev->dma;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ u8 *hw_status = (u8 *)dev_priv->hw_status_page;
+ int i;
+ int my_idx = 24;
+
+ if(dma->buf_count > 1019) {
+ /* Not enough space in the status page for the freelist */
+ return -EINVAL;
}
- if (--expire) {
- if (missed != atomic_read(&dma->total_missed_sched)) {
- atomic_inc(&dma->total_lost);
- if (i810_dma_is_ready(dev)) goto again;
- }
- if (processed && i810_dma_is_ready(dev)) {
- atomic_inc(&dma->total_lost);
- processed = 0;
- goto again;
- }
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[ i ];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+
+ buf_priv->in_use = hw_status + my_idx;
+ DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use);
+ *buf_priv->in_use = I810_BUF_FREE;
+ buf_priv->my_use_idx = my_idx;
+ my_idx += 4;
}
-
- clear_bit(0, &dev->interrupt_flag);
-
-#if DRM_DMA_HISTOGRAM
- atomic_inc(&dev->histo.schedule[drm_histogram_slot(get_cycles()
- - schedule_start)]);
-#endif
- return retcode;
+ return 0;
}
-static int i810_dma_priority(drm_device_t *dev, drm_dma_t *d)
+static int i810_dma_initialize(drm_device_t *dev,
+ drm_i810_private_t *dev_priv,
+ drm_i810_init_t *init)
{
- unsigned long address;
- unsigned long length;
- int must_free = 0;
- int retcode = 0;
- int i;
- int idx;
- drm_buf_t *buf;
- drm_buf_t *last_buf = NULL;
- drm_device_dma_t *dma = dev->dma;
- DECLARE_WAITQUEUE(entry, current);
-
- /* Turn off interrupt handling */
- while (test_and_set_bit(0, &dev->interrupt_flag)) {
- schedule();
- if (signal_pending(current)) return -EINTR;
- }
- if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) {
- while (!drm_lock_take(&dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- schedule();
- if (signal_pending(current)) {
- clear_bit(0, &dev->interrupt_flag);
- return -EINTR;
- }
- }
- ++must_free;
- }
- atomic_inc(&dma->total_prio);
-
- for (i = 0; i < d->send_count; i++) {
- idx = d->send_indices[i];
- if (idx < 0 || idx >= dma->buf_count) {
- DRM_ERROR("Index %d (of %d max)\n",
- d->send_indices[i], dma->buf_count - 1);
- continue;
- }
- buf = dma->buflist[ idx ];
- if (buf->pid != current->pid) {
- DRM_ERROR("Process %d using buffer owned by %d\n",
- current->pid, buf->pid);
- retcode = -EINVAL;
- goto cleanup;
- }
- if (buf->list != DRM_LIST_NONE) {
- DRM_ERROR("Process %d using %d's buffer on list %d\n",
- current->pid, buf->pid, buf->list);
- retcode = -EINVAL;
- goto cleanup;
- }
- /* This isn't a race condition on
- buf->list, since our concern is the
- buffer reclaim during the time the
- process closes the /dev/drm? handle, so
- it can't also be doing DMA. */
- buf->list = DRM_LIST_PRIO;
- buf->used = d->send_sizes[i];
- buf->context = d->context;
- buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
- address = (unsigned long)buf->address;
- length = buf->used;
- if (!length) {
- DRM_ERROR("0 length buffer\n");
- }
- if (buf->pending) {
- DRM_ERROR("Sending pending buffer:"
- " buffer %d, offset %d\n",
- d->send_indices[i], i);
- retcode = -EINVAL;
- goto cleanup;
- }
- if (buf->waiting) {
- DRM_ERROR("Sending waiting buffer:"
- " buffer %d, offset %d\n",
- d->send_indices[i], i);
- retcode = -EINVAL;
- goto cleanup;
- }
- buf->pending = 1;
-
- if (dev->last_context != buf->context
- && !(dev->queuelist[buf->context]->flags
- & _DRM_CONTEXT_PRESERVED)) {
- add_wait_queue(&dev->context_wait, &entry);
- current->state = TASK_INTERRUPTIBLE;
- /* PRE: dev->last_context != buf->context */
- drm_context_switch(dev, dev->last_context,
- buf->context);
- /* POST: we will wait for the context
- switch and will dispatch on a later call
- when dev->last_context == buf->context.
- NOTE WE HOLD THE LOCK THROUGHOUT THIS
- TIME! */
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev->context_wait, &entry);
- if (signal_pending(current)) {
- retcode = -EINTR;
- goto cleanup;
- }
- if (dev->last_context != buf->context) {
- DRM_ERROR("Context mismatch: %d %d\n",
- dev->last_context,
- buf->context);
- }
- }
-
-#if DRM_DMA_HISTOGRAM
- buf->time_queued = get_cycles();
- buf->time_dispatched = buf->time_queued;
-#endif
- i810_dma_dispatch(dev, address, length);
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
- }
-
- atomic_add(length, &dma->total_bytes);
- atomic_inc(&dma->total_dmas);
-
- if (last_buf) {
- drm_free_buffer(dev, last_buf);
- }
- last_buf = buf;
- }
+ drm_map_t *sarea_map;
+ dev->dev_private = (void *) dev_priv;
+ memset(dev_priv, 0, sizeof(drm_i810_private_t));
-cleanup:
- if (last_buf) {
- i810_dma_ready(dev);
- drm_free_buffer(dev, last_buf);
+ if (init->ring_map_idx >= dev->map_count ||
+ init->buffer_map_idx >= dev->map_count) {
+ i810_dma_cleanup(dev);
+ DRM_ERROR("ring_map or buffer_map are invalid\n");
+ return -EINVAL;
}
-
- if (must_free && !dev->context_flag) {
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
- }
+
+ dev_priv->ring_map_idx = init->ring_map_idx;
+ dev_priv->buffer_map_idx = init->buffer_map_idx;
+ sarea_map = dev->maplist[0];
+ dev_priv->sarea_priv = (drm_i810_sarea_t *)
+ ((u8 *)sarea_map->handle +
+ init->sarea_priv_offset);
+
+ atomic_set(&dev_priv->flush_done, 0);
+ init_waitqueue_head(&dev_priv->flush_queue);
+
+ dev_priv->ring.Start = init->ring_start;
+ dev_priv->ring.End = init->ring_end;
+ dev_priv->ring.Size = init->ring_size;
+ dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
+ init->ring_start,
+ init->ring_size);
+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+
+ if (dev_priv->ring.virtual_start == NULL) {
+ i810_dma_cleanup(dev);
+ DRM_ERROR("can not ioremap virtual address for"
+ " ring buffer\n");
+ return -ENOMEM;
}
- clear_bit(0, &dev->interrupt_flag);
- return retcode;
+
+ /* Program Hardware Status Page */
+ dev_priv->hw_status_page = i810_alloc_page(dev);
+ memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
+ if(dev_priv->hw_status_page == 0UL) {
+ i810_dma_cleanup(dev);
+ DRM_ERROR("Can not allocate hardware status page\n");
+ return -ENOMEM;
+ }
+ DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
+
+ I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+ DRM_DEBUG("Enabled hardware status page\n");
+
+ /* Now we need to init our freelist */
+ if(i810_freelist_init(dev) != 0) {
+ i810_dma_cleanup(dev);
+ DRM_ERROR("Not enough space in the status page for"
+ " the freelist\n");
+ return -ENOMEM;
+ }
+ return 0;
}
-static int i810_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
+int i810_dma_init(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- DECLARE_WAITQUEUE(entry, current);
- drm_buf_t *last_buf = NULL;
- int retcode = 0;
- drm_device_dma_t *dma = dev->dma;
-
- if (d->flags & _DRM_DMA_BLOCK) {
- last_buf = dma->buflist[d->send_indices[d->send_count-1]];
- add_wait_queue(&last_buf->dma_wait, &entry);
- }
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_private_t *dev_priv;
+ drm_i810_init_t init;
+ int retcode = 0;
- if ((retcode = drm_dma_enqueue(dev, d))) {
- if (d->flags & _DRM_DMA_BLOCK)
- remove_wait_queue(&last_buf->dma_wait, &entry);
- return retcode;
- }
-
- i810_dma_schedule(dev, 0);
+ copy_from_user_ret(&init, (drm_i810_init_t *)arg,
+ sizeof(init), -EFAULT);
- if (d->flags & _DRM_DMA_BLOCK) {
- DRM_DEBUG("%d waiting\n", current->pid);
- current->state = TASK_INTERRUPTIBLE;
- for (;;) {
- if (!last_buf->waiting
- && !last_buf->pending)
- break; /* finished */
- schedule();
- if (signal_pending(current)) {
- retcode = -EINTR; /* Can't restart */
- break;
- }
- }
- current->state = TASK_RUNNING;
- DRM_DEBUG("%d running\n", current->pid);
- remove_wait_queue(&last_buf->dma_wait, &entry);
- if (!retcode
- || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {
- if (!waitqueue_active(&last_buf->dma_wait)) {
- drm_free_buffer(dev, last_buf);
- }
- }
- if (retcode) {
- DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n",
- d->context,
- last_buf->waiting,
- last_buf->pending,
- DRM_WAITCOUNT(dev, d->context),
- last_buf->idx,
- last_buf->list,
- last_buf->pid,
- current->pid);
- }
+ switch(init.func) {
+ case I810_INIT_DMA:
+ dev_priv = drm_alloc(sizeof(drm_i810_private_t),
+ DRM_MEM_DRIVER);
+ if(dev_priv == NULL) return -ENOMEM;
+ retcode = i810_dma_initialize(dev, dev_priv, &init);
+ break;
+ case I810_CLEANUP_DMA:
+ retcode = i810_dma_cleanup(dev);
+ break;
+ default:
+ retcode = -EINVAL;
+ break;
}
- return retcode;
+
+ return retcode;
}
-int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf,
+ int used )
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
- int retcode = 0;
- drm_dma_t d;
-
- printk("i810_dma start\n");
- copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
- DRM_DEBUG("%d %d: %d send, %d req\n",
- current->pid, d.context, d.send_count, d.request_count);
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ unsigned long address = (unsigned long)buf->bus_address;
+ unsigned long start = address - dev->agp->base;
+ RING_LOCALS;
+
+ dev_priv->counter++;
+ DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
+ DRM_DEBUG( "i810_dma_dispatch\n");
+ DRM_DEBUG( "start : 0x%lx\n", start);
+ DRM_DEBUG( "used : 0x%x\n", used);
+ DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4);
+ i810_kernel_lost_context(dev);
+
+ BEGIN_LP_RING(10);
+ OUT_RING( CMD_OP_BATCH_BUFFER );
+ OUT_RING( start | BB1_PROTECTED );
+ OUT_RING( start + used - 4 );
+ OUT_RING( CMD_STORE_DWORD_IDX );
+ OUT_RING( 20 );
+ OUT_RING( dev_priv->counter );
+ OUT_RING( CMD_STORE_DWORD_IDX );
+ OUT_RING( buf_priv->my_use_idx );
+ OUT_RING( I810_BUF_FREE );
+ OUT_RING( CMD_REPORT_HEAD );
+ ADVANCE_LP_RING();
+}
- if (d.context == DRM_KERNEL_CONTEXT || d.context >= dev->queue_slots) {
- DRM_ERROR("Process %d using context %d\n",
- current->pid, d.context);
- return -EINVAL;
- }
+static void i810_dma_dispatch_vertex(drm_device_t *dev,
+ drm_buf_t *buf,
+ int discard,
+ int used)
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_clip_rect_t *box = sarea_priv->boxes;
+ int nbox = sarea_priv->nbox;
+ unsigned long address = (unsigned long)buf->bus_address;
+ unsigned long start = address - dev->agp->base;
+ int i = 0;
+ RING_LOCALS;
- if (d.send_count < 0 || d.send_count > dma->buf_count) {
- DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
- current->pid, d.send_count, dma->buf_count);
- return -EINVAL;
- }
- if (d.request_count < 0 || d.request_count > dma->buf_count) {
- DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
- current->pid, d.request_count, dma->buf_count);
- return -EINVAL;
+
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ nbox = I810_NR_SAREA_CLIPRECTS;
+
+ DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
+ address, used, nbox);
+
+ dev_priv->counter++;
+ DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
+ DRM_DEBUG( "i810_dma_dispatch\n");
+ DRM_DEBUG( "start : %lx\n", start);
+ DRM_DEBUG( "used : %d\n", used);
+ DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
+ i810_kernel_lost_context(dev);
+
+ if (used) {
+ do {
+ if (i < nbox) {
+ BEGIN_LP_RING(4);
+ OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
+ SC_ENABLE );
+ OUT_RING( GFX_OP_SCISSOR_INFO );
+ OUT_RING( box[i].x1 | (box[i].y1 << 16) );
+ OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
+ ADVANCE_LP_RING();
+ }
+
+ BEGIN_LP_RING(4);
+ OUT_RING( CMD_OP_BATCH_BUFFER );
+ OUT_RING( start | BB1_PROTECTED );
+ OUT_RING( start + used - 4 );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+
+ } while (++i < nbox);
}
- if (d.send_count) {
-#if 0
- if (d.flags & _DRM_DMA_PRIORITY)
- retcode = i810_dma_priority(dev, &d);
- else
- retcode = i810_dma_send_buffers(dev, &d);
-#endif
- printk("i810_dma priority\n");
+ BEGIN_LP_RING(10);
+ OUT_RING( CMD_STORE_DWORD_IDX );
+ OUT_RING( 20 );
+ OUT_RING( dev_priv->counter );
+ OUT_RING( 0 );
- retcode = i810_dma_priority(dev, &d);
+ if (discard) {
+ OUT_RING( CMD_STORE_DWORD_IDX );
+ OUT_RING( buf_priv->my_use_idx );
+ OUT_RING( I810_BUF_FREE );
+ OUT_RING( 0 );
}
- d.granted_count = 0;
+ OUT_RING( CMD_REPORT_HEAD );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+}
- if (!retcode && d.request_count) {
- retcode = drm_dma_get_buffers(dev, &d);
- }
- DRM_DEBUG("%d returning, granted = %d\n",
- current->pid, d.granted_count);
- copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
+/* Interrupts are only for flushing */
+static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
+{
+ drm_device_t *dev = (drm_device_t *)device;
+ u16 temp;
+
+ atomic_inc(&dev->total_irq);
+ temp = I810_READ16(I810REG_INT_IDENTITY_R);
+ temp = temp & ~(0x6000);
+ if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
+ temp); /* Clear all interrupts */
+
+ queue_task(&dev->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
- printk("i810_dma end (granted)\n");
- return retcode;
+static void i810_dma_task_queue(void *device)
+{
+ drm_device_t *dev = (drm_device_t *) device;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+
+ atomic_set(&dev_priv->flush_done, 1);
+ wake_up_interruptible(&dev_priv->flush_queue);
}
int i810_irq_install(drm_device_t *dev, int irq)
{
int retcode;
-
+ u16 temp;
+
if (!irq) return -EINVAL;
down(&dev->struct_sem);
@@ -591,6 +508,7 @@ int i810_irq_install(drm_device_t *dev, int irq)
dev->irq = irq;
up(&dev->struct_sem);
+ DRM_DEBUG( "Interrupt Install : %d\n", irq);
DRM_DEBUG("%d\n", irq);
dev->context_flag = 0;
@@ -603,12 +521,21 @@ int i810_irq_install(drm_device_t *dev, int irq)
dev->tq.next = NULL;
dev->tq.sync = 0;
- dev->tq.routine = i810_dma_schedule_tq_wrapper;
+ dev->tq.routine = i810_dma_task_queue;
dev->tq.data = dev;
-
/* Before installing handler */
- /* TODO */
+ temp = I810_READ16(I810REG_HWSTAM);
+ temp = temp & 0x6000;
+ I810_WRITE16(I810REG_HWSTAM, temp);
+
+ temp = I810_READ16(I810REG_INT_MASK_R);
+ temp = temp & 0x6000;
+ I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */
+ temp = I810_READ16(I810REG_INT_ENABLE_R);
+ temp = temp & 0x6000;
+ I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */
+
/* Install handler */
if ((retcode = request_irq(dev->irq,
i810_dma_service,
@@ -620,15 +547,18 @@ int i810_irq_install(drm_device_t *dev, int irq)
up(&dev->struct_sem);
return retcode;
}
-
- /* After installing handler */
- /* TODO */
+ temp = I810_READ16(I810REG_INT_ENABLE_R);
+ temp = temp & 0x6000;
+ temp = temp | 0x0003;
+ I810_WRITE16(I810REG_INT_ENABLE_R,
+ temp); /* Enable bp & user interrupts */
return 0;
}
int i810_irq_uninstall(drm_device_t *dev)
{
int irq;
+ u16 temp;
down(&dev->struct_sem);
irq = dev->irq;
@@ -636,16 +566,25 @@ int i810_irq_uninstall(drm_device_t *dev)
up(&dev->struct_sem);
if (!irq) return -EINVAL;
-
+
+ DRM_DEBUG( "Interrupt UnInstall: %d\n", irq);
DRM_DEBUG("%d\n", irq);
-
- /* TODO : Disable interrupts */
+
+ temp = I810_READ16(I810REG_INT_IDENTITY_R);
+ temp = temp & ~(0x6000);
+ if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
+ temp); /* Clear all interrupts */
+
+ temp = I810_READ16(I810REG_INT_ENABLE_R);
+ temp = temp & 0x6000;
+ I810_WRITE16(I810REG_INT_ENABLE_R,
+ temp); /* Disable all interrupts */
+
free_irq(irq, dev);
return 0;
}
-
int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -654,8 +593,7 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
drm_control_t ctl;
int retcode;
- printk(KERN_INFO "i810_control\n");
- i810_dma_init(dev);
+ DRM_DEBUG( "i810_control\n");
copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
@@ -674,20 +612,134 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
return 0;
}
+static inline void i810_dma_emit_flush(drm_device_t *dev)
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
+
+ i810_kernel_lost_context(dev);
+ BEGIN_LP_RING(2);
+ OUT_RING( CMD_REPORT_HEAD );
+ OUT_RING( GFX_OP_USER_INTERRUPT );
+ ADVANCE_LP_RING();
+}
+
+static inline void i810_dma_quiescent_emit(drm_device_t *dev)
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
+
+ i810_kernel_lost_context(dev);
+ BEGIN_LP_RING(4);
+
+ OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
+ OUT_RING( CMD_REPORT_HEAD );
+ OUT_RING( GFX_OP_USER_INTERRUPT );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+}
+
+static void i810_dma_quiescent(drm_device_t *dev)
+{
+ DECLARE_WAITQUEUE(entry, current);
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ unsigned long end;
+
+ if(dev_priv == NULL) {
+ return;
+ }
+ atomic_set(&dev_priv->flush_done, 0);
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&dev_priv->flush_queue, &entry);
+ end = jiffies + (HZ*3);
+
+ for (;;) {
+ i810_dma_quiescent_emit(dev);
+ if (atomic_read(&dev_priv->flush_done) == 1) break;
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("lockup\n");
+ break;
+ }
+ schedule_timeout(HZ*3);
+ if (signal_pending(current)) {
+ break;
+ }
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev_priv->flush_queue, &entry);
+
+ return;
+}
+
+static int i810_flush_queue(drm_device_t *dev)
+{
+ DECLARE_WAITQUEUE(entry, current);
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ unsigned long end;
+ int ret = 0;
+
+ if(dev_priv == NULL) {
+ return 0;
+ }
+ atomic_set(&dev_priv->flush_done, 0);
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&dev_priv->flush_queue, &entry);
+ end = jiffies + (HZ*3);
+ for (;;) {
+ i810_dma_emit_flush(dev);
+ if (atomic_read(&dev_priv->flush_done) == 1) break;
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("lockup\n");
+ break;
+ }
+ schedule_timeout(HZ*3);
+ if (signal_pending(current)) {
+ ret = -EINTR; /* Can't restart */
+ break;
+ }
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev_priv->flush_queue, &entry);
+
+ return ret;
+}
+
+/* Must be called with the lock held */
+void i810_reclaim_buffers(drm_device_t *dev, pid_t pid)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+
+ if (!dma) return;
+ if(dev->dev_private == NULL) return;
+
+ i810_flush_queue(dev);
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[ i ];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+
+ if (buf->pid == pid) {
+ /* Only buffers that need to get reclaimed ever
+ * get set to free */
+ if(buf_priv == NULL) return;
+ cmpxchg(buf_priv->in_use,
+ I810_BUF_USED, I810_BUF_FREE);
+ }
+ }
+}
+
int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+
DECLARE_WAITQUEUE(entry, current);
int ret = 0;
drm_lock_t lock;
- drm_queue_t *q;
-#if DRM_DMA_HISTOGRAM
- cycles_t start;
-
- dev->lck_start = start = get_cycles();
-#endif
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
@@ -696,16 +748,20 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
current->pid, lock.context);
return -EINVAL;
}
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, current->pid, dev->lock.hw_lock->lock,
+ lock.flags);
- if (lock.context < 0 || lock.context >= dev->queue_count) {
+ if (lock.context < 0) {
return -EINVAL;
}
- q = dev->queuelist[lock.context];
-
- ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
+ /* Only one queue:
+ */
if (!ret) {
- if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
+#if 0
+ if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
!= lock.context) {
long j = jiffies - dev->lock.lock_time;
@@ -716,6 +772,7 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
schedule_timeout(j);
}
}
+#endif
add_wait_queue(&dev->lock.lock_queue, &entry);
for (;;) {
if (!dev->lock.hw_lock) {
@@ -728,13 +785,13 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
dev->lock.pid = current->pid;
dev->lock.lock_time = jiffies;
atomic_inc(&dev->total_locks);
- atomic_inc(&q->total_locks);
break; /* Got lock */
}
/* Contention */
atomic_inc(&dev->total_sleeps);
current->state = TASK_INTERRUPTIBLE;
+ DRM_DEBUG("Calling lock schedule\n");
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
@@ -744,19 +801,184 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
current->state = TASK_RUNNING;
remove_wait_queue(&dev->lock.lock_queue, &entry);
}
-
- drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */
if (!ret) {
- if (lock.flags & _DRM_LOCK_READY)
- i810_dma_ready(dev);
- if (lock.flags & _DRM_LOCK_QUIESCENT)
- i810_dma_quiescent(dev);
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
+ DRM_DEBUG("fred\n");
+ i810_dma_quiescent(dev);
+ }
}
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+ return ret;
+}
-#if DRM_DMA_HISTOGRAM
- atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
-#endif
+int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ DRM_DEBUG("i810_flush_ioctl\n");
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("i810_flush_ioctl called without lock held\n");
+ return -EINVAL;
+ }
+
+ i810_flush_queue(dev);
+ return 0;
+}
+
+static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf = dma->buflist[ args->idx ];
+
+ if (!args->used) {
+ i810_freelist_put(dev, buf);
+ } else {
+ i810_dma_dispatch_general( dev, buf, args->used );
+ atomic_add(args->used, &dma->total_bytes);
+ atomic_inc(&dma->total_dmas);
+ }
+ return 0;
+}
+
+static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf = dma->buflist[ args->idx ];
+ i810_dma_dispatch_vertex( dev, buf, args->discard, args->used );
+ atomic_add(args->used, &dma->total_bytes);
+ atomic_inc(&dma->total_dmas);
+ return 0;
+}
+
+int i810_dma_general(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_general_t general;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
+
+ int retcode = 0;
- return ret;
+ copy_from_user_ret(&general, (drm_i810_general_t *)arg, sizeof(general),
+ -EFAULT);
+
+ DRM_DEBUG("i810 dma general idx %d used %d\n",
+ general.idx, general.used);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("i810_dma_general called without lock held\n");
+ return -EINVAL;
+ }
+
+ retcode = i810DmaGeneral(dev, &general);
+ sarea_priv->last_enqueue = dev_priv->counter-1;
+ sarea_priv->last_dispatch = (int) hw_status[5];
+
+ return retcode;
+}
+
+int i810_dma_vertex(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
+ drm_i810_vertex_t vertex;
+ int retcode = 0;
+
+ copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex),
+ -EFAULT);
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("i810_dma_vertex called without lock held\n");
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
+ vertex.idx, vertex.used, vertex.discard);
+
+ retcode = i810DmaVertex(dev, &vertex);
+ sarea_priv->last_enqueue = dev_priv->counter-1;
+ sarea_priv->last_dispatch = (int) hw_status[5];
+
+ return retcode;
+
+}
+
+int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
+
+ sarea_priv->last_dispatch = (int) hw_status[5];
+ return 0;
+}
+
+int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_device_dma_t *dma = dev->dma;
+ int retcode = 0;
+ drm_dma_t d;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+ drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+ dev_priv->sarea_priv;
+
+
+ copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
+ DRM_DEBUG("%d %d: %d send, %d req\n",
+ current->pid, d.context, d.send_count, d.request_count);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("i810_dma called without lock held\n");
+ return -EINVAL;
+ }
+
+ /* Please don't send us buffers.
+ */
+ if (d.send_count != 0) {
+ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+ current->pid, d.send_count);
+ return -EINVAL;
+ }
+
+ /* We'll send you buffers.
+ */
+ if (d.request_count < 0 || d.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ current->pid, d.request_count, dma->buf_count);
+ return -EINVAL;
+ }
+
+ d.granted_count = 0;
+
+ if (!retcode && d.request_count) {
+ retcode = i810_dma_get_buffers(dev, &d);
+ }
+
+ DRM_DEBUG("i810_dma: %d returning, granted = %d\n",
+ current->pid, d.granted_count);
+
+ copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
+ sarea_priv->last_dispatch = (int) hw_status[5];
+
+ return retcode;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
new file mode 100644
index 000000000..0754874c6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
@@ -0,0 +1,93 @@
+#ifndef _I810_DRM_H_
+#define _I810_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+/* Might one day want to support the client-side ringbuffer code again.
+ */
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+
+#define I810_USE_BATCH 1
+#define I810_DMA_BUF_ORDER 12
+#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR 256
+#define I810_NR_SAREA_CLIPRECTS 2
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+typedef struct _drm_i810_init {
+ enum {
+ I810_INIT_DMA = 0x01,
+ I810_CLEANUP_DMA = 0x02
+ } func;
+ int ring_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ unsigned long ring_start;
+ unsigned long ring_end;
+ unsigned long ring_size;
+} drm_i810_init_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_i810_tex_region {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} drm_i810_tex_region_t;
+
+typedef struct _drm_i810_sarea {
+ unsigned int nbox;
+ drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
+
+ /* Maintain an LRU of contiguous regions of texture space. If
+ * you think you own a region of texture memory, and it has an
+ * age different to the one you set, then you are mistaken and
+ * it has been stolen by another client. If global texAge
+ * hasn't changed, there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained
+ * texture information of other clients - by maintaining them
+ * in the same lru which is used to age their own textures,
+ * clients have an approximate lru for the whole of global
+ * texture space, and can make informed decisions as to which
+ * areas to kick out. There is no need to choose whether to
+ * kick out your own texture or someone else's - simply eject
+ * them all in LRU order.
+ */
+
+ drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
+ /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+ int ctxOwner; /* last context to upload state */
+} drm_i810_sarea_t;
+
+typedef struct _drm_i810_general {
+ int idx;
+ int used;
+} drm_i810_general_t;
+
+/* These may be placeholders if we have more cliprects than
+ * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
+ * false, indicating that the buffer will be dispatched again with a
+ * new set of cliprects.
+ */
+typedef struct _drm_i810_vertex {
+ int idx; /* buffer index */
+ int used; /* nr bytes in use */
+ int discard; /* client is finished with the buffer? */
+} drm_i810_vertex_t;
+
+#endif /* _I810_DRM_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c
index f33153a36..d3b35c493 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c
@@ -33,11 +33,13 @@
#define EXPORT_SYMTAB
#include "drmP.h"
#include "i810_drv.h"
+
+
EXPORT_SYMBOL(i810_init);
EXPORT_SYMBOL(i810_cleanup);
#define I810_NAME "i810"
-#define I810_DESC "Matrox g200/g400"
+#define I810_DESC "Intel I810"
#define I810_DATE "19991213"
#define I810_MAJOR 0
#define I810_MINOR 0
@@ -54,6 +56,7 @@ static struct file_operations i810_fops = {
mmap: drm_mmap,
read: drm_read,
fasync: drm_fasync,
+ poll: drm_poll,
};
static struct miscdevice i810_misc = {
@@ -80,13 +83,13 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { i810_mapbufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { i810_freebufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { i810_addctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { i810_rmctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { i810_modctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { i810_getctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { i810_switchctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { i810_newctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { i810_resctx, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
@@ -104,6 +107,11 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 },
};
#define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls)
@@ -121,7 +129,7 @@ MODULE_PARM(i810, "s");
int init_module(void)
{
- printk("doing i810_init()\n");
+ DRM_DEBUG("doing i810_init()\n");
return i810_init();
}
@@ -364,7 +372,7 @@ int i810_init(void)
#ifdef MODULE
drm_parse_options(i810);
#endif
- printk("doing misc_register\n");
+ DRM_DEBUG("doing misc_register\n");
if ((retcode = misc_register(&i810_misc))) {
DRM_ERROR("Cannot register \"%s\"\n", I810_NAME);
return retcode;
@@ -372,13 +380,22 @@ int i810_init(void)
dev->device = MKDEV(MISC_MAJOR, i810_misc.minor);
dev->name = I810_NAME;
- printk("doing mem init\n");
+ DRM_DEBUG("doing mem init\n");
drm_mem_init();
- printk("doing proc init\n");
+ DRM_DEBUG("doing proc init\n");
drm_proc_init(dev);
- printk("doing agp init\n");
+ DRM_DEBUG("doing agp init\n");
dev->agp = drm_agp_init();
- printk("doing ctxbitmap init\n");
+ if(dev->agp == NULL) {
+ DRM_INFO("The i810 drm module requires the agpgart module"
+ " to function correctly\nPlease load the agpgart"
+ " module before you load the i810 module\n");
+ drm_proc_cleanup();
+ misc_deregister(&i810_misc);
+ i810_takedown(dev);
+ return -ENOMEM;
+ }
+ DRM_DEBUG("doing ctxbitmap init\n");
if((retcode = drm_ctxbitmap_init(dev))) {
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
drm_proc_cleanup();
@@ -386,10 +403,6 @@ int i810_init(void)
i810_takedown(dev);
return retcode;
}
-#if 0
- printk("doing i810_dma_init\n");
- i810_dma_init(dev);
-#endif
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
I810_NAME,
@@ -417,7 +430,6 @@ void i810_cleanup(void)
DRM_INFO("Module unloaded\n");
}
drm_ctxbitmap_cleanup(dev);
- i810_dma_cleanup(dev);
i810_takedown(dev);
if (dev->agp) {
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
@@ -484,24 +496,82 @@ int i810_release(struct inode *inode, struct file *filp)
drm_device_t *dev = priv->dev;
int retcode = 0;
- DRM_DEBUG("open_count = %d\n", dev->open_count);
- if (!(retcode = drm_release(inode, filp))) {
- MOD_DEC_USE_COUNT;
- atomic_inc(&dev->total_close);
- spin_lock(&dev->count_lock);
- if (!--dev->open_count) {
- if (atomic_read(&dev->ioctl_count) || dev->blocked) {
- DRM_ERROR("Device busy: %d %d\n",
- atomic_read(&dev->ioctl_count),
- dev->blocked);
- spin_unlock(&dev->count_lock);
- return -EBUSY;
+ DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
+ current->pid, dev->device, dev->open_count);
+
+ if (_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
+ && dev->lock.pid == current->pid) {
+ i810_reclaim_buffers(dev, priv->pid);
+ DRM_ERROR("Process %d dead, freeing lock for context %d\n",
+ current->pid,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ drm_lock_free(dev,
+ &dev->lock.hw_lock->lock,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+
+ /* FIXME: may require heavy-handed reset of
+ hardware at this point, possibly
+ processed via a callback to the X
+ server. */
+ } else {
+ /* The lock is required to reclaim buffers */
+ DECLARE_WAITQUEUE(entry, current);
+ add_wait_queue(&dev->lock.lock_queue, &entry);
+ for (;;) {
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ retcode = -EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ dev->lock.pid = priv->pid;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->total_locks);
+ break; /* Got lock */
+ }
+ /* Contention */
+ atomic_inc(&dev->total_sleeps);
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (signal_pending(current)) {
+ retcode = -ERESTARTSYS;
+ break;
}
- spin_unlock(&dev->count_lock);
- return i810_takedown(dev);
}
- spin_unlock(&dev->count_lock);
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
+ if(!retcode) {
+ i810_reclaim_buffers(dev, priv->pid);
+ drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT);
+ }
+ }
+ drm_fasync(-1, filp, 0);
+
+ down(&dev->struct_sem);
+ if (priv->prev) priv->prev->next = priv->next;
+ else dev->file_first = priv->next;
+ if (priv->next) priv->next->prev = priv->prev;
+ else dev->file_last = priv->prev;
+ up(&dev->struct_sem);
+
+ drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+ MOD_DEC_USE_COUNT;
+ atomic_inc(&dev->total_close);
+ spin_lock(&dev->count_lock);
+ if (!--dev->open_count) {
+ if (atomic_read(&dev->ioctl_count) || dev->blocked) {
+ DRM_ERROR("Device busy: %d %d\n",
+ atomic_read(&dev->ioctl_count),
+ dev->blocked);
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ spin_unlock(&dev->count_lock);
+ return i810_takedown(dev);
}
+ spin_unlock(&dev->count_lock);
return retcode;
}
@@ -566,8 +636,7 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
atomic_inc(&dev->total_unlocks);
if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
atomic_inc(&dev->total_contends);
- drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
- i810_dma_schedule(dev, 1);
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
if (!dev->context_flag) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
index 0f5f42bb6..1badd36b8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
@@ -32,6 +32,31 @@
#ifndef _I810_DRV_H_
#define _I810_DRV_H_
+typedef struct _drm_i810_ring_buffer{
+ int tail_mask;
+ unsigned long Start;
+ unsigned long End;
+ unsigned long Size;
+ u8 *virtual_start;
+ int head;
+ int tail;
+ int space;
+} drm_i810_ring_buffer_t;
+
+typedef struct drm_i810_private {
+ int ring_map_idx;
+ int buffer_map_idx;
+
+ drm_i810_ring_buffer_t ring;
+ drm_i810_sarea_t *sarea_priv;
+
+ unsigned long hw_status_page;
+ unsigned long counter;
+
+ atomic_t flush_done;
+ wait_queue_head_t flush_queue; /* Processes waiting until flush */
+} drm_i810_private_t;
+
/* i810_drv.c */
extern int i810_init(void);
extern void i810_cleanup(void);
@@ -54,8 +79,13 @@ extern int i810_control(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern void i810_dma_init(drm_device_t *dev);
-extern void i810_dma_cleanup(drm_device_t *dev);
+extern int i810_dma_init(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid);
+extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg);
/* i810_bufs.c */
@@ -72,5 +102,103 @@ extern int i810_mapbufs(struct inode *inode, struct file *filp,
extern int i810_addmap(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+ /* i810_context.c */
+extern int i810_resctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_addctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_modctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_getctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_switchctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_newctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int i810_rmctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+extern int i810_context_switch(drm_device_t *dev, int old, int new);
+extern int i810_context_switch_complete(drm_device_t *dev, int new);
+
+
+
+
+/* Copy the outstanding cliprects for every I810_DMA_VERTEX buffer.
+ * This can be fixed by emitting directly to the ringbuffer in the
+ * 'vertex_dma' ioctl.
+*/
+typedef struct {
+ u32 *in_use;
+ int my_use_idx;
+} drm_i810_buf_priv_t;
+
+
+#define I810_DMA_GENERAL 0
+#define I810_DMA_VERTEX 1
+#define I810_DMA_DISCARD 2 /* not used */
+
+#define I810_VERBOSE 0
+
+
+int i810_dma_vertex(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+int i810_dma_general(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+
+#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
+#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
+#define CMD_REPORT_HEAD (7<<23)
+#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
+#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
+
+#define INST_PARSER_CLIENT 0x00000000
+#define INST_OP_FLUSH 0x02000000
+#define INST_FLUSH_MAP_CACHE 0x00000001
+
+
+#define BB1_START_ADDR_MASK (~0x7)
+#define BB1_PROTECTED (1<<0)
+#define BB1_UNPROTECTED (0<<0)
+#define BB2_END_ADDR_MASK (~0x7)
+
+#define I810REG_HWSTAM 0x02098
+#define I810REG_INT_IDENTITY_R 0x020a4
+#define I810REG_INT_MASK_R 0x020a8
+#define I810REG_INT_ENABLE_R 0x020a0
+
+#define LP_RING 0x2030
+#define HP_RING 0x2040
+#define RING_TAIL 0x00
+#define TAIL_ADDR 0x000FFFF8
+#define RING_HEAD 0x04
+#define HEAD_WRAP_COUNT 0xFFE00000
+#define HEAD_WRAP_ONE 0x00200000
+#define HEAD_ADDR 0x001FFFFC
+#define RING_START 0x08
+#define START_ADDR 0x00FFFFF8
+#define RING_LEN 0x0C
+#define RING_NR_PAGES 0x000FF000
+#define RING_REPORT_MASK 0x00000006
+#define RING_REPORT_64K 0x00000002
+#define RING_REPORT_128K 0x00000004
+#define RING_NO_REPORT 0x00000000
+#define RING_VALID_MASK 0x00000001
+#define RING_VALID 0x00000001
+#define RING_INVALID 0x00000000
+
+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR (0x1<<1)
+#define SC_ENABLE_MASK (0x1<<0)
+#define SC_ENABLE (0x1<<0)
+
+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK (0xffff<<16)
+#define SCI_XMIN_MASK (0xffff<<0)
+#define SCI_YMAX_MASK (0xffff<<16)
+#define SCI_XMAX_MASK (0xffff<<0)
#endif
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c
index a8a81abd8..559ac7391 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c
@@ -44,21 +44,25 @@ static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
static unsigned long drm_ram_available = 0; /* In pages */
static unsigned long drm_ram_used = 0;
static drm_mem_stats_t drm_mem_stats[] = {
- [DRM_MEM_DMA] = { "dmabufs" },
- [DRM_MEM_SAREA] = { "sareas" },
- [DRM_MEM_DRIVER] = { "driver" },
- [DRM_MEM_MAGIC] = { "magic" },
- [DRM_MEM_IOCTLS] = { "ioctltab" },
- [DRM_MEM_MAPS] = { "maplist" },
- [DRM_MEM_VMAS] = { "vmalist" },
- [DRM_MEM_BUFS] = { "buflist" },
- [DRM_MEM_SEGS] = { "seglist" },
- [DRM_MEM_PAGES] = { "pagelist" },
- [DRM_MEM_FILES] = { "files" },
- [DRM_MEM_QUEUES] = { "queues" },
- [DRM_MEM_CMDS] = { "commands" },
- [DRM_MEM_MAPPINGS] = { "mappings" },
- [DRM_MEM_BUFLISTS] = { "buflists" },
+ [DRM_MEM_DMA] = { "dmabufs" },
+ [DRM_MEM_SAREA] = { "sareas" },
+ [DRM_MEM_DRIVER] = { "driver" },
+ [DRM_MEM_MAGIC] = { "magic" },
+ [DRM_MEM_IOCTLS] = { "ioctltab" },
+ [DRM_MEM_MAPS] = { "maplist" },
+ [DRM_MEM_VMAS] = { "vmalist" },
+ [DRM_MEM_BUFS] = { "buflist" },
+ [DRM_MEM_SEGS] = { "seglist" },
+ [DRM_MEM_PAGES] = { "pagelist" },
+ [DRM_MEM_FILES] = { "files" },
+ [DRM_MEM_QUEUES] = { "queues" },
+ [DRM_MEM_CMDS] = { "commands" },
+ [DRM_MEM_MAPPINGS] = { "mappings" },
+ [DRM_MEM_BUFLISTS] = { "buflists" },
+ [DRM_MEM_AGPLISTS] = { "agplist" },
+ [DRM_MEM_TOTALAGP] = { "totalagp" },
+ [DRM_MEM_BOUNDAGP] = { "boundagp" },
+ [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
{ NULL, 0, } /* Last entry must be null */
};
@@ -324,3 +328,120 @@ void drm_ioremapfree(void *pt, unsigned long size)
free_count, alloc_count);
}
}
+
+#ifdef DRM_AGP
+agp_memory *drm_alloc_agp(int pages, u32 type)
+{
+ agp_memory *handle;
+
+ if (!pages) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
+ return NULL;
+ }
+
+ if (drm_agp.allocate_memory) {
+ if ((handle = (*drm_agp.allocate_memory)(pages,
+ type))) {
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
+ += pages << PAGE_SHIFT;
+ spin_unlock(&drm_mem_lock);
+ return handle;
+ }
+ }
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return NULL;
+}
+
+int drm_free_agp(agp_memory *handle, int pages)
+{
+ int alloc_count;
+ int free_count;
+ int retval = -EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Attempt to free NULL AGP handle\n");
+ return retval;;
+ }
+
+ if (drm_agp.free_memory) {
+ (*drm_agp.free_memory)(handle);
+ spin_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
+ += pages << PAGE_SHIFT;
+ spin_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return 0;
+ }
+ return retval;
+}
+
+int drm_bind_agp(agp_memory *handle, unsigned int start)
+{
+ int retcode = -EINVAL;
+
+ DRM_DEBUG("drm_bind_agp called\n");
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to bind NULL AGP handle\n");
+ return retcode;
+ }
+
+ DRM_DEBUG("drm_agp.bind_memory : %p\n", drm_agp.bind_memory);
+ if (drm_agp.bind_memory) {
+ if (!(retcode = (*drm_agp.bind_memory)(handle, start))) {
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
+ += handle->page_count << PAGE_SHIFT;
+ spin_unlock(&drm_mem_lock);
+ DRM_DEBUG("drm_agp.bind_memory: retcode %d\n", retcode);
+ return retcode;
+ }
+ }
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return retcode;
+}
+
+int drm_unbind_agp(agp_memory *handle)
+{
+ int alloc_count;
+ int free_count;
+ int retcode = -EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to unbind NULL AGP handle\n");
+ return retcode;
+ }
+
+ if (drm_agp.unbind_memory) {
+ int c = handle->page_count;
+ if ((retcode = (*drm_agp.unbind_memory)(handle)))
+ return retcode;
+ spin_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed += c << PAGE_SHIFT;
+ spin_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ }
+ return retcode;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c
index 34f1112a6..3ce428b27 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_bufs.c
@@ -33,169 +33,168 @@
#define __NO_VERSION__
#include "drmP.h"
#include "mga_drv.h"
-#include "mga_dma.h"
#include "linux/un.h"
int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_desc_t request;
- drm_buf_entry_t *entry;
- drm_buf_t *buf;
- unsigned long offset;
- unsigned long agp_offset;
- int count;
- int order;
- int size;
- int alignment;
- int page_order;
- int total;
- int byte_count;
- int i;
-
- if (!dma) return -EINVAL;
-
- copy_from_user_ret(&request,
- (drm_buf_desc_t *)arg,
- sizeof(request),
- -EFAULT);
-
- count = request.count;
- order = drm_order(request.size);
- size = 1 << order;
- agp_offset = request.agp_start;
- alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
- page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
- total = PAGE_SIZE << page_order;
- byte_count = 0;
-
- DRM_DEBUG("count: %d\n", count);
- DRM_DEBUG("order: %d\n", order);
- DRM_DEBUG("size: %d\n", size);
- DRM_DEBUG("agp_offset: %d\n", agp_offset);
- DRM_DEBUG("alignment: %d\n", alignment);
- DRM_DEBUG("page_order: %d\n", page_order);
- DRM_DEBUG("total: %d\n", total);
- DRM_DEBUG("byte_count: %d\n", byte_count);
-
- if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
- if (dev->queue_count) return -EBUSY; /* Not while in use */
- spin_lock(&dev->count_lock);
- if (dev->buf_use) {
- spin_unlock(&dev->count_lock);
- return -EBUSY;
- }
- atomic_inc(&dev->buf_alloc);
- spin_unlock(&dev->count_lock);
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_desc_t request;
+ drm_buf_entry_t *entry;
+ drm_buf_t *buf;
+ unsigned long offset;
+ unsigned long agp_offset;
+ int count;
+ int order;
+ int size;
+ int alignment;
+ int page_order;
+ int total;
+ int byte_count;
+ int i;
+
+ if (!dma) return -EINVAL;
+
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ count = request.count;
+ order = drm_order(request.size);
+ size = 1 << order;
+ agp_offset = request.agp_start;
+ alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+ byte_count = 0;
+
+ DRM_DEBUG("count: %d\n", count);
+ DRM_DEBUG("order: %d\n", order);
+ DRM_DEBUG("size: %d\n", size);
+ DRM_DEBUG("agp_offset: %ld\n", agp_offset);
+ DRM_DEBUG("alignment: %d\n", alignment);
+ DRM_DEBUG("page_order: %d\n", page_order);
+ DRM_DEBUG("total: %d\n", total);
+ DRM_DEBUG("byte_count: %d\n", byte_count);
+
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
+ if (dev->queue_count) return -EBUSY; /* Not while in use */
+ spin_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ atomic_inc(&dev->buf_alloc);
+ spin_unlock(&dev->count_lock);
- down(&dev->struct_sem);
- entry = &dma->bufs[order];
- if (entry->buf_count) {
- up(&dev->struct_sem);
- atomic_dec(&dev->buf_alloc);
- return -ENOMEM; /* May only call once for each order */
- }
+ down(&dev->struct_sem);
+ entry = &dma->bufs[order];
+ if (entry->buf_count) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM; /* May only call once for each order */
+ }
- entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
- DRM_MEM_BUFS);
- if (!entry->buflist) {
- up(&dev->struct_sem);
- atomic_dec(&dev->buf_alloc);
- return -ENOMEM;
- }
- memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM;
+ }
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
- entry->buf_size = size;
- entry->page_order = page_order;
- offset = 0;
+ entry->buf_size = size;
+ entry->page_order = page_order;
+ offset = 0;
- while(entry->buf_count < count) {
- buf = &entry->buflist[entry->buf_count];
- buf->idx = dma->buf_count + entry->buf_count;
- buf->total = alignment;
- buf->order = order;
- buf->used = 0;
-
- DRM_DEBUG("offset : %d\n", offset);
-
- buf->offset = offset; /* Hrm */
- buf->bus_address = dev->agp->base + agp_offset + offset;
- buf->address = (void *)(agp_offset + offset + dev->agp->base);
- buf->next = NULL;
- buf->waiting = 0;
- buf->pending = 0;
- init_waitqueue_head(&buf->dma_wait);
- buf->pid = 0;
-
- buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS);
- buf->dev_priv_size = sizeof(drm_mga_buf_priv_t);
+ while(entry->buf_count < count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+
+ DRM_DEBUG("offset : %ld\n", offset);
+
+ buf->offset = offset; /* Hrm */
+ buf->bus_address = dev->agp->base + agp_offset + offset;
+ buf->address = (void *)(agp_offset + offset + dev->agp->base);
+ buf->next = NULL;
+ buf->waiting = 0;
+ buf->pending = 0;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->pid = 0;
+
+ buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS);
+ buf->dev_priv_size = sizeof(drm_mga_buf_priv_t);
#if DRM_DMA_HISTOGRAM
- buf->time_queued = 0;
- buf->time_dispatched = 0;
- buf->time_completed = 0;
- buf->time_freed = 0;
+ buf->time_queued = 0;
+ buf->time_dispatched = 0;
+ buf->time_completed = 0;
+ buf->time_freed = 0;
#endif
- offset = offset + alignment;
- entry->buf_count++;
- byte_count += PAGE_SIZE << page_order;
+ offset = offset + alignment;
+ entry->buf_count++;
+ byte_count += PAGE_SIZE << page_order;
- DRM_DEBUG("buffer %d @ %p\n",
- entry->buf_count, buf->address);
- }
+ DRM_DEBUG("buffer %d @ %p\n",
+ entry->buf_count, buf->address);
+ }
- dma->buflist = drm_realloc(dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- (dma->buf_count + entry->buf_count)
- * sizeof(*dma->buflist),
- DRM_MEM_BUFS);
- for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
- dma->buflist[i] = &entry->buflist[i - dma->buf_count];
+ dma->buflist = drm_realloc(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist),
+ DRM_MEM_BUFS);
+ for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
+ dma->buflist[i] = &entry->buflist[i - dma->buf_count];
- dma->buf_count += entry->buf_count;
+ dma->buf_count += entry->buf_count;
- DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
+ DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
- dma->byte_count += byte_count;
+ dma->byte_count += byte_count;
- DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
+ DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
- drm_freelist_create(&entry->freelist, entry->buf_count);
- for (i = 0; i < entry->buf_count; i++) {
- drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
- }
+ drm_freelist_create(&entry->freelist, entry->buf_count);
+ for (i = 0; i < entry->buf_count; i++) {
+ drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
+ }
- up(&dev->struct_sem);
+ up(&dev->struct_sem);
- request.count = entry->buf_count;
- request.size = size;
+ request.count = entry->buf_count;
+ request.size = size;
- copy_to_user_ret((drm_buf_desc_t *)arg,
- &request,
- sizeof(request),
- -EFAULT);
+ copy_to_user_ret((drm_buf_desc_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
- atomic_dec(&dev->buf_alloc);
+ atomic_dec(&dev->buf_alloc);
- DRM_DEBUG("count: %d\n", count);
- DRM_DEBUG("order: %d\n", order);
- DRM_DEBUG("size: %d\n", size);
- DRM_DEBUG("agp_offset: %d\n", agp_offset);
- DRM_DEBUG("alignment: %d\n", alignment);
- DRM_DEBUG("page_order: %d\n", page_order);
- DRM_DEBUG("total: %d\n", total);
- DRM_DEBUG("byte_count: %d\n", byte_count);
+ DRM_DEBUG("count: %d\n", count);
+ DRM_DEBUG("order: %d\n", order);
+ DRM_DEBUG("size: %d\n", size);
+ DRM_DEBUG("agp_offset: %ld\n", agp_offset);
+ DRM_DEBUG("alignment: %d\n", alignment);
+ DRM_DEBUG("page_order: %d\n", page_order);
+ DRM_DEBUG("total: %d\n", total);
+ DRM_DEBUG("byte_count: %d\n", byte_count);
- dma->flags = _DRM_DMA_USE_AGP;
+ dma->flags = _DRM_DMA_USE_AGP;
- DRM_DEBUG("dma->flags : %lx\n", dma->flags);
+ DRM_DEBUG("dma->flags : %x\n", dma->flags);
- return 0;
+ return 0;
}
int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -362,17 +361,17 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
- drm_buf_desc_t request;
+ drm_buf_desc_t request;
- copy_from_user_ret(&request,
- (drm_buf_desc_t *)arg,
- sizeof(request),
- -EFAULT);
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
- if(request.flags & _DRM_AGP_BUFFER)
- return mga_addbufs_agp(inode, filp, cmd, arg);
- else
- return mga_addbufs_pci(inode, filp, cmd, arg);
+ if(request.flags & _DRM_AGP_BUFFER)
+ return mga_addbufs_agp(inode, filp, cmd, arg);
+ else
+ return mga_addbufs_pci(inode, filp, cmd, arg);
}
int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -546,7 +545,7 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
spin_lock(&dev->count_lock);
if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock);
- DRM_DEBUG("Buzy\n");
+ DRM_DEBUG("Busy\n");
return -EBUSY;
}
++dev->buf_use; /* Can't allocate more after this call */
@@ -558,79 +557,84 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-EFAULT);
DRM_DEBUG("mga_mapbufs\n");
- DRM_DEBUG("dma->flags : %lx\n", dma->flags);
+ DRM_DEBUG("dma->flags : %x\n", dma->flags);
- if (request.count >= dma->buf_count) {
- if(dma->flags & _DRM_DMA_USE_AGP) {
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_map_t *map = NULL;
+ if (request.count >= dma->buf_count) {
+ if(dma->flags & _DRM_DMA_USE_AGP) {
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_map_t *map = NULL;
- map = dev->maplist[dev_priv->buffer_map_idx];
- if (!map) {
- DRM_DEBUG("map is null\n");
- retcode = -EINVAL;
- goto done;
- }
-
- DRM_DEBUG("map->offset : %lx\n", map->offset);
- DRM_DEBUG("map->size : %lx\n", map->size);
- DRM_DEBUG("map->type : %d\n", map->type);
- DRM_DEBUG("map->flags : %x\n", map->flags);
- DRM_DEBUG("map->handle : %lx\n", map->handle);
- DRM_DEBUG("map->mtrr : %d\n", map->mtrr);
-
- virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE,
- MAP_SHARED, (unsigned long)map->offset);
- } else {
- virtual = do_mmap(filp, 0, dma->byte_count,
- PROT_READ|PROT_WRITE, MAP_SHARED, 0);
- }
- if (virtual > -1024UL) {
- /* Real error */
- DRM_DEBUG("mmap error\n");
- retcode = (signed long)virtual;
- goto done;
- }
- request.virtual = (void *)virtual;
+ map = dev->maplist[dev_priv->buffer_map_idx];
+ if (!map) {
+ DRM_DEBUG("map is null\n");
+ retcode = -EINVAL;
+ goto done;
+ }
+
+ DRM_DEBUG("map->offset : %lx\n", map->offset);
+ DRM_DEBUG("map->size : %lx\n", map->size);
+ DRM_DEBUG("map->type : %d\n", map->type);
+ DRM_DEBUG("map->flags : %x\n", map->flags);
+ DRM_DEBUG("map->handle : %p\n", map->handle);
+ DRM_DEBUG("map->mtrr : %d\n", map->mtrr);
+ down(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, map->size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ (unsigned long)map->offset);
+ up(&current->mm->mmap_sem);
+ } else {
+ down(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, dma->byte_count,
+ PROT_READ|PROT_WRITE, MAP_SHARED, 0);
+ up(&current->mm->mmap_sem);
+ }
+ if (virtual > -1024UL) {
+ /* Real error */
+ DRM_DEBUG("mmap error\n");
+ retcode = (signed long)virtual;
+ goto done;
+ }
+ request.virtual = (void *)virtual;
- for (i = 0; i < dma->buf_count; i++) {
- if (copy_to_user(&request.list[i].idx,
- &dma->buflist[i]->idx,
- sizeof(request.list[0].idx))) {
- retcode = -EFAULT;
- goto done;
- }
- if (copy_to_user(&request.list[i].total,
- &dma->buflist[i]->total,
- sizeof(request.list[0].total))) {
- retcode = -EFAULT;
- goto done;
- }
- if (copy_to_user(&request.list[i].used,
- &zero,
- sizeof(zero))) {
- retcode = -EFAULT;
- goto done;
- }
- address = virtual + dma->buflist[i]->offset;
- if (copy_to_user(&request.list[i].address,
- &address,
- sizeof(address))) {
- retcode = -EFAULT;
- goto done;
- }
- }
- }
- done:
- request.count = dma->buf_count;
- DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
+ for (i = 0; i < dma->buf_count; i++) {
+ if (copy_to_user(&request.list[i].idx,
+ &dma->buflist[i]->idx,
+ sizeof(request.list[0].idx))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ if (copy_to_user(&request.list[i].total,
+ &dma->buflist[i]->total,
+ sizeof(request.list[0].total))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ if (copy_to_user(&request.list[i].used,
+ &zero,
+ sizeof(zero))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ address = virtual + dma->buflist[i]->offset;
+ if (copy_to_user(&request.list[i].address,
+ &address,
+ sizeof(address))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ }
+ }
+ done:
+ request.count = dma->buf_count;
+ DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
- copy_to_user_ret((drm_buf_map_t *)arg,
- &request,
- sizeof(request),
- -EFAULT);
+ copy_to_user_ret((drm_buf_map_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
- DRM_DEBUG("retcode : %d\n", retcode);
+ DRM_DEBUG("retcode : %d\n", retcode);
- return retcode;
+ return retcode;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c
deleted file mode 100644
index 05895415e..000000000
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_clear.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/* mga_state.c -- State support for mga g200/g400 -*- linux-c -*-
- *
- * Created: February 2000 by keithw@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, 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, 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
- * PRECISION INSIGHT 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.
- *
- * Authors:
- * Keith Whitwell <keithw@precisioninsight.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "mga_drv.h"
-#include "mgareg_flags.h"
-#include "mga_dma.h"
-#include "mga_state.h"
-
-#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \
- DC_sgnzero_enable | DC_shftzero_enable | \
- (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \
- DC_solid_enable | DC_transc_enable)
-
-
-#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \
- DC_solid_disable | DC_arzero_disable | \
- DC_sgnzero_enable | DC_shftzero_enable | \
- (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \
- DC_pattern_disable | DC_transc_disable | \
- DC_clipdis_enable) \
-
-
-
-/* Build and queue a TT_GENERAL secondary buffer to do the clears.
- * With Jeff's ringbuffer idea, it might make sense if there are only
- * one or two cliprects to emit straight to the primary buffer.
- */
-static int mgaClearBuffers(drm_device_t *dev,
- int clear_color,
- int clear_depth,
- int flags)
-{
- int cmd, i;
- drm_device_dma_t *dma = dev->dma;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- xf86drmClipRectRec *pbox = sarea_priv->boxes;
- int nbox = sarea_priv->nbox;
- drm_buf_t *buf;
- drm_dma_t d;
- int order = 10; /* ??? what orders do we have ???*/
- DMALOCALS;
-
-
- if (!nbox)
- return -EINVAL;
-
- if ( dev_priv->sgram )
- cmd = MGA_CLEAR_CMD | DC_atype_blk;
- else
- cmd = MGA_CLEAR_CMD | DC_atype_rstr;
-
- buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT);
-
-
- DMAGETPTR( buf );
-
- for (i = 0 ; i < nbox ; i++) {
- unsigned int height = pbox[i].y2 - pbox[i].y1;
-
- /* Is it necessary to be this paranoid? I don't think so.
- if (pbox[i].x1 > dev_priv->width) continue;
- if (pbox[i].y1 > dev_priv->height) continue;
- if (pbox[i].x2 > dev_priv->width) continue;
- if (pbox[i].y2 > dev_priv->height) continue;
- if (pbox[i].x2 <= pbox[i].x1) continue;
- if (pbox[i].y2 <= pbox[i].x1) continue;
- */
-
- DMAOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
- DMAOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
-
- if ( flags & MGA_CLEAR_FRONT ) {
- DMAOUTREG(MGAREG_FCOL, clear_color);
- DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg);
- DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
- }
-
- if ( flags & MGA_CLEAR_BACK ) {
- DMAOUTREG(MGAREG_FCOL, clear_color);
- DMAOUTREG(MGAREG_DSTORG, dev_priv->backOrg);
- DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
- }
-
- if ( flags & MGA_CLEAR_DEPTH )
- {
- DMAOUTREG(MGAREG_FCOL, clear_depth);
- DMAOUTREG(MGAREG_DSTORG, dev_priv->depthOrg);
- DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
- }
- }
-
- DMAADVANCE( buf );
-
- /* Make sure we restore the 3D state next time.
- */
- sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
-
- ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL;
-
- d.context = DRM_KERNEL_CONTEXT;
- d.send_count = 1;
- d.send_indices = &buf->idx;
- d.send_sizes = &buf->used;
- d.flags = 0;
- d.request_count = 0;
- d.request_size = 0;
- d.request_indices = NULL;
- d.request_sizes = NULL;
- d.granted_count = 0;
-
- atomic_inc(&dev_priv->pending_bufs);
- if((drm_dma_enqueue(dev, &d)) != 0)
- atomic_dec(&dev_priv->pending_bufs);
- mga_dma_schedule(dev, 1);
- return 0;
-}
-
-int mgaSwapBuffers(drm_device_t *dev, int flags)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- xf86drmClipRectRec *pbox = sarea_priv->boxes;
- int nbox = sarea_priv->nbox;
- drm_buf_t *buf;
- drm_dma_t d;
- int order = 10; /* ??? */
- int i;
- DMALOCALS;
-
- if (!nbox)
- return -EINVAL;
-
- buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT);
-
- DMAGETPTR(buf);
-
- DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg);
- DMAOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
- DMAOUTREG(MGAREG_SRCORG, dev_priv->backOrg);
- DMAOUTREG(MGAREG_AR5, dev_priv->stride); /* unnecessary? */
- DMAOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
-
- for (i = 0 ; i < nbox; i++) {
- unsigned int h = pbox[i].y2 - pbox[i].y1;
- unsigned int start = pbox[i].y1 * dev_priv->stride;
-
- /*
- if (pbox[i].x1 > dev_priv->width) continue;
- if (pbox[i].y1 > dev_priv->height) continue;
- if (pbox[i].x2 > dev_priv->width) continue;
- if (pbox[i].y2 > dev_priv->height) continue;
- if (pbox[i].x2 <= pbox[i].x1) continue;
- if (pbox[i].y2 <= pbox[i].x1) continue;
- */
-
- DMAOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
- DMAOUTREG(MGAREG_AR3, start + pbox[i].x1);
- DMAOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16));
- DMAOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h);
- }
-
- DMAOUTREG(MGAREG_SRCORG, 0);
- DMAADVANCE( buf );
-
- /* Make sure we restore the 3D state next time.
- */
- sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
-
- ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL;
-
- d.context = DRM_KERNEL_CONTEXT;
- d.send_count = 1;
- d.send_indices = &buf->idx;
- d.send_sizes = &buf->used;
- d.flags = 0;
- d.request_count = 0;
- d.request_size = 0;
- d.request_indices = NULL;
- d.request_sizes = NULL;
- d.granted_count = 0;
-
- atomic_inc(&dev_priv->pending_bufs);
- if((drm_dma_enqueue(dev, &d)) != 0)
- atomic_dec(&dev_priv->pending_bufs);
- mga_dma_schedule(dev, 1);
- return 0;
-}
-
-
-static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf = dma->buflist[ args->idx ];
- drm_mga_buf_priv_t *buf_priv = (drm_mga_buf_priv_t *)buf->dev_private;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_dma_t d;
- int pixperdword;
-
- buf_priv->dma_type = MGA_DMA_ILOAD;
- buf_priv->boxes[0].y1 = args->texture.y1;
- buf_priv->boxes[0].y2 = args->texture.y2;
- buf_priv->boxes[0].x1 = args->texture.x1;
- buf_priv->boxes[0].x2 = args->texture.x2;
- buf_priv->ContextState[MGA_CTXREG_DSTORG] = args->destOrg;
- buf_priv->ContextState[MGA_CTXREG_MACCESS] = args->mAccess;
- buf_priv->ServerState[MGA_2DREG_PITCH] = args->pitch;
- buf_priv->nbox = 1;
- sarea_priv->dirty |= (MGASAREA_NEW_CONTEXT | MGASAREA_NEW_2D);
- switch((args->mAccess & 0x00000003)) {
- case 0:
- pixperdword = 4;
- break;
- case 1:
- pixperdword = 2;
- break;
- case 2:
- pixperdword = 1;
- break;
- default:
- DRM_ERROR("Invalid maccess value passed"
- " to mgaIload\n");
- return -EINVAL;
- }
- buf->used = ((args->texture.y2 - args->texture.y1) *
- (args->texture.x2 - args->texture.x1) /
- pixperdword);
- DRM_DEBUG("buf->used : %d\n", buf->used);
- d.context = DRM_KERNEL_CONTEXT;
- d.send_count = 1;
- d.send_indices = &buf->idx;
- d.send_sizes = &buf->used;
- d.flags = 0;
- d.request_count = 0;
- d.request_size = 0;
- d.request_indices = NULL;
- d.request_sizes = NULL;
- d.granted_count = 0;
-
- atomic_inc(&dev_priv->pending_bufs);
- if((drm_dma_enqueue(dev, &d)) != 0)
- atomic_dec(&dev_priv->pending_bufs);
- mga_dma_schedule(dev, 1);
-
- return 0;
-}
-
-
-/* Necessary? Not necessary??
- */
-static int check_lock(void)
-{
- return 1;
-}
-
-int mga_clear_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_mga_clear_t clear;
- int retcode;
-
- copy_from_user_ret(&clear, (drm_mga_clear_t *)arg,
- sizeof(clear), -EFAULT);
-
-/* if (!check_lock( dev )) */
-/* return -EIEIO; */
-
- retcode = mgaClearBuffers(dev, clear.clear_color,
- clear.clear_depth,
- clear.flags);
-
- return retcode;
-}
-
-int mga_swap_bufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_mga_swap_t swap;
- int retcode = 0;
-
-/* if (!check_lock( dev )) */
-/* return -EIEIO; */
-
- copy_from_user_ret(&swap, (drm_mga_swap_t *)arg,
- sizeof(swap), -EFAULT);
-
- retcode = mgaSwapBuffers(dev, swap.flags);
-
- return retcode;
-}
-
-int mga_iload(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_mga_iload_t iload;
- int retcode = 0;
-
-/* if (!check_lock( dev )) */
-/* return -EIEIO; */
-
- copy_from_user_ret(&iload, (drm_mga_iload_t *)arg,
- sizeof(iload), -EFAULT);
-
- retcode = mgaIload(dev, &iload);
-
- return retcode;
-}
-
-
-int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
- int retcode = 0;
- drm_dma_t d;
-
- copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
- DRM_DEBUG("%d %d: %d send, %d req\n",
- current->pid, d.context, d.send_count, d.request_count);
-
- /* Per-context queues are unworkable if you are trying to do
- * state management from the client.
- */
- d.context = DRM_KERNEL_CONTEXT;
- d.flags &= ~_DRM_DMA_WHILE_LOCKED;
-
- /* Maybe multiple buffers is useful for iload...
- * But this ioctl is only for *despatching* vertex data...
- */
- if (d.send_count < 0 || d.send_count > 1) {
- DRM_ERROR("Process %d trying to send %d buffers (max 1)\n",
- current->pid, d.send_count);
- return -EINVAL;
- }
-
-
- /* But it *is* used to request buffers for all types of dma:
- */
- if (d.request_count < 0 || d.request_count > dma->buf_count) {
- DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
- current->pid, d.request_count, dma->buf_count);
- return -EINVAL;
- }
-
- if (d.send_count) {
- int idx = d.send_indices[0];
- drm_mga_buf_priv_t *buf_priv = dma->buflist[ idx ]->dev_private;
- drm_mga_private_t *dev_priv = dev->dev_private;
-
- buf_priv->dma_type = MGA_DMA_VERTEX;
-
-/* if (!check_lock( dev )) */
-/* return -EIEIO; */
-
- /* Snapshot the relevent bits of the sarea...
- */
- mgaCopyAndVerifyState( dev_priv, buf_priv );
-
- atomic_inc(&dev_priv->pending_bufs);
- retcode = drm_dma_enqueue(dev, &d);
- if(retcode != 0)
- atomic_dec(&dev_priv->pending_bufs);
- mga_dma_schedule(dev, 1);
- }
-
- d.granted_count = 0;
-
- if (!retcode && d.request_count) {
- retcode = drm_dma_get_buffers(dev, &d);
- }
-
- DRM_DEBUG("%d returning, granted = %d\n",
- current->pid, d.granted_count);
- copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
-
- return retcode;
-}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c
index fb0d336fa..2459b35bb 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_context.c
@@ -38,7 +38,7 @@
static int mga_alloc_queue(drm_device_t *dev)
{
int temp = drm_ctxbitmap_next(dev);
- printk("mga_alloc_queue: %d\n", temp);
+ DRM_DEBUG("mga_alloc_queue: %d\n", temp);
return temp;
}
@@ -57,7 +57,7 @@ int mga_context_switch(drm_device_t *dev, int old, int new)
dev->ctx_start = get_cycles();
#endif
- printk("Context switch from %d to %d\n", old, new);
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
if (new == dev->last_context) {
clear_bit(0, &dev->context_flag);
@@ -104,7 +104,7 @@ int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
drm_ctx_t ctx;
int i;
- printk("%d\n", DRM_RESERVED_CONTEXTS);
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
if (res.count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
@@ -134,11 +134,11 @@ int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
ctx.handle = mga_alloc_queue(dev);
}
if (ctx.handle == -1) {
- printk("Not enough free contexts.\n");
+ DRM_DEBUG("Not enough free contexts.\n");
/* Should this return -EBUSY instead? */
return -ENOMEM;
}
- printk("%d\n", ctx.handle);
+ DRM_DEBUG("%d\n", ctx.handle);
copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
return 0;
}
@@ -170,7 +170,7 @@ int mga_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
- printk("%d\n", ctx.handle);
+ DRM_DEBUG("%d\n", ctx.handle);
return mga_context_switch(dev, dev->last_context, ctx.handle);
}
@@ -182,7 +182,7 @@ int mga_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
- printk("%d\n", ctx.handle);
+ DRM_DEBUG("%d\n", ctx.handle);
mga_context_switch_complete(dev, ctx.handle);
return 0;
@@ -194,51 +194,11 @@ int mga_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
- drm_queue_t *q;
- drm_buf_t *buf;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
- printk("%d\n", ctx.handle);
- if(ctx.handle == DRM_KERNEL_CONTEXT) {
- q = dev->queuelist[ctx.handle];
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
- atomic_inc(&q->finalization); /* Mark queue in finalization state */
- atomic_sub(2, &q->use_count);
- /* Mark queue as unused (pending finalization) */
-
- while (test_and_set_bit(0, &dev->interrupt_flag)) {
- printk("Calling schedule from rmctx\n");
- schedule();
- if (signal_pending(current)) {
- clear_bit(0, &dev->interrupt_flag);
- return -EINTR;
- }
- }
-
- /* Remove queued buffers */
- while ((buf = drm_waitlist_get(&q->waitlist))) {
- drm_free_buffer(dev, buf);
- }
- clear_bit(0, &dev->interrupt_flag);
-
- /* Wakeup blocked processes */
- wake_up_interruptible(&q->read_queue);
- wake_up_interruptible(&q->write_queue);
- wake_up_interruptible(&q->flush_queue);
-
- /* Finalization over. Queue is made
- available when both use_count and
- finalization become 0, which won't
- happen until all the waiting processes
- stop waiting. */
- atomic_dec(&q->finalization);
- } else {
- drm_ctxbitmap_free(dev, ctx.handle);
+ DRM_DEBUG("%d\n", ctx.handle);
+ if(ctx.handle != DRM_KERNEL_CONTEXT) {
+ drm_ctxbitmap_free(dev, ctx.handle);
}
return 0;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
index 2e24e5b48..59cbad6b4 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
@@ -25,17 +25,15 @@
*
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
* Jeff Hartmann <jhartmann@precisioninsight.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
*
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c,v 1.1 2000/02/11 17:26:07 dawes Exp $
+ * $XFree86$
*
*/
#define __NO_VERSION__
#include "drmP.h"
#include "mga_drv.h"
-#include "mgareg_flags.h"
-#include "mga_dma.h"
-#include "mga_state.h"
#include <linux/interrupt.h> /* For task queue support */
@@ -48,643 +46,599 @@
#define MGA_WRITE(reg,val) do { MGA_DEREF(reg) = val; } while (0)
#define PDEA_pagpxfer_enable 0x2
-#define MGA_SYNC_TAG 0x423f4200
-typedef enum {
- TT_GENERAL,
- TT_BLIT,
- TT_VECTOR,
- TT_VERTEX
-} transferType_t;
+static int mga_flush_queue(drm_device_t *dev);
+static unsigned long mga_alloc_page(drm_device_t *dev)
+{
+ unsigned long address;
+
+ address = __get_free_page(GFP_KERNEL);
+ if(address == 0UL) {
+ return 0;
+ }
+ atomic_inc(&mem_map[MAP_NR((void *) address)].count);
+ set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags);
+
+ return address;
+}
+
+static void mga_free_page(drm_device_t *dev, unsigned long page)
+{
+ if(page == 0UL) {
+ return;
+ }
+ atomic_dec(&mem_map[MAP_NR((void *) page)].count);
+ clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags);
+ wake_up(&mem_map[MAP_NR((void *) page)].wait);
+ free_page(page);
+ return;
+}
static void mga_delay(void)
{
return;
}
-int mga_dma_cleanup(drm_device_t *dev)
+static void mga_flush_write_combine(void)
{
- if(dev->dev_private) {
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *) dev->dev_private;
-
- if(dev_priv->ioremap) {
- int temp = (dev_priv->warp_ucode_size +
- dev_priv->primary_size +
- PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
-
- drm_ioremapfree((void *) dev_priv->ioremap, temp);
- }
-
- drm_free(dev->dev_private, sizeof(drm_mga_private_t),
- DRM_MEM_DRIVER);
- dev->dev_private = NULL;
- }
-
- return 0;
+ int xchangeDummy;
+ __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));
+ __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"
+ " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"
+ " pop %%eax" : /* no outputs */ : /* no inputs */ );
}
-static int mga_alloc_kernel_queue(drm_device_t *dev)
+/* These are two age tags that will never be sent to
+ * the hardware */
+#define MGA_BUF_USED 0xffffffff
+#define MGA_BUF_FREE 0
+
+static void mga_freelist_debug(drm_mga_freelist_t *item)
{
- drm_queue_t *queue = NULL;
- /* Allocate a new queue */
- down(&dev->struct_sem);
-
- if(dev->queue_count != 0) {
- /* Reseting the kernel context here is not
- * a race, since it can only happen when that
- * queue is empty.
- */
- queue = dev->queuelist[DRM_KERNEL_CONTEXT];
- printk("Kernel queue already allocated\n");
+ if(item->buf != NULL) {
+ DRM_DEBUG("buf index : %d\n", item->buf->idx);
} else {
- queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES);
- if(!queue) {
- up(&dev->struct_sem);
- printk("out of memory\n");
- return -ENOMEM;
- }
- ++dev->queue_count;
- dev->queuelist = drm_alloc(sizeof(*dev->queuelist),
- DRM_MEM_QUEUES);
- if(!dev->queuelist) {
- up(&dev->struct_sem);
- drm_free(queue, sizeof(*queue), DRM_MEM_QUEUES);
- printk("out of memory\n");
- return -ENOMEM;
- }
+ DRM_DEBUG("Freelist head\n");
}
-
- memset(queue, 0, sizeof(*queue));
- atomic_set(&queue->use_count, 1);
- atomic_set(&queue->finalization, 0);
- atomic_set(&queue->block_count, 0);
- atomic_set(&queue->block_read, 0);
- atomic_set(&queue->block_write, 0);
- atomic_set(&queue->total_queued, 0);
- atomic_set(&queue->total_flushed, 0);
- atomic_set(&queue->total_locks, 0);
-
- init_waitqueue_head(&queue->write_queue);
- init_waitqueue_head(&queue->read_queue);
- init_waitqueue_head(&queue->flush_queue);
-
- queue->flags = 0;
-
- drm_waitlist_create(&queue->waitlist, dev->dma->buf_count);
-
- dev->queue_slots = 1;
- dev->queuelist[DRM_KERNEL_CONTEXT] = queue;
- dev->queue_count--;
-
- up(&dev->struct_sem);
- printk("%d (new)\n", dev->queue_count - 1);
- return DRM_KERNEL_CONTEXT;
+ DRM_DEBUG("item->age : %x\n", item->age);
+ DRM_DEBUG("item->next : %p\n", item->next);
+ DRM_DEBUG("item->prev : %p\n", item->prev);
}
-static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
- drm_mga_private_t *dev_priv;
- drm_map_t *prim_map = NULL;
- drm_map_t *sarea_map = NULL;
- int temp;
-
-
- dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
- if(dev_priv == NULL) return -ENOMEM;
- dev->dev_private = (void *) dev_priv;
-
- printk("dev_private\n");
-
- memset(dev_priv, 0, sizeof(drm_mga_private_t));
- atomic_set(&dev_priv->pending_bufs, 0);
-
- if((init->reserved_map_idx >= dev->map_count) ||
- (init->buffer_map_idx >= dev->map_count)) {
- mga_dma_cleanup(dev);
- printk("reserved_map or buffer_map are invalid\n");
- return -EINVAL;
- }
+static int mga_freelist_init(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf;
+ drm_mga_buf_priv_t *buf_priv;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_freelist_t *item;
+ int i;
+
+ dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
+ if(dev_priv->head == NULL) return -ENOMEM;
+ memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
+ dev_priv->head->age = MGA_BUF_USED;
- if(mga_alloc_kernel_queue(dev) != DRM_KERNEL_CONTEXT) {
- mga_dma_cleanup(dev);
- DRM_ERROR("Kernel context queue not present\n");
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[ i ];
+ buf_priv = buf->dev_private;
+ item = drm_alloc(sizeof(drm_mga_freelist_t),
+ DRM_MEM_DRIVER);
+ if(item == NULL) return -ENOMEM;
+ memset(item, 0, sizeof(drm_mga_freelist_t));
+ item->age = MGA_BUF_FREE;
+ item->prev = dev_priv->head;
+ item->next = dev_priv->head->next;
+ if(dev_priv->head->next != NULL)
+ dev_priv->head->next->prev = item;
+ if(item->next == NULL) dev_priv->tail = item;
+ item->buf = buf;
+ buf_priv->my_freelist = item;
+ buf_priv->discard = 0;
+ dev_priv->head->next = item;
}
-
- dev_priv->reserved_map_idx = init->reserved_map_idx;
- dev_priv->buffer_map_idx = init->buffer_map_idx;
- sarea_map = dev->maplist[0];
- dev_priv->sarea_priv = (drm_mga_sarea_t *)
- ((u8 *)sarea_map->handle +
- init->sarea_priv_offset);
- printk("sarea_priv\n");
-
- /* Scale primary size to the next page */
- dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
- PAGE_SIZE) * PAGE_SIZE;
- dev_priv->warp_ucode_size = init->warp_ucode_size;
- dev_priv->chipset = init->chipset;
- dev_priv->fbOffset = init->fbOffset;
- dev_priv->backOffset = init->backOffset;
- dev_priv->depthOffset = init->depthOffset;
- dev_priv->textureOffset = init->textureOffset;
- dev_priv->textureSize = init->textureSize;
- dev_priv->cpp = init->cpp;
- dev_priv->sgram = init->sgram;
- dev_priv->stride = init->stride;
-
- dev_priv->frontOrg = init->frontOrg;
- dev_priv->backOrg = init->backOrg;
- dev_priv->depthOrg = init->depthOrg;
- dev_priv->mAccess = init->mAccess;
-
- printk("memcpy\n");
- memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
- sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES);
- printk("memcpy done\n");
- prim_map = dev->maplist[init->reserved_map_idx];
- dev_priv->prim_phys_head = dev->agp->base + init->reserved_map_agpstart;
- temp = init->warp_ucode_size + dev_priv->primary_size;
- temp = ((temp + PAGE_SIZE - 1) /
- PAGE_SIZE) * PAGE_SIZE;
- printk("temp : %x\n", temp);
- printk("dev->agp->base: %lx\n", dev->agp->base);
- printk("init->reserved_map_agpstart: %x\n", init->reserved_map_agpstart);
-
-
- dev_priv->ioremap = drm_ioremap(dev->agp->base + init->reserved_map_agpstart,
- temp);
- if(dev_priv->ioremap == NULL) {
- printk("Ioremap failed\n");
- mga_dma_cleanup(dev);
- return -ENOMEM;
+ item = dev_priv->head;
+ while(item) {
+ mga_freelist_debug(item);
+ item = item->next;
}
-
-
-
- dev_priv->prim_head = (u32 *)dev_priv->ioremap;
- printk("dev_priv->prim_head : %p\n", dev_priv->prim_head);
- dev_priv->current_dma_ptr = dev_priv->prim_head;
- dev_priv->prim_num_dwords = 0;
- dev_priv->prim_max_dwords = dev_priv->primary_size / 4;
+ DRM_DEBUG("Head\n");
+ mga_freelist_debug(dev_priv->head);
+ DRM_DEBUG("Tail\n");
+ mga_freelist_debug(dev_priv->tail);
- printk("dma initialization\n");
-
- /* Private is now filled in, initialize the hardware */
- {
- PRIMLOCALS;
- PRIMRESET( dev_priv );
- PRIMGETPTR( dev_priv );
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, 0);
- PRIMOUTREG(MGAREG_SOFTRAP, 0);
- PRIMADVANCE( dev_priv );
+ return 0;
+}
- /* Poll for the first buffer to insure that
- * the status register will be correct
- */
- printk("phys_head : %lx\n", phys_head);
+static void mga_freelist_cleanup(drm_device_t *dev)
+{
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_freelist_t *item;
+ drm_mga_freelist_t *prev;
+
+ item = dev_priv->head;
+ while(item) {
+ prev = item;
+ item = item->next;
+ drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
+ }
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
+ dev_priv->head = dev_priv->tail = NULL;
+}
- while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) {
- int i;
- for(i = 0 ; i < 4096; i++) mga_delay();
+/* Frees dispatch lock */
+static inline void mga_dma_quiescent(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ unsigned long end;
+ int i;
+
+ end = jiffies + (HZ*3);
+ while(1) {
+ if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
+ break;
}
-
- MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
-
- MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
- PDEA_pagpxfer_enable));
-
- while(MGA_READ(MGAREG_DWGSYNC) == MGA_SYNC_TAG) {
- int i;
- for(i = 0; i < 4096; i++) mga_delay();
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
+ atomic_read(&dma->total_lost));
+ DRM_ERROR("lockup\n");
+ goto out_nolock;
}
-
+ for (i = 0 ; i < 2000 ; i++) mga_delay();
}
-
- printk("dma init was successful\n");
- return 0;
+ end = jiffies + (HZ*3);
+ DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
+ while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
+ atomic_read(&dma->total_lost));
+ DRM_ERROR("lockup\n");
+ goto out_status;
+ }
+ for (i = 0 ; i < 2000 ; i++) mga_delay();
+ }
+ DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1],
+ dev_priv->last_sync_tag);
+ sarea_priv->dirty |= MGA_DMA_FLUSH;
+
+out_status:
+ clear_bit(0, &dev_priv->dispatch_lock);
+out_nolock:
}
-int mga_dma_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+#define FREELIST_INITIAL (MGA_DMA_BUF_NR * 2)
+#define FREELIST_COMPARE(age) ((age >> 2))
+
+unsigned int mga_create_sync_tag(drm_device_t *dev)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_mga_init_t init;
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+ unsigned int temp;
+ drm_buf_t *buf;
+ drm_mga_buf_priv_t *buf_priv;
+ drm_device_dma_t *dma = dev->dma;
+ int i;
- copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT);
+ dev_priv->sync_tag++;
- switch(init.func) {
- case MGA_INIT_DMA:
- return mga_dma_initialize(dev, &init);
- case MGA_CLEANUP_DMA:
- return mga_dma_cleanup(dev);
+ if(dev_priv->sync_tag < FREELIST_INITIAL) {
+ dev_priv->sync_tag = FREELIST_INITIAL;
}
+ if(dev_priv->sync_tag > 0x3fffffff) {
+ mga_flush_queue(dev);
+ mga_dma_quiescent(dev);
+
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[ i ];
+ buf_priv = buf->dev_private;
+ buf_priv->my_freelist->age = MGA_BUF_FREE;
+ }
+
+ dev_priv->sync_tag = FREELIST_INITIAL;
+ }
+ temp = dev_priv->sync_tag << 2;
- return -EINVAL;
-}
-
-#define MGA_ILOAD_CMD (DC_opcod_iload | DC_atype_rpl | \
- DC_linear_linear | DC_bltmod_bfcol | \
- (0xC << DC_bop_SHIFT) | DC_sgnzero_enable | \
- DC_shftzero_enable | DC_clipdis_enable)
+ dev_priv->sarea_priv->last_enqueue = temp;
-static void __mga_iload_small(drm_device_t *dev,
- drm_buf_t *buf,
- int use_agp)
-{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned long address = (unsigned long)buf->bus_address;
- int length = buf->used;
- int y1 = buf_priv->boxes[0].y1;
- int x1 = buf_priv->boxes[0].x1;
- int y2 = buf_priv->boxes[0].y2;
- int x2 = buf_priv->boxes[0].x2;
- int dstorg = buf_priv->ContextState[MGA_CTXREG_DSTORG];
- int maccess = buf_priv->ContextState[MGA_CTXREG_MACCESS];
- PRIMLOCALS;
-
- PRIMRESET(dev_priv);
- PRIMGETPTR(dev_priv);
-
- PRIMOUTREG(MGAREG_DSTORG, dstorg | use_agp);
- PRIMOUTREG(MGAREG_MACCESS, maccess);
- PRIMOUTREG(MGAREG_PITCH, (1 << 15));
- PRIMOUTREG(MGAREG_YDST, y1 * (x2 - x1));
- PRIMOUTREG(MGAREG_LEN, 1);
- PRIMOUTREG(MGAREG_FXBNDRY, ((x2 - x1) * (y2 - y1) - 1) << 16);
- PRIMOUTREG(MGAREG_AR0, (x2 - x1) * (y2 - y1) - 1);
- PRIMOUTREG(MGAREG_AR3, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT);
- PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, 0);
- PRIMOUTREG(MGAREG_SOFTRAP, 0);
- PRIMADVANCE(dev_priv);
-#if 0
- /* For now we need to set this in the ioctl */
- sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
-#endif
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
- while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
-
- MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
- MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
+ DRM_DEBUG("sync_tag : %x\n", temp);
+ return temp;
}
-static void __mga_iload_xy(drm_device_t *dev,
- drm_buf_t *buf,
- int use_agp)
+/* Least recently used :
+ * These operations are not atomic b/c they are protected by the
+ * hardware lock */
+
+drm_buf_t *mga_freelist_get(drm_device_t *dev)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned long address = (unsigned long)buf->bus_address;
- int length = buf->used;
- int y1 = buf_priv->boxes[0].y1;
- int x1 = buf_priv->boxes[0].x1;
- int y2 = buf_priv->boxes[0].y2;
- int x2 = buf_priv->boxes[0].x2;
- int dstorg = buf_priv->ContextState[MGA_CTXREG_DSTORG];
- int maccess = buf_priv->ContextState[MGA_CTXREG_MACCESS];
- int pitch = buf_priv->ServerState[MGA_2DREG_PITCH];
- int width, height;
- int texperdword = 0;
- PRIMLOCALS;
-
- width = (x2 - x1);
- height = (y2 - y1);
- switch((maccess & 0x00000003)) {
- case 0:
- texperdword = 4;
- break;
- case 1:
- texperdword = 2;
- break;
- case 2:
- texperdword = 1;
- break;
- default:
- DRM_ERROR("Invalid maccess value passed to __mga_iload_xy\n");
- return;
- }
-
- x2 = x1 + width;
- x2 = (x2 + (texperdword - 1)) & ~(texperdword - 1);
- x1 = (x1 + (texperdword - 1)) & ~(texperdword - 1);
- width = x2 - x1;
-
- PRIMRESET(dev_priv);
- PRIMGETPTR(dev_priv);
- PRIMOUTREG(MGAREG_DSTORG, dstorg | use_agp);
- PRIMOUTREG(MGAREG_MACCESS, maccess);
- PRIMOUTREG(MGAREG_PITCH, pitch);
- PRIMOUTREG(MGAREG_YDSTLEN, (y1 << 16) | height);
-
- PRIMOUTREG(MGAREG_FXBNDRY, ((x1+width-1) << 16) | x1);
- PRIMOUTREG(MGAREG_AR0, width * height - 1);
- PRIMOUTREG(MGAREG_AR3, 0 );
- PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD);
-
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT);
- PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp);
-
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, 0);
- PRIMOUTREG(MGAREG_SOFTRAP, 0);
- PRIMADVANCE(dev_priv);
-#if 0
- /* For now we need to set this in the ioctl */
- sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
-#endif
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
- while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
-
- MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
- MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ drm_mga_freelist_t *prev;
+ drm_mga_freelist_t *next;
+
+ if((dev_priv->tail->age >> 2) <= FREELIST_COMPARE(status[1])) {
+ prev = dev_priv->tail->prev;
+ next = dev_priv->tail;
+ prev->next = NULL;
+ next->prev = next->next = NULL;
+ dev_priv->tail = prev;
+ next->age = MGA_BUF_USED;
+ return next->buf;
+ }
+
+ return NULL;
}
-static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf)
+int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
{
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
-
- int use_agp = PDEA_pagpxfer_enable;
- int x1 = buf_priv->boxes[0].x1;
- int x2 = buf_priv->boxes[0].x2;
-
- if((x2 - x1) < 32) {
- printk("using iload small\n");
- __mga_iload_small(dev, buf, use_agp);
+ drm_mga_freelist_t *prev;
+ drm_mga_freelist_t *head;
+ drm_mga_freelist_t *next;
+
+ if(buf_priv->my_freelist->age == MGA_BUF_USED) {
+ /* Discarded buffer, put it on the tail */
+ next = buf_priv->my_freelist;
+ next->age = MGA_BUF_FREE;
+ prev = dev_priv->tail;
+ prev->next = next;
+ next->prev = prev;
+ next->next = NULL;
+ dev_priv->tail = next;
+ DRM_DEBUG("Discarded\n");
} else {
- printk("using iload xy\n");
- __mga_iload_xy(dev, buf, use_agp);
- }
+ /* Normally aged buffer, put it on the head + 1,
+ * as the real head is a sentinal element
+ */
+ next = buf_priv->my_freelist;
+ head = dev_priv->head;
+ prev = head->next;
+ head->next = next;
+ prev->prev = next;
+ next->prev = head;
+ next->next = prev;
+ }
+
+ return 0;
}
-static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf)
+static void mga_print_all_primary(drm_device_t *dev)
{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- unsigned long address = (unsigned long)buf->bus_address;
- int length = buf->used;
- int use_agp = PDEA_pagpxfer_enable;
- int i, count;
- PRIMLOCALS;
-
- PRIMRESET(dev_priv);
-
- count = buf_priv->nbox;
- if (count == 0)
- count = 1;
-
- mgaEmitState( dev_priv, buf_priv );
-
- for (i = 0 ; i < count ; i++) {
- if (i < buf_priv->nbox)
- mgaEmitClipRect( dev_priv, &buf_priv->boxes[i] );
-
- PRIMGETPTR(dev_priv);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_SECADDRESS, address | TT_VERTEX);
- PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp);
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGSYNC, 0);
- PRIMOUTREG( MGAREG_SOFTRAP, 0);
- PRIMADVANCE(dev_priv);
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_prim_buf_t *prim;
+ int i;
+
+ DRM_DEBUG("Full list of primarys\n");
+ for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
+ prim = dev_priv->prim_bufs[i];
+ DRM_DEBUG("index : %d num_dwords : %d "
+ "max_dwords : %d phy_head : %x\n",
+ prim->idx, prim->num_dwords,
+ prim->max_dwords, prim->phys_head);
+ DRM_DEBUG("sec_used : %d swap_pending : %x "
+ "in_use : %x force_fire : %d\n",
+ prim->sec_used, prim->swap_pending,
+ prim->in_use, atomic_read(&prim->force_fire));
+ DRM_DEBUG("needs_overflow : %d\n",
+ atomic_read(&prim->needs_overflow));
}
-
- PRIMGETPTR( dev_priv );
-
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
- while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
-
- MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
- MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
+
+ DRM_DEBUG("current_idx : %d, next_idx : %d, last_idx : %d\n",
+ dev_priv->next_prim->idx, dev_priv->last_prim->idx,
+ dev_priv->current_prim->idx);
}
-
-/* Used internally for the small buffers generated from client state
- * information.
- */
-static void mga_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf)
+static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
{
drm_mga_private_t *dev_priv = dev->dev_private;
- unsigned long address = (unsigned long)buf->bus_address;
- int length = buf->used;
- int use_agp = PDEA_pagpxfer_enable;
- PRIMLOCALS;
-
- PRIMRESET(dev_priv);
- PRIMGETPTR(dev_priv);
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_SECADDRESS, address | TT_GENERAL);
- PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp);
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGSYNC, 0);
- PRIMOUTREG( MGAREG_SOFTRAP, 0);
- PRIMADVANCE(dev_priv);
-
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
- while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
-
- MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
- MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
-}
+ drm_mga_prim_buf_t *prim_buffer;
+ int i, temp, size_of_buf;
+ int offset = init->reserved_map_agpstart;
-/* Frees dispatch lock */
-static inline void mga_dma_quiescent(drm_device_t *dev)
-{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-
- while(1) {
- atomic_inc(&dev_priv->dispatch_lock);
- if(atomic_read(&dev_priv->dispatch_lock) == 1) {
- break;
- } else {
- atomic_dec(&dev_priv->dispatch_lock);
- }
- }
- while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) ;
-#if 0
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
-#endif
- while(MGA_READ(MGAREG_DWGSYNC) == MGA_SYNC_TAG) ;
- MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
- while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
- atomic_dec(&dev_priv->dispatch_lock);
+ DRM_DEBUG("mga_init_primary_bufs\n");
+ dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
+ PAGE_SIZE) * PAGE_SIZE;
+ DRM_DEBUG("primary_size\n");
+ size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
+ dev_priv->warp_ucode_size = init->warp_ucode_size;
+ dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
+ (MGA_NUM_PRIM_BUFS + 1),
+ DRM_MEM_DRIVER);
+ if(dev_priv->prim_bufs == NULL) {
+ DRM_ERROR("Unable to allocate memory for prim_buf\n");
+ return -ENOMEM;
+ }
+ DRM_DEBUG("memset\n");
+ memset(dev_priv->prim_bufs,
+ 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
+
+ temp = init->warp_ucode_size + dev_priv->primary_size;
+ temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
+
+ DRM_DEBUG("temp : %x\n", temp);
+ DRM_DEBUG("dev->agp->base: %lx\n", dev->agp->base);
+ DRM_DEBUG("init->reserved_map_agpstart: %x\n",
+ init->reserved_map_agpstart);
+ DRM_DEBUG("ioremap\n");
+ dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
+ temp);
+ if(dev_priv->ioremap == NULL) {
+ DRM_DEBUG("Ioremap failed\n");
+ return -ENOMEM;
+ }
+ init_waitqueue_head(&dev_priv->wait_queue);
+
+ for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
+ DRM_DEBUG("For loop\n");
+ prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
+ DRM_MEM_DRIVER);
+ if(prim_buffer == NULL) return -ENOMEM;
+ DRM_DEBUG("memset\n");
+ memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
+ prim_buffer->phys_head = offset + dev->agp->base;
+ prim_buffer->current_dma_ptr =
+ prim_buffer->head =
+ (u32 *) (dev_priv->ioremap +
+ offset -
+ init->reserved_map_agpstart);
+ prim_buffer->num_dwords = 0;
+ prim_buffer->max_dwords = size_of_buf / sizeof(u32);
+ prim_buffer->max_dwords -= 5; /* Leave room for the softrap */
+ prim_buffer->sec_used = 0;
+ prim_buffer->idx = i;
+ offset = offset + size_of_buf;
+ dev_priv->prim_bufs[i] = prim_buffer;
+ DRM_DEBUG("Looping\n");
+ }
+ dev_priv->current_prim_idx = 0;
+ dev_priv->next_prim =
+ dev_priv->last_prim =
+ dev_priv->current_prim =
+ dev_priv->prim_bufs[0];
+ set_bit(0, &dev_priv->current_prim->in_use);
+ DRM_DEBUG("init done\n");
+ return 0;
}
-/* Keeps dispatch lock held */
-
-static inline int mga_dma_is_ready(drm_device_t *dev)
+void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int use_agp = PDEA_pagpxfer_enable;
+ unsigned long end;
+ int i;
+ int next_idx;
+ PRIMLOCALS;
+
+ DRM_DEBUG("mga_fire_primary\n");
+ dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+ dev_priv->last_prim = prim;
- atomic_inc(&dev_priv->dispatch_lock);
- if(atomic_read(&dev_priv->dispatch_lock) == 1) {
- /* We got the lock */
- return 1;
+ /* We never check for overflow, b/c there is always room */
+ PRIMPTR(prim);
+ if(num_dwords <= 0) {
+ DRM_DEBUG("num_dwords == 0 when dispatched\n");
+ goto out_prim_wait;
+ }
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMOUTREG( MGAREG_SOFTRAP, 0);
+ PRIMFINISH(prim);
+
+ end = jiffies + (HZ*3);
+ if(sarea_priv->dirty & MGA_DMA_FLUSH) {
+ DRM_DEBUG("Dma top flush\n");
+ while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
+ atomic_read(&dma->total_lost));
+ DRM_ERROR("lockup in fire primary "
+ "(Dma Top Flush)\n");
+ goto out_prim_wait;
+ }
+
+ for (i = 0 ; i < 4096 ; i++) mga_delay();
+ }
+ sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
} else {
- atomic_dec(&dev_priv->dispatch_lock);
- return 0;
+ DRM_DEBUG("Status wait\n");
+ while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
+ if((signed)(end - jiffies) <= 0) {
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
+ atomic_read(&dma->total_lost));
+ DRM_ERROR("lockup in fire primary "
+ "(Status Wait)\n");
+ goto out_prim_wait;
+ }
+
+ for (i = 0 ; i < 4096 ; i++) mga_delay();
+ }
}
+
+ mga_flush_write_combine();
+ atomic_inc(&dev_priv->pending_bufs);
+ atomic_inc(&dma->total_lost);
+ MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
+ MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
+ prim->num_dwords = 0;
+
+ next_idx = prim->idx + 1;
+ if(next_idx >= MGA_NUM_PRIM_BUFS)
+ next_idx = 0;
+
+ dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
+ return;
+
+ out_prim_wait:
+ prim->num_dwords = 0;
+ prim->sec_used = 0;
+ clear_bit(0, &prim->in_use);
+ wake_up_interruptible(&dev_priv->wait_queue);
+ clear_bit(0, &prim->swap_pending);
+ clear_bit(0, &dev_priv->dispatch_lock);
+ atomic_dec(&dev_priv->pending_bufs);
}
-static inline int mga_dma_is_ready_no_hold(drm_device_t *dev)
+int mga_advance_primary(drm_device_t *dev)
{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ DECLARE_WAITQUEUE(entry, current);
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_prim_buf_t *prim_buffer;
+ drm_device_dma_t *dma = dev->dma;
+ int next_prim_idx;
+ int ret = 0;
- atomic_inc(&dev_priv->dispatch_lock);
- if(atomic_read(&dev_priv->dispatch_lock) == 1) {
- /* We got the lock, but free it */
- atomic_dec(&dev_priv->dispatch_lock);
- return 1;
- } else {
- atomic_dec(&dev_priv->dispatch_lock);
- return 0;
+ /* This needs to reset the primary buffer if available,
+ * we should collect stats on how many times it bites
+ * it's tail */
+
+ next_prim_idx = dev_priv->current_prim_idx + 1;
+ if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
+ next_prim_idx = 0;
+ prim_buffer = dev_priv->prim_bufs[next_prim_idx];
+ atomic_set(&dev_priv->in_wait, 1);
+
+ /* In use is cleared in interrupt handler */
+
+ if(test_and_set_bit(0, &prim_buffer->in_use)) {
+ add_wait_queue(&dev_priv->wait_queue, &entry);
+ for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
+ mga_dma_schedule(dev, 0);
+ if(!test_and_set_bit(0, &prim_buffer->in_use)) break;
+ atomic_inc(&dev->total_sleeps);
+ atomic_inc(&dma->total_missed_sched);
+ mga_print_all_primary(dev);
+ DRM_DEBUG("Schedule in advance\n");
+ /* Three second delay */
+ schedule_timeout(HZ*3);
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev_priv->wait_queue, &entry);
+ if(ret) return ret;
}
+ atomic_set(&dev_priv->in_wait, 0);
+ /* This primary buffer is now free to use */
+ prim_buffer->current_dma_ptr = prim_buffer->head;
+ prim_buffer->num_dwords = 0;
+ prim_buffer->sec_used = 0;
+ atomic_set(&prim_buffer->needs_overflow, 0);
+ dev_priv->current_prim = prim_buffer;
+ dev_priv->current_prim_idx = next_prim_idx;
+ DRM_DEBUG("Primarys at advance\n");
+ mga_print_all_primary(dev);
+ return 0;
}
-static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
+/* More dynamic performance decisions */
+static inline int mga_decide_to_fire(drm_device_t *dev)
{
- drm_device_t *dev = (drm_device_t *)device;
- drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+
+ if(atomic_read(&dev_priv->next_prim->force_fire))
+ {
+ atomic_inc(&dma->total_prio);
+ return 1;
+ }
- atomic_dec(&dev_priv->dispatch_lock);
- atomic_inc(&dev->total_irq);
- MGA_WRITE(MGAREG_ICLEAR, 0xfa7);
-
- /* Free previous buffer */
- if (test_and_set_bit(0, &dev->dma_flag)) {
- atomic_inc(&dma->total_missed_free);
- return;
+ if (atomic_read(&dev_priv->in_flush) && dev_priv->next_prim->num_dwords)
+ {
+ atomic_inc(&dma->total_prio);
+ return 1;
}
- if (dma->this_buffer) {
- drm_free_buffer(dev, dma->this_buffer);
- dma->this_buffer = NULL;
+
+ if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
+ if(test_bit(0, &dev_priv->next_prim->swap_pending)) {
+ atomic_inc(&dma->total_dmas);
+ return 1;
+ }
}
- clear_bit(0, &dev->dma_flag);
- /* Dispatch new buffer */
- queue_task(&dev->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
+ if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
+ atomic_inc(&dma->total_hit);
+ return 1;
+ }
+ }
+ if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
+ if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
+ atomic_inc(&dma->total_missed_free);
+ return 1;
+ }
+ }
+
+ atomic_inc(&dma->total_tried);
+ return 0;
}
-/* Only called by mga_dma_schedule. */
-static int mga_do_dma(drm_device_t *dev, int locked)
+int mga_dma_schedule(drm_device_t *dev, int locked)
{
- drm_buf_t *buf;
- int retcode = 0;
- drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_buf_priv_t *buf_priv;
+ drm_device_dma_t *dma = dev->dma;
- printk("mga_do_dma\n");
- if (test_and_set_bit(0, &dev->dma_flag)) {
+ if (test_and_set_bit(0, &dev->dma_flag)) {
atomic_inc(&dma->total_missed_dma);
return -EBUSY;
}
-
- if (!dma->next_buffer) {
- DRM_ERROR("No next_buffer\n");
- clear_bit(0, &dev->dma_flag);
- return -EINVAL;
- }
-
- buf = dma->next_buffer;
-
- printk("context %d, buffer %d\n", buf->context, buf->idx);
-
- if (buf->list == DRM_LIST_RECLAIM) {
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
- clear_bit(0, &dev->dma_flag);
- return -EINVAL;
- }
+
+ DRM_DEBUG("mga_dma_schedule\n");
- if (!buf->used) {
- DRM_ERROR("0 length buffer\n");
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
- clear_bit(0, &dev->dma_flag);
- return 0;
- }
-
- if (mga_dma_is_ready(dev) == 0) {
- clear_bit(0, &dev->dma_flag);
- return -EBUSY;
+ if(atomic_read(&dev_priv->in_flush) ||
+ atomic_read(&dev_priv->in_wait)) {
+ locked = 1;
}
- /* Always hold the hardware lock while dispatching.
- */
- if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- atomic_inc(&dma->total_missed_lock);
- clear_bit(0, &dev->dma_flag);
- atomic_dec(&dev_priv->dispatch_lock);
- return -EBUSY;
+ if (!locked &&
+ !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
+ atomic_inc(&dma->total_missed_lock);
+ clear_bit(0, &dev->dma_flag);
+ return -EBUSY;
}
+ DRM_DEBUG("I'm locked\n");
- dma->next_queue = dev->queuelist[DRM_KERNEL_CONTEXT];
- drm_clear_next_buffer(dev);
- buf->pending = 1;
- buf->waiting = 0;
- buf->list = DRM_LIST_PEND;
-
- buf_priv = buf->dev_private;
-
- printk("dispatch!\n");
- switch (buf_priv->dma_type) {
- case MGA_DMA_GENERAL:
- mga_dma_dispatch_general(dev, buf);
- break;
- case MGA_DMA_VERTEX:
- mga_dma_dispatch_vertex(dev, buf);
- break;
-/* case MGA_DMA_SETUP: */
-/* mga_dma_dispatch_setup(dev, address, length); */
-/* break; */
- case MGA_DMA_ILOAD:
- mga_dma_dispatch_iload(dev, buf);
- break;
- default:
- printk("bad buffer type %x in dispatch\n", buf_priv->dma_type);
- break;
+
+ if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
+ /* Fire dma buffer */
+ if(mga_decide_to_fire(dev)) {
+ DRM_DEBUG("mga_fire_primary\n");
+ DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
+ atomic_set(&dev_priv->next_prim->force_fire, 0);
+ if(dev_priv->current_prim == dev_priv->next_prim &&
+ dev_priv->next_prim->num_dwords != 0) {
+ /* Schedule overflow for a later time */
+ atomic_set(
+ &dev_priv->current_prim->needs_overflow,
+ 1);
+ }
+ mga_fire_primary(dev, dev_priv->next_prim);
+ } else {
+ clear_bit(0, &dev_priv->dispatch_lock);
+ }
+ } else {
+ DRM_DEBUG("I can't get the dispatch lock\n");
}
- atomic_dec(&dev_priv->pending_bufs);
-
- drm_free_buffer(dev, dma->this_buffer);
- dma->this_buffer = buf;
-
- atomic_add(buf->used, &dma->total_bytes);
- atomic_inc(&dma->total_dmas);
-
+
if (!locked) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
@@ -692,90 +646,251 @@ static int mga_do_dma(drm_device_t *dev, int locked)
}
}
- clear_bit(0, &dev->dma_flag);
-
- if(!atomic_read(&dev_priv->pending_bufs)) {
- wake_up_interruptible(&dev->queuelist[DRM_KERNEL_CONTEXT]->flush_queue);
- }
-
-#if 0
- wake_up_interruptible(&dev->lock.lock_queue);
-#endif
+ clear_bit(0, &dev->dma_flag);
- /* We hold the dispatch lock until the interrupt handler
- * frees it
- */
- return retcode;
+ if(atomic_read(&dev_priv->in_flush) == 1 &&
+ dev_priv->next_prim->num_dwords == 0) {
+ /* Everything is on the hardware */
+ DRM_DEBUG("Primarys at Flush\n");
+ mga_print_all_primary(dev);
+ atomic_set(&dev_priv->in_flush, 0);
+ wake_up_interruptible(&dev_priv->flush_queue);
+ }
+
+ return 0;
}
-static void mga_dma_schedule_timer_wrapper(unsigned long dev)
+static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
{
- mga_dma_schedule((drm_device_t *)dev, 0);
+ drm_device_t *dev = (drm_device_t *)device;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_prim_buf_t *last_prim_buffer;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+
+ atomic_inc(&dev->total_irq);
+ MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
+ last_prim_buffer = dev_priv->last_prim;
+ last_prim_buffer->num_dwords = 0;
+ last_prim_buffer->sec_used = 0;
+ clear_bit(0, &last_prim_buffer->in_use);
+ wake_up_interruptible(&dev_priv->wait_queue);
+ clear_bit(0, &last_prim_buffer->swap_pending);
+ clear_bit(0, &dev_priv->dispatch_lock);
+ atomic_dec(&dev_priv->pending_bufs);
+ dev_priv->sarea_priv->last_dispatch = status[1];
+ queue_task(&dev->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
}
-static void mga_dma_schedule_tq_wrapper(void *dev)
+static void mga_dma_task_queue(void *device)
{
+ drm_device_t *dev = (drm_device_t *) device;
+
mga_dma_schedule(dev, 0);
}
-int mga_dma_schedule(drm_device_t *dev, int locked)
+int mga_dma_cleanup(drm_device_t *dev)
{
- drm_queue_t *q;
- drm_buf_t *buf;
- int retcode = 0;
- int processed = 0;
- int missed;
- int expire = 20;
- drm_device_dma_t *dma = dev->dma;
-
- printk("mga_dma_schedule\n");
-
- if (test_and_set_bit(0, &dev->interrupt_flag)) {
- /* Not reentrant */
- atomic_inc(&dma->total_missed_sched);
- return -EBUSY;
- }
- missed = atomic_read(&dma->total_missed_sched);
+ if(dev->dev_private) {
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+
+ if(dev_priv->ioremap) {
+ int temp = (dev_priv->warp_ucode_size +
+ dev_priv->primary_size +
+ PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
-again:
- /* There is only one queue:
- */
- if (!dma->next_buffer && DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) {
- q = dev->queuelist[DRM_KERNEL_CONTEXT];
- buf = drm_waitlist_get(&q->waitlist);
- dma->next_buffer = buf;
- dma->next_queue = q;
- if (buf && buf->list == DRM_LIST_RECLAIM) {
- drm_clear_next_buffer(dev);
- drm_free_buffer(dev, buf);
+ drm_ioremapfree((void *) dev_priv->ioremap, temp);
+ }
+ if(dev_priv->status_page != NULL) {
+ iounmap(dev_priv->status_page);
+ }
+ if(dev_priv->real_status_page != 0UL) {
+ mga_free_page(dev, dev_priv->real_status_page);
+ }
+ if(dev_priv->prim_bufs != NULL) {
+ int i;
+ for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
+ if(dev_priv->prim_bufs[i] != NULL) {
+ drm_free(dev_priv->prim_bufs[i],
+ sizeof(drm_mga_prim_buf_t),
+ DRM_MEM_DRIVER);
+ }
+ }
+ drm_free(dev_priv->prim_bufs, sizeof(void *) *
+ (MGA_NUM_PRIM_BUFS + 1),
+ DRM_MEM_DRIVER);
+ }
+ if(dev_priv->head != NULL) {
+ mga_freelist_cleanup(dev);
}
+
+
+ drm_free(dev->dev_private, sizeof(drm_mga_private_t),
+ DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
}
- if (dma->next_buffer) {
- if (!(retcode = mga_do_dma(dev, locked)))
- ++processed;
+ return 0;
+}
+
+static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
+ drm_mga_private_t *dev_priv;
+ drm_map_t *sarea_map = NULL;
+ int i;
+
+ dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
+ if(dev_priv == NULL) return -ENOMEM;
+ dev->dev_private = (void *) dev_priv;
+
+ DRM_DEBUG("dev_private\n");
+
+ memset(dev_priv, 0, sizeof(drm_mga_private_t));
+ atomic_set(&dev_priv->in_flush, 0);
+
+ if((init->reserved_map_idx >= dev->map_count) ||
+ (init->buffer_map_idx >= dev->map_count)) {
+ mga_dma_cleanup(dev);
+ DRM_DEBUG("reserved_map or buffer_map are invalid\n");
+ return -EINVAL;
}
+
+ dev_priv->reserved_map_idx = init->reserved_map_idx;
+ dev_priv->buffer_map_idx = init->buffer_map_idx;
+ sarea_map = dev->maplist[0];
+ dev_priv->sarea_priv = (drm_mga_sarea_t *)
+ ((u8 *)sarea_map->handle +
+ init->sarea_priv_offset);
+ DRM_DEBUG("sarea_priv\n");
- /* Try again if we succesfully dispatched a buffer, or if someone
- * tried to schedule while we were working.
- */
- if (--expire) {
- if (missed != atomic_read(&dma->total_missed_sched)) {
- atomic_inc(&dma->total_lost);
- if (mga_dma_is_ready_no_hold(dev))
- goto again;
- }
+ /* Scale primary size to the next page */
+ dev_priv->chipset = init->chipset;
+ dev_priv->frontOffset = init->frontOffset;
+ dev_priv->backOffset = init->backOffset;
+ dev_priv->depthOffset = init->depthOffset;
+ dev_priv->textureOffset = init->textureOffset;
+ dev_priv->textureSize = init->textureSize;
+ dev_priv->cpp = init->cpp;
+ dev_priv->sgram = init->sgram;
+ dev_priv->stride = init->stride;
- if (processed && mga_dma_is_ready_no_hold(dev)) {
- atomic_inc(&dma->total_lost);
- processed = 0;
- goto again;
- }
+ dev_priv->mAccess = init->mAccess;
+ init_waitqueue_head(&dev_priv->flush_queue);
+ dev_priv->WarpPipe = -1;
+
+ DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
+ dev_priv->chipset, dev_priv->warp_ucode_size,
+ dev_priv->backOffset, dev_priv->depthOffset);
+ DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n",
+ dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
+ dev_priv->mAccess);
+
+ memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
+ sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
+
+ for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++)
+ DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n",
+ i,
+ dev_priv->WarpIndex[i].installed,
+ dev_priv->WarpIndex[i].phys_addr,
+ dev_priv->WarpIndex[i].size);
+
+ DRM_DEBUG("Doing init prim buffers\n");
+ if(mga_init_primary_bufs(dev, init) != 0) {
+ DRM_ERROR("Can not initialize primary buffers\n");
+ mga_dma_cleanup(dev);
+ return -ENOMEM;
}
-
- clear_bit(0, &dev->interrupt_flag);
-
- return retcode;
+ DRM_DEBUG("Done with init prim buffers\n");
+ dev_priv->real_status_page = mga_alloc_page(dev);
+ if(dev_priv->real_status_page == 0UL) {
+ mga_dma_cleanup(dev);
+ DRM_ERROR("Can not allocate status page\n");
+ return -ENOMEM;
+ }
+ DRM_DEBUG("Status page at %lx\n", dev_priv->real_status_page);
+
+ dev_priv->status_page =
+ ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
+ PAGE_SIZE);
+
+ if(dev_priv->status_page == NULL) {
+ mga_dma_cleanup(dev);
+ DRM_ERROR("Can not remap status page\n");
+ return -ENOMEM;
+ }
+
+ DRM_DEBUG("Status page remapped to %p\n", dev_priv->status_page);
+ /* Write status page when secend or softrap occurs */
+ MGA_WRITE(MGAREG_PRIMPTR,
+ virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
+
+ dev_priv->device = pci_find_device(0x102b, 0x0525, NULL);
+ if(dev_priv->device == NULL) {
+ DRM_ERROR("Could not find pci device for card\n");
+ mga_dma_cleanup(dev);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("dma initialization\n");
+
+ /* Private is now filled in, initialize the hardware */
+ {
+ __volatile__ unsigned int *status =
+ (unsigned int *)dev_priv->status_page;
+ PRIMLOCALS;
+ PRIMGETPTR( dev_priv );
+
+ dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMOUTREG(MGAREG_SOFTRAP, 0);
+ /* Poll for the first buffer to insure that
+ * the status register will be correct
+ */
+ DRM_DEBUG("phys_head : %lx\n", (unsigned long)phys_head);
+ status[1] = 0;
+
+ mga_flush_write_combine();
+ MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
+
+ MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
+ PDEA_pagpxfer_enable));
+
+ while(MGA_READ(MGAREG_DWGSYNC) != dev_priv->last_sync_tag) ;
+ DRM_DEBUG("status[0] after initialization : %x\n", status[0]);
+ DRM_DEBUG("status[1] after initialization : %x\n", status[1]);
+ }
+
+ if(mga_freelist_init(dev) != 0) {
+ DRM_ERROR("Could not initialize freelist\n");
+ mga_dma_cleanup(dev);
+ return -ENOMEM;
+ }
+ DRM_DEBUG("dma init was successful\n");
+ return 0;
+}
+
+int mga_dma_init(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_mga_init_t init;
+
+ copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT);
+
+ switch(init.func) {
+ case MGA_INIT_DMA:
+ return mga_dma_initialize(dev, &init);
+ case MGA_CLEANUP_DMA:
+ return mga_dma_cleanup(dev);
+ }
+
+ return -EINVAL;
}
int mga_irq_install(drm_device_t *dev, int irq)
@@ -792,7 +907,7 @@ int mga_irq_install(drm_device_t *dev, int irq)
dev->irq = irq;
up(&dev->struct_sem);
- printk("install irq handler %d\n", irq);
+ DRM_DEBUG("install irq handler %d\n", irq);
dev->context_flag = 0;
dev->interrupt_flag = 0;
@@ -802,13 +917,11 @@ int mga_irq_install(drm_device_t *dev, int irq)
dev->dma->this_buffer = NULL;
dev->tq.next = NULL;
dev->tq.sync = 0;
- dev->tq.routine = mga_dma_schedule_tq_wrapper;
+ dev->tq.routine = mga_dma_task_queue;
dev->tq.data = dev;
/* Before installing handler */
- MGA_WRITE(MGAREG_ICLEAR, 0xfa7);
MGA_WRITE(MGAREG_IEN, 0);
-
/* Install handler */
if ((retcode = request_irq(dev->irq,
mga_dma_service,
@@ -820,11 +933,9 @@ int mga_irq_install(drm_device_t *dev, int irq)
up(&dev->struct_sem);
return retcode;
}
-
/* After installing handler */
- MGA_WRITE(MGAREG_ICLEAR, 0xfa7);
+ MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
MGA_WRITE(MGAREG_IEN, 0x00000001);
-
return 0;
}
@@ -838,19 +949,13 @@ int mga_irq_uninstall(drm_device_t *dev)
up(&dev->struct_sem);
if (!irq) return -EINVAL;
-
- printk("remove irq handler %d\n", irq);
-
- MGA_WRITE(MGAREG_ICLEAR, 0xfa7);
+ DRM_DEBUG("remove irq handler %d\n", irq);
+ MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
MGA_WRITE(MGAREG_IEN, 0);
- MGA_WRITE(MGAREG_ICLEAR, 0xfa7);
-
free_irq(irq, dev);
-
return 0;
}
-
int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -870,36 +975,64 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
}
}
-int mga_flush_queue(drm_device_t *dev)
+static int mga_flush_queue(drm_device_t *dev)
{
DECLARE_WAITQUEUE(entry, current);
- drm_queue_t *q = dev->queuelist[DRM_KERNEL_CONTEXT];
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
int ret = 0;
-
- printk("mga_flush_queue\n");
- if(atomic_read(&dev_priv->pending_bufs) != 0) {
- current->state = TASK_INTERRUPTIBLE;
- add_wait_queue(&q->flush_queue, &entry);
- for (;;) {
- if (!atomic_read(&dev_priv->pending_bufs)) break;
- printk("Calling schedule from flush_queue : %d\n",
- atomic_read(&dev_priv->pending_bufs));
- mga_dma_schedule(dev, 1);
- schedule();
- if (signal_pending(current)) {
- ret = -EINTR; /* Can't restart */
- break;
- }
- }
- printk("Exited out of schedule from flush_queue\n");
- current->state = TASK_RUNNING;
- remove_wait_queue(&q->flush_queue, &entry);
+
+ if(dev_priv == NULL) {
+ return 0;
}
+ if(dev_priv->next_prim->num_dwords != 0) {
+ atomic_set(&dev_priv->in_flush, 1);
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&dev_priv->flush_queue, &entry);
+ for (;;) {
+ mga_dma_schedule(dev, 0);
+ if (atomic_read(&dev_priv->in_flush) == 0)
+ break;
+ atomic_inc(&dev->total_sleeps);
+ DRM_DEBUG("Schedule in flush_queue\n");
+ schedule_timeout(HZ*3);
+ if (signal_pending(current)) {
+ ret = -EINTR; /* Can't restart */
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev_priv->flush_queue, &entry);
+ }
+ atomic_set(&dev_priv->in_flush, 0);
return ret;
}
+/* Must be called with the lock held */
+void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+
+ if (!dma) return;
+ if(dev->dev_private == NULL) return;
+
+ mga_flush_queue(dev);
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[ i ];
+ drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+
+ if (buf->pid == pid) {
+ if(buf_priv == NULL) return;
+ /* Only buffers that need to get reclaimed ever
+ * get set to free */
+ if(buf_priv->my_freelist->age == MGA_BUF_USED)
+ buf_priv->my_freelist->age = MGA_BUF_FREE;
+ }
+ }
+}
+
int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -916,16 +1049,15 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
current->pid, lock.context);
return -EINVAL;
}
-
- printk("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock.context, current->pid, dev->lock.hw_lock->lock,
- lock.flags);
-
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, current->pid, dev->lock.hw_lock->lock,
+ lock.flags);
if (lock.context < 0) {
return -EINVAL;
}
-
+
/* Only one queue:
*/
@@ -948,8 +1080,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
/* Contention */
atomic_inc(&dev->total_sleeps);
current->state = TASK_INTERRUPTIBLE;
- current->policy |= SCHED_YIELD;
- printk("Calling lock schedule\n");
+ DRM_DEBUG("Calling lock schedule\n");
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
@@ -962,17 +1093,60 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
if (!ret) {
if (lock.flags & _DRM_LOCK_QUIESCENT) {
- printk("_DRM_LOCK_QUIESCENT\n");
- ret = mga_flush_queue(dev);
- if(ret != 0) {
- drm_lock_free(dev, &dev->lock.hw_lock->lock,
- lock.context);
- } else {
- mga_dma_quiescent(dev);
- }
+ DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
+ mga_flush_queue(dev);
+ mga_dma_quiescent(dev);
}
}
- printk("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
return ret;
}
+int mga_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_lock_t lock;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ int i;
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_flush_ioctl called without lock held\n");
+ return -EINVAL;
+ }
+
+ if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
+ mga_flush_queue(dev);
+
+ if((MGA_READ(MGAREG_STATUS) & 0x00030001) == 0x00020000 &&
+ status[1] != dev_priv->last_sync_tag)
+ {
+ DRM_DEBUG("Reseting hardware status\n");
+ MGA_WRITE(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+
+ while(MGA_READ(MGAREG_DWGSYNC) !=
+ dev_priv->last_sync_tag)
+ {
+ for(i = 0; i < 4096; i++) mga_delay();
+ }
+
+ status[1] =
+ sarea_priv->last_dispatch =
+ dev_priv->last_sync_tag;
+ } else {
+ sarea_priv->last_dispatch = status[1];
+ }
+ }
+ if(lock.flags & _DRM_LOCK_QUIESCENT) {
+ mga_dma_quiescent(dev);
+ }
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h
deleted file mode 100644
index 7f1c57957..000000000
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef MGA_DMA_H
-#define MGA_DMA_H
-
-#include "mga_drm_public.h"
-
-
-/* Isn't this fun. This has to be fixed asap by emitting primary
- * dma commands in the 'do_dma' ioctl.
- */
-typedef struct {
- int dma_type;
-
- unsigned int ContextState[MGA_CTX_SETUP_SIZE];
- unsigned int ServerState[MGA_2D_SETUP_SIZE];
- unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
- unsigned int WarpPipe;
- unsigned int dirty;
-
- unsigned int nbox;
- xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
-} drm_mga_buf_priv_t;
-
-
-#define MGA_DMA_GENERAL 0
-#define MGA_DMA_VERTEX 1
-#define MGA_DMA_SETUP 2
-#define MGA_DMA_ILOAD 3
-
-
-#define DWGREG0 0x1c00
-#define DWGREG0_END 0x1dff
-#define DWGREG1 0x2c00
-#define DWGREG1_END 0x2dff
-
-#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END)
-#define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2)
-#define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
-#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r))
-
-
-/* Macros for inserting commands into a secondary dma buffer.
- */
-
-#define DMALOCALS u8 tempIndex[4]; u32 *dma_ptr; \
- int outcount, num_dwords;
-
-#define DMAGETPTR(buf) do { \
- dma_ptr = (u32 *)((u8 *)buf->address + buf->used); \
- outcount = 0; \
- num_dwords = buf->used / 4; \
-} while(0)
-
-#define DMAADVANCE(buf) do { \
- buf->used = num_dwords * 4; \
-} while(0)
-
-#define DMAOUTREG(reg, val) do { \
- tempIndex[outcount]=ADRINDEX(reg); \
- dma_ptr[++outcount] = val; \
- if (outcount == 4) { \
- outcount = 0; \
- dma_ptr[0] = *(u32 *)tempIndex; \
- dma_ptr+=5; \
- num_dwords += 5; \
- } \
-}while (0)
-
-
-
-#define VERBO 0
-
-
-/* Primary buffer versions of above -- pretty similar really.
- */
-#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \
- int outcount, num_dwords
-
-#define PRIMRESET(dev_priv) do { \
- dev_priv->prim_num_dwords = 0; \
- dev_priv->current_dma_ptr = dev_priv->prim_head; \
-} while (0)
-
-#define PRIMGETPTR(dev_priv) do { \
- dma_ptr = dev_priv->current_dma_ptr; \
- phys_head = dev_priv->prim_phys_head; \
- num_dwords = dev_priv->prim_num_dwords; \
- outcount = 0; \
-} while (0)
-
-#define PRIMADVANCE(dev_priv) do { \
- dev_priv->prim_num_dwords = num_dwords; \
- dev_priv->current_dma_ptr = dma_ptr; \
-} while (0)
-
-#define PRIMOUTREG(reg, val) do { \
- tempIndex[outcount]=ADRINDEX(reg); \
- dma_ptr[1+outcount] = val; \
- if( ++outcount == 4) { \
- outcount = 0; \
- dma_ptr[0] = *(u32 *)tempIndex; \
- dma_ptr+=5; \
- num_dwords += 5; \
- } \
- if (VERBO) \
- printk(KERN_INFO \
- "OUT %x val %x dma_ptr %p nr_dwords %d\n", \
- outcount, ADRINDEX(reg), dma_ptr, \
- num_dwords); \
-}while (0)
-
-
-#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
index 8b21df11f..12a858e7a 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
@@ -1,4 +1,4 @@
-/* mga_drm_public.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*-
+/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*-
* Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -26,12 +26,17 @@
* Authors: Jeff Hartmann <jhartmann@precisioninsight.com>
* Keith Whitwell <keithw@precisioninsight.com>
*
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h,v 1.1 2000/02/11 17:26:07 dawes Exp $
+ * $XFree86$
*/
-#ifndef _MGA_DRM_PUBLIC_H_
-#define _MGA_DRM_PUBLIC_H_
+#ifndef _MGA_DRM_H_
+#define _MGA_DRM_H_
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmMga.h)
+ */
+#ifndef _MGA_DEFINES_
+#define _MGA_DEFINES_
#define MGA_F 0x1 /* fog */
#define MGA_A 0x2 /* alpha */
#define MGA_S 0x4 /* specular */
@@ -54,66 +59,18 @@
#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
-
#define MGA_MAX_G400_PIPES 16
#define MGA_MAX_G200_PIPES 8 /* no multitex */
-
#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
#define MGA_CARD_TYPE_G200 1
#define MGA_CARD_TYPE_G400 2
+#define MGA_FRONT 0x1
+#define MGA_BACK 0x2
+#define MGA_DEPTH 0x4
-
-typedef struct _drm_mga_warp_index {
- int installed;
- unsigned long phys_addr;
- int size;
-} mgaWarpIndex;
-
-typedef struct drm_mga_init {
- enum {
- MGA_INIT_DMA = 0x01,
- MGA_CLEANUP_DMA = 0x02
- } func;
- int reserved_map_agpstart;
- int reserved_map_idx;
- int buffer_map_idx;
- int sarea_priv_offset;
- int primary_size;
- int warp_ucode_size;
- int fbOffset;
- int backOffset;
- int depthOffset;
- int textureOffset;
- int textureSize;
- int cpp;
- int stride;
- int sgram;
- int chipset;
- mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
-
- /* Redundant?
- */
- int frontOrg;
- int backOrg;
- int depthOrg;
- int mAccess;
-} drm_mga_init_t;
-
-typedef struct _xf86drmClipRectRec {
- unsigned short x1;
- unsigned short y1;
- unsigned short x2;
- unsigned short y2;
-} xf86drmClipRectRec;
-
-#define MGA_CLEAR_FRONT 0x1
-#define MGA_CLEAR_BACK 0x2
-#define MGA_CLEAR_DEPTH 0x4
-
-
-/* Each context has a state:
+/* 3d state excluding texture units:
*/
#define MGA_CTXREG_DSTORG 0 /* validated */
#define MGA_CTXREG_MACCESS 1
@@ -124,7 +81,8 @@ typedef struct _xf86drmClipRectRec {
#define MGA_CTXREG_WFLAG 6
#define MGA_CTXREG_TDUAL0 7
#define MGA_CTXREG_TDUAL1 8
-#define MGA_CTX_SETUP_SIZE 9
+#define MGA_CTXREG_FCOL 9
+#define MGA_CTX_SETUP_SIZE 10
/* 2d state
*/
@@ -146,33 +104,89 @@ typedef struct _xf86drmClipRectRec {
#define MGA_TEXREG_HEIGHT 10
#define MGA_TEX_SETUP_SIZE 11
-
/* What needs to be changed for the current vertex dma buffer?
*/
-#define MGASAREA_NEW_CONTEXT 0x1
-#define MGASAREA_NEW_TEX0 0x2
-#define MGASAREA_NEW_TEX1 0x4
-#define MGASAREA_NEW_PIPE 0x8
-#define MGASAREA_NEW_2D 0x10
-
+#define MGA_UPLOAD_CTX 0x1
+#define MGA_UPLOAD_TEX0 0x2
+#define MGA_UPLOAD_TEX1 0x4
+#define MGA_UPLOAD_PIPE 0x8
+#define MGA_UPLOAD_TEX0IMAGE 0x10
+#define MGA_UPLOAD_TEX1IMAGE 0x20
+#define MGA_UPLOAD_2D 0x40
+#define MGA_WAIT_AGE 0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
+#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
+ quiescent */
+
+/* 64 buffers of 16k each, total 1 meg.
+ */
+#define MGA_DMA_BUF_ORDER 14
+#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER)
+#define MGA_DMA_BUF_NR 63
-/* Keep this small for testing
+/* Keep these small for testing.
*/
-#define MGA_NR_SAREA_CLIPRECTS 2
+#define MGA_NR_SAREA_CLIPRECTS 8
-/* Upto 128 regions. Minimum region size of 256k.
+/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+ * regions, subject to a minimum region size of (1<<16) == 64k.
+ *
+ * Clients may subdivide regions internally, but when sharing between
+ * clients, the region size is the minimum granularity.
*/
-#define MGA_NR_TEX_REGIONS 128
-#define MGA_MIN_LOG_TEX_GRANULARITY 18
-typedef struct {
- unsigned char next, prev;
- unsigned char in_use;
- int age;
-} mgaTexRegion;
+#define MGA_CARD_HEAP 0
+#define MGA_AGP_HEAP 1
+#define MGA_NR_TEX_HEAPS 2
+#define MGA_NR_TEX_REGIONS 16
+#define MGA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+typedef struct _drm_mga_warp_index {
+ int installed;
+ unsigned long phys_addr;
+ int size;
+} drm_mga_warp_index_t;
+
+typedef struct drm_mga_init {
+ enum {
+ MGA_INIT_DMA = 0x01,
+ MGA_CLEANUP_DMA = 0x02
+ } func;
+ int reserved_map_agpstart;
+ int reserved_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ int primary_size;
+ int warp_ucode_size;
+ int frontOffset;
+ int backOffset;
+ int depthOffset;
+ int textureOffset;
+ int textureSize;
+ int agpTextureOffset;
+ int agpTextureSize;
+ int cpp;
+ int stride;
+ int sgram;
+ int chipset;
+ drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES];
+ int mAccess;
+} drm_mga_init_t;
+
+/* Warning: if you change the sarea structure, you must change the Xserver
+ * structures as well */
+
+typedef struct _drm_mga_tex_region {
+ unsigned char next, prev;
+ unsigned char in_use;
+ int age;
+} drm_mga_tex_region_t;
-typedef struct
-{
+typedef struct _drm_mga_sarea {
+ /* The channel for communication of state information to the kernel
+ * on firing a vertex dma buffer.
+ */
unsigned int ContextState[MGA_CTX_SETUP_SIZE];
unsigned int ServerState[MGA_2D_SETUP_SIZE];
unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
@@ -180,39 +194,68 @@ typedef struct
unsigned int dirty;
unsigned int nbox;
- xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
+ drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
- /* kernel doesn't touch from here down */
- int ctxOwner;
- mgaTexRegion texList[MGA_NR_TEX_REGIONS+1];
- int texAge;
-} drm_mga_sarea_t;
+
+ /* Information about the most recently used 3d drawable. The
+ * client fills in the req_* fields, the server fills in the
+ * exported_ fields and puts the cliprects into boxes, above.
+ *
+ * The client clears the exported_drawable field before
+ * clobbering the boxes data.
+ */
+ unsigned int req_drawable; /* the X drawable id */
+ unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
+
+ unsigned int exported_drawable;
+ unsigned int exported_index;
+ unsigned int exported_stamp;
+ unsigned int exported_buffers;
+ unsigned int exported_nfront;
+ unsigned int exported_nback;
+ int exported_back_x, exported_front_x, exported_w;
+ int exported_back_y, exported_front_y, exported_h;
+ drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+
+ /* Counters for aging textures and for client-side throttling.
+ */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+ /* LRU lists for texture memory in agp space and on the card
+ */
+ drm_mga_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+ unsigned int texAge[MGA_NR_TEX_HEAPS];
+
+ /* Mechanism to validate card state.
+ */
+ int ctxOwner;
+} drm_mga_sarea_t;
+
/* Device specific ioctls:
*/
-typedef struct {
+typedef struct _drm_mga_clear {
int clear_color;
int clear_depth;
int flags;
} drm_mga_clear_t;
-
-typedef struct {
- int flags; /* not actually used? */
+typedef struct _drm_mga_swap {
+ int dummy;
} drm_mga_swap_t;
-typedef struct {
+typedef struct _drm_mga_iload {
+ int idx;
+ int length;
unsigned int destOrg;
- unsigned int mAccess;
- unsigned int pitch;
- xf86drmClipRectRec texture;
- int idx;
} drm_mga_iload_t;
+typedef struct _drm_mga_vertex {
+ int idx; /* buffer to queue */
+ int used; /* bytes in use */
+ int discard; /* client finished with buffer? */
+} drm_mga_vertex_t;
-#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
-#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
-#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
-#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c
index 8bc25617e..480413549 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c
@@ -54,6 +54,7 @@ static struct file_operations mga_fops = {
mmap: drm_mmap,
read: drm_read,
fasync: drm_fasync,
+ poll: drm_poll,
};
static struct miscdevice mga_misc = {
@@ -105,9 +106,11 @@ static drm_ioctl_desc_t mga_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_clear_bufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_swap_bufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0 },
};
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
@@ -380,6 +383,21 @@ int mga_init(void)
drm_proc_init(dev);
DRM_DEBUG("doing agp init\n");
dev->agp = drm_agp_init();
+ if(dev->agp == NULL) {
+ DRM_DEBUG("The mga drm module requires the agpgart module"
+ " to function correctly\nPlease load the agpgart"
+ " module before you load the mga module\n");
+ drm_proc_cleanup();
+ misc_deregister(&mga_misc);
+ mga_takedown(dev);
+ return -ENOMEM;
+ }
+#ifdef CONFIG_MTRR
+ dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size * 1024 * 1024,
+ MTRR_TYPE_WRCOMB,
+ 1);
+#endif
DRM_DEBUG("doing ctxbitmap init\n");
if((retcode = drm_ctxbitmap_init(dev))) {
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
@@ -416,6 +434,16 @@ void mga_cleanup(void)
}
drm_ctxbitmap_cleanup(dev);
mga_dma_cleanup(dev);
+#ifdef CONFIG_MTRR
+ if(dev->agp && dev->agp->agp_mtrr) {
+ int retval;
+ retval = mtrr_del(dev->agp->agp_mtrr,
+ dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size * 1024*1024);
+ DRM_DEBUG("mtrr_del = %d\n", retval);
+ }
+#endif
+
mga_takedown(dev);
if (dev->agp) {
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h
index bc7808b0a..43deb613e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h
@@ -26,12 +26,32 @@
* Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
* Jeff Hartmann <jhartmann@precisioninsight.com>
*
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h,v 1.1 2000/02/11 17:26:08 dawes Exp $
+ * $XFree86$
*/
#ifndef _MGA_DRV_H_
#define _MGA_DRV_H_
-#include "mga_drm_public.h"
+
+typedef struct {
+ unsigned int num_dwords;
+ unsigned int max_dwords;
+ u32 *current_dma_ptr;
+ u32 *head;
+ u32 phys_head;
+ int sec_used;
+ int idx;
+ int swap_pending;
+ u32 in_use;
+ atomic_t force_fire;
+ atomic_t needs_overflow;
+} drm_mga_prim_buf_t;
+
+typedef struct _drm_mga_freelist {
+ unsigned int age;
+ drm_buf_t *buf;
+ struct _drm_mga_freelist *next;
+ struct _drm_mga_freelist *prev;
+} drm_mga_freelist_t;
typedef struct _drm_mga_private {
int reserved_map_idx;
@@ -40,7 +60,7 @@ typedef struct _drm_mga_private {
int primary_size;
int warp_ucode_size;
int chipset;
- int fbOffset;
+ int frontOffset;
int backOffset;
int depthOffset;
int textureOffset;
@@ -49,25 +69,32 @@ typedef struct _drm_mga_private {
int stride;
int sgram;
int use_agp;
- mgaWarpIndex WarpIndex[MGA_MAX_G400_PIPES];
+ drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
+ unsigned int WarpPipe;
__volatile__ unsigned long softrap_age;
- atomic_t dispatch_lock;
+ u32 dispatch_lock;
+ atomic_t in_flush;
+ atomic_t in_wait;
atomic_t pending_bufs;
- void *ioremap;
- u32 *prim_head;
- u32 *current_dma_ptr;
- u32 prim_phys_head;
- int prim_num_dwords;
- int prim_max_dwords;
-
+ unsigned int last_sync_tag;
+ unsigned int sync_tag;
+ void *status_page;
+ unsigned long real_status_page;
+ u8 *ioremap;
+ drm_mga_prim_buf_t **prim_bufs;
+ drm_mga_prim_buf_t *next_prim;
+ drm_mga_prim_buf_t *last_prim;
+ drm_mga_prim_buf_t *current_prim;
+ int current_prim_idx;
+ struct pci_dev *device;
+ drm_mga_freelist_t *head;
+ drm_mga_freelist_t *tail;
+ wait_queue_head_t flush_queue; /* Processes waiting until flush */
+ wait_queue_head_t wait_queue; /* Processes waiting until interrupt */
/* Some validated register values:
*/
- u32 frontOrg;
- u32 backOrg;
- u32 depthOrg;
u32 mAccess;
-
} drm_mga_private_t;
/* mga_drv.c */
@@ -92,16 +119,18 @@ extern int mga_control(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-#if 0
-extern void mga_dma_init(drm_device_t *dev);
-extern void mga_dma_cleanup(drm_device_t *dev);
-#endif
+/* mga_dma_init does init and release */
extern int mga_dma_init(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_dma_cleanup(drm_device_t *dev);
+extern int mga_flush_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
-/* mga_dma_init does init and release */
+extern unsigned int mga_create_sync_tag(drm_device_t *dev);
+extern drm_buf_t *mga_freelist_get(drm_device_t *dev);
+extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf);
+extern int mga_advance_primary(drm_device_t *dev);
/* mga_bufs.c */
@@ -124,6 +153,8 @@ extern int mga_swap_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_iload(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int mga_vertex(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* mga_context.c */
extern int mga_resctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
@@ -144,13 +175,115 @@ extern int mga_context_switch(drm_device_t *dev, int old, int new);
extern int mga_context_switch_complete(drm_device_t *dev, int new);
+typedef enum {
+ TT_GENERAL,
+ TT_BLIT,
+ TT_VECTOR,
+ TT_VERTEX
+} transferType_t;
+
+typedef struct {
+ drm_mga_freelist_t *my_freelist;
+ int discard;
+} drm_mga_buf_priv_t;
+
+#define DWGREG0 0x1c00
+#define DWGREG0_END 0x1dff
+#define DWGREG1 0x2c00
+#define DWGREG1_END 0x2dff
+
+#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END)
+#define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2)
+#define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
+#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r))
+
+#define MGA_VERBOSE 0
+#define MGA_NUM_PRIM_BUFS 8
+
+#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \
+ int outcount, num_dwords
+
+#define PRIM_OVERFLOW(dev, dev_priv, length) do { \
+ drm_mga_prim_buf_t *tmp_buf = \
+ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+ if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \
+ tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
+ atomic_set(&tmp_buf->force_fire, 1); \
+ mga_advance_primary(dev); \
+ mga_dma_schedule(dev, 1); \
+ } else if( atomic_read(&tmp_buf->needs_overflow)) { \
+ mga_advance_primary(dev); \
+ mga_dma_schedule(dev, 1); \
+ } \
+} while(0)
+
+#define PRIMGETPTR(dev_priv) do { \
+ drm_mga_prim_buf_t *tmp_buf = \
+ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+ if(MGA_VERBOSE) \
+ DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \
+ dma_ptr = tmp_buf->current_dma_ptr; \
+ num_dwords = tmp_buf->num_dwords; \
+ phys_head = tmp_buf->phys_head; \
+ outcount = 0; \
+} while(0)
+
+#define PRIMPTR(prim_buf) do { \
+ if(MGA_VERBOSE) \
+ DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \
+ dma_ptr = prim_buf->current_dma_ptr; \
+ num_dwords = prim_buf->num_dwords; \
+ phys_head = prim_buf->phys_head; \
+ outcount = 0; \
+} while(0)
+
+#define PRIMFINISH(prim_buf) do { \
+ if (MGA_VERBOSE) { \
+ DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \
+ if (outcount & 3) \
+ DRM_DEBUG(" --- truncation\n"); \
+ } \
+ prim_buf->num_dwords = num_dwords; \
+ prim_buf->current_dma_ptr = dma_ptr; \
+} while(0)
+
+#define PRIMADVANCE(dev_priv) do { \
+drm_mga_prim_buf_t *tmp_buf = \
+ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+ if (MGA_VERBOSE) { \
+ DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \
+ if (outcount & 3) \
+ DRM_DEBUG(" --- truncation\n"); \
+ } \
+ tmp_buf->num_dwords = num_dwords; \
+ tmp_buf->current_dma_ptr = dma_ptr; \
+} while (0)
+
+#define PRIMUPDATE(dev_priv) do { \
+ drm_mga_prim_buf_t *tmp_buf = \
+ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+ tmp_buf->sec_used++; \
+} while (0)
+
+#define PRIMOUTREG(reg, val) do { \
+ tempIndex[outcount]=ADRINDEX(reg); \
+ dma_ptr[1+outcount] = val; \
+ if (MGA_VERBOSE) \
+ DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \
+ num_dwords + 1 + outcount, ADRINDEX(reg), val); \
+ if( ++outcount == 4) { \
+ outcount = 0; \
+ dma_ptr[0] = *(u32 *)tempIndex; \
+ dma_ptr+=5; \
+ num_dwords += 5; \
+ } \
+}while (0)
+
+/* A reduced set of the mga registers.
+ */
#define MGAREG_MGA_EXEC 0x0100
-#define MGAREG_AGP_PLL 0x1e4c
#define MGAREG_ALPHACTRL 0x2c7c
-#define MGAREG_ALPHASTART 0x2c70
-#define MGAREG_ALPHAXINC 0x2c74
-#define MGAREG_ALPHAYINC 0x2c78
#define MGAREG_AR0 0x1c60
#define MGAREG_AR1 0x1c64
#define MGAREG_AR2 0x1c68
@@ -158,39 +291,16 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new);
#define MGAREG_AR4 0x1c70
#define MGAREG_AR5 0x1c74
#define MGAREG_AR6 0x1c78
-#define MGAREG_BCOL 0x1c20
#define MGAREG_CXBNDRY 0x1c80
#define MGAREG_CXLEFT 0x1ca0
#define MGAREG_CXRIGHT 0x1ca4
#define MGAREG_DMAPAD 0x1c54
-#define MGAREG_DR0_Z32LSB 0x2c50
-#define MGAREG_DR0_Z32MSB 0x2c54
-#define MGAREG_DR2_Z32LSB 0x2c60
-#define MGAREG_DR2_Z32MSB 0x2c64
-#define MGAREG_DR3_Z32LSB 0x2c68
-#define MGAREG_DR3_Z32MSB 0x2c6c
-#define MGAREG_DR0 0x1cc0
-#define MGAREG_DR2 0x1cc8
-#define MGAREG_DR3 0x1ccc
-#define MGAREG_DR4 0x1cd0
-#define MGAREG_DR6 0x1cd8
-#define MGAREG_DR7 0x1cdc
-#define MGAREG_DR8 0x1ce0
-#define MGAREG_DR10 0x1ce8
-#define MGAREG_DR11 0x1cec
-#define MGAREG_DR12 0x1cf0
-#define MGAREG_DR14 0x1cf8
-#define MGAREG_DR15 0x1cfc
#define MGAREG_DSTORG 0x2cb8
-#define MGAREG_DWG_INDIR_WT 0x1e80
#define MGAREG_DWGCTL 0x1c00
#define MGAREG_DWGSYNC 0x2c4c
#define MGAREG_FCOL 0x1c24
#define MGAREG_FIFOSTATUS 0x1e10
#define MGAREG_FOGCOL 0x1cf4
-#define MGAREG_FOGSTART 0x1cc4
-#define MGAREG_FOGXINC 0x1cd4
-#define MGAREG_FOGYINC 0x1ce4
#define MGAREG_FXBNDRY 0x1c84
#define MGAREG_FXLEFT 0x1ca8
#define MGAREG_FXRIGHT 0x1cac
@@ -198,44 +308,22 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new);
#define MGAREG_IEN 0x1e1c
#define MGAREG_LEN 0x1c5c
#define MGAREG_MACCESS 0x1c04
-#define MGAREG_MCTLWTST 0x1c08
-#define MGAREG_MEMRDBK 0x1e44
-#define MGAREG_OPMODE 0x1e54
-#define MGAREG_PAT0 0x1c10
-#define MGAREG_PAT1 0x1c14
#define MGAREG_PITCH 0x1c8c
#define MGAREG_PLNWT 0x1c1c
#define MGAREG_PRIMADDRESS 0x1e58
#define MGAREG_PRIMEND 0x1e5c
#define MGAREG_PRIMPTR 0x1e50
-#define MGAREG_RST 0x1e40
#define MGAREG_SECADDRESS 0x2c40
#define MGAREG_SECEND 0x2c44
#define MGAREG_SETUPADDRESS 0x2cd0
#define MGAREG_SETUPEND 0x2cd4
-#define MGAREG_SGN 0x1c58
-#define MGAREG_SHIFT 0x1c50
#define MGAREG_SOFTRAP 0x2c48
-#define MGAREG_SPECBSTART 0x2c98
-#define MGAREG_SPECBXINC 0x2c9c
-#define MGAREG_SPECBYINC 0x2ca0
-#define MGAREG_SPECGSTART 0x2c8c
-#define MGAREG_SPECGXINC 0x2c90
-#define MGAREG_SPECGYINC 0x2c94
-#define MGAREG_SPECRSTART 0x2c80
-#define MGAREG_SPECRXINC 0x2c84
-#define MGAREG_SPECRYINC 0x2c88
-#define MGAREG_SRC0 0x1c30
-#define MGAREG_SRC1 0x1c34
-#define MGAREG_SRC2 0x1c38
-#define MGAREG_SRC3 0x1c3c
#define MGAREG_SRCORG 0x2cb4
#define MGAREG_STATUS 0x1e14
#define MGAREG_STENCIL 0x2cc8
#define MGAREG_STENCILCTL 0x2ccc
#define MGAREG_TDUALSTAGE0 0x2cf8
#define MGAREG_TDUALSTAGE1 0x2cfc
-#define MGAREG_TEST0 0x1e48
#define MGAREG_TEXBORDERCOL 0x2c5c
#define MGAREG_TEXCTL 0x2c30
#define MGAREG_TEXCTL2 0x2c3c
@@ -249,18 +337,6 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new);
#define MGAREG_TEXTRANS 0x2c34
#define MGAREG_TEXTRANSHIGH 0x2c38
#define MGAREG_TEXWIDTH 0x2c28
-#define MGAREG_TMR0 0x2c00
-#define MGAREG_TMR1 0x2c04
-#define MGAREG_TMR2 0x2c08
-#define MGAREG_TMR3 0x2c0c
-#define MGAREG_TMR4 0x2c10
-#define MGAREG_TMR5 0x2c14
-#define MGAREG_TMR6 0x2c18
-#define MGAREG_TMR7 0x2c1c
-#define MGAREG_TMR8 0x2c20
-#define MGAREG_VBIADDR0 0x3e08
-#define MGAREG_VBIADDR1 0x3e0c
-#define MGAREG_VCOUNT 0x1e20
#define MGAREG_WACCEPTSEQ 0x1dd4
#define MGAREG_WCODEADDR 0x1e6c
#define MGAREG_WFLAG 0x1dc4
@@ -270,18 +346,8 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new);
#define MGAREG_WGETMSB 0x1dc8
#define MGAREG_WIADDR 0x1dc0
#define MGAREG_WIADDR2 0x1dd8
-#define MGAREG_WIADDRNB 0x1e60
-#define MGAREG_WIADDRNB1 0x1e04
-#define MGAREG_WIADDRNB2 0x1e00
-#define MGAREG_WIMEMADDR 0x1e68
-#define MGAREG_WIMEMDATA 0x2000
-#define MGAREG_WIMEMDATA1 0x2100
#define MGAREG_WMISC 0x1e70
-#define MGAREG_WR 0x2d00
#define MGAREG_WVRTXSZ 0x1dcc
-#define MGAREG_XDST 0x1cb0
-#define MGAREG_XYEND 0x1c44
-#define MGAREG_XYSTRT 0x1c40
#define MGAREG_YBOT 0x1c9c
#define MGAREG_YDST 0x1c90
#define MGAREG_YDSTLEN 0x1c88
@@ -289,4 +355,40 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new);
#define MGAREG_YTOP 0x1c98
#define MGAREG_ZORG 0x1c0c
+#define DC_atype_rstr 0x10
+#define DC_atype_blk 0x40
+#define PDEA_pagpxfer_enable 0x2
+#define WIA_wmode_suspend 0x0
+#define WIA_wmode_start 0x3
+#define WIA_wagp_agp 0x4
+#define DC_opcod_trap 0x4
+#define DC_arzero_enable 0x1000
+#define DC_sgnzero_enable 0x2000
+#define DC_shftzero_enable 0x4000
+#define DC_bop_SHIFT 16
+#define DC_clipdis_enable 0x80000000
+#define DC_solid_enable 0x800
+#define DC_transc_enable 0x40000000
+#define DC_opcod_bitblt 0x8
+#define DC_atype_rpl 0x0
+#define DC_linear_xy 0x0
+#define DC_solid_disable 0x0
+#define DC_arzero_disable 0x0
+#define DC_bltmod_bfcol 0x4000000
+#define DC_pattern_disable 0x0
+#define DC_transc_disable 0x0
+
+#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \
+ DC_sgnzero_enable | DC_shftzero_enable | \
+ (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \
+ DC_solid_enable | DC_transc_enable)
+
+
+#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \
+ DC_solid_disable | DC_arzero_disable | \
+ DC_sgnzero_enable | DC_shftzero_enable | \
+ (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \
+ DC_pattern_disable | DC_transc_disable | \
+ DC_clipdis_enable) \
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c
index d09881bad..a70f86d22 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c
@@ -26,189 +26,217 @@
* Authors: Jeff Hartmann <jhartmann@precisioninsight.com>
* Keith Whitwell <keithw@precisioninsight.com>
*
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c,v 1.1 2000/02/11 17:26:08 dawes Exp $
+ * $XFree86$
*
*/
#define __NO_VERSION__
#include "drmP.h"
#include "mga_drv.h"
-#include "mgareg_flags.h"
-#include "mga_dma.h"
-#include "mga_state.h"
#include "drm.h"
-void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box )
+static void mgaEmitClipRect( drm_mga_private_t *dev_priv,
+ drm_clip_rect_t *box )
{
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int *regs = sarea_priv->ContextState;
PRIMLOCALS;
+ /* This takes 10 dwords */
PRIMGETPTR( dev_priv );
+
+ /* Force reset of dwgctl (eliminates clip disable) */
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
+ PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
+ PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
- /* The G400 seems to have an issue with the second WARP not
- * stalling clipper register writes. This bothers me, but the only
- * way I could get it to never clip the last triangle under any
- * circumstances is by inserting TWO dwgsync commands.
- */
- if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
- PRIMOUTREG( MGAREG_DWGSYNC, 0 );
- PRIMOUTREG( MGAREG_DWGSYNC, 0 );
- }
-
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
- PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride );
- PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride );
+ PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride/2 );
+ PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride/2 );
+
PRIMADVANCE( dev_priv );
}
-
-static void mgaEmitContext(drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv)
+static void mgaEmitContext(drm_mga_private_t *dev_priv )
{
- unsigned int *regs = buf_priv->ContextState;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int *regs = sarea_priv->ContextState;
PRIMLOCALS;
+ /* This takes a max of 15 dwords */
PRIMGETPTR( dev_priv );
+
PRIMOUTREG( MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG] );
PRIMOUTREG( MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS] );
PRIMOUTREG( MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT] );
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
+
PRIMOUTREG( MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL] );
PRIMOUTREG( MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR] );
PRIMOUTREG( MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG] );
+ PRIMOUTREG( MGAREG_ZORG, dev_priv->depthOffset ); /* invarient */
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
PRIMOUTREG( MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG] );
PRIMOUTREG( MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0] );
PRIMOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] );
- }
+ PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] );
+ } else {
+ PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] );
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ }
PRIMADVANCE( dev_priv );
}
-static void mgaG200EmitTex( drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv )
+static void mgaG200EmitTex( drm_mga_private_t *dev_priv )
{
- unsigned int *regs = buf_priv->TexState[0];
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int *regs = sarea_priv->TexState[0];
PRIMLOCALS;
PRIMGETPTR( dev_priv );
+
+ /* This takes 20 dwords */
+
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
+
PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
+
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
-
+ PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] );
+
PRIMOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] );
+ PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
+ PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
PRIMADVANCE( dev_priv );
}
-static void mgaG400EmitTex0( drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv )
+static void mgaG400EmitTex0( drm_mga_private_t *dev_priv )
{
- unsigned int *regs = buf_priv->TexState[0];
- int multitex = buf_priv->WarpPipe & MGA_T2;
-
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int *regs = sarea_priv->TexState[0];
+ int multitex = sarea_priv->WarpPipe & MGA_T2;
PRIMLOCALS;
+
PRIMGETPTR( dev_priv );
+
+ /* This takes a max of 30 dwords */
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
+
PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
+
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
-
+ PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG(0x2d00 + 49*4, 0);
+
PRIMOUTREG(0x2d00 + 57*4, 0);
PRIMOUTREG(0x2d00 + 53*4, 0);
PRIMOUTREG(0x2d00 + 61*4, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
if (!multitex) {
PRIMOUTREG(0x2d00 + 52*4, 0x40 );
PRIMOUTREG(0x2d00 + 60*4, 0x40 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
}
- PRIMOUTREG(0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
- PRIMOUTREG(0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
+ PRIMOUTREG( 0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
+ PRIMOUTREG( 0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
+ PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
+ PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
PRIMADVANCE( dev_priv );
}
#define TMC_map1_enable 0x80000000
-
-static void mgaG400EmitTex1( drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv )
+static void mgaG400EmitTex1( drm_mga_private_t *dev_priv )
{
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->TexState[1];
-
PRIMLOCALS;
+
PRIMGETPTR(dev_priv);
+ /* This takes 25 dwords */
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable);
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
+
PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
+
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
-
+ PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG(0x2d00 + 49*4, 0);
+
PRIMOUTREG(0x2d00 + 57*4, 0);
PRIMOUTREG(0x2d00 + 53*4, 0);
PRIMOUTREG(0x2d00 + 61*4, 0);
-
PRIMOUTREG(0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
- PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
+ PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
+ PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
+ PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
- PRIMADVANCE( dev_priv );
+ PRIMADVANCE( dev_priv );
}
-
-static void mgaG400EmitPipe(drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv)
+static void mgaG400EmitPipe(drm_mga_private_t *dev_priv )
{
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
float fParam = 12800.0f;
PRIMLOCALS;
PRIMGETPTR(dev_priv);
- PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
+
+ /* This takes 25 dwords */
/* Establish vertex size.
*/
if (pipe & MGA_T2) {
+ PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
+ PRIMOUTREG(MGAREG_WFLAG, 0);
} else {
+ PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000);
- }
-
- PRIMOUTREG(MGAREG_WFLAG, 0);
- PRIMOUTREG(MGAREG_WFLAG1, 0);
-
+ PRIMOUTREG(MGAREG_WFLAG, 0);
+ }
+
+ PRIMOUTREG(MGAREG_WFLAG1, 0);
PRIMOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam)));
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -227,19 +255,21 @@ static void mgaG400EmitPipe(drm_mga_private_t *dev_priv,
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_WIADDR2, (dev_priv->WarpIndex[pipe].phys_addr |
- WIA_wmode_start | WIA_wagp_agp));
+ PRIMOUTREG(MGAREG_WIADDR2, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
+ WIA_wmode_start | WIA_wagp_agp));
PRIMADVANCE(dev_priv);
}
-static void mgaG200EmitPipe( drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv )
+static void mgaG200EmitPipe( drm_mga_private_t *dev_priv )
{
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
PRIMLOCALS;
PRIMGETPTR(dev_priv);
+
+ /* This takes 15 dwords */
+
PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
PRIMOUTREG(MGAREG_WVRTXSZ, 7);
PRIMOUTREG(MGAREG_WFLAG, 0);
@@ -254,109 +284,629 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv,
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_WIADDR, (dev_priv->WarpIndex[pipe].phys_addr |
- WIA_wmode_start | WIA_wagp_agp));
+ PRIMOUTREG(MGAREG_WIADDR, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
+ WIA_wmode_start | WIA_wagp_agp));
PRIMADVANCE(dev_priv);
}
-void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv )
+static void mgaEmitState( drm_mga_private_t *dev_priv )
{
- unsigned int dirty = buf_priv->dirty;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int dirty = sarea_priv->dirty;
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
- if (dirty & MGASAREA_NEW_CONTEXT)
- mgaEmitContext( dev_priv, buf_priv );
-
- if (dirty & MGASAREA_NEW_TEX1)
- mgaG400EmitTex1( dev_priv, buf_priv );
-
- if (dirty & MGASAREA_NEW_TEX0)
- mgaG400EmitTex0( dev_priv, buf_priv );
-
- if (dirty & MGASAREA_NEW_PIPE)
- mgaG400EmitPipe( dev_priv, buf_priv );
+ int multitex = sarea_priv->WarpPipe & MGA_T2;
+
+ if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
+ mgaG400EmitPipe( dev_priv );
+ dev_priv->WarpPipe = sarea_priv->WarpPipe;
+ }
+
+ if (dirty & MGA_UPLOAD_CTX) {
+ mgaEmitContext( dev_priv );
+ sarea_priv->dirty &= ~MGA_UPLOAD_CTX;
+ }
+
+ if (dirty & MGA_UPLOAD_TEX0) {
+ mgaG400EmitTex0( dev_priv );
+ sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
+ }
+
+ if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
+ mgaG400EmitTex1( dev_priv );
+ sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
+ }
} else {
- if (dirty & MGASAREA_NEW_CONTEXT)
- mgaEmitContext( dev_priv, buf_priv );
-
- if (dirty & MGASAREA_NEW_TEX0)
- mgaG200EmitTex( dev_priv, buf_priv );
-
- if (dirty & MGASAREA_NEW_PIPE)
- mgaG200EmitPipe( dev_priv, buf_priv );
- }
+ if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
+ mgaG200EmitPipe( dev_priv );
+ dev_priv->WarpPipe = sarea_priv->WarpPipe;
+ }
+
+ if (dirty & MGA_UPLOAD_CTX) {
+ mgaEmitContext( dev_priv );
+ sarea_priv->dirty &= ~MGA_UPLOAD_CTX;
+ }
+
+ if (dirty & MGA_UPLOAD_TEX0) {
+ mgaG200EmitTex( dev_priv );
+ sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
+ }
+ }
}
-
/* Disallow all write destinations except the front and backbuffer.
*/
-static int mgaCopyContext(drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv)
+static int mgaVerifyContext(drm_mga_private_t *dev_priv )
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
-
- if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOrg &&
- regs[MGA_CTXREG_DSTORG] != dev_priv->backOrg)
+
+ if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset &&
+ regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) {
+ DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n",
+ regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset,
+ dev_priv->backOffset);
+ regs[MGA_CTXREG_DSTORG] = 0;
return -1;
+ }
- memcpy(buf_priv->ContextState, sarea_priv->ContextState,
- sizeof(buf_priv->ContextState));
return 0;
}
-
/* Disallow texture reads from PCI space.
*/
-static int mgaCopyTex(drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv,
+static int mgaVerifyTex(drm_mga_private_t *dev_priv,
int unit)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1)
+ if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) {
+ DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n",
+ sarea_priv->TexState[unit][MGA_TEXREG_ORG],
+ unit);
+ sarea_priv->TexState[unit][MGA_TEXREG_ORG] = 0;
return -1;
-
- memcpy(buf_priv->TexState[unit], sarea_priv->TexState[unit],
- sizeof(buf_priv->TexState[0]));
+ }
return 0;
}
-
-int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv )
+static int mgaVerifyState( drm_mga_private_t *dev_priv )
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned int dirty = sarea_priv->dirty ;
+ unsigned int dirty = sarea_priv->dirty;
int rv = 0;
- buf_priv->dirty = sarea_priv->dirty;
- buf_priv->WarpPipe = sarea_priv->WarpPipe;
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
- if (dirty & MGASAREA_NEW_CONTEXT)
- rv |= mgaCopyContext( dev_priv, buf_priv );
+ if (dirty & MGA_UPLOAD_CTX)
+ rv |= mgaVerifyContext( dev_priv );
- if (dirty & MGASAREA_NEW_TEX0)
- rv |= mgaCopyTex( dev_priv, buf_priv, 0 );
+ if (dirty & MGA_UPLOAD_TEX0)
+ rv |= mgaVerifyTex( dev_priv, 0 );
if (dev_priv->chipset == MGA_CARD_TYPE_G400)
{
- if (dirty & MGASAREA_NEW_TEX1)
- rv |= mgaCopyTex( dev_priv, buf_priv, 1 );
+ if (dirty & MGA_UPLOAD_TEX1)
+ rv |= mgaVerifyTex( dev_priv, 1 );
- if (dirty & MGASAREA_NEW_PIPE)
- rv |= (buf_priv->WarpPipe > MGA_MAX_G400_PIPES);
+ if (dirty & MGA_UPLOAD_PIPE)
+ rv |= (sarea_priv->WarpPipe > MGA_MAX_G400_PIPES);
}
else
{
- if (dirty & MGASAREA_NEW_PIPE)
- rv |= (buf_priv->WarpPipe > MGA_MAX_G200_PIPES);
+ if (dirty & MGA_UPLOAD_PIPE)
+ rv |= (sarea_priv->WarpPipe > MGA_MAX_G200_PIPES);
}
return rv == 0;
}
+static int mgaVerifyIload( drm_mga_private_t *dev_priv,
+ unsigned long bus_address,
+ unsigned int dstOrg, int length )
+{
+ if(dstOrg < dev_priv->textureOffset ||
+ dstOrg + length >
+ (dev_priv->textureOffset + dev_priv->textureSize)) {
+ return -EINVAL;
+ }
+ if(length % 64) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* This copies a 64 byte aligned agp region to the frambuffer
+ * with a standard blit, the ioctl needs to do checking */
+
+static void mga_dma_dispatch_tex_blit( drm_device_t *dev,
+ unsigned long bus_address,
+ int length,
+ unsigned int destOrg )
+{
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ int use_agp = PDEA_pagpxfer_enable | 0x00000001;
+ u16 y2;
+ PRIMLOCALS;
+
+ y2 = length / 64;
+
+ PRIM_OVERFLOW(dev, dev_priv, 30);
+ PRIMGETPTR( dev_priv );
+
+ dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+
+ PRIMOUTREG( MGAREG_DSTORG, destOrg);
+ PRIMOUTREG( MGAREG_MACCESS, 0x00000000);
+ DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp);
+ PRIMOUTREG( MGAREG_SRCORG, (u32) bus_address | use_agp);
+ PRIMOUTREG( MGAREG_AR5, 64);
+
+ PRIMOUTREG( MGAREG_PITCH, 64);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD);
+
+ PRIMOUTREG(MGAREG_AR0, 63);
+ PRIMOUTREG(MGAREG_AR3, 0);
+ PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
+ PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, y2);
+
+ PRIMOUTREG( MGAREG_SRCORG, 0);
+ PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMADVANCE(dev_priv);
+}
+
+static void mga_dma_dispatch_vertex(drm_device_t *dev,
+ drm_buf_t *buf)
+{
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned long address = (unsigned long)buf->bus_address;
+ int length = buf->used;
+ int use_agp = PDEA_pagpxfer_enable;
+ int i = 0;
+ int primary_needed;
+ PRIMLOCALS;
+
+ DRM_DEBUG("dispatch vertex %d addr 0x%lx, "
+ "length 0x%x nbox %d dirty %x\n",
+ buf->idx, address, length,
+ sarea_priv->nbox, sarea_priv->dirty);
+
+
+ dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+
+ if (buf_priv->discard) {
+ buf_priv->my_freelist->age = dev_priv->last_sync_tag;
+ mga_freelist_put(dev, buf);
+ }
+
+
+ /* WARNING: if you change any of the state functions verify
+ * these numbers (Overestimating this doesn't hurt).
+ */
+ primary_needed = (25+15+30+25+
+ 10 +
+ 15 * MGA_NR_SAREA_CLIPRECTS);
+
+
+ PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+ mgaEmitState( dev_priv );
+
+ if (buf->used) {
+ do {
+ if (i < sarea_priv->nbox) {
+ DRM_DEBUG("idx %d Emit box %d/%d:"
+ "%d,%d - %d,%d\n",
+ buf->idx,
+ i, sarea_priv->nbox,
+ sarea_priv->boxes[i].x1,
+ sarea_priv->boxes[i].y1,
+ sarea_priv->boxes[i].x2,
+ sarea_priv->boxes[i].y2);
+
+ mgaEmitClipRect( dev_priv,
+ &sarea_priv->boxes[i] );
+ }
+
+ PRIMGETPTR(dev_priv);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_SECADDRESS,
+ ((__u32)address) | TT_VERTEX);
+ PRIMOUTREG( MGAREG_SECEND,
+ (((__u32)(address + length)) |
+ use_agp));
+ PRIMADVANCE( dev_priv );
+ } while (++i < sarea_priv->nbox);
+ }
+
+ PRIMGETPTR( dev_priv );
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMADVANCE( dev_priv );
+}
+
+static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
+ unsigned int clear_color,
+ unsigned int clear_zval )
+{
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int *regs = sarea_priv->ContextState;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ unsigned int cmd;
+ int i;
+ int primary_needed;
+ PRIMLOCALS;
+
+ if ( dev_priv->sgram )
+ cmd = MGA_CLEAR_CMD | DC_atype_blk;
+ else
+ cmd = MGA_CLEAR_CMD | DC_atype_rstr;
+
+ primary_needed = nbox * 70;
+ if(primary_needed == 0) primary_needed = 70;
+ PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+ PRIMGETPTR( dev_priv );
+ dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+
+ for (i = 0 ; i < nbox ; i++) {
+ unsigned int height = pbox[i].y2 - pbox[i].y1;
+
+ DRM_DEBUG("dispatch clear %d,%d-%d,%d flags %x!\n",
+ pbox[i].x1, pbox[i].y1, pbox[i].x2,
+ pbox[i].y2, flags);
+
+ if ( flags & MGA_FRONT ) {
+ DRM_DEBUG("clear front\n");
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
+ PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_FCOL, clear_color);
+ PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
+ PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
+ }
+
+ if ( flags & MGA_BACK ) {
+ DRM_DEBUG("clear back\n");
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
+ PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_FCOL, clear_color);
+ PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset);
+ PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
+ }
+
+ if ( flags & MGA_DEPTH ) {
+ DRM_DEBUG("clear depth\n");
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
+ PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_FCOL, clear_zval);
+ PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset);
+ PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
+ }
+ }
+
+ /* Force reset of DWGCTL */
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMADVANCE(dev_priv);
+}
+
+static void mga_dma_dispatch_swap( drm_device_t *dev )
+{
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int *regs = sarea_priv->ContextState;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ int i;
+ int primary_needed;
+ PRIMLOCALS;
+
+ primary_needed = nbox * 5;
+ primary_needed += 60;
+ PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+ PRIMGETPTR( dev_priv );
+
+ dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+
+ PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
+ PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
+ PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
+ PRIMOUTREG(MGAREG_AR5, dev_priv->stride/2);
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
+
+ for (i = 0 ; i < nbox; i++) {
+ unsigned int h = pbox[i].y2 - pbox[i].y1;
+ unsigned int start = pbox[i].y1 * dev_priv->stride/2;
+
+ DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
+ pbox[i].x1, pbox[i].y1,
+ pbox[i].x2, pbox[i].y2);
+
+ PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
+ PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
+ PRIMOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16));
+ PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h);
+ }
+
+ /* Force reset of DWGCTL */
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
+
+ PRIMOUTREG( MGAREG_SRCORG, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMADVANCE(dev_priv);
+}
+
+int mga_clear_bufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ drm_mga_clear_t clear;
+
+ copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear),
+ -EFAULT);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_clear_bufs called without lock held\n");
+ return -EINVAL;
+ }
+
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+
+ /* Make sure we restore the 3D state next time.
+ */
+ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
+ mga_dma_dispatch_clear( dev, clear.flags,
+ clear.clear_color,
+ clear.clear_depth );
+ PRIMUPDATE(dev_priv);
+ mga_dma_schedule(dev, 1);
+ sarea_priv->last_dispatch = status[1];
+ return 0;
+}
+
+int mga_swap_bufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_swap_bufs called without lock held\n");
+ return -EINVAL;
+ }
+
+ if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+ sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+
+ /* Make sure we restore the 3D state next time.
+ */
+ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
+ mga_dma_dispatch_swap( dev );
+ PRIMUPDATE(dev_priv);
+ set_bit(0, &dev_priv->current_prim->swap_pending);
+ dev_priv->current_prim->swap_pending = 1;
+ mga_dma_schedule(dev, 1);
+ sarea_priv->last_dispatch = status[1];
+ return 0;
+}
+
+int mga_iload(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_device_dma_t *dma = dev->dma;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ drm_buf_t *buf;
+ drm_mga_buf_priv_t *buf_priv;
+ drm_mga_iload_t iload;
+ unsigned long bus_address;
+
+ DRM_DEBUG("Starting Iload\n");
+ copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
+ -EFAULT);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_iload called without lock held\n");
+ return -EINVAL;
+ }
+
+ buf = dma->buflist[ iload.idx ];
+ buf_priv = buf->dev_private;
+ bus_address = buf->bus_address;
+ DRM_DEBUG("bus_address %lx, length %d, destorg : %x\n",
+ bus_address, iload.length, iload.destOrg);
+
+ if(mgaVerifyIload(dev_priv,
+ bus_address,
+ iload.destOrg,
+ iload.length)) {
+ mga_freelist_put(dev, buf);
+ return -EINVAL;
+ }
+
+ sarea_priv->dirty |= MGA_UPLOAD_CTX;
+
+ mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,
+ iload.destOrg);
+ buf_priv->my_freelist->age = dev_priv->last_sync_tag;
+ buf_priv->discard = 1;
+ mga_freelist_put(dev, buf);
+ mga_dma_schedule(dev, 1);
+ sarea_priv->last_dispatch = status[1];
+ return 0;
+}
+
+int mga_vertex(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf;
+ drm_mga_buf_priv_t *buf_priv;
+ drm_mga_vertex_t vertex;
+
+ copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex),
+ -EFAULT);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_vertex called without lock held\n");
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("mga_vertex\n");
+
+ buf = dma->buflist[ vertex.idx ];
+ buf_priv = buf->dev_private;
+
+ buf->used = vertex.used;
+ buf_priv->discard = vertex.discard;
+
+ if (!mgaVerifyState(dev_priv)) {
+ if (vertex.discard) {
+ buf_priv->my_freelist->age = dev_priv->last_sync_tag;
+ mga_freelist_put(dev, buf);
+ }
+ return -EINVAL;
+ }
+
+ mga_dma_dispatch_vertex(dev, buf);
+
+ PRIMUPDATE(dev_priv);
+ mga_dma_schedule(dev, 1);
+ sarea_priv->last_dispatch = status[1];
+ return 0;
+}
+
+static int mga_dma_get_buffers(drm_device_t *dev, drm_dma_t *d)
+{
+ int i;
+ drm_buf_t *buf;
+
+ for (i = d->granted_count; i < d->request_count; i++) {
+ buf = mga_freelist_get(dev);
+ if (!buf) break;
+ buf->pid = current->pid;
+ copy_to_user_ret(&d->request_indices[i],
+ &buf->idx,
+ sizeof(buf->idx),
+ -EFAULT);
+ copy_to_user_ret(&d->request_sizes[i],
+ &buf->total,
+ sizeof(buf->total),
+ -EFAULT);
+ ++d->granted_count;
+ }
+ return 0;
+}
+
+int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_device_dma_t *dma = dev->dma;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ __volatile__ unsigned int *status =
+ (__volatile__ unsigned int *)dev_priv->status_page;
+ int retcode = 0;
+ drm_dma_t d;
+
+ copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
+ DRM_DEBUG("%d %d: %d send, %d req\n",
+ current->pid, d.context, d.send_count, d.request_count);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_dma called without lock held\n");
+ return -EINVAL;
+ }
+
+ /* Please don't send us buffers.
+ */
+ if (d.send_count != 0) {
+ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+ current->pid, d.send_count);
+ return -EINVAL;
+ }
+
+ /* We'll send you buffers.
+ */
+ if (d.request_count < 0 || d.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ current->pid, d.request_count, dma->buf_count);
+ return -EINVAL;
+ }
+
+ d.granted_count = 0;
+
+ if (d.request_count) {
+ retcode = mga_dma_get_buffers(dev, &d);
+ }
+
+ DRM_DEBUG("%d returning, granted = %d\n",
+ current->pid, d.granted_count);
+ copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
+ sarea_priv->last_dispatch = status[1];
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h
deleted file mode 100644
index e7b952e0c..000000000
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef MGA_STATE_H
-#define MGA_STATE_H
-
-#include "mga_drv.h"
-
-int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv,
- drm_mga_buf_priv_t *buf_priv );
-
-void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box );
-
-void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv );
-
-#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h
deleted file mode 100644
index 901f18310..000000000
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mgareg_flags.h
+++ /dev/null
@@ -1,930 +0,0 @@
-/* author: stephen crowley, crow@debian.org */
-
-/*
- * 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 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
- * STEPHEN CROWLEY, OR ANY OTHER CONTRIBUTORS 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 _MGAREGS_H_
-#define _MGAREGS_H_
-
-/*************** (START) AUTOMATICLY GENERATED REGISTER FILE *****************/
-/*
- * Generated on Sat Nov 20 21:25:36 CST 1999
- */
-
-
-
-/*
- * Power Graphic Mode Memory Space Registers
- */
-
- #define AGP_PLL_agp2xpllen_MASK 0xfffffffe /* bit 0 */
- #define AGP_PLL_agp2xpllen_disable 0x0
- #define AGP_PLL_agp2xpllen_enable 0x1
-
- #define AC_src_MASK 0xfffffff0 /* bits 0-3 */
- #define AC_src_zero 0x0 /* val 0, shift 0 */
- #define AC_src_one 0x1 /* val 1, shift 0 */
- #define AC_src_dst_color 0x2 /* val 2, shift 0 */
- #define AC_src_om_dst_color 0x3 /* val 3, shift 0 */
- #define AC_src_src_alpha 0x4 /* val 4, shift 0 */
- #define AC_src_om_src_alpha 0x5 /* val 5, shift 0 */
- #define AC_src_dst_alpha 0x6 /* val 6, shift 0 */
- #define AC_src_om_dst_alpha 0x7 /* val 7, shift 0 */
- #define AC_src_src_alpha_sat 0x8 /* val 8, shift 0 */
- #define AC_dst_MASK 0xffffff0f /* bits 4-7 */
- #define AC_dst_zero 0x0 /* val 0, shift 4 */
- #define AC_dst_one 0x10 /* val 1, shift 4 */
- #define AC_dst_src_color 0x20 /* val 2, shift 4 */
- #define AC_dst_om_src_color 0x30 /* val 3, shift 4 */
- #define AC_dst_src_alpha 0x40 /* val 4, shift 4 */
- #define AC_dst_om_src_alpha 0x50 /* val 5, shift 4 */
- #define AC_dst_dst_alpha 0x60 /* val 6, shift 4 */
- #define AC_dst_om_dst_alpha 0x70 /* val 7, shift 4 */
- #define AC_amode_MASK 0xfffffcff /* bits 8-9 */
- #define AC_amode_FCOL 0x0 /* val 0, shift 8 */
- #define AC_amode_alpha_channel 0x100 /* val 1, shift 8 */
- #define AC_amode_video_alpha 0x200 /* val 2, shift 8 */
- #define AC_amode_RSVD 0x300 /* val 3, shift 8 */
- #define AC_astipple_MASK 0xfffff7ff /* bit 11 */
- #define AC_astipple_disable 0x0
- #define AC_astipple_enable 0x800
- #define AC_aten_MASK 0xffffefff /* bit 12 */
- #define AC_aten_disable 0x0
- #define AC_aten_enable 0x1000
- #define AC_atmode_MASK 0xffff1fff /* bits 13-15 */
- #define AC_atmode_noacmp 0x0 /* val 0, shift 13 */
- #define AC_atmode_ae 0x4000 /* val 2, shift 13 */
- #define AC_atmode_ane 0x6000 /* val 3, shift 13 */
- #define AC_atmode_alt 0x8000 /* val 4, shift 13 */
- #define AC_atmode_alte 0xa000 /* val 5, shift 13 */
- #define AC_atmode_agt 0xc000 /* val 6, shift 13 */
- #define AC_atmode_agte 0xe000 /* val 7, shift 13 */
- #define AC_atref_MASK 0xff00ffff /* bits 16-23 */
- #define AC_atref_SHIFT 16
- #define AC_alphasel_MASK 0xfcffffff /* bits 24-25 */
- #define AC_alphasel_fromtex 0x0 /* val 0, shift 24 */
- #define AC_alphasel_diffused 0x1000000 /* val 1, shift 24 */
- #define AC_alphasel_modulated 0x2000000 /* val 2, shift 24 */
- #define AC_alphasel_trans 0x3000000 /* val 3, shift 24 */
-
- #define AR0_ar0_MASK 0xfffc0000 /* bits 0-17 */
- #define AR0_ar0_SHIFT 0
-
- #define AR1_ar1_MASK 0xff000000 /* bits 0-23 */
- #define AR1_ar1_SHIFT 0
-
- #define AR2_ar2_MASK 0xfffc0000 /* bits 0-17 */
- #define AR2_ar2_SHIFT 0
-
- #define AR3_ar3_MASK 0xff000000 /* bits 0-23 */
- #define AR3_ar3_SHIFT 0
- #define AR3_spage_MASK 0xf8ffffff /* bits 24-26 */
- #define AR3_spage_SHIFT 24
-
- #define AR4_ar4_MASK 0xfffc0000 /* bits 0-17 */
- #define AR4_ar4_SHIFT 0
-
- #define AR5_ar5_MASK 0xfffc0000 /* bits 0-17 */
- #define AR5_ar5_SHIFT 0
-
- #define AR6_ar6_MASK 0xfffc0000 /* bits 0-17 */
- #define AR6_ar6_SHIFT 0
-
- #define BC_besen_MASK 0xfffffffe /* bit 0 */
- #define BC_besen_disable 0x0
- #define BC_besen_enable 0x1
- #define BC_besv1srcstp_MASK 0xffffffbf /* bit 6 */
- #define BC_besv1srcstp_even 0x0
- #define BC_besv1srcstp_odd 0x40
- #define BC_besv2srcstp_MASK 0xfffffeff /* bit 8 */
- #define BC_besv2srcstp_disable 0x0
- #define BC_besv2srcstp_enable 0x100
- #define BC_beshfen_MASK 0xfffffbff /* bit 10 */
- #define BC_beshfen_disable 0x0
- #define BC_beshfen_enable 0x400
- #define BC_besvfen_MASK 0xfffff7ff /* bit 11 */
- #define BC_besvfen_disable 0x0
- #define BC_besvfen_enable 0x800
- #define BC_beshfixc_MASK 0xffffefff /* bit 12 */
- #define BC_beshfixc_weight 0x0
- #define BC_beshfixc_coeff 0x1000
- #define BC_bescups_MASK 0xfffeffff /* bit 16 */
- #define BC_bescups_disable 0x0
- #define BC_bescups_enable 0x10000
- #define BC_bes420pl_MASK 0xfffdffff /* bit 17 */
- #define BC_bes420pl_422 0x0
- #define BC_bes420pl_420 0x20000
- #define BC_besdith_MASK 0xfffbffff /* bit 18 */
- #define BC_besdith_disable 0x0
- #define BC_besdith_enable 0x40000
- #define BC_beshmir_MASK 0xfff7ffff /* bit 19 */
- #define BC_beshmir_disable 0x0
- #define BC_beshmir_enable 0x80000
- #define BC_besbwen_MASK 0xffefffff /* bit 20 */
- #define BC_besbwen_color 0x0
- #define BC_besbwen_bw 0x100000
- #define BC_besblank_MASK 0xffdfffff /* bit 21 */
- #define BC_besblank_disable 0x0
- #define BC_besblank_enable 0x200000
- #define BC_besfselm_MASK 0xfeffffff /* bit 24 */
- #define BC_besfselm_soft 0x0
- #define BC_besfselm_hard 0x1000000
- #define BC_besfsel_MASK 0xf9ffffff /* bits 25-26 */
- #define BC_besfsel_a1 0x0 /* val 0, shift 25 */
- #define BC_besfsel_a2 0x2000000 /* val 1, shift 25 */
- #define BC_besfsel_b1 0x4000000 /* val 2, shift 25 */
- #define BC_besfsel_b2 0x6000000 /* val 3, shift 25 */
-
- #define BGC_beshzoom_MASK 0xfffffffe /* bit 0 */
- #define BGC_beshzoom_disable 0x0
- #define BGC_beshzoom_enable 0x1
- #define BGC_beshzoomf_MASK 0xfffffffd /* bit 1 */
- #define BGC_beshzoomf_disable 0x0
- #define BGC_beshzoomf_enable 0x2
- #define BGC_bescorder_MASK 0xfffffff7 /* bit 3 */
- #define BGC_bescorder_even 0x0
- #define BGC_bescorder_odd 0x8
- #define BGC_besreghup_MASK 0xffffffef /* bit 4 */
- #define BGC_besreghup_disable 0x0
- #define BGC_besreghup_enable 0x10
- #define BGC_besvcnt_MASK 0xf000ffff /* bits 16-27 */
- #define BGC_besvcnt_SHIFT 16
-
- #define BHC_besright_MASK 0xfffff800 /* bits 0-10 */
- #define BHC_besright_SHIFT 0
- #define BHC_besleft_MASK 0xf800ffff /* bits 16-26 */
- #define BHC_besleft_SHIFT 16
-
- #define BHISF_beshiscal_MASK 0xffe00003 /* bits 2-20 */
- #define BHISF_beshiscal_SHIFT 2
-
- #define BHSE_beshsrcend_MASK 0xfc000003 /* bits 2-25 */
- #define BHSE_beshsrcend_SHIFT 2
-
- #define BHSL_beshsrclst_MASK 0xfc00ffff /* bits 16-25 */
- #define BHSL_beshsrclst_SHIFT 16
-
- #define BHSS_beshsrcst_MASK 0xfc000003 /* bits 2-25 */
- #define BHSS_beshsrcst_SHIFT 2
-
- #define BP_bespitch_MASK 0xfffff000 /* bits 0-11 */
- #define BP_bespitch_SHIFT 0
-
- #define BS_besstat_MASK 0xfffffffc /* bits 0-1 */
- #define BS_besstat_a1 0x0 /* val 0, shift 0 */
- #define BS_besstat_a2 0x1 /* val 1, shift 0 */
- #define BS_besstat_b1 0x2 /* val 2, shift 0 */
- #define BS_besstat_b2 0x3 /* val 3, shift 0 */
-
- #define BSF_besv1srclast_MASK 0xfffffc00 /* bits 0-9 */
- #define BSF_besv1srclast_SHIFT 0
-
- #define BSF_besv2srclst_MASK 0xfffffc00 /* bits 0-9 */
- #define BSF_besv2srclst_SHIFT 0
-
- #define BSF_besv1wght_MASK 0xffff0003 /* bits 2-15 */
- #define BSF_besv1wght_SHIFT 2
- #define BSF_besv1wghts_MASK 0xfffeffff /* bit 16 */
- #define BSF_besv1wghts_disable 0x0
- #define BSF_besv1wghts_enable 0x10000
-
- #define BSF_besv2wght_MASK 0xffff0003 /* bits 2-15 */
- #define BSF_besv2wght_SHIFT 2
- #define BSF_besv2wghts_MASK 0xfffeffff /* bit 16 */
- #define BSF_besv2wghts_disable 0x0
- #define BSF_besv2wghts_enable 0x10000
-
- #define BVC_besbot_MASK 0xfffff800 /* bits 0-10 */
- #define BVC_besbot_SHIFT 0
- #define BVC_bestop_MASK 0xf800ffff /* bits 16-26 */
- #define BVC_bestop_SHIFT 16
-
- #define BVISF_besviscal_MASK 0xffe00003 /* bits 2-20 */
- #define BVISF_besviscal_SHIFT 2
-
- #define CXB_cxleft_MASK 0xfffff000 /* bits 0-11 */
- #define CXB_cxleft_SHIFT 0
- #define CXB_cxright_MASK 0xf000ffff /* bits 16-27 */
- #define CXB_cxright_SHIFT 16
-
- #define DO_dstmap_MASK 0xfffffffe /* bit 0 */
- #define DO_dstmap_fb 0x0
- #define DO_dstmap_sys 0x1
- #define DO_dstacc_MASK 0xfffffffd /* bit 1 */
- #define DO_dstacc_pci 0x0
- #define DO_dstacc_agp 0x2
- #define DO_dstorg_MASK 0x7 /* bits 3-31 */
- #define DO_dstorg_SHIFT 3
-
- #define DC_opcod_MASK 0xfffffff0 /* bits 0-3 */
- #define DC_opcod_line_open 0x0 /* val 0, shift 0 */
- #define DC_opcod_autoline_open 0x1 /* val 1, shift 0 */
- #define DC_opcod_line_close 0x2 /* val 2, shift 0 */
- #define DC_opcod_autoline_close 0x3 /* val 3, shift 0 */
- #define DC_opcod_trap 0x4 /* val 4, shift 0 */
- #define DC_opcod_texture_trap 0x6 /* val 6, shift 0 */
- #define DC_opcod_bitblt 0x8 /* val 8, shift 0 */
- #define DC_opcod_iload 0x9 /* val 9, shift 0 */
- #define DC_atype_MASK 0xffffff8f /* bits 4-6 */
- #define DC_atype_rpl 0x0 /* val 0, shift 4 */
- #define DC_atype_rstr 0x10 /* val 1, shift 4 */
- #define DC_atype_zi 0x30 /* val 3, shift 4 */
- #define DC_atype_blk 0x40 /* val 4, shift 4 */
- #define DC_atype_i 0x70 /* val 7, shift 4 */
- #define DC_linear_MASK 0xffffff7f /* bit 7 */
- #define DC_linear_xy 0x0
- #define DC_linear_linear 0x80
- #define DC_zmode_MASK 0xfffff8ff /* bits 8-10 */
- #define DC_zmode_nozcmp 0x0 /* val 0, shift 8 */
- #define DC_zmode_ze 0x200 /* val 2, shift 8 */
- #define DC_zmode_zne 0x300 /* val 3, shift 8 */
- #define DC_zmode_zlt 0x400 /* val 4, shift 8 */
- #define DC_zmode_zlte 0x500 /* val 5, shift 8 */
- #define DC_zmode_zgt 0x600 /* val 6, shift 8 */
- #define DC_zmode_zgte 0x700 /* val 7, shift 8 */
- #define DC_solid_MASK 0xfffff7ff /* bit 11 */
- #define DC_solid_disable 0x0
- #define DC_solid_enable 0x800
- #define DC_arzero_MASK 0xffffefff /* bit 12 */
- #define DC_arzero_disable 0x0
- #define DC_arzero_enable 0x1000
- #define DC_sgnzero_MASK 0xffffdfff /* bit 13 */
- #define DC_sgnzero_disable 0x0
- #define DC_sgnzero_enable 0x2000
- #define DC_shftzero_MASK 0xffffbfff /* bit 14 */
- #define DC_shftzero_disable 0x0
- #define DC_shftzero_enable 0x4000
- #define DC_bop_MASK 0xfff0ffff /* bits 16-19 */
- #define DC_bop_SHIFT 16
- #define DC_trans_MASK 0xff0fffff /* bits 20-23 */
- #define DC_trans_SHIFT 20
- #define DC_bltmod_MASK 0xe1ffffff /* bits 25-28 */
- #define DC_bltmod_bmonolef 0x0 /* val 0, shift 25 */
- #define DC_bltmod_bmonowf 0x8000000 /* val 4, shift 25 */
- #define DC_bltmod_bplan 0x2000000 /* val 1, shift 25 */
- #define DC_bltmod_bfcol 0x4000000 /* val 2, shift 25 */
- #define DC_bltmod_bu32bgr 0x6000000 /* val 3, shift 25 */
- #define DC_bltmod_bu32rgb 0xe000000 /* val 7, shift 25 */
- #define DC_bltmod_bu24bgr 0x16000000 /* val 11, shift 25 */
- #define DC_bltmod_bu24rgb 0x1e000000 /* val 15, shift 25 */
- #define DC_pattern_MASK 0xdfffffff /* bit 29 */
- #define DC_pattern_disable 0x0
- #define DC_pattern_enable 0x20000000
- #define DC_transc_MASK 0xbfffffff /* bit 30 */
- #define DC_transc_disable 0x0
- #define DC_transc_enable 0x40000000
- #define DC_clipdis_MASK 0x7fffffff /* bit 31 */
- #define DC_clipdis_disable 0x0
- #define DC_clipdis_enable 0x80000000
-
- #define DS_dwgsyncaddr_MASK 0x3 /* bits 2-31 */
- #define DS_dwgsyncaddr_SHIFT 2
-
- #define FS_fifocount_MASK 0xffffff80 /* bits 0-6 */
- #define FS_fifocount_SHIFT 0
- #define FS_bfull_MASK 0xfffffeff /* bit 8 */
- #define FS_bfull_disable 0x0
- #define FS_bfull_enable 0x100
- #define FS_bempty_MASK 0xfffffdff /* bit 9 */
- #define FS_bempty_disable 0x0
- #define FS_bempty_enable 0x200
-
- #define XA_fxleft_MASK 0xffff0000 /* bits 0-15 */
- #define XA_fxleft_SHIFT 0
- #define XA_fxright_MASK 0xffff /* bits 16-31 */
- #define XA_fxright_SHIFT 16
-
- #define IC_softrapiclr_MASK 0xfffffffe /* bit 0 */
- #define IC_softrapiclr_disable 0x0
- #define IC_softrapiclr_enable 0x1
- #define IC_pickiclr_MASK 0xfffffffb /* bit 2 */
- #define IC_pickiclr_disable 0x0
- #define IC_pickiclr_enable 0x4
- #define IC_vlineiclr_MASK 0xffffffdf /* bit 5 */
- #define IC_vlineiclr_disable 0x0
- #define IC_vlineiclr_enable 0x20
- #define IC_wiclr_MASK 0xffffff7f /* bit 7 */
- #define IC_wiclr_disable 0x0
- #define IC_wiclr_enable 0x80
- #define IC_wciclr_MASK 0xfffffeff /* bit 8 */
- #define IC_wciclr_disable 0x0
- #define IC_wciclr_enable 0x100
-
- #define IE_softrapien_MASK 0xfffffffe /* bit 0 */
- #define IE_softrapien_disable 0x0
- #define IE_softrapien_enable 0x1
- #define IE_pickien_MASK 0xfffffffb /* bit 2 */
- #define IE_pickien_disable 0x0
- #define IE_pickien_enable 0x4
- #define IE_vlineien_MASK 0xffffffdf /* bit 5 */
- #define IE_vlineien_disable 0x0
- #define IE_vlineien_enable 0x20
- #define IE_extien_MASK 0xffffffbf /* bit 6 */
- #define IE_extien_disable 0x0
- #define IE_extien_enable 0x40
- #define IE_wien_MASK 0xffffff7f /* bit 7 */
- #define IE_wien_disable 0x0
- #define IE_wien_enable 0x80
- #define IE_wcien_MASK 0xfffffeff /* bit 8 */
- #define IE_wcien_disable 0x0
- #define IE_wcien_enable 0x100
-
- #define MA_pwidth_MASK 0xfffffffc /* bits 0-1 */
- #define MA_pwidth_8 0x0 /* val 0, shift 0 */
- #define MA_pwidth_16 0x1 /* val 1, shift 0 */
- #define MA_pwidth_32 0x2 /* val 2, shift 0 */
- #define MA_pwidth_24 0x3 /* val 3, shift 0 */
- #define MA_zwidth_MASK 0xffffffe7 /* bits 3-4 */
- #define MA_zwidth_16 0x0 /* val 0, shift 3 */
- #define MA_zwidth_32 0x8 /* val 1, shift 3 */
- #define MA_zwidth_15 0x10 /* val 2, shift 3 */
- #define MA_zwidth_24 0x18 /* val 3, shift 3 */
- #define MA_memreset_MASK 0xffff7fff /* bit 15 */
- #define MA_memreset_disable 0x0
- #define MA_memreset_enable 0x8000
- #define MA_fogen_MASK 0xfbffffff /* bit 26 */
- #define MA_fogen_disable 0x0
- #define MA_fogen_enable 0x4000000
- #define MA_tlutload_MASK 0xdfffffff /* bit 29 */
- #define MA_tlutload_disable 0x0
- #define MA_tlutload_enable 0x20000000
- #define MA_nodither_MASK 0xbfffffff /* bit 30 */
- #define MA_nodither_disable 0x0
- #define MA_nodither_enable 0x40000000
- #define MA_dit555_MASK 0x7fffffff /* bit 31 */
- #define MA_dit555_disable 0x0
- #define MA_dit555_enable 0x80000000
-
- #define MCWS_casltncy_MASK 0xfffffff8 /* bits 0-2 */
- #define MCWS_casltncy_SHIFT 0
- #define MCWS_rrddelay_MASK 0xffffffcf /* bits 4-5 */
- #define MCWS_rcddelay_MASK 0xfffffe7f /* bits 7-8 */
- #define MCWS_rasmin_MASK 0xffffe3ff /* bits 10-12 */
- #define MCWS_rasmin_SHIFT 10
- #define MCWS_rpdelay_MASK 0xffff3fff /* bits 14-15 */
- #define MCWS_wrdelay_MASK 0xfff3ffff /* bits 18-19 */
- #define MCWS_rddelay_MASK 0xffdfffff /* bit 21 */
- #define MCWS_rddelay_disable 0x0
- #define MCWS_rddelay_enable 0x200000
- #define MCWS_smrdelay_MASK 0xfe7fffff /* bits 23-24 */
- #define MCWS_bwcdelay_MASK 0xf3ffffff /* bits 26-27 */
- #define MCWS_bpldelay_MASK 0x1fffffff /* bits 29-31 */
- #define MCWS_bpldelay_SHIFT 29
-
- #define MRB_mclkbrd0_MASK 0xfffffff0 /* bits 0-3 */
- #define MRB_mclkbrd0_SHIFT 0
- #define MRB_mclkbrd1_MASK 0xfffffe1f /* bits 5-8 */
- #define MRB_mclkbrd1_SHIFT 5
- #define MRB_strmfctl_MASK 0xff3fffff /* bits 22-23 */
- #define MRB_mrsopcod_MASK 0xe1ffffff /* bits 25-28 */
- #define MRB_mrsopcod_SHIFT 25
-
- #define OM_dmamod_MASK 0xfffffff3 /* bits 2-3 */
- #define OM_dmamod_general 0x0 /* val 0, shift 2 */
- #define OM_dmamod_blit 0x4 /* val 1, shift 2 */
- #define OM_dmamod_vector 0x8 /* val 2, shift 2 */
- #define OM_dmamod_vertex 0xc /* val 3, shift 2 */
- #define OM_dmadatasiz_MASK 0xfffffcff /* bits 8-9 */
- #define OM_dmadatasiz_8 0x0 /* val 0, shift 8 */
- #define OM_dmadatasiz_16 0x100 /* val 1, shift 8 */
- #define OM_dmadatasiz_32 0x200 /* val 2, shift 8 */
- #define OM_dirdatasiz_MASK 0xfffcffff /* bits 16-17 */
- #define OM_dirdatasiz_8 0x0 /* val 0, shift 16 */
- #define OM_dirdatasiz_16 0x10000 /* val 1, shift 16 */
- #define OM_dirdatasiz_32 0x20000 /* val 2, shift 16 */
-
- #define P_iy_MASK 0xffffe000 /* bits 0-12 */
- #define P_iy_SHIFT 0
- #define P_ylin_MASK 0xffff7fff /* bit 15 */
- #define P_ylin_disable 0x0
- #define P_ylin_enable 0x8000
-
- #define PDCA_primod_MASK 0xfffffffc /* bits 0-1 */
- #define PDCA_primod_general 0x0 /* val 0, shift 0 */
- #define PDCA_primod_blit 0x1 /* val 1, shift 0 */
- #define PDCA_primod_vector 0x2 /* val 2, shift 0 */
- #define PDCA_primod_vertex 0x3 /* val 3, shift 0 */
- #define PDCA_primaddress_MASK 0x3 /* bits 2-31 */
- #define PDCA_primaddress_SHIFT 2
-
- #define PDEA_primnostart_MASK 0xfffffffe /* bit 0 */
- #define PDEA_primnostart_disable 0x0
- #define PDEA_primnostart_enable 0x1
- #define PDEA_pagpxfer_MASK 0xfffffffd /* bit 1 */
- #define PDEA_pagpxfer_disable 0x0
- #define PDEA_pagpxfer_enable 0x2
- #define PDEA_primend_MASK 0x3 /* bits 2-31 */
- #define PDEA_primend_SHIFT 2
-
- #define PLS_primptren0_MASK 0xfffffffe /* bit 0 */
- #define PLS_primptren0_disable 0x0
- #define PLS_primptren0_enable 0x1
- #define PLS_primptren1_MASK 0xfffffffd /* bit 1 */
- #define PLS_primptren1_disable 0x0
- #define PLS_primptren1_enable 0x2
- #define PLS_primptr_MASK 0x7 /* bits 3-31 */
- #define PLS_primptr_SHIFT 3
-
- #define R_softreset_MASK 0xfffffffe /* bit 0 */
- #define R_softreset_disable 0x0
- #define R_softreset_enable 0x1
- #define R_softextrst_MASK 0xfffffffd /* bit 1 */
- #define R_softextrst_disable 0x0
- #define R_softextrst_enable 0x2
-
- #define SDCA_secmod_MASK 0xfffffffc /* bits 0-1 */
- #define SDCA_secmod_general 0x0 /* val 0, shift 0 */
- #define SDCA_secmod_blit 0x1 /* val 1, shift 0 */
- #define SDCA_secmod_vector 0x2 /* val 2, shift 0 */
- #define SDCA_secmod_vertex 0x3 /* val 3, shift 0 */
- #define SDCA_secaddress_MASK 0x3 /* bits 2-31 */
- #define SDCA_secaddress_SHIFT 2
-
- #define SDEA_sagpxfer_MASK 0xfffffffd /* bit 1 */
- #define SDEA_sagpxfer_disable 0x0
- #define SDEA_sagpxfer_enable 0x2
- #define SDEA_secend_MASK 0x3 /* bits 2-31 */
- #define SDEA_secend_SHIFT 2
-
- #define SETDCA_setupmod_MASK 0xfffffffc /* bits 0-1 */
- #define SETDCA_setupmod_vertlist 0x0 /* val 0, shift 0 */
- #define SETDCA_setupaddress_MASK 0x3 /* bits 2-31 */
- #define SETDCA_setupaddress_SHIFT 2
-
- #define SETDEA_setupagpxfer_MASK 0xfffffffd /* bit 1 */
- #define SETDEA_setupagpxfer_disable 0x0
- #define SETDEA_setupagpxfer_enable 0x2
- #define SETDEA_setupend_MASK 0x3 /* bits 2-31 */
- #define SETDEA_setupend_SHIFT 2
-
- #define S_sdydxl_MASK 0xfffffffe /* bit 0 */
- #define S_sdydxl_y 0x0
- #define S_sdydxl_x 0x1
- #define S_scanleft_MASK 0xfffffffe /* bit 0 */
- #define S_scanleft_disable 0x0
- #define S_scanleft_enable 0x1
- #define S_sdxl_MASK 0xfffffffd /* bit 1 */
- #define S_sdxl_pos 0x0
- #define S_sdxl_neg 0x2
- #define S_sdy_MASK 0xfffffffb /* bit 2 */
- #define S_sdy_pos 0x0
- #define S_sdy_neg 0x4
- #define S_sdxr_MASK 0xffffffdf /* bit 5 */
- #define S_sdxr_pos 0x0
- #define S_sdxr_neg 0x20
- #define S_brkleft_MASK 0xfffffeff /* bit 8 */
- #define S_brkleft_disable 0x0
- #define S_brkleft_enable 0x100
- #define S_errorinit_MASK 0x7fffffff /* bit 31 */
- #define S_errorinit_disable 0x0
- #define S_errorinit_enable 0x80000000
-
- #define FSC_x_off_MASK 0xfffffff0 /* bits 0-3 */
- #define FSC_x_off_SHIFT 0
- #define FSC_funcnt_MASK 0xffffff80 /* bits 0-6 */
- #define FSC_funcnt_SHIFT 0
- #define FSC_y_off_MASK 0xffffff8f /* bits 4-6 */
- #define FSC_y_off_SHIFT 4
- #define FSC_funoff_MASK 0xffc0ffff /* bits 16-21 */
- #define FSC_funoff_SHIFT 16
- #define FSC_stylelen_MASK 0xffc0ffff /* bits 16-21 */
- #define FSC_stylelen_SHIFT 16
-
-
- #define STH_softraphand_MASK 0x3 /* bits 2-31 */
- #define STH_softraphand_SHIFT 2
-
- #define SO_srcmap_MASK 0xfffffffe /* bit 0 */
- #define SO_srcmap_fb 0x0
- #define SO_srcmap_sys 0x1
- #define SO_srcacc_MASK 0xfffffffd /* bit 1 */
- #define SO_srcacc_pci 0x0
- #define SO_srcacc_agp 0x2
- #define SO_srcorg_MASK 0x7 /* bits 3-31 */
- #define SO_srcorg_SHIFT 3
-
- #define STAT_softrapen_MASK 0xfffffffe /* bit 0 */
- #define STAT_softrapen_disable 0x0
- #define STAT_softrapen_enable 0x1
- #define STAT_pickpen_MASK 0xfffffffb /* bit 2 */
- #define STAT_pickpen_disable 0x0
- #define STAT_pickpen_enable 0x4
- #define STAT_vsyncsts_MASK 0xfffffff7 /* bit 3 */
- #define STAT_vsyncsts_disable 0x0
- #define STAT_vsyncsts_enable 0x8
- #define STAT_vsyncpen_MASK 0xffffffef /* bit 4 */
- #define STAT_vsyncpen_disable 0x0
- #define STAT_vsyncpen_enable 0x10
- #define STAT_vlinepen_MASK 0xffffffdf /* bit 5 */
- #define STAT_vlinepen_disable 0x0
- #define STAT_vlinepen_enable 0x20
- #define STAT_extpen_MASK 0xffffffbf /* bit 6 */
- #define STAT_extpen_disable 0x0
- #define STAT_extpen_enable 0x40
- #define STAT_wpen_MASK 0xffffff7f /* bit 7 */
- #define STAT_wpen_disable 0x0
- #define STAT_wpen_enable 0x80
- #define STAT_wcpen_MASK 0xfffffeff /* bit 8 */
- #define STAT_wcpen_disable 0x0
- #define STAT_wcpen_enable 0x100
- #define STAT_dwgengsts_MASK 0xfffeffff /* bit 16 */
- #define STAT_dwgengsts_disable 0x0
- #define STAT_dwgengsts_enable 0x10000
- #define STAT_endprdmasts_MASK 0xfffdffff /* bit 17 */
- #define STAT_endprdmasts_disable 0x0
- #define STAT_endprdmasts_enable 0x20000
- #define STAT_wbusy_MASK 0xfffbffff /* bit 18 */
- #define STAT_wbusy_disable 0x0
- #define STAT_wbusy_enable 0x40000
- #define STAT_swflag_MASK 0xfffffff /* bits 28-31 */
- #define STAT_swflag_SHIFT 28
-
- #define S_sref_MASK 0xffffff00 /* bits 0-7 */
- #define S_sref_SHIFT 0
- #define S_smsk_MASK 0xffff00ff /* bits 8-15 */
- #define S_smsk_SHIFT 8
- #define S_swtmsk_MASK 0xff00ffff /* bits 16-23 */
- #define S_swtmsk_SHIFT 16
-
- #define SC_smode_MASK 0xfffffff8 /* bits 0-2 */
- #define SC_smode_salways 0x0 /* val 0, shift 0 */
- #define SC_smode_snever 0x1 /* val 1, shift 0 */
- #define SC_smode_se 0x2 /* val 2, shift 0 */
- #define SC_smode_sne 0x3 /* val 3, shift 0 */
- #define SC_smode_slt 0x4 /* val 4, shift 0 */
- #define SC_smode_slte 0x5 /* val 5, shift 0 */
- #define SC_smode_sgt 0x6 /* val 6, shift 0 */
- #define SC_smode_sgte 0x7 /* val 7, shift 0 */
- #define SC_sfailop_MASK 0xffffffc7 /* bits 3-5 */
- #define SC_sfailop_keep 0x0 /* val 0, shift 3 */
- #define SC_sfailop_zero 0x8 /* val 1, shift 3 */
- #define SC_sfailop_replace 0x10 /* val 2, shift 3 */
- #define SC_sfailop_incrsat 0x18 /* val 3, shift 3 */
- #define SC_sfailop_decrsat 0x20 /* val 4, shift 3 */
- #define SC_sfailop_invert 0x28 /* val 5, shift 3 */
- #define SC_sfailop_incr 0x30 /* val 6, shift 3 */
- #define SC_sfailop_decr 0x38 /* val 7, shift 3 */
- #define SC_szfailop_MASK 0xfffffe3f /* bits 6-8 */
- #define SC_szfailop_keep 0x0 /* val 0, shift 6 */
- #define SC_szfailop_zero 0x40 /* val 1, shift 6 */
- #define SC_szfailop_replace 0x80 /* val 2, shift 6 */
- #define SC_szfailop_incrsat 0xc0 /* val 3, shift 6 */
- #define SC_szfailop_decrsat 0x100 /* val 4, shift 6 */
- #define SC_szfailop_invert 0x140 /* val 5, shift 6 */
- #define SC_szfailop_incr 0x180 /* val 6, shift 6 */
- #define SC_szfailop_decr 0x1c0 /* val 7, shift 6 */
- #define SC_szpassop_MASK 0xfffff1ff /* bits 9-11 */
- #define SC_szpassop_keep 0x0 /* val 0, shift 9 */
- #define SC_szpassop_zero 0x200 /* val 1, shift 9 */
- #define SC_szpassop_replace 0x400 /* val 2, shift 9 */
- #define SC_szpassop_incrsat 0x600 /* val 3, shift 9 */
- #define SC_szpassop_decrsat 0x800 /* val 4, shift 9 */
- #define SC_szpassop_invert 0xa00 /* val 5, shift 9 */
- #define SC_szpassop_incr 0xc00 /* val 6, shift 9 */
- #define SC_szpassop_decr 0xe00 /* val 7, shift 9 */
-
- #define TD1_color1arg2selMASK 0xfffffffc /* bits 0-1 */
- #define TD1_color1alphaselMASK 0xffffffe3 /* bits 2-4 */
- #define TD1_color1alphaselSHIFT 2
- #define TD1_color1arg1alphaMASK 0xffffffdf /* bit 5 */
- #define TD1_color1arg1alphadisable 0x0
- #define TD1_color1arg1alphaenable 0x20
- #define TD1_color1arg1invMASK 0xffffffbf /* bit 6 */
- #define TD1_color1arg1invdisable 0x0
- #define TD1_color1arg1invenable 0x40
- #define TD1_color1arg2alphaMASK 0xffffff7f /* bit 7 */
- #define TD1_color1arg2alphadisable 0x0
- #define TD1_color1arg2alphaenable 0x80
- #define TD1_color1arg2invMASK 0xfffffeff /* bit 8 */
- #define TD1_color1arg2invdisable 0x0
- #define TD1_color1arg2invenable 0x100
- #define TD1_color1alpha1invMASK 0xfffffdff /* bit 9 */
- #define TD1_color1alpha1invdisable 0x0
- #define TD1_color1alpha1invenable 0x200
- #define TD1_color1alpha2invMASK 0xfffffbff /* bit 10 */
- #define TD1_color1alpha2invdisable 0x0
- #define TD1_color1alpha2invenable 0x400
- #define TD1_color1selMASK 0xff9fffff /* bits 21-22 */
- #define TD1_color1selarg1 0x0 /* val 0, shift 21 */
- #define TD1_color1selarg2 0x200000 /* val 1, shift 21 */
- #define TD1_color1seladd 0x400000 /* val 2, shift 21 */
- #define TD1_color1selmul 0x600000 /* val 3, shift 21 */
- #define TD1_alpha1selMASK 0x3fffffff /* bits 30-31 */
- #define TD1_alpha1selarg1 0x0 /* val 0, shift 30 */
- #define TD1_alpha1selarg2 0x40000000 /* val 1, shift 30 */
- #define TD1_alpha1seladd 0x80000000 /* val 2, shift 30 */
- #define TD1_alpha1selmul 0xc0000000 /* val 3, shift 30 */
-
- #define TST_ramtsten_MASK 0xfffffffe /* bit 0 */
- #define TST_ramtsten_disable 0x0
- #define TST_ramtsten_enable 0x1
- #define TST_ramtstdone_MASK 0xfffffffd /* bit 1 */
- #define TST_ramtstdone_disable 0x0
- #define TST_ramtstdone_enable 0x2
- #define TST_wramtstpass_MASK 0xfffffffb /* bit 2 */
- #define TST_wramtstpass_disable 0x0
- #define TST_wramtstpass_enable 0x4
- #define TST_tcachetstpass_MASK 0xfffffff7 /* bit 3 */
- #define TST_tcachetstpass_disable 0x0
- #define TST_tcachetstpass_enable 0x8
- #define TST_tluttstpass_MASK 0xffffffef /* bit 4 */
- #define TST_tluttstpass_disable 0x0
- #define TST_tluttstpass_enable 0x10
- #define TST_luttstpass_MASK 0xffffffdf /* bit 5 */
- #define TST_luttstpass_disable 0x0
- #define TST_luttstpass_enable 0x20
- #define TST_besramtstpass_MASK 0xffffffbf /* bit 6 */
- #define TST_besramtstpass_disable 0x0
- #define TST_besramtstpass_enable 0x40
- #define TST_ringen_MASK 0xfffffeff /* bit 8 */
- #define TST_ringen_disable 0x0
- #define TST_ringen_enable 0x100
- #define TST_apllbyp_MASK 0xfffffdff /* bit 9 */
- #define TST_apllbyp_disable 0x0
- #define TST_apllbyp_enable 0x200
- #define TST_hiten_MASK 0xfffffbff /* bit 10 */
- #define TST_hiten_disable 0x0
- #define TST_hiten_enable 0x400
- #define TST_tmode_MASK 0xffffc7ff /* bits 11-13 */
- #define TST_tmode_SHIFT 11
- #define TST_tclksel_MASK 0xfffe3fff /* bits 14-16 */
- #define TST_tclksel_SHIFT 14
- #define TST_ringcnten_MASK 0xfffdffff /* bit 17 */
- #define TST_ringcnten_disable 0x0
- #define TST_ringcnten_enable 0x20000
- #define TST_ringcnt_MASK 0xc003ffff /* bits 18-29 */
- #define TST_ringcnt_SHIFT 18
- #define TST_ringcntclksl_MASK 0xbfffffff /* bit 30 */
- #define TST_ringcntclksl_disable 0x0
- #define TST_ringcntclksl_enable 0x40000000
- #define TST_biosboot_MASK 0x7fffffff /* bit 31 */
- #define TST_biosboot_disable 0x0
- #define TST_biosboot_enable 0x80000000
-
- #define TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */
- #define TMC_tformat_tw4 0x0 /* val 0, shift 0 */
- #define TMC_tformat_tw8 0x1 /* val 1, shift 0 */
- #define TMC_tformat_tw15 0x2 /* val 2, shift 0 */
- #define TMC_tformat_tw16 0x3 /* val 3, shift 0 */
- #define TMC_tformat_tw12 0x4 /* val 4, shift 0 */
- #define TMC_tformat_tw32 0x6 /* val 6, shift 0 */
- #define TMC_tformat_tw422 0xa /* val 10, shift 0 */
- #define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */
- #define TMC_tpitchlin_disable 0x0
- #define TMC_tpitchlin_enable 0x100
- #define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */
- #define TMC_tpitchext_SHIFT 9
- #define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */
- #define TMC_tpitch_SHIFT 16
- #define TMC_owalpha_MASK 0xffbfffff /* bit 22 */
- #define TMC_owalpha_disable 0x0
- #define TMC_owalpha_enable 0x400000
- #define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */
- #define TMC_azeroextend_disable 0x0
- #define TMC_azeroextend_enable 0x800000
- #define TMC_decalckey_MASK 0xfeffffff /* bit 24 */
- #define TMC_decalckey_disable 0x0
- #define TMC_decalckey_enable 0x1000000
- #define TMC_takey_MASK 0xfdffffff /* bit 25 */
- #define TMC_takey_0 0x0
- #define TMC_takey_1 0x2000000
- #define TMC_tamask_MASK 0xfbffffff /* bit 26 */
- #define TMC_tamask_0 0x0
- #define TMC_tamask_1 0x4000000
- #define TMC_clampv_MASK 0xf7ffffff /* bit 27 */
- #define TMC_clampv_disable 0x0
- #define TMC_clampv_enable 0x8000000
- #define TMC_clampu_MASK 0xefffffff /* bit 28 */
- #define TMC_clampu_disable 0x0
- #define TMC_clampu_enable 0x10000000
- #define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */
- #define TMC_tmodulate_disable 0x0
- #define TMC_tmodulate_enable 0x20000000
- #define TMC_strans_MASK 0xbfffffff /* bit 30 */
- #define TMC_strans_disable 0x0
- #define TMC_strans_enable 0x40000000
- #define TMC_itrans_MASK 0x7fffffff /* bit 31 */
- #define TMC_itrans_disable 0x0
- #define TMC_itrans_enable 0x80000000
-
- #define TMC_decalblend_MASK 0xfffffffe /* bit 0 */
- #define TMC_decalblend_disable 0x0
- #define TMC_decalblend_enable 0x1
- #define TMC_idecal_MASK 0xfffffffd /* bit 1 */
- #define TMC_idecal_disable 0x0
- #define TMC_idecal_enable 0x2
- #define TMC_decaldis_MASK 0xfffffffb /* bit 2 */
- #define TMC_decaldis_disable 0x0
- #define TMC_decaldis_enable 0x4
- #define TMC_ckstransdis_MASK 0xffffffef /* bit 4 */
- #define TMC_ckstransdis_disable 0x0
- #define TMC_ckstransdis_enable 0x10
- #define TMC_borderen_MASK 0xffffffdf /* bit 5 */
- #define TMC_borderen_disable 0x0
- #define TMC_borderen_enable 0x20
- #define TMC_specen_MASK 0xffffffbf /* bit 6 */
- #define TMC_specen_disable 0x0
- #define TMC_specen_enable 0x40
-
- #define TF_minfilter_MASK 0xfffffff0 /* bits 0-3 */
- #define TF_minfilter_nrst 0x0 /* val 0, shift 0 */
- #define TF_minfilter_bilin 0x2 /* val 2, shift 0 */
- #define TF_minfilter_cnst 0x3 /* val 3, shift 0 */
- #define TF_minfilter_mm1s 0x8 /* val 8, shift 0 */
- #define TF_minfilter_mm2s 0x9 /* val 9, shift 0 */
- #define TF_minfilter_mm4s 0xa /* val 10, shift 0 */
- #define TF_minfilter_mm8s 0xc /* val 12, shift 0 */
- #define TF_magfilter_MASK 0xffffff0f /* bits 4-7 */
- #define TF_magfilter_nrst 0x0 /* val 0, shift 4 */
- #define TF_magfilter_bilin 0x20 /* val 2, shift 4 */
- #define TF_magfilter_cnst 0x30 /* val 3, shift 4 */
- #define TF_avgstride_MASK 0xfff7ffff /* bit 19 */
- #define TF_avgstride_disable 0x0
- #define TF_avgstride_enable 0x80000
- #define TF_filteralpha_MASK 0xffefffff /* bit 20 */
- #define TF_filteralpha_disable 0x0
- #define TF_filteralpha_enable 0x100000
- #define TF_fthres_MASK 0xe01fffff /* bits 21-28 */
- #define TF_fthres_SHIFT 21
- #define TF_mapnb_MASK 0x1fffffff /* bits 29-31 */
- #define TF_mapnb_SHIFT 29
-
- #define TH_th_MASK 0xffffffc0 /* bits 0-5 */
- #define TH_th_SHIFT 0
- #define TH_rfh_MASK 0xffff81ff /* bits 9-14 */
- #define TH_rfh_SHIFT 9
- #define TH_thmask_MASK 0xe003ffff /* bits 18-28 */
- #define TH_thmask_SHIFT 18
-
- #define TO_texorgmap_MASK 0xfffffffe /* bit 0 */
- #define TO_texorgmap_fb 0x0
- #define TO_texorgmap_sys 0x1
- #define TO_texorgacc_MASK 0xfffffffd /* bit 1 */
- #define TO_texorgacc_pci 0x0
- #define TO_texorgacc_agp 0x2
- #define TO_texorg_MASK 0x1f /* bits 5-31 */
- #define TO_texorg_SHIFT 5
-
- #define TT_tckey_MASK 0xffff0000 /* bits 0-15 */
- #define TT_tckey_SHIFT 0
- #define TT_tkmask_MASK 0xffff /* bits 16-31 */
- #define TT_tkmask_SHIFT 16
-
- #define TT_tckeyh_MASK 0xffff0000 /* bits 0-15 */
- #define TT_tckeyh_SHIFT 0
- #define TT_tkmaskh_MASK 0xffff /* bits 16-31 */
- #define TT_tkmaskh_SHIFT 16
-
- #define TW_tw_MASK 0xffffffc0 /* bits 0-5 */
- #define TW_tw_SHIFT 0
- #define TW_rfw_MASK 0xffff81ff /* bits 9-14 */
- #define TW_rfw_SHIFT 9
- #define TW_twmask_MASK 0xe003ffff /* bits 18-28 */
- #define TW_twmask_SHIFT 18
-
- #define WAS_seqdst0_MASK 0xffffffc0 /* bits 0-5 */
- #define WAS_seqdst0_SHIFT 0
- #define WAS_seqdst1_MASK 0xfffff03f /* bits 6-11 */
- #define WAS_seqdst1_SHIFT 6
- #define WAS_seqdst2_MASK 0xfffc0fff /* bits 12-17 */
- #define WAS_seqdst2_SHIFT 12
- #define WAS_seqdst3_MASK 0xff03ffff /* bits 18-23 */
- #define WAS_seqdst3_SHIFT 18
- #define WAS_seqlen_MASK 0xfcffffff /* bits 24-25 */
- #define WAS_wfirsttag_MASK 0xfbffffff /* bit 26 */
- #define WAS_wfirsttag_disable 0x0
- #define WAS_wfirsttag_enable 0x4000000
- #define WAS_wsametag_MASK 0xf7ffffff /* bit 27 */
- #define WAS_wsametag_disable 0x0
- #define WAS_wsametag_enable 0x8000000
- #define WAS_seqoff_MASK 0xefffffff /* bit 28 */
- #define WAS_seqoff_disable 0x0
- #define WAS_seqoff_enable 0x10000000
-
- #define WMA_wcodeaddr_MASK 0xff /* bits 8-31 */
- #define WMA_wcodeaddr_SHIFT 8
-
- #define WF_walustsflag_MASK 0xffffff00 /* bits 0-7 */
- #define WF_walustsflag_SHIFT 0
- #define WF_walucfgflag_MASK 0xffff00ff /* bits 8-15 */
- #define WF_walucfgflag_SHIFT 8
- #define WF_wprgflag_MASK 0xffff /* bits 16-31 */
- #define WF_wprgflag_SHIFT 16
-
- #define WF1_walustsflag1_MASK 0xffffff00 /* bits 0-7 */
- #define WF1_walustsflag1_SHIFT 0
- #define WF1_walucfgflag1_MASK 0xffff00ff /* bits 8-15 */
- #define WF1_walucfgflag1_SHIFT 8
- #define WF1_wprgflag1_MASK 0xffff /* bits 16-31 */
- #define WF1_wprgflag1_SHIFT 16
-
- #define WGV_wgetmsbmin_MASK 0xffffffe0 /* bits 0-4 */
- #define WGV_wgetmsbmin_SHIFT 0
- #define WGV_wgetmsbmax_MASK 0xffffe0ff /* bits 8-12 */
- #define WGV_wgetmsbmax_SHIFT 8
- #define WGV_wbrklefttop_MASK 0xfffeffff /* bit 16 */
- #define WGV_wbrklefttop_disable 0x0
- #define WGV_wbrklefttop_enable 0x10000
- #define WGV_wfastcrop_MASK 0xfffdffff /* bit 17 */
- #define WGV_wfastcrop_disable 0x0
- #define WGV_wfastcrop_enable 0x20000
- #define WGV_wcentersnap_MASK 0xfffbffff /* bit 18 */
- #define WGV_wcentersnap_disable 0x0
- #define WGV_wcentersnap_enable 0x40000
- #define WGV_wbrkrighttop_MASK 0xfff7ffff /* bit 19 */
- #define WGV_wbrkrighttop_disable 0x0
- #define WGV_wbrkrighttop_enable 0x80000
-
- #define WIA_wmode_MASK 0xfffffffc /* bits 0-1 */
- #define WIA_wmode_suspend 0x0 /* val 0, shift 0 */
- #define WIA_wmode_resume 0x1 /* val 1, shift 0 */
- #define WIA_wmode_jump 0x2 /* val 2, shift 0 */
- #define WIA_wmode_start 0x3 /* val 3, shift 0 */
- #define WIA_wagp_MASK 0xfffffffb /* bit 2 */
- #define WIA_wagp_pci 0x0
- #define WIA_wagp_agp 0x4
- #define WIA_wiaddr_MASK 0x7 /* bits 3-31 */
- #define WIA_wiaddr_SHIFT 3
-
- #define WIA2_wmode_MASK 0xfffffffc /* bits 0-1 */
- #define WIA2_wmode_suspend 0x0 /* val 0, shift 0 */
- #define WIA2_wmode_resume 0x1 /* val 1, shift 0 */
- #define WIA2_wmode_jump 0x2 /* val 2, shift 0 */
- #define WIA2_wmode_start 0x3 /* val 3, shift 0 */
- #define WIA2_wagp_MASK 0xfffffffb /* bit 2 */
- #define WIA2_wagp_pci 0x0
- #define WIA2_wagp_agp 0x4
- #define WIA2_wiaddr_MASK 0x7 /* bits 3-31 */
- #define WIA2_wiaddr_SHIFT 3
-
- #define WIMA_wimemaddr_MASK 0xffffff00 /* bits 0-7 */
- #define WIMA_wimemaddr_SHIFT 0
-
- #define WM_wucodecache_MASK 0xfffffffe /* bit 0 */
- #define WM_wucodecache_disable 0x0
- #define WM_wucodecache_enable 0x1
- #define WM_wmaster_MASK 0xfffffffd /* bit 1 */
- #define WM_wmaster_disable 0x0
- #define WM_wmaster_enable 0x2
- #define WM_wcacheflush_MASK 0xfffffff7 /* bit 3 */
- #define WM_wcacheflush_disable 0x0
- #define WM_wcacheflush_enable 0x8
-
- #define WVS_wvrtxsz_MASK 0xffffffc0 /* bits 0-5 */
- #define WVS_wvrtxsz_SHIFT 0
- #define WVS_primsz_MASK 0xffffc0ff /* bits 8-13 */
- #define WVS_primsz_SHIFT 8
-
- #define XYEA_x_end_MASK 0xffff0000 /* bits 0-15 */
- #define XYEA_x_end_SHIFT 0
- #define XYEA_y_end_MASK 0xffff /* bits 16-31 */
- #define XYEA_y_end_SHIFT 16
-
- #define XYSA_x_start_MASK 0xffff0000 /* bits 0-15 */
- #define XYSA_x_start_SHIFT 0
- #define XYSA_y_start_MASK 0xffff /* bits 16-31 */
- #define XYSA_y_start_SHIFT 16
-
- #define YA_ydst_MASK 0xff800000 /* bits 0-22 */
- #define YA_ydst_SHIFT 0
- #define YA_sellin_MASK 0x1fffffff /* bits 29-31 */
- #define YA_sellin_SHIFT 29
-
- #define YDL_length_MASK 0xffff0000 /* bits 0-15 */
- #define YDL_length_SHIFT 0
- #define YDL_yval_MASK 0xffff /* bits 16-31 */
- #define YDL_yval_SHIFT 16
-
- #define ZO_zorgmap_MASK 0xfffffffe /* bit 0 */
- #define ZO_zorgmap_fb 0x0
- #define ZO_zorgmap_sys 0x1
- #define ZO_zorgacc_MASK 0xfffffffd /* bit 1 */
- #define ZO_zorgacc_pci 0x0
- #define ZO_zorgacc_agp 0x2
- #define ZO_zorg_MASK 0x3 /* bits 2-31 */
- #define ZO_zorg_SHIFT 2
-
-
-
-
-/**************** (END) AUTOMATICLY GENERATED REGISTER FILE ******************/
-
-#endif /* _MGAREGS_H_ */
-
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c
index ecdb2c15a..0bd8bfd57 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c
@@ -9,6 +9,16 @@
#define CONFIG_MODVERSIONS 0
#endif
+#ifndef CONFIG_AGP_MODULE
+#define CONFIG_AGP_MODULE 0
+#endif
+
+#ifndef CONFIG_AGP
+#define CONFIG_AGP 0
+#endif
+
SMP = CONFIG_SMP
MODVERSIONS = CONFIG_MODVERSIONS
+AGP = CONFIG_AGP
+AGP_MODULE = CONFIG_AGP_MODULE
RELEASE = UTS_RELEASE
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c
index 54aba58c4..db98fd6a4 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c
@@ -164,7 +164,10 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
{
drm_device_t *dev = (drm_device_t *)data;
drm_map_t *map;
- const char *types[] = { "FB", "REG", "SHM" };
+ /* Hardcoded from _DRM_FRAME_BUFFER,
+ _DRM_REGISTERS, _DRM_SHM, and
+ _DRM_AGP. */
+ const char *types[] = { "FB", "REG", "SHM", "AGP" };
const char *type;
int i;
@@ -175,7 +178,7 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
"address mtrr\n\n");
for (i = 0; i < dev->map_count; i++) {
map = dev->maplist[i];
- if (map->type < 0 || map->type > 2) type = "??";
+ if (map->type < 0 || map->type > 3) type = "??";
else type = types[map->type];
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c
index 842d6f5d5..74b107bd2 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_context.c
@@ -38,9 +38,7 @@ extern drm_ctx_t tdfx_res_ctx;
static int tdfx_alloc_queue(drm_device_t *dev)
{
- static int context = 0;
-
- return ++context; /* Should this reuse contexts in the future? */
+ return drm_ctxbitmap_next(dev);
}
int tdfx_context_switch(drm_device_t *dev, int old, int new)
@@ -137,6 +135,12 @@ int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
ctx.handle = tdfx_alloc_queue(dev);
}
DRM_DEBUG("%d\n", ctx.handle);
+ if (ctx.handle == -1) {
+ DRM_DEBUG("Not enough free contexts.\n");
+ /* Should this return -EBUSY instead? */
+ return -ENOMEM;
+ }
+
copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
return 0;
}
@@ -193,13 +197,13 @@ int tdfx_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
int tdfx_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
DRM_DEBUG("%d\n", ctx.handle);
- /* This is currently a noop because we
- don't reuse context values. Perhaps we
- should? */
-
+ drm_ctxbitmap_free(dev, ctx.handle);
+
return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c
index 57c1c719d..fb7a997b4 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/tdfx_drv.c
@@ -85,6 +85,16 @@ static drm_ioctl_desc_t tdfx_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { tdfx_lock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { tdfx_unlock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
+#ifdef DRM_AGP
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_unbind, 1, 1},
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_bind, 1, 1},
+#endif
};
#define TDFX_IOCTL_COUNT DRM_ARRAY_SIZE(tdfx_ioctls)
@@ -228,7 +238,24 @@ static int tdfx_takedown(drm_device_t *dev)
}
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
-
+#ifdef DRM_AGP
+ /* Clear AGP information */
+ if (dev->agp) {
+ drm_agp_mem_t *temp;
+ drm_agp_mem_t *temp_next;
+
+ temp = dev->agp->memory;
+ while(temp != NULL) {
+ temp_next = temp->next;
+ drm_free_agp(temp->memory, temp->pages);
+ drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS);
+ temp = temp_next;
+ }
+ if(dev->agp->acquired) (*drm_agp.release)();
+ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+ dev->agp = NULL;
+ }
+#endif
/* Clear vma list (only built for debugging) */
if (dev->vmalist) {
for (vma = dev->vmalist; vma; vma = vma_next) {
@@ -262,6 +289,10 @@ static int tdfx_takedown(drm_device_t *dev)
- PAGE_SHIFT,
DRM_MEM_SAREA);
break;
+ case _DRM_AGP:
+ /* Do nothing here, because this is all
+ handled in the AGP/GART driver. */
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
@@ -309,6 +340,16 @@ int tdfx_init(void)
drm_mem_init();
drm_proc_init(dev);
+#ifdef DRM_AGP
+ dev->agp = drm_agp_init();
+#endif
+ if((retcode = drm_ctxbitmap_init(dev))) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ drm_proc_cleanup();
+ misc_deregister(&tdfx_misc);
+ tdfx_takedown(dev);
+ return retcode;
+ }
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
TDFX_NAME,
@@ -335,6 +376,7 @@ void tdfx_cleanup(void)
} else {
DRM_INFO("Module unloaded\n");
}
+ drm_ctxbitmap_cleanup(dev);
tdfx_takedown(dev);
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c
index 85470ac52..389f2faee 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c
@@ -250,9 +250,10 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
switch (map->type) {
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
+ case _DRM_AGP:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
#if defined(__i386__)
- if (boot_cpu_data.x86 > 3) {
+ if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
index 3b0f98acd..8b97c7da9 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
@@ -418,7 +418,8 @@ int drmAddMap(int fd,
return 0;
}
-int drmAddBufs(int fd, int count, int size, int flags)
+int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
+ int agp_offset)
{
drm_buf_desc_t request;
@@ -427,6 +428,8 @@ int drmAddBufs(int fd, int count, int size, int flags)
request.low_mark = 0;
request.high_mark = 0;
request.flags = flags;
+ request.agp_start = agp_offset;
+
if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
return request.count;
}
@@ -744,6 +747,143 @@ int drmDestroyDrawable(int fd, drmDrawable handle)
return 0;
}
+int drmAgpAcquire(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno;
+ return 0;
+}
+
+int drmAgpRelease(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno;
+ return 0;
+}
+
+int drmAgpEnable(int fd, unsigned long mode)
+{
+ drm_agp_mode_t m;
+
+ m.mode = mode;
+ if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno;
+ return 0;
+}
+
+int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
+ unsigned long *address, unsigned long *handle)
+{
+ drm_agp_buffer_t b;
+ *handle = 0;
+ b.size = size;
+ b.handle = 0;
+ b.type = type;
+ if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno;
+ if (address != 0UL) *address = b.physical;
+ *handle = b.handle;
+ return 0;
+}
+
+int drmAgpFree(int fd, unsigned long handle)
+{
+ drm_agp_buffer_t b;
+
+ b.size = 0;
+ b.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno;
+ return 0;
+}
+
+int drmAgpBind(int fd, unsigned long handle, unsigned long offset)
+{
+ drm_agp_binding_t b;
+
+ b.handle = handle;
+ b.offset = offset;
+ if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno;
+ return 0;
+}
+
+int drmAgpUnbind(int fd, unsigned long handle)
+{
+ drm_agp_binding_t b;
+
+ b.handle = handle;
+ b.offset = 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno;
+ return 0;
+}
+
+int drmAgpVersionMajor(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ return i.agp_version_major;
+}
+
+int drmAgpVersionMinor(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ return i.agp_version_minor;
+}
+
+unsigned long drmAgpGetMode(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.mode;
+}
+
+unsigned long drmAgpBase(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.aperture_base;
+}
+
+unsigned long drmAgpSize(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.aperture_size;
+}
+
+unsigned long drmAgpMemoryUsed(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.memory_used;
+}
+
+unsigned long drmAgpMemoryAvail(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.memory_allowed;
+}
+
+unsigned int drmAgpVendorId(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.id_vendor;
+}
+
+unsigned int drmAgpDeviceId(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.id_device;
+}
+
int drmError(int err, const char *label)
{
switch (err) {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
new file mode 100644
index 000000000..a7b95fbf0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
@@ -0,0 +1,81 @@
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include <sys/sysmacros.h> /* for makedev() */
+#include "xf86drm.h"
+#include "xf86drmI810.h"
+#include "drm.h"
+
+Bool drmI810CleanupDma(int driSubFD)
+{
+ drm_i810_init_t init;
+
+ memset(&init, 0, sizeof(drm_i810_init_t));
+ init.func = I810_CLEANUP_DMA;
+
+ if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmI810InitDma(int driSubFD, unsigned long start, unsigned long end,
+ unsigned long size, int ring_map_idx, int buffer_map_idx,
+ int sarea_off)
+{
+ drm_i810_init_t init;
+
+ memset(&init, 0, sizeof(drm_i810_init_t));
+ init.func = I810_INIT_DMA;
+ init.ring_map_idx = ring_map_idx;
+ init.buffer_map_idx = buffer_map_idx;
+ init.ring_start = start;
+ init.ring_end = end;
+ init.ring_size = size;
+ init.sarea_priv_offset = sarea_off;
+
+ if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) {
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c
new file mode 100644
index 000000000..5957ffe33
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmMga.c
@@ -0,0 +1,117 @@
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include <sys/sysmacros.h> /* for makedev() */
+#include "xf86drm.h"
+#include "xf86drmMga.h"
+#include "drm.h"
+
+Bool drmMgaCleanupDma(int driSubFD)
+{
+ drm_mga_init_t init;
+ memset(&init, 0, sizeof(drm_mga_init_t));
+ init.func = MGA_CLEANUP_DMA;
+ if(ioctl(driSubFD, DRM_IOCTL_MGA_INIT, &init)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmMgaLockUpdate(int driSubFD, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ memset(&lock, 0, sizeof(drm_lock_t));
+
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+
+ if(ioctl(driSubFD, DRM_IOCTL_MGA_FLUSH, &lock)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmMgaInitDma(int driSubFD, drmMgaInit *info)
+{
+ drm_mga_init_t init;
+ int i;
+
+ memset(&init, 0, sizeof(drm_mga_init_t));
+ init.func = MGA_INIT_DMA;
+ init.reserved_map_agpstart = info->reserved_map_agpstart;
+ init.reserved_map_idx = info->reserved_map_idx;
+ init.buffer_map_idx = info->buffer_map_idx;
+ init.sarea_priv_offset = info->sarea_priv_offset;
+ init.primary_size = info->primary_size;
+ init.warp_ucode_size = info->warp_ucode_size;
+ init.frontOffset = info->frontOffset;
+ init.backOffset = info->backOffset;
+ init.depthOffset = info->depthOffset;
+ init.textureOffset = info->textureOffset;
+ init.textureSize = info->textureSize;
+ init.agpTextureSize = info->agpTextureSize;
+ init.agpTextureOffset = info->agpTextureOffset;
+ init.cpp = info->cpp;
+ init.stride = info->stride;
+ init.sgram = info->sgram;
+ init.chipset = info->chipset;
+
+ for(i = 0; i < MGA_MAX_WARP_PIPES; i++) {
+ init.WarpIndex[i].installed = info->WarpIndex[i].installed;
+ init.WarpIndex[i].phys_addr = info->WarpIndex[i].phys_addr;
+ init.WarpIndex[i].size = info->WarpIndex[i].size;
+ }
+
+ init.mAccess = info->mAccess;
+
+
+
+ if(ioctl(driSubFD, DRM_IOCTL_MGA_INIT, &init)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index 7b8e88265..ae4c65ca3 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -61,6 +61,19 @@ typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
+/* Warning: If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well */
+
+typedef struct drm_clip_rect {
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
+} drm_clip_rect_t;
+
+/* Seperate include files for the i810/mga specific structures */
+#include "mga_drm.h"
+#include "i810_drm.h"
typedef struct drm_version {
int version_major; /* Major version */
@@ -101,7 +114,8 @@ typedef struct drm_control {
typedef enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
_DRM_REGISTERS = 1, /* no caching, no core dump */
- _DRM_SHM = 2 /* shared, cached */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3 /* AGP/GART */
} drm_map_type_t;
typedef enum drm_map_flags {
@@ -165,8 +179,11 @@ typedef struct drm_buf_desc {
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
enum {
- DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */
+ _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
} flags;
+ unsigned long agp_start; /* Start address of where the agp buffers
+ * are in the agp aperture */
} drm_buf_desc_t;
typedef struct drm_buf_info {
@@ -237,6 +254,38 @@ typedef struct drm_irq_busid {
int funcnum;
} drm_irq_busid_t;
+typedef struct drm_agp_mode {
+ unsigned long mode;
+} drm_agp_mode_t;
+
+ /* For drm_agp_alloc -- allocated a buffer */
+typedef struct drm_agp_buffer {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for BIND/UNBIND ioctls */
+ unsigned long type; /* Type of memory to allocate */
+ unsigned long physical; /* Physical used by i810 */
+} drm_agp_buffer_t;
+
+ /* For drm_agp_bind */
+typedef struct drm_agp_binding {
+ unsigned long handle; /* From drm_agp_buffer */
+ unsigned long offset; /* In bytes -- will round to page boundary */
+} drm_agp_binding_t;
+
+typedef struct drm_agp_info {
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
+ unsigned short id_vendor;
+ unsigned short id_device;
+} drm_agp_info_t;
+
#define DRM_IOCTL_BASE 'd'
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
@@ -276,4 +325,28 @@ typedef struct drm_irq_busid {
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOR( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOW( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+
+/* Mga specific ioctls */
+#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
+#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
+#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
+#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
+#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+
+/* I810 specific ioctls */
+#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t)
+#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
+#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
index 61287e3e2..0fd1141b5 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -65,7 +65,8 @@ typedef struct _drmVersion {
typedef enum {
DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */
DRM_REGISTERS = 1, /* no caching, no core dump */
- DRM_SHM = 2 /* shared, cached */
+ DRM_SHM = 2, /* shared, cached */
+ DRM_AGP = 3 /* AGP/GART */
} drmMapType;
typedef enum {
@@ -95,6 +96,11 @@ typedef enum { /* These values *MUST* match drm.h */
} drmDMAFlags;
typedef enum {
+ DRM_PAGE_ALIGN = 0x01,
+ DRM_AGP_BUFFER = 0x02
+} drmBufDescFlags;
+
+typedef enum {
DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
@@ -196,7 +202,7 @@ typedef struct { unsigned int a[100]; } __drm_dummy_lock_t;
#endif
#ifndef DRM_CAS
-#define DRM_CAS(lock,old,new,ret) /* FAST LOCK FAILS */
+#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */
#endif
#define DRM_LIGHT_LOCK(fd,lock,context) \
@@ -291,7 +297,9 @@ extern int drmAddMap(int fd,
drmMapType type,
drmMapFlags flags,
drmHandlePtr handle);
-extern int drmAddBufs(int fd, int count, int size, int flags);
+extern int drmAddBufs(int fd, int count, int size,
+ drmBufDescFlags flags,
+ int agp_offset);
extern int drmMarkBufs(int fd, double low, double high);
extern int drmCreateContext(int fd, drmContextPtr handle);
extern int drmSetContextFlags(int fd, drmContext context,
@@ -332,6 +340,29 @@ extern int drmGetLock(int fd,
extern int drmUnlock(int fd, drmContext context);
extern int drmFinish(int fd, int context, drmLockFlags flags);
+/* AGP/GART support: X server (root) only */
+extern int drmAgpAcquire(int fd);
+extern int drmAgpRelease(int fd);
+extern int drmAgpEnable(int fd, unsigned long mode);
+extern int drmAgpAlloc(int fd, unsigned long size,
+ unsigned long type, unsigned long *address,
+ unsigned long *handle);
+extern int drmAgpFree(int fd, unsigned long handle);
+extern int drmAgpBind(int fd, unsigned long handle,
+ unsigned long offset);
+extern int drmAgpUnbind(int fd, unsigned long handle);
+
+/* AGP/GART info: authenticated client and/or X */
+extern int drmAgpVersionMajor(int fd);
+extern int drmAgpVersionMinor(int fd);
+extern unsigned long drmAgpGetMode(int fd);
+extern unsigned long drmAgpBase(int fd); /* Physical location */
+extern unsigned long drmAgpSize(int fd); /* Bytes */
+extern unsigned long drmAgpMemoryUsed(int fd);
+extern unsigned long drmAgpMemoryAvail(int fd);
+extern unsigned int drmAgpVendorId(int fd);
+extern unsigned int drmAgpDeviceId(int fd);
+
/* Support routines */
extern int drmError(int err, const char *label);
extern void *drmMalloc(int size);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
new file mode 100644
index 000000000..88bb58a3b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
@@ -0,0 +1,29 @@
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (i810_drm.h)
+ */
+
+#ifndef _XF86DRI_I810_H_
+#define _XF86DRI_I810_H_
+
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+#define I810_USE_BATCH 1
+
+#define I810_DMA_BUF_ORDER 12
+#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR 256
+
+#define I810_NR_SAREA_CLIPRECTS 2
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+Bool drmI810CleanupDma(int driSubFD);
+Bool drmI810InitDma(int driSubFD, unsigned long start, unsigned long end,
+ unsigned long size, int ring_map_idx, int buffer_map_idx,
+ int sarea_off);
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
new file mode 100644
index 000000000..9525a2710
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
@@ -0,0 +1,147 @@
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (mga_drm.h)
+ */
+
+#ifndef _XF86DRI_MGA_H_
+#define _XF86DRI_MGA_H_
+#ifndef _MGA_DEFINES_
+#define _MGA_DEFINES_
+#define MGA_F 0x1 /* fog */
+#define MGA_A 0x2 /* alpha */
+#define MGA_S 0x4 /* specular */
+#define MGA_T2 0x8 /* multitexture */
+
+#define MGA_WARP_TGZ 0
+#define MGA_WARP_TGZF (MGA_F)
+#define MGA_WARP_TGZA (MGA_A)
+#define MGA_WARP_TGZAF (MGA_F|MGA_A)
+#define MGA_WARP_TGZS (MGA_S)
+#define MGA_WARP_TGZSF (MGA_S|MGA_F)
+#define MGA_WARP_TGZSA (MGA_S|MGA_A)
+#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A)
+#define MGA_WARP_T2GZ (MGA_T2)
+#define MGA_WARP_T2GZF (MGA_T2|MGA_F)
+#define MGA_WARP_T2GZA (MGA_T2|MGA_A)
+#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F)
+#define MGA_WARP_T2GZS (MGA_T2|MGA_S)
+#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F)
+#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
+#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
+
+#define MGA_MAX_G400_PIPES 16
+#define MGA_MAX_G200_PIPES 8 /* no multitex */
+
+#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
+
+#define MGA_CARD_TYPE_G200 1
+#define MGA_CARD_TYPE_G400 2
+#define MGA_FRONT 0x1
+#define MGA_BACK 0x2
+#define MGA_DEPTH 0x4
+
+/* 3d state excluding texture units:
+ */
+#define MGA_CTXREG_DSTORG 0 /* validated */
+#define MGA_CTXREG_MACCESS 1
+#define MGA_CTXREG_PLNWT 2
+#define MGA_CTXREG_DWGCTL 3
+#define MGA_CTXREG_ALPHACTRL 4
+#define MGA_CTXREG_FOGCOLOR 5
+#define MGA_CTXREG_WFLAG 6
+#define MGA_CTXREG_TDUAL0 7
+#define MGA_CTXREG_TDUAL1 8
+#define MGA_CTXREG_FCOL 9
+#define MGA_CTX_SETUP_SIZE 10
+
+/* 2d state
+ */
+#define MGA_2DREG_PITCH 0
+#define MGA_2D_SETUP_SIZE 1
+
+/* Each texture unit has a state:
+ */
+#define MGA_TEXREG_CTL 0
+#define MGA_TEXREG_CTL2 1
+#define MGA_TEXREG_FILTER 2
+#define MGA_TEXREG_BORDERCOL 3
+#define MGA_TEXREG_ORG 4 /* validated */
+#define MGA_TEXREG_ORG1 5
+#define MGA_TEXREG_ORG2 6
+#define MGA_TEXREG_ORG3 7
+#define MGA_TEXREG_ORG4 8
+#define MGA_TEXREG_WIDTH 9
+#define MGA_TEXREG_HEIGHT 10
+#define MGA_TEX_SETUP_SIZE 11
+
+/* What needs to be changed for the current vertex dma buffer?
+ */
+#define MGA_UPLOAD_CTX 0x1
+#define MGA_UPLOAD_TEX0 0x2
+#define MGA_UPLOAD_TEX1 0x4
+#define MGA_UPLOAD_PIPE 0x8
+#define MGA_UPLOAD_TEX0IMAGE 0x10
+#define MGA_UPLOAD_TEX1IMAGE 0x20
+#define MGA_UPLOAD_2D 0x40
+#define MGA_WAIT_AGE 0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
+#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
+ quiescent */
+
+/* 64 buffers of 16k each, total 1 meg.
+ */
+#define MGA_DMA_BUF_ORDER 14
+#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER)
+#define MGA_DMA_BUF_NR 63
+
+/* Keep these small for testing.
+ */
+#define MGA_NR_SAREA_CLIPRECTS 8
+
+/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+ * regions, subject to a minimum region size of (1<<16) == 64k.
+ *
+ * Clients may subdivide regions internally, but when sharing between
+ * clients, the region size is the minimum granularity.
+ */
+
+#define MGA_CARD_HEAP 0
+#define MGA_AGP_HEAP 1
+#define MGA_NR_TEX_HEAPS 2
+#define MGA_NR_TEX_REGIONS 16
+#define MGA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+typedef struct _drmMgaWarpIndex {
+ int installed;
+ unsigned long phys_addr;
+ int size;
+} drmMgaWarpIndex;
+
+typedef struct _drmMgaInit {
+ int reserved_map_agpstart;
+ int reserved_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ int primary_size;
+ int warp_ucode_size;
+ int frontOffset;
+ int backOffset;
+ int depthOffset;
+ int textureOffset;
+ int textureSize;
+ int agpTextureSize;
+ int agpTextureOffset;
+ int cpp;
+ int stride;
+ int sgram;
+ int chipset;
+ drmMgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
+ int mAccess;
+} drmMgaInit;
+
+
+Bool drmMgaCleanupDma(int driSubFD);
+Bool drmMgaLockUpdate(int driSubFD, drmLockFlags flags);
+Bool drmMgaInitDma(int driSubFD, drmMgaInit *info);
+#endif