From 92d69e5e06f9906b2aaf32f2f8e6f670fe262be2 Mon Sep 17 00:00:00 2001 From: kem Date: Wed, 20 Dec 2000 00:25:49 +0000 Subject: Add basic Radeon 3D driver (not fully functional yet) --- xc/config/cf/host.def | 51 + xc/config/cf/xfree86.cf | 7 +- xc/lib/GL/Imakefile | 125 +- xc/lib/GL/mesa/src/drv/Imakefile | 7 +- xc/lib/GL/mesa/src/drv/radeon/Imakefile | 379 +++++ xc/lib/GL/mesa/src/drv/radeon/radeon_context.c | 237 +++ xc/lib/GL/mesa/src/drv/radeon/radeon_context.h | 269 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c | 206 +++ xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h | 46 + xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c | 562 +++++++ xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h | 312 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c | 542 +++++++ xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h | 196 +++ xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c | 613 ++++++++ xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h | 195 +++ xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c | 94 ++ xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h | 110 ++ xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c | 169 ++ xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h | 51 + xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c | 280 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h | 118 ++ xc/lib/GL/mesa/src/drv/radeon/radeon_span.c | 340 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_span.h | 45 + xc/lib/GL/mesa/src/drv/radeon/radeon_state.c | 1343 ++++++++++++++++ xc/lib/GL/mesa/src/drv/radeon/radeon_state.h | 57 + xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c | 1663 ++++++++++++++++++++ xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h | 91 ++ xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h | 82 + xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c | 210 +++ xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h | 321 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h | 384 +++++ xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c | 484 ++++++ xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h | 137 ++ xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c | 284 ++++ .../Xserver/hw/xfree86/drivers/ati/r128_accel.c | 8 +- .../Xserver/hw/xfree86/drivers/ati/radeon_accel.c | 2 +- .../Xserver/hw/xfree86/drivers/ati/radeon_dri.c | 20 +- .../Xserver/hw/xfree86/drivers/ati/radeon_dri.h | 3 +- .../Xserver/hw/xfree86/drivers/ati/radeon_reg.h | 899 +++++------ .../Xserver/hw/xfree86/drivers/ati/radeon_sarea.h | 145 +- .../os-support/linux/drm/kernel/radeon_cp.c | 37 +- .../os-support/linux/drm/kernel/radeon_drm.h | 172 +- .../os-support/linux/drm/kernel/radeon_drv.c | 2 +- .../os-support/linux/drm/kernel/radeon_drv.h | 160 +- .../os-support/linux/drm/kernel/radeon_state.c | 431 +++-- .../xfree86/os-support/linux/drm/xf86drmRadeon.c | 2 + .../Xserver/hw/xfree86/os-support/xf86drmRadeon.h | 2 + 47 files changed, 10967 insertions(+), 926 deletions(-) create mode 100644 xc/config/cf/host.def create mode 100644 xc/lib/GL/mesa/src/drv/radeon/Imakefile create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_context.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_context.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_span.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_span.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_state.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_state.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h create mode 100644 xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def new file mode 100644 index 000000000..dabf6ed5c --- /dev/null +++ b/xc/config/cf/host.def @@ -0,0 +1,51 @@ + +#define DefaultGcc2i386Opt -O2 +#define LibraryCDebugFlags -O2 +#define BuildServersOnly YES +#define XF86CardDrivers vga tdfx i810 mga ati glint +#define LinuxDistribution LinuxRedHat +#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 + +#ifdef i386Architecture +#define MesaUse3DNow +#if HasKatmaiSupport +# define MesaUseKatmai +#endif +#endif + +/* To do profiling of the dynamically loaded 'xyz_dri.so' object, turn + * this on. + * Use 'xc/lib/GL/makeprofile.sh' to make it work. + */ +/* #define GlxSoProf YES */ + +#ifdef GlxSoProf +# undef DefaultCCOptions +# define DefaultCCOptions -ansi GccWarningOptions -pipe -g -p +#endif + +/* Optionally turn these on for debugging */ +/* #define GlxBuiltInTdfx YES */ +/* #define GlxBuiltInI810 YES */ +/* #define GlxBuiltInMga YES */ +/* #define GlxBuiltInR128 YES */ +/* #define GlxBuiltInRadeon YES */ +/* #define DoLoadableServer NO */ + +/* Optionally turn this on to change the place where you install the build */ +/* #define ProjectRoot /usr/XF86-main */ + +/* Optionally turn this on to force the kernel modules to build */ +/* #define BuildXF86DRM YES */ + +#define XnestServer NO +#define XVirtualFramebufferServer NO +#define XprtServer NO + diff --git a/xc/config/cf/xfree86.cf b/xc/config/cf/xfree86.cf index 9f07a6e3e..99cdf005c 100644 --- a/xc/config/cf/xfree86.cf +++ b/xc/config/cf/xfree86.cf @@ -565,6 +565,9 @@ IPLAN2P8_DEFS = -DUSE_IPLAN2P8 # ifndef GlxBuiltInR128 # define GlxBuiltInR128 NO # endif +# ifndef GlxBuiltInRadeon +# define GlxBuiltInRadeon NO +# endif # ifndef GlxBuiltInFfb # define GlxBuiltInFfb NO # endif @@ -572,11 +575,11 @@ IPLAN2P8_DEFS = -DUSE_IPLAN2P8 # define GlxBuiltInSIS NO # endif -# if GlxBuiltInTdfx || GlxBuiltInMga || GlxBuiltInI810 || GlxBuiltInR128 || GlxBuildInFfb || GlxBuiltInSIS +# if GlxBuiltInTdfx || GlxBuiltInMga || GlxBuiltInI810 || GlxBuiltInR128 || GlxBuiltInRadeon || GlxBuildInFfb || GlxBuiltInSIS # define GlxDriverUsesMesa YES # endif -# if GlxBuiltInGamma || GlxBuiltInTdfx || GlxBuiltInMga || GlxBuiltInI810 || GlxBuiltInR128 || GlxBuiltInFfb || GlxBuiltInSIS || GlxBuiltInMesa +# if GlxBuiltInGamma || GlxBuiltInTdfx || GlxBuiltInMga || GlxBuiltInI810 || GlxBuiltInR128 || GlxBuiltInRadeon || GlxBuiltInFfb || GlxBuiltInSIS || GlxBuiltInMesa # define GlxUseBuiltInDRIDriver YES # define DRIDynLoadDefines /**/ # else diff --git a/xc/lib/GL/Imakefile b/xc/lib/GL/Imakefile index 59af03fed..a21fef13c 100644 --- a/xc/lib/GL/Imakefile +++ b/xc/lib/GL/Imakefile @@ -31,37 +31,43 @@ NormalLintTarget($(PROFSRC)) #endif #if BuildXF86DRI && defined(i386Architecture) - GLAPI_OBJ = glx/glapi_x86.o + GLAPI_OBJ = glx/glapi_x86.o #endif - GLXOBJS = glx/?*.o - GLXUOBJS = glx/unshared/?*.o $(GLAPI_OBJ) - GLXDOBJS = glx/debugger/?*.o $(GLAPI_OBJ) - GLXPOBJS = glx/profiled/?*.o $(GLAPI_OBJ) - GLXDONES = glx/DONE + GLXOBJS = glx/?*.o + GLXUOBJS = glx/unshared/?*.o $(GLAPI_OBJ) + GLXDOBJS = glx/debugger/?*.o $(GLAPI_OBJ) + GLXPOBJS = glx/profiled/?*.o $(GLAPI_OBJ) + GLXDONES = glx/DONE #if BuildXF86DRI - DRIOBJS = dri/XF86dri.o dri/dri_glx.o - DRIUOBJS = dri/unshared/XF86dri.o dri/unshared/dri_glx.o - DRIDOBJS = dri/debugger/XF86dri.o dri/debugger/dri_glx.o - DRIPOBJS = dri/profiled/XF86dri.o dri/profiled/dri_glx.o - DRIDONES = dri/DONE - - DRMOBJS = dri/drm/?*.o - DRMUOBJS = dri/drm/unshared/?*.o - DRMDOBJS = dri/drm/debugger/?*.o - DRMPOBJS = dri/drm/profiled/?*.o - DRMDONES = dri/drm/DONE - - MESAOBJS = mesa/src/?*.o + DRIOBJS = dri/XF86dri.o dri/dri_glx.o + DRIUOBJS = dri/unshared/XF86dri.o dri/unshared/dri_glx.o + DRIDOBJS = dri/debugger/XF86dri.o dri/debugger/dri_glx.o + DRIPOBJS = dri/profiled/XF86dri.o dri/profiled/dri_glx.o + DRIDONES = dri/DONE + + DRMOBJS = dri/drm/?*.o + DRMUOBJS = dri/drm/unshared/?*.o + DRMDOBJS = dri/drm/debugger/?*.o + DRMPOBJS = dri/drm/profiled/?*.o + DRMDONES = dri/drm/DONE + + MESAOBJS = mesa/src/?*.o #ifdef i386Architecture - ASM_OBJS = mesa/src/X86/common_x86asm.o \ - mesa/src/X86/mmx_blend.o \ - mesa/src/X86/vertex.o \ - mesa/src/X86/x86a.o + ASM_OBJS = mesa/src/X86/common_x86_asm.o \ + mesa/src/X86/x86_cliptest.o \ + mesa/src/X86/x86_vertex.o \ + mesa/src/X86/x86_xform_masked2.o \ + mesa/src/X86/x86_xform_masked3.o \ + mesa/src/X86/x86_xform_masked4.o \ + mesa/src/X86/x86_xform_raw2.o \ + mesa/src/X86/x86_xform_raw3.o \ + mesa/src/X86/x86_xform_raw4.o \ + mesa/src/X86/mmx_blend.o #ifdef MesaUse3DNow - ASM_OBJS += mesa/src/X86/3dnow_norm.o \ - mesa/src/X86/3dnow_norm_raw.o \ + ASM_OBJS += mesa/src/X86/3dnow_norm_raw.o \ + mesa/src/X86/3dnow_vertex.o \ mesa/src/X86/3dnow_xform_masked1.o \ mesa/src/X86/3dnow_xform_masked2.o \ mesa/src/X86/3dnow_xform_masked3.o \ @@ -69,12 +75,11 @@ NormalLintTarget($(PROFSRC)) mesa/src/X86/3dnow_xform_raw1.o \ mesa/src/X86/3dnow_xform_raw2.o \ mesa/src/X86/3dnow_xform_raw3.o \ - mesa/src/X86/3dnow_xform_raw4.o \ - mesa/src/X86/vertex_3dnow.o + mesa/src/X86/3dnow_xform_raw4.o #endif #ifdef MesaUseKatmai - ASM_OBJS += mesa/src/X86/katmai_norm.o \ - mesa/src/X86/katmai_norm_raw.o \ + ASM_OBJS += mesa/src/X86/katmai_norm_raw.o \ + mesa/src/X86/katmai_vertex.o \ mesa/src/X86/katmai_xform_masked1.o \ mesa/src/X86/katmai_xform_masked2.o \ mesa/src/X86/katmai_xform_masked3.o \ @@ -82,8 +87,7 @@ NormalLintTarget($(PROFSRC)) mesa/src/X86/katmai_xform_raw1.o \ mesa/src/X86/katmai_xform_raw2.o \ mesa/src/X86/katmai_xform_raw3.o \ - mesa/src/X86/katmai_xform_raw4.o \ - mesa/src/X86/vertex_katmai.o + mesa/src/X86/katmai_xform_raw4.o #endif MESAOBJS = mesa/src/?*.o mesa/src/X86/?*.o @@ -119,13 +123,14 @@ XCOMM nothing GAMMAPOBJS = mesa/src/drv/gamma/profiled/?*.o GAMMADONES = mesa/src/drv/gamma/DONE - DRVOBJS = $(GAMMAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(GAMMAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(GAMMAUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(GAMMADOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(GAMMAPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(GAMMADONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/gamma + DRVSUBDIRS = mesa/src/drv/gamma + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInTdfx @@ -135,7 +140,7 @@ XCOMM nothing TDFXPOBJS = mesa/src/drv/tdfx/profiled/?*.o TDFXDONES = mesa/src/drv/tdfx/DONE - DRVOBJS = $(TDFXOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(TDFXOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(TDFXUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(TDFXDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(TDFXPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) @@ -143,7 +148,8 @@ XCOMM nothing REQUIREDLIBS += -lglide3 -ldl - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/tdfx + DRVSUBDIRS = mesa/src/drv/tdfx + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInI810 @@ -153,13 +159,14 @@ REQUIREDLIBS += -lglide3 -ldl I810POBJS = mesa/src/drv/i810/profiled/?*.o I810DONES = mesa/src/drv/i810/DONE - DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + 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) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/i810 + DRVSUBDIRS = mesa/src/drv/i810 + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInMga @@ -169,13 +176,14 @@ REQUIREDLIBS += -lglide3 -ldl MGAPOBJS = mesa/src/drv/mga/profiled/?*.o MGADONES = mesa/src/drv/mga/DONE - DRVOBJS = $(MGAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(MGAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(MGAUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(MGADOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(MGAPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(MGADONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/mga + DRVSUBDIRS = mesa/src/drv/mga + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInR128 @@ -185,13 +193,31 @@ REQUIREDLIBS += -lglide3 -ldl R128POBJS = mesa/src/drv/r128/profiled/?*.o R128DONES = mesa/src/drv/r128/DONE - DRVOBJS = $(R128OBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) - DRVUOBJS = $(R128UOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(R128DOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(R128POBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) - DRVDONES = $(R128DONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) + DRVOBJS = $(R128OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVUOBJS = $(R128UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) + DRVDOBJS = $(R128DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) + DRVPOBJS = $(R128POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) + DRVDONES = $(R128DONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/r128 + DRVSUBDIRS = mesa/src/drv/common mesa/src/drv/r128 + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) + +#elif GlxBuiltInRadeon + + RADEONOBJS = mesa/src/drv/radeon/?*.o + RADEONUOBJS = mesa/src/drv/radeon/unshared/?*.o + RADEONDOBJS = mesa/src/drv/radeon/debugger/?*.o + RADEONPOBJS = mesa/src/drv/radeon/profiled/?*.o + RADEONDONES = mesa/src/drv/radeon/DONE + + DRVOBJS = $(RADEONOBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVUOBJS = $(RADEONUOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) + DRVDOBJS = $(RADEONDOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) + DRVPOBJS = $(RADEONPOBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) + DRVDONES = $(RADEONDONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) + + DRVSUBDIRS = mesa/src/drv/common mesa/src/drv/radeon + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInFfb @@ -207,7 +233,8 @@ REQUIREDLIBS += -lglide3 -ldl DRVPOBJS = $(FFBPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(FFBDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/ffb + DRVSUBDIRS = mesa/src/drv/ffb + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInSIS @@ -217,13 +244,14 @@ REQUIREDLIBS += -lglide3 -ldl SISPOBJS = mesa/src/drv/sis/profiled/?*.o SISDONES = mesa/src/drv/sis/DONE - DRVOBJS = $(SISOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(SISOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(SISUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(SISDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(SISPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(SISDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/sis + DRVSUBDIRS = mesa/src/drv/sis + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInMesa @@ -333,6 +361,7 @@ XCOMM libGL has now been made, continue with building the drivers. !GlxBuiltInI810 && \ !GlxBuiltInMga && \ !GlxBuiltInR128 && \ + !GlxBuiltInRadeon && \ !GlxBuiltInFfb && \ !GlxBuiltInSIS && \ !GlxBuiltInMesa diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index b01e433ff..f8fb6120f 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -23,7 +23,10 @@ DRIVER += common mga DRIVER += common i810 #endif #if GlxBuiltInR128 -DRIVER += r128 +DRIVER += common r128 +#endif +#if GlxBuiltInRadeon +DRIVER += common radeon #endif #if GlxBuiltInFfb DRIVER += ffb @@ -43,6 +46,7 @@ SUBDIRS += common SUBDIRS += mga SUBDIRS += i810 SUBDIRS += r128 +SUBDIRS += radeon SUBDIRS += sis #elif defined(AlphaArchitecture) SUBDIRS += gamma @@ -52,6 +56,7 @@ SUBDIRS += tdfx SUBDIRS += common SUBDIRS += mga SUBDIRS += r128 +SUBDIRS += radeon #elif defined(SparcArchitecture) SUBDIRS += ffb #endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile new file mode 100644 index 000000000..8675ca88b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile @@ -0,0 +1,379 @@ +XCOMM $XFree86$ + +#include + +#define DoNormalLib NormalLibGlx +#define DoSharedLib SharedLibGlx +#define DoExtraLib SharedLibGlx +#define DoDebugLib DebugLibGlx +#define DoProfileLib ProfileLibGlx + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + +#ifdef i386Architecture +#ifdef MesaUse3DNow + 3DNOW_DEFS = -DUSE_3DNOW_ASM +#endif +#ifdef MesaUseKatmai + KATMAI_DEFS = -DUSE_KATMAI_ASM +#endif + ASM_DEFINES = -DUSE_X86_ASM -DUSE_MMX_ASM $(3DNOW_DEFS) $(KATMAI_DEFS) +#endif + +#if BuildXF86DRI + DRI_DEFINES = GlxDefines -DDRIVERTS + DRI_INCLUDES = -I../../../../dri \ + -I../../../../glx \ + -I../../../dri \ + -I$(TOP)/include \ + -I$(TOP)/include/GL \ + -I$(XF86OSSRC) \ + -I$(XF86COMSRC) \ + -I$(SERVERSRC)/GL/dri \ + -I$(XF86DRIVERSRC)/ati \ + -I../../../include \ + -I../.. \ + -I../../X \ + -I../common +#endif + +MESA_INCLUDES = -I. -I.. -I../../include \ + -I../../../../dri/drm + + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFINES) + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + + RADEONSRCS = radeon_context.c \ + radeon_dd.c \ + radeon_fastpath.c \ + radeon_eltpath.c \ + radeon_ioctl.c \ + radeon_pipeline.c \ + radeon_screen.c \ + radeon_span.c \ + radeon_state.c \ + radeon_tex.c \ + radeon_tris.c \ + radeon_vb.c \ + radeon_xmesa.c + + RADEONOBJS = radeon_context.o \ + radeon_dd.o \ + radeon_fastpath.o \ + radeon_eltpath.o \ + radeon_ioctl.o \ + radeon_pipeline.o \ + radeon_screen.o \ + radeon_span.o \ + radeon_state.o \ + radeon_tex.o \ + radeon_tris.o \ + radeon_vb.o \ + radeon_xmesa.o + +#if !GlxUseBuiltInDRIDriver + 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 \ + ../../../../dri/drm/xf86drmRadeon.c + + DRMOBJS = ../../../../dri/drm/xf86drm.o \ + ../../../../dri/drm/xf86drmHash.o \ + ../../../../dri/drm/xf86drmRandom.o \ + ../../../../dri/drm/xf86drmSL.o \ + ../../../../dri/drm/xf86drmRadeon.o + + MESASRCS = ../../aatriangle.c \ + ../../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.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.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 \ + ../../texutil.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 + + MESAOBJS = ../../aatriangle.o \ + ../../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 \ + ../../pixeltex.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 \ + ../../texutil.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/common_x86.c \ + ../../X86/common_x86_asm.S \ + ../../X86/x86.c \ + ../../X86/x86_cliptest.S \ + ../../X86/x86_vertex.S \ + ../../X86/x86_xform_masked2.S \ + ../../X86/x86_xform_masked3.S \ + ../../X86/x86_xform_masked4.S \ + ../../X86/x86_xform_raw2.S \ + ../../X86/x86_xform_raw3.S \ + ../../X86/x86_xform_raw4.S + + X86_OBJS = ../../X86/common_x86.o \ + ../../X86/common_x86_asm.o \ + ../../X86/x86.o \ + ../../X86/x86_cliptest.o \ + ../../X86/x86_vertex.o \ + ../../X86/x86_xform_masked2.o \ + ../../X86/x86_xform_masked3.o \ + ../../X86/x86_xform_masked4.o \ + ../../X86/x86_xform_raw2.o \ + ../../X86/x86_xform_raw3.o \ + ../../X86/x86_xform_raw4.o + + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o + +#ifdef MesaUse3DNow + 3DNOW_SRCS = ../../X86/3dnow.c \ + ../../X86/3dnow_norm_raw.S \ + ../../X86/3dnow_vertex.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 + + 3DNOW_OBJS = ../../X86/3dnow.o \ + ../../X86/3dnow_norm_raw.o \ + ../../X86/3dnow_vertex.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 +#endif + +#ifdef MesaUseKatmai + KATMAI_SRCS = ../../X86/katmai.c \ + ../../X86/katmai_norm_raw.S \ + ../../X86/katmai_vertex.S \ + ../../X86/katmai_xform_masked1.S \ + ../../X86/katmai_xform_masked2.S \ + ../../X86/katmai_xform_masked3.S \ + ../../X86/katmai_xform_masked4.S \ + ../../X86/katmai_xform_raw1.S \ + ../../X86/katmai_xform_raw2.S \ + ../../X86/katmai_xform_raw3.S \ + ../../X86/katmai_xform_raw4.S + + KATMAI_OBJS = ../../X86/katmai.o \ + ../../X86/katmai_norm_raw.o \ + ../../X86/katmai_vertex.o \ + ../../X86/katmai_xform_masked1.o \ + ../../X86/katmai_xform_masked2.o \ + ../../X86/katmai_xform_masked3.o \ + ../../X86/katmai_xform_masked4.o \ + ../../X86/katmai_xform_raw1.o \ + ../../X86/katmai_xform_raw2.o \ + ../../X86/katmai_xform_raw3.o \ + ../../X86/katmai_xform_raw4.o +#endif +#endif +#endif + +#ifdef GlxSoProf + LOSRCS = ../../../../lowpc.c + HISRCS = ../../../../highpc.c + + LOOBJS = ../../../../lowpc.o + HIOBJS = ../../../../highpc.o +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) $(KATMAI_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) $(KATMAI_OBJS) + + COMMONSRCS = ../common/mm.c ../common/hwlog.c + COMMONOBJS = ../common/mm.o ../common/hwlog.o + + SRCS = $(LOSRCS) $(DRISRCS) $(DRMSRCS) $(MESASRCS) \ + $(ASMSRCS) $(COMMONSRCS) $(RADEONSRCS) $(HISRCS) + OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) \ + $(ASMOBJS) $(COMMONOBJS) $(RADEONOBJS) $(HIOBJS) + +REQUIREDLIBS += MathLibrary +#if !GlxBuiltInRadeon +REQUIREDLIBS += -L../../../.. -lGL +#endif + + +#if !GlxUseBuiltInDRIDriver +#undef DoNormalLib NormalLibGlx +#undef DoExtraLib SharedLibGlx +#undef DoDebugLib DebugLibGlx +#undef DoProfileLib ProfileLibGlx +#endif + +#include + +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +#if !GlxUseBuiltInDRIDriver +LIBNAME = radeon_dri.so +ALL_OBJS = $(OBJS) +ALL_DEPS = DONE +SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) + +#ifdef GlxSoProf +SOPROF_LIBNAME = _radeon_dri_p +NormalDepLibraryTarget($(SOPROF_LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallLibrary($(SOPROF_LIBNAME),$(MODULEDIR)/dri) +#endif +#endif + +DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c new file mode 100644 index 000000000..086fd4a59 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -0,0 +1,237 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_dd.h" +#include "radeon_state.h" +#include "radeon_span.h" +#include "radeon_tex.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "context.h" +#include "simple_list.h" +#include "mem.h" + +/* Create the device specific context */ +GLboolean radeonCreateContext(Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv) +{ + radeonContextPtr radeon_ctx; + radeonScreenPtr radeon_scrn; + GLcontext *ctx = driContextPriv->mesaContext; + int i; + char *v; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + + radeon_ctx = (radeonContextPtr)Xcalloc(1, sizeof(*radeon_ctx)); + if (!radeon_ctx) return GL_FALSE; + + /* Initialize radeonContext */ + radeon_ctx->glCtx = ctx; + radeon_ctx->display = dpy; + + radeon_ctx->driContext = driContextPriv; + radeon_ctx->driScreen = sPriv; + radeon_ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + + radeon_ctx->hHWContext = driContextPriv->hHWContext; + radeon_ctx->driFd = sPriv->fd; + radeon_ctx->driHwLock = &sPriv->pSAREA->lock; + + radeon_scrn = radeon_ctx->radeonScreen = (radeonScreenPtr)(sPriv->private); + + radeon_ctx->sarea = (RADEONSAREAPriv *)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); + + radeon_ctx->CurrentTexObj[0] = NULL; + radeon_ctx->CurrentTexObj[1] = NULL; + make_empty_list(&radeon_ctx->SwappedOut); + for (i = 0; i < radeon_scrn->NRTexHeaps; i++) { + make_empty_list(&radeon_ctx->TexObjList[i]); + radeon_ctx->texHeap[i] = mmInit(0, radeon_scrn->texSize[i]); + radeon_ctx->lastTexAge[i] = -1; + } + radeon_ctx->lastTexHeap = radeon_scrn->NRTexHeaps; + + radeon_ctx->BufferSize = glVisual->DepthBits; + radeon_ctx->DepthSize = glVisual->DepthBits; + radeon_ctx->StencilSize = glVisual->StencilBits; + + radeon_ctx->useFastPath = GL_FALSE; + radeon_ctx->lod_bias = 0x3f; + + radeon_ctx->num_verts = 0; + radeon_ctx->vert_buf = NULL; + + radeon_ctx->BlitRects = (drmRadeonBlitRectPtr) + MALLOC( RADEON_MAX_BLIT_BUFFERS * sizeof(drmRadeonBlitRectRec) ); + radeon_ctx->BlitBuffers = (drmBufPtr *) + MALLOC( RADEON_MAX_BLIT_BUFFERS * sizeof(drmBufPtr) ); + radeon_ctx->numBlitBuffers = 0; + + radeon_ctx->CPbuf = (CARD32 *)MALLOC(sizeof(*radeon_ctx->CPbuf) * + radeon_scrn->ringEntries); + radeon_ctx->CPcount = 0; + + if ((v = getenv("LIBGL_CP_TIMEOUT"))) + radeon_ctx->CPtimeout = strtoul(v, NULL, 10); + else + radeon_ctx->CPtimeout = (RADEON_DEFAULT_TOTAL_CP_TIMEOUT / + RADEON_DEFAULT_CP_TIMEOUT); + if (radeon_ctx->CPtimeout <= 0) radeon_ctx->CPtimeout = 1; + + /* Initialize GLcontext */ + ctx->DriverCtx = (void *)radeon_ctx; + + radeonDDInitExtensions(ctx); + + radeonDDInitDriverFuncs(ctx); + radeonDDInitIoctlFuncs(ctx); + radeonDDInitStateFuncs(ctx); + radeonDDInitSpanFuncs(ctx); + radeonDDInitTextureFuncs(ctx); + + ctx->Driver.TriangleCaps = (DD_TRI_CULL + | DD_TRI_LIGHT_TWOSIDE + | DD_TRI_OFFSET); + + /* Ask Mesa to clip fog coordinates for us + */ + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; + + /* Reset Mesa's current 2D texture pointers to the driver's textures */ + ctx->Shared->DefaultD[2][0].DriverData = NULL; + ctx->Shared->DefaultD[2][1].DriverData = NULL; + + /* KW: Set the maximum texture size small enough that we can + * guarentee that both texture units can bind a maximal texture + * and have them both in on-card memory at once. (Kevin or + * Gareth: Please check these numbers are OK) + */ + if (radeon_scrn->texSize[0] < 2*1024*1024) { + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = 1 << 8; + } else if (radeon_scrn->texSize[0] < 8*1024*1024) { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = 1 << 9; + } else { + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = 1 << 10; + } + + ctx->Const.MaxTextureUnits = 2; + +#if ENABLE_PERF_BOXES + if (getenv("LIBGL_PERFORMANCE_BOXES")) + radeon_ctx->boxes = 1; + else + radeon_ctx->boxes = 0; +#endif + + /* If Mesa has current a vertex buffer, make sure the driver's VB + data is up to date */ + if (ctx->VB) radeonDDRegisterVB(ctx->VB); + + /* Register the fast path */ + if (ctx->NrPipelineStages) + ctx->NrPipelineStages = + radeonDDRegisterPipelineStages(ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages); + + radeonDDInitState(radeon_ctx); + + driContextPriv->driverPrivate = (void *)radeon_ctx; + + return GL_TRUE; +} + +/* Destroy the device specific context */ +void radeonDestroyContext(radeonContextPtr radeon_ctx) +{ + if (radeon_ctx) { + radeonTexObjPtr t, next_t; + int i; + + FREE( radeon_ctx->BlitRects ); + FREE( radeon_ctx->BlitBuffers ); + FREE( radeon_ctx->CPbuf ); + + for (i = 0; i < radeon_ctx->radeonScreen->NRTexHeaps; i++) { + foreach_s (t, next_t, &radeon_ctx->TexObjList[i]) + radeonDestroyTexObj(radeon_ctx, t); + } + + foreach_s (t, next_t, &radeon_ctx->SwappedOut) + radeonDestroyTexObj(radeon_ctx, t); + + Xfree(radeon_ctx); + } + +#if 0 + glx_fini_prof(); +#endif +} + +/* Load the device specific context into the hardware. The actual + setting of the hardware state is done in the radeonUpdateHWState(). */ +radeonContextPtr radeonMakeCurrent(radeonContextPtr oldCtx, + radeonContextPtr newCtx, + __DRIdrawablePrivate *dPriv) +{ + if (oldCtx) { + if (!RADEONCP_USE_RING_BUFFER(newCtx->radeonScreen->CPMode)) + newCtx->dirty |= RADEON_REQUIRE_QUIESCENCE; + if (oldCtx != newCtx) { + newCtx->new_state |= RADEON_NEW_CONTEXT; + newCtx->dirty = RADEON_UPLOAD_ALL; + } + if (oldCtx->driDrawable != dPriv) { + newCtx->new_state |= RADEON_NEW_WINDOW; + } + } else { + newCtx->new_state |= RADEON_NEW_CONTEXT; + newCtx->dirty = RADEON_UPLOAD_ALL; + } + + newCtx->driDrawable = dPriv; + + return newCtx; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h new file mode 100644 index 000000000..80536c88c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -0,0 +1,269 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_CONTEXT_H_ +#define _RADEON_CONTEXT_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include + +#include "dri_mesaint.h" +#include "dri_tmm.h" + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +#include "types.h" + +#include "radeon_sarea.h" +#include "radeon_reg.h" + +struct radeon_context; +typedef struct radeon_context radeonContextRec; +typedef struct radeon_context *radeonContextPtr; + +#include "radeon_lock.h" +#include "radeon_texobj.h" +#include "radeon_screen.h" + +/* Flags for what context state needs to be updated */ +#define RADEON_NEW_ALPHA 0x0001 +#define RADEON_NEW_DEPTH 0x0002 +#define RADEON_NEW_FOG 0x0004 +#define RADEON_NEW_CLIP 0x0008 +#define RADEON_NEW_CULL 0x0010 +#define RADEON_NEW_MASKS 0x0020 +#define RADEON_NEW_RENDER 0x0040 +#define RADEON_NEW_WINDOW 0x0080 +#define RADEON_NEW_TEXTURE 0x0100 +#define RADEON_NEW_CONTEXT 0x0200 +#define RADEON_NEW_ALL 0x03ff + +/* Flags for software fallback cases */ +#define RADEON_FALLBACK_TEXTURE 0x0001 +#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +#define RADEON_FALLBACK_READ_BUFFER 0x0004 +#define RADEON_FALLBACK_STENCIL 0x0008 +#define RADEON_FALLBACK_RENDER_MODE 0x0010 +#define RADEON_FALLBACK_MULTIDRAW 0x0020 +#define RADEON_FALLBACK_LOGICOP 0x0040 + +typedef void (*radeon_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); + +struct radeon_elt_tab { + void (*emit_unclipped_verts)( struct vertex_buffer *VB ); + + void (*build_tri_verts)( radeonContextPtr radeon_ctx, + struct vertex_buffer *VB, + GLfloat *O, GLuint *elt ); + + void (*interp)( GLfloat t, GLfloat *O, + const GLfloat *I, const GLfloat *J ); + + void (*project_and_emit_verts)( radeonContextPtr radeon_ctx, + const GLfloat *verts, + GLuint *elts, + int nr ); +}; + +struct radeon_context { + GLcontext *glCtx; /* Mesa context */ + + /* Driver and hardware state management + */ + GLuint new_state; + GLuint dirty; /* Hardware state to be updated */ + radeon_context_regs_t setup; + + GLuint vertsize; + CARD32 vc_format; + GLfloat depth_scale; + + CARD32 Color; /* Current draw color */ + CARD32 ClearColor; /* Color used to clear color buffer */ + CARD32 ClearDepth; /* Value used to clear depth buffer */ + CARD32 ClearStencil; /* Value used to clear stencil */ + + /* Map GL texture units onto hardware + */ + GLint multitex; + GLint tmu_source[2]; + GLint tex_dest[2]; + GLuint blend_flags; + GLuint envcolor; + GLint lod_bias; + + /* Texture object bookkeeping + */ + radeonTexObjPtr CurrentTexObj[2]; + radeonTexObj TexObjList[RADEON_NR_TEX_HEAPS]; + radeonTexObj SwappedOut; + memHeap_t *texHeap[RADEON_NR_TEX_HEAPS]; + GLint lastTexAge[RADEON_NR_TEX_HEAPS]; + GLint lastTexHeap; + + /* Current rendering state, fallbacks + */ + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + + CARD32 IndirectTriangles; + CARD32 Fallback; + + /* Fast path + */ + GLuint useFastPath; + GLuint SetupIndex; + GLuint SetupDone; + GLuint RenderIndex; + radeon_interp_func interp; + + /* Vertex buffers + */ + GLuint num_verts; + drmBufPtr vert_buf; + + /* Elt path + */ + drmBufPtr elt_buf, retained_buf; + GLushort *first_elt, *next_elt; + GLfloat *next_vert; + GLushort next_vert_index; + GLushort first_vert_index; + struct radeon_elt_tab *elt_tab; + GLfloat device_matrix[16]; + + /* Texture blit buffers + */ + drmRadeonBlitRectPtr BlitRects; + drmBufPtr *BlitBuffers; + GLint numBlitBuffers; + + /* CP command packets + */ + CARD32 *CPbuf; /* buffer to submit to CP */ + GLuint CPcount; /* number of dwords in CPbuf */ + GLint CPtimeout; /* number of times to loop + before exiting */ + + /* Visual, drawable, cliprect and scissor information + */ + GLint BufferSize; /* Bits in color buffer */ + GLint DepthSize; /* Bits in depth buffer */ + GLint StencilSize; /* Bits in stencil buffer */ + + GLenum DrawBuffer; /* Optimize draw buffer update */ + GLint drawOffset, drawPitch; + GLint drawX, drawY; + GLint readOffset, readPitch; + GLint readX, readY; + + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + + GLuint scissor; + XF86DRIClipRectRec ScissorRect; /* Current software scissor */ + + /* Mirrors of some DRI state + */ + Display *display; /* X server display */ + + __DRIcontextPrivate *driContext; /* DRI context */ + __DRIscreenPrivate *driScreen; /* DRI screen */ + __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + RADEONSAREAPriv *sarea; /* Private SAREA data */ + + /* Performance counters + */ + GLuint boxes; /* Draw performance boxes */ + GLuint hardwareWentIdle; + GLuint c_clears; + GLuint c_drawWaits; + GLuint c_textureSwaps; + GLuint c_textureBytes; + GLuint c_vertexBuffers; +}; + +#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx)) + +#define RADEON_MESACTX(radeon_ctx) ((radeon_ctx)->glCtx) +#define RADEON_DRIDRAWABLE(radeon_ctx) ((radeon_ctx)->driDrawable) +#define RADEON_DRISCREEN(radeon_ctx) ((radeon_ctx)->radeonScreen->driScreen) + + +extern GLboolean radeonCreateContext(Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv); +extern void radeonDestroyContext(radeonContextPtr radeon_ctx); +extern radeonContextPtr radeonMakeCurrent(radeonContextPtr oldCtx, + radeonContextPtr newCtx, + __DRIdrawablePrivate *dPriv); + + +/* ================================================================ + * Debugging: + */ +#define DEBUG 0 +#define DEBUG_LOCKING 0 +#define ENABLE_PERF_BOXES 0 + +#if DEBUG +extern int RADEON_DEBUG; +#else +#define RADEON_DEBUG 0 +#endif + +#define DEBUG_ALWAYS_SYNC 0x01 +#define DEBUG_VERBOSE_API 0x02 +#define DEBUG_VERBOSE_MSG 0x04 +#define DEBUG_VERBOSE_LRU 0x08 +#define DEBUG_VERBOSE_DRI 0x10 +#define DEBUG_VERBOSE_IOCTL 0x20 +#define DEBUG_VERBOSE_2D 0x40 + +#endif +#endif /* _RADEON_CONTEXT_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c new file mode 100644 index 000000000..288acf705 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c @@ -0,0 +1,206 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" +#include "radeon_dd.h" + +#include "extensions.h" +#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM) +#include "X86/common_x86_asm.h" +#endif + +#define RADEON_DATE "20001106" + +/* Return the current color buffer size */ +static void radeonDDGetBufferSize( GLcontext *ctx, + GLuint *width, GLuint *height ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + *width = radeon_ctx->driDrawable->w; + *height = radeon_ctx->driDrawable->h; +} + +/* Return various strings for glGetString() */ +static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + static GLubyte buffer[128]; + + switch ( name ) { + case GL_VENDOR: + return "VA Linux Systems, Inc."; + + case GL_RENDERER: + sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE ); + + /* Append any chipset-specific information. + */ + + /* Append any AGP-specific information. + */ + switch ( radeon_ctx->radeonScreen->AGPMode ) { + case 1: + strncat( buffer, " AGP 1x", 7 ); + break; + case 2: + strncat( buffer, " AGP 2x", 7 ); + break; + case 4: + strncat( buffer, " AGP 4x", 7 ); + break; + } + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( gl_x86_cpu_features ) { + strncat( buffer, " x86", 4 ); + } +#endif +#ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + strncat( buffer, "/3DNow!", 7 ); + } +#endif +#ifdef USE_KATMAI_ASM + if ( cpu_has_xmm ) { + strncat( buffer, "/SSE", 4 ); + } +#endif + return buffer; + + default: + return NULL; + } +} + +/* Send all commands to the hardware. If vertex buffers or indirect + * buffers are in use, then we need to make sure they are sent to the + * hardware. All commands that are normally sent to the ring are + * already considered `flushed'. + */ +static void radeonDDFlush( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + +#if ENABLE_PERF_BOXES + if ( radeon_ctx->boxes ) { + LOCK_HARDWARE( radeon_ctx ); + radeonPerformanceBoxesLocked( radeon_ctx ); + UNLOCK_HARDWARE( radeon_ctx ); + } + + /* Log the performance counters if necessary */ + radeonPerformanceCounters( radeon_ctx ); +#endif +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +static void radeonDDFinish( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + radeon_ctx->c_drawWaits++; +#endif + + radeonDDFlush( ctx ); + radeonWaitForIdle( radeon_ctx ); +} + +/* Return various parameters requested by Mesa (this is deprecated) */ +static GLint radeonDDGetParameteri( const GLcontext *ctx, GLint param ) +{ + switch (param) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + return 0; + } +} + +/* Initialize the extensions supported by this driver */ +void radeonDDInitExtensions( GLcontext *ctx ) +{ + /* FIXME: Are there other extensions to enable/disable??? */ + gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); + gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); + gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); + gl_extensions_disable( ctx, "ARB_imaging" ); + gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); + gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + + if ( getenv( "LIBGL_NO_MULTITEXTURE" ) ) + gl_extensions_disable( ctx, "GL_ARB_multitexture" ); + + gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); + gl_extensions_disable( ctx, "GL_SGI_color_table" ); + gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); + gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); + gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); + gl_extensions_disable( ctx, "GL_EXT_convolution" ); +} + +/* Initialize the driver's misc functions */ +void radeonDDInitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = radeonDDGetBufferSize; + ctx->Driver.GetString = radeonDDGetString; + ctx->Driver.Finish = radeonDDFinish; + ctx->Driver.Flush = radeonDDFlush; + + ctx->Driver.Error = NULL; + ctx->Driver.GetParameteri = radeonDDGetParameteri; + + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; + + ctx->Driver.RegisterVB = radeonDDRegisterVB; + ctx->Driver.UnregisterVB = radeonDDUnregisterVB; + ctx->Driver.BuildPrecalcPipeline = radeonDDBuildPrecalcPipeline; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h new file mode 100644 index 000000000..17560796d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h @@ -0,0 +1,46 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_DD_H_ +#define _RADEON_DD_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonDDInitExtensions(GLcontext *ctx); +extern void radeonDDInitDriverFuncs(GLcontext *ctx); + +#endif +#endif /* _RADEON_DD_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c new file mode 100644 index 000000000..29a49c0a3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c @@ -0,0 +1,562 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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 + * Kevin E. Martin + * Gareth Hughes + * + */ + +/* + * GLX Hardware Device Driver for Matrox G400 + * 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 + +#include "radeon_context.h" +#include "radeon_pipeline.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_state.h" +#include "radeon_vb.h" + +#include "types.h" +#include "enums.h" +#include "cva.h" +#include "vertices.h" +#include "mmath.h" +#include "xform.h" + +/* Always use a full-sized stride for vertices. [FIXME] + * Stride in the buffers must be a quadword multiple. + * + * GTH: Vertex buffers must be multiples of 32K, otherwise the 10-dword + * stride multitextured vertices won't fit in evenly. 8-dword vertices + * are fine in any case. + */ +#define CLIP_STRIDE 10 + +#define MAX_ELT (0x3fff + 0x5) + +static void fire_elts( radeonContextPtr radeon_ctx ) +{ + int vertsize = radeon_ctx->vertsize; + int offset, adjust; + + LOCK_HARDWARE( radeon_ctx ); + + fprintf( stderr, "\n%s: elt=%p ret=%p vs=%d\n", + __FUNCTION__, radeon_ctx->elt_buf, + radeon_ctx->retained_buf, vertsize ); + + /* Fire queued elements and discard that buffer if its contents + * won't be referenced by future elements. + */ + if ( radeon_ctx->elt_buf ) + { + GLuint retain = (radeon_ctx->elt_buf == radeon_ctx->retained_buf); + + if ( radeon_ctx->first_elt != radeon_ctx->next_elt ) { + radeonFireEltsLocked( radeon_ctx, + ((GLuint)radeon_ctx->first_elt - + (GLuint)radeon_ctx->elt_buf->address), + ((GLuint)radeon_ctx->next_elt - + (GLuint)radeon_ctx->elt_buf->address), + !retain ); + } else if ( !retain ) { + radeonReleaseBufLocked( radeon_ctx, radeon_ctx->elt_buf ); + } + + radeon_ctx->elt_buf = 0; + } + else if ( radeon_ctx->vert_buf ) + { + radeonFlushVerticesLocked( radeon_ctx ); + } + + radeonGetEltBufLocked( radeon_ctx ); + + UNLOCK_HARDWARE( radeon_ctx ); + + switch ( vertsize ) { + case 8: + radeon_ctx->next_vert = + (GLfloat *)((GLuint)radeon_ctx->elt_buf->address + + radeon_ctx->elt_buf->total - 8 * sizeof(GLfloat)); + + radeon_ctx->next_vert_index = + (GLushort)(((radeon_ctx->elt_buf->idx + 1) * + RADEON_BUFFER_SIZE / (8 * sizeof(GLuint))) - 1); + break; + + case 10: + fprintf( stderr, "*** multitextured elt path not done! ***\n" ); + exit( -1 ); + break; + } + + radeon_ctx->first_elt = radeon_ctx->next_elt = (GLushort *) + ((GLubyte *)radeon_ctx->elt_buf->address + RADEON_INDEX_PRIM_OFFSET); + + + fprintf( stderr, "new elt=%p idx=%d tot=%d next=%p idx=%d\n\n", + radeon_ctx->elt_buf, radeon_ctx->elt_buf->idx, + radeon_ctx->elt_buf->total, radeon_ctx->next_vert, + radeon_ctx->next_vert_index ); +} + + +static void release_bufs( radeonContextPtr radeon_ctx ) +{ + fprintf( stderr, "%s\n", __FUNCTION__ ); + + if ( radeon_ctx->retained_buf && radeon_ctx->retained_buf + != radeon_ctx->elt_buf ) + { + LOCK_HARDWARE( radeon_ctx ); + if ( radeon_ctx->first_elt != radeon_ctx->next_elt ) { + radeonFireEltsLocked( radeon_ctx, + ((GLuint)radeon_ctx->first_elt - + (GLuint)radeon_ctx->elt_buf->address), + ((GLuint)radeon_ctx->next_elt - + (GLuint)radeon_ctx->elt_buf->address), + 0 ); + + radeon_ctx->first_elt = radeon_ctx->next_elt; + } + + radeonReleaseBufLocked( radeon_ctx, radeon_ctx->retained_buf ); + UNLOCK_HARDWARE( radeon_ctx ); + } + + radeon_ctx->retained_buf = 0; +} + + + + +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) + + +#define INTERP_RGBA(t, out, a, b) { \ + int i; \ + for (i = 0; i < 4; i++) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \ + GLfloat fo = LINTERP(t, fa, fb); \ + FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \ + } \ +} + + +#define CLIP(SGN,V,PLANE) \ +if (mask & PLANE) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]]; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + for (i = n = 0 ; i < nr ; i++) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i]; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert]; \ + outdata[n++] = next_vert++; \ + \ + if (NEGATIVE(dpI)) { \ + GLfloat t = dpI / (dpI - dpJ); \ + interp(t, O, I, J); \ + } \ + else \ + { \ + GLfloat t = dpJ / (dpJ - dpI); \ + interp(t, O, J, I); \ + } \ + } \ + \ + if (!NEGATIVE(dpI)) \ + outdata[n++] = elt_i; \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return; \ +} + + +static void radeon_tri_clip( radeonContextPtr radeon_ctx, + struct vertex_buffer *VB, + GLuint *elt, + GLubyte mask ) +{ + struct radeon_elt_tab *tab = radeon_ctx->elt_tab; + radeon_interp_func interp = tab->interp; + int vertsize = radeon_ctx->vertsize; + GLuint inlist[2][VB_MAX_CLIPPED_VERTS]; + GLuint in = 0; + GLuint n = 3, next_vert = 3; + GLuint i; + GLfloat verts[VB_MAX_CLIPPED_VERTS][CLIP_STRIDE]; + + /* Build temporary vertices in clipspace. This is the potential + * downside to this path. + */ + tab->build_tri_verts( radeon_ctx, VB, (GLfloat *)verts, elt ); + + inlist[0][0] = 0; + inlist[0][1] = 1; + inlist[0][2] = 2; + + CLIP(-,0,CLIP_RIGHT_BIT); + CLIP(+,0,CLIP_LEFT_BIT); + CLIP(-,1,CLIP_TOP_BIT); + CLIP(+,1,CLIP_BOTTOM_BIT); + CLIP(-,2,CLIP_FAR_BIT); + CLIP(+,2,CLIP_NEAR_BIT); + + + { + GLuint *out = inlist[in]; + GLuint space = + ((GLuint)radeon_ctx->next_vert - (GLuint)radeon_ctx->next_elt); + + if ( space < n * (vertsize + 2) * sizeof(GLuint) ) { + fire_elts( radeon_ctx ); + } + + /* Project the new vertices and emit to dma buffers. Translate + * out values to physical addresses for setup dma. + */ + tab->project_and_emit_verts( radeon_ctx, (GLfloat *)verts, out, n ); + + /* Convert the planar polygon to a list of triangles and emit to + * elt buffers. + */ + for (i = 2 ; i < n ; i++) { + radeon_ctx->next_elt[0] = (GLushort) out[0]; + radeon_ctx->next_elt[1] = (GLushort) out[i-1]; + radeon_ctx->next_elt[2] = (GLushort) out[i]; + radeon_ctx->next_elt += 3; + } + } +} + + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ + +#define INIT(x) + +#if 1 +#define TRI_THRESHOLD (3 * sizeof(GLuint)) +#else +#define TRI_THRESHOLD (16230) +#endif + +#define UNCLIPPED_VERT(x) (GLushort)(radeon_ctx->first_vert_index - x) + +#define TRIANGLE( e2, e1, e0 ) \ +do { \ + fprintf( stderr, " nv=%p ne=%p space=%d thresh=%d %d\n", \ + radeon_ctx->next_vert, radeon_ctx->next_elt, \ + (GLuint)radeon_ctx->next_vert - \ + (GLuint)radeon_ctx->next_elt, TRI_THRESHOLD, \ + ( (GLuint)radeon_ctx->next_vert - \ + (GLuint)radeon_ctx->next_elt < TRI_THRESHOLD ) ); \ + if ( (GLuint)radeon_ctx->next_vert - \ + (GLuint)radeon_ctx->next_elt < TRI_THRESHOLD ) { \ + fprintf( stderr, " firing elts...\n" ); \ + fire_elts( radeon_ctx ); \ + } \ + radeon_ctx->next_elt[0] = UNCLIPPED_VERT( e2 ); \ + radeon_ctx->next_elt[1] = UNCLIPPED_VERT( e1 ); \ + radeon_ctx->next_elt[2] = UNCLIPPED_VERT( e0 ); \ + if ( 1 ) \ + fprintf( stderr, " tri %d,%d,%d -> %hd,%hd,%hd\n", \ + e2, e1, e0, radeon_ctx->next_elt[0], \ + radeon_ctx->next_elt[1], radeon_ctx->next_elt[2]); \ + radeon_ctx->next_elt += 3; \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask = mask[e2] | mask[e1] | mask[e0]; \ + if ( ormask == 0 ) { \ + TRIANGLE( e2, e1, e0 ); \ + } else if ( (mask[e2] & mask[e1] & mask[e0]) == 0 ) { \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + radeon_tri_clip( radeon_ctx, VB, out, ormask ); \ + } \ +} while (0) + +#define LOCAL_VARS \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( VB->ctx ); \ + GLuint *elt = VB->EltPtr->data; \ + GLuint out[VB_MAX_CLIPPED_VERTS]; \ + GLubyte *mask = VB->ClipMask; \ + (void) mask; (void) out; (void) elt; (void) radeon_ctx; + + + +#define RENDER_POINTS( start, count ) +#define RENDER_LINE( i1, i0 ) +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parity) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ) + +#define TAG(x) radeon_##x##_elt +#include "render_tmp.h" + + + +#define LOCAL_VARS \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( VB->ctx ); \ + GLuint *elt = VB->EltPtr->data; \ + (void) elt; (void) radeon_ctx; + +#define RENDER_POINTS( start, count ) +#define RENDER_LINE( i1, i0 ) +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parity) e2 = elt[i1], e1 = elt[i2]; \ + TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i0, pv ) \ + TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + TRIANGLE( elt[i2], elt[i1], elt[i0] ) + +#define TAG(x) radeon_##x##_elt_unclipped +#include "render_tmp.h" + + + + +static void refresh_projection_matrix( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + GLmatrix *mat = &ctx->Viewport.WindowMap; + GLfloat *m = radeon_ctx->device_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY] + radeon_ctx->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * radeon_ctx->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * radeon_ctx->depth_scale; +} + +#define CLIP_UBYTE_B 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_R 2 +#define CLIP_UBYTE_A 3 + + +#define TYPE (0) +#define TAG(x) x +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "radeon_elttmp.h" + +#define TYPE (RADEON_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "radeon_elttmp.h" + + +/* Very sparsely popluated array - fix the indices. + */ +static struct radeon_elt_tab radeonEltTab[0x80]; + +void radeonDDEltPathInit( void ) +{ + radeon_render_init_elt(); + radeon_render_init_elt_unclipped(); + + radeon_init_eltpath( &radeonEltTab[0] ); + radeon_init_eltpath_RGBA( &radeonEltTab[RADEON_RGBA_BIT] ); + radeon_init_eltpath_TEX0( &radeonEltTab[RADEON_TEX0_BIT] ); + radeon_init_eltpath_RGBA_TEX0( &radeonEltTab[RADEON_RGBA_BIT | + RADEON_TEX0_BIT] ); + radeon_init_eltpath_TEX0_TEX1( &radeonEltTab[RADEON_TEX0_BIT | + RADEON_TEX1_BIT] ); + radeon_init_eltpath_RGBA_TEX0_TEX1( &radeonEltTab[RADEON_RGBA_BIT | + RADEON_TEX0_BIT | + RADEON_TEX1_BIT] ); +} + +#define VALID_SETUP (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) + + + +/* Use a temporary array for device coordinates, so that we can easily + * tap into existing mesa assembly. Otherwise consider emitting + * device coordinates to dma buffers directly from the project/cliptest + * routine. (requires output stride, potential loss of writecombining + * efficiency?) + * + * This path is a lot closer to the standard vertex path in the + * initial stages than the original fastpath. A slightly more optimal + * path could be constructed, but would require us to write new + * assembly. + */ +void radeonDDEltPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + struct radeon_elt_tab *tab = + &radeonEltTab[radeon_ctx->SetupIndex & VALID_SETUP]; + int vertsize = radeon_ctx->vertsize; + + if ( 1 ) + fprintf( stderr, "%s:\n", __FUNCTION__ ); + + VB->ClipPtr = TransformRaw( &VB->Clip, + &ctx->ModelProjectMatrix, + VB->ObjPtr ); + + refresh_projection_matrix( ctx ); + + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &VB->Win, + VB->ClipMask, + &VB->ClipOrMask, + &VB->ClipAndMask ); + + if ( VB->ClipAndMask ) { + return; + } + if ( radeon_ctx->vert_buf ) { + radeonFlushVertices( radeon_ctx ); + } + if ( radeon_ctx->new_state ) { + radeonDDUpdateHWState( ctx ); + } + + /* Allocate a single buffer to hold unclipped vertices. All + * unclipped vertices must be contiguous. + */ + if ( (GLuint)radeon_ctx->next_vert - (GLuint)radeon_ctx->next_elt < + VB->Count * vertsize * sizeof(GLuint) ) { + fire_elts( radeon_ctx ); + } else { + /* Make room for the next indexed prim packet header, and + * dword-align the resulting address. + */ + radeon_ctx->next_elt = + (GLushort *)((GLubyte *)radeon_ctx->next_elt + + RADEON_INDEX_PRIM_OFFSET); + radeon_ctx->next_elt = + (GLushort *)(((GLuint)radeon_ctx->next_elt + 3) & ~0x3); + radeon_ctx->first_elt = radeon_ctx->next_elt; + } + + radeon_ctx->retained_buf = radeon_ctx->elt_buf; + + /* Emit unclipped vertices to the buffer. + */ + tab->emit_unclipped_verts( VB ); + + /* Emit indices and clipped vertices to one or more buffers. + */ + if ( VB->ClipOrMask ) { + radeon_ctx->elt_tab = tab; + radeon_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 ); + } else { + radeon_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 ); + } + + /* Send to hardware and release the elt buffer. + */ + release_bufs( radeon_ctx ); + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h new file mode 100644 index 000000000..bb7349aff --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h @@ -0,0 +1,312 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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 + * Kevin E. Martin + * Gareth Hughes + * + */ + +/* + * DRI Hardware Device Driver for G200/G400 + * 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. + * + */ + +/* Buffers fill from high addresses down with vertices and from low + * addresses up with elements. + */ + + +/* Emit the bulk of the vertices to the first dma buffer. Leave + * empty slots for clipped vertices so that we can still address + * vertices by index. + */ +static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) +{ + GLuint i; + radeonContextPtr radeon_ctx = RADEON_CONTEXT(VB->ctx); + GLfloat *dev = VB->Projected->start; + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + GLuint buffer_stride = radeon_ctx->vertsize; + + GLfloat *f = radeon_ctx->next_vert; + GLuint count = VB->Count; + GLubyte *clipmask = VB->ClipMask; + + const GLfloat *m = radeon_ctx->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + + if ( 1 ) + fprintf(stderr, "%s:\n", __FUNCTION__); + + radeon_ctx->retained_buf = radeon_ctx->elt_buf; + radeon_ctx->first_vert_index = radeon_ctx->next_vert_index; + + for ( i = 0 ; i < count ; f -= buffer_stride, i++ ) + { + if ( !clipmask[i] ) + { + if ( 1 ) + fprintf( stderr, "vert=%d addr=%p space=0x%x\n", + i, f, (GLuint)f - (GLuint)radeon_ctx->elt_buf->address ); + + f[0] = sx * dev[0] + tx; + f[1] = sy * dev[1] + ty; + f[2] = sz * dev[2] + tz; + f[3] = dev[3]; + + if (TYPE & RADEON_RGBA_BIT) { +#if defined(USE_X86_ASM) + __asm__ ( + "movl (%%edx),%%eax \n" + "bswap %%eax \n" + "rorl $8,%%eax \n" + "movl %%eax,16(%%edi) \n" + : + : "d" (color), "D" (f) + : "%eax" ); +#else + GLubyte *b = (GLubyte *)&f[4]; + b[CLIP_UBYTE_B] = color[2]; + b[CLIP_UBYTE_G] = color[1]; + b[CLIP_UBYTE_R] = color[0]; + b[CLIP_UBYTE_A] = color[3]; +#endif + } + + if (TYPE & RADEON_TEX0_BIT) { + *(int*)&f[6] = *(int*)&tex0_data[0]; + *(int*)&f[7] = *(int*)&tex0_data[1]; + } + + if (TYPE & RADEON_TEX1_BIT) { + *(int*)&f[8] = *(int*)&tex1_data[0]; + *(int*)&f[9] = *(int*)&tex1_data[1]; + } + } + + STRIDE_F(dev, 16); + if (TYPE & RADEON_RGBA_BIT) color += color_stride; + if (TYPE & RADEON_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); + if (TYPE & RADEON_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); + } + + radeon_ctx->next_vert = f; + radeon_ctx->next_vert_index -= count; +} + + +/* Build three temporary clipspace vertex for clipping a triangle. + * Recreate from the VB data rather than trying to read back from + * uncached memory. + */ +static void TAG(build_tri_verts)( radeonContextPtr radeon_ctx, + struct vertex_buffer *VB, + GLfloat *O, + GLuint *elt ) +{ + int i; + + for ( i = 0 ; i < 3 ; i++, O += CLIP_STRIDE ) { + GLfloat *clip = VB->Clip.start + elt[i]*4; + + O[0] = clip[0]; + O[1] = clip[1]; + O[2] = clip[2]; + O[3] = clip[3]; + + if (TYPE & RADEON_RGBA_BIT) { + GLubyte *col = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]); + GLubyte *b = (GLubyte *)&O[4]; + b[CLIP_UBYTE_R] = col[0]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_A] = col[3]; + } + + if ( 1 ) + fprintf(stderr, + "build_tri_vert elt[%d]: %d phys: %x " + "(first_index %x elt_buf %x\n", + i, elt[i], (GLuint)UNCLIPPED_VERT(elt[i]), + (GLuint)radeon_ctx->first_vert_index, + (GLuint)radeon_ctx->elt_buf); + + *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]); + + if (TYPE & RADEON_TEX0_BIT) { + GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]); + *(int*)&O[6] = *(int*)&tex0_data[0]; + *(int*)&O[7] = *(int*)&tex0_data[1]; + } + + if (TYPE & RADEON_TEX1_BIT) { + GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]); + *(int*)&O[8] = *(int*)&tex1_data[0]; + *(int*)&O[9] = *(int*)&tex1_data[1]; + } + } +} + + +/* Interpolate between two of the vertices constructed above. + */ +static void TAG(interp)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) +{ + O[0] = LINTERP(t, I[0], J[0]); + O[1] = LINTERP(t, I[1], J[1]); + O[2] = LINTERP(t, I[2], J[2]); + O[3] = LINTERP(t, I[3], J[3]); + + if (TYPE & RADEON_RGBA_BIT) { + INTERP_RGBA(t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4]))); + } + + if (1) fprintf(stderr, "setting 0x%x to ~0\n", (GLuint)&O[5]); + + *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */ + + if (TYPE & RADEON_TEX0_BIT) { + O[6] = LINTERP(t, I[6], J[6]); + O[7] = LINTERP(t, I[7], J[7]); + } + + if (TYPE & RADEON_TEX1_BIT) { + O[8] = LINTERP(t, I[8], J[8]); + O[9] = LINTERP(t, I[9], J[9]); + } +} + + + +/* When clipping is complete, scan the final vertex list and emit any + * new ones to dma buffers. Update the element list to a format + * suitable for sending to hardware. + */ +static void TAG(project_and_emit_verts)( radeonContextPtr radeon_ctx, + const GLfloat *verts, + GLuint *elt, + int nr) +{ + GLfloat *O = radeon_ctx->next_vert; + GLushort index = radeon_ctx->next_vert_index; + GLuint buffer_stride = radeon_ctx->vertsize * sizeof(GLuint); + + const GLfloat *m = radeon_ctx->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; + + for (i = 0 ; i < nr ; i++) { + const GLfloat *I = &verts[elt[i] * CLIP_STRIDE]; + GLuint tmp = *(GLuint *)&I[5]; + + if (1) fprintf(stderr, "elt[%d] (tmp 0x%x %d) %d --> ", + i, (GLuint)&I[5], tmp, elt[i]); + + if ((elt[i] = tmp) == ~0) + { + GLfloat oow = 1.0/I[3]; + + elt[i] = index++; + + O[0] = sx * I[0] * oow + tx; + O[1] = sy * I[1] * oow + ty; + O[2] = sz * I[2] * oow + tz; + O[3] = oow; + + if (TYPE & RADEON_RGBA_BIT) { + *(int*)&O[4] = *(int*)&I[4]; + } + + if (TYPE & RADEON_TEX0_BIT) { + *(int*)&O[6] = *(int*)&I[6]; + *(int*)&O[7] = *(int*)&I[7]; + } + + if (TYPE & RADEON_TEX1_BIT) { + *(int*)&O[8] = *(int*)&I[8]; + *(int*)&O[9] = *(int*)&I[9]; + } + + O += buffer_stride; + } + if (1) fprintf(stderr, "0x%x\n", elt[i]); + } + + radeon_ctx->next_vert = O; + radeon_ctx->next_vert_index = index; +} + + + +static void TAG(radeon_init_eltpath)( struct radeon_elt_tab *tab ) +{ + tab->emit_unclipped_verts = TAG(emit_unclipped_verts); + tab->build_tri_verts = TAG(build_tri_verts); + tab->interp = TAG(interp); + tab->project_and_emit_verts = TAG(project_and_emit_verts); +} + +#undef TYPE +#undef TAG +#undef STRIDE diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c new file mode 100644 index 000000000..c560f74ea --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c @@ -0,0 +1,542 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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 + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_state.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" + +#include "mmath.h" +#include "cva.h" +#include "vertices.h" + +/* HACK: Declare this global for now */ +static GLfloat m[16] __attribute__ ((aligned (16))); + +struct radeon_fast_tab { + void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); + void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); +}; + +#define POINT(x) radeon_draw_point( radeon_ctx, &vert[x], psize ) +#define LINE(x,y) radeon_draw_line( radeon_ctx, &vert[x], &vert[y], lwidth ) +#define TRI(x,y,z) radeon_draw_triangle( radeon_ctx, &vert[x], &vert[y], &vert[z] ) + + +/* Direct, and no clipping required. The clip funcs have not been + written yet, so this is only useful for the fast path. */ +#define RENDER_POINTS(start, count) \ +do { \ + GLuint e; \ + for (e = start; e <= count; e++) \ + POINT(elt[e]); \ +} while (0) + +#define RENDER_LINE(i1, i) \ +do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + LINE(e1, e); \ +} while (0) + +#define RENDER_TRI(i2, i1, i, pv, parity) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if (parity) { \ + GLuint tmp = e2; \ + e2 = e1; \ + e1 = tmp; \ + } \ + TRI(e2, e1, e); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i, pv) \ +do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + TRI(e3, e2, e); \ + TRI(e2, e1, e); \ +} while (0) + +#define LOCAL_VARS \ + radeonVertexPtr vert = RADEON_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + GLcontext *ctx = VB->ctx; \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); \ + const GLfloat lwidth = ctx->Line.Width; \ + const GLfloat psize = ctx->Point.Size; \ + (void) lwidth; (void) psize; (void) vert; + +#define TAG(x) radeon_##x##_smooth_indirect +#include "render_tmp.h" + + +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A))) + + +#define INTERP_RGBA(t, out, a, b) \ +do { \ + int i; \ + for (i = 0; i < 4; i++) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \ + GLfloat fo = LINTERP(t, fa, fb); \ + FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \ + } \ +} while (0) + + +#define CLIP(SGN, V, PLANE) \ +do { \ + if (mask & PLANE) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]].f; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + inlist[0] = vlist1; \ + for (i = n = 0 ; i < nr ; i++) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i].f; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t, *in, *out; \ + \ + if (NEGATIVE(dpI)) { \ + t = dpI / (dpI - dpJ); \ + in = I; \ + out = J; \ + } else { \ + t = dpJ / (dpJ - dpI); \ + in = J; \ + out = I; \ + } \ + \ + interp(t, O, in, out); \ + \ + clipmask[next_vert] = 0; \ + outdata[n++] = next_vert++; \ + } \ + \ + clipmask[elt_i] |= PLANE; /* don't set up */ \ + \ + if (!NEGATIVE(dpI)) { \ + outdata[n++] = elt_i; \ + clipmask[elt_i] &= ~PLANE; /* set up after all */ \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return; \ + } \ +} while (0) + +#define LINE_CLIP(x,y,z,w,PLANE) \ +do { \ + if (mask & PLANE) { \ + GLfloat dpI = DOT4V(I,x,y,z,w); \ + GLfloat dpJ = DOT4V(J,x,y,z,w); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + \ + interp(t, O, I, J); \ + \ + clipmask[next_vert] = 0; \ + \ + if (NEGATIVE(dpI)) { \ + clipmask[elts[0]] |= PLANE; \ + I = O; \ + elts[0] = next_vert++; \ + } else { \ + clipmask[elts[1]] |= PLANE; \ + J = O; \ + elts[1] = next_vert++; \ + } \ + } else if (NEGATIVE(dpI)) return; \ + } \ +} while (0) + + +static __inline void radeon_tri_clip( GLuint **p_elts, + radeonVertex *verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + radeon_interp_func interp ) +{ + GLuint *elts = *p_elts; + GLuint next_vert = *p_next_vert; + GLuint in = 0; + GLuint n = 3; + GLuint vlist1[VB_MAX_CLIPPED_VERTS]; + GLuint vlist2[VB_MAX_CLIPPED_VERTS]; + GLuint *inlist[2]; + GLuint *out; + GLuint i; + + inlist[0] = elts; + inlist[1] = vlist2; + + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); + + /* Convert the planar polygon to a list of triangles */ + out = inlist[in]; + + for (i = 2 ; i < n ; i++) { + elts[0] = out[0]; + elts[1] = out[i-1]; + elts[2] = out[i]; + elts += 3; + } + + *p_next_vert = next_vert; + *p_elts = elts; +} + + +static __inline void radeon_line_clip( GLuint **p_elts, + radeonVertex *verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + radeon_interp_func interp ) +{ + GLuint *elts = *p_elts; + GLfloat *I = verts[elts[0]].f; + GLfloat *J = verts[elts[1]].f; + GLuint next_vert = *p_next_vert; + + LINE_CLIP( 1, 0, 0, -1, CLIP_LEFT_BIT ); + LINE_CLIP( -1, 0, 0, 1, CLIP_RIGHT_BIT ); + LINE_CLIP( 0, 1, 0, -1, CLIP_TOP_BIT ); + LINE_CLIP( 0, -1, 0, 1, CLIP_BOTTOM_BIT ); + LINE_CLIP( 0, 0, 1, -1, CLIP_FAR_BIT ); + LINE_CLIP( 0, 0, -1, 1, CLIP_NEAR_BIT ); + + *p_next_vert = next_vert; + *p_elts += 2; +} + + + +#define CLIP_POINT(e) \ +do { \ + if (mask[e]) *out++ = e; \ +} while (0) + +#define CLIP_LINE(e1, e0) \ +do { \ + GLubyte ormask = mask[e0] | mask[e1]; \ + out[0] = e1; \ + out[1] = e0; \ + out += 2; \ + if (ormask) { \ + out-=2; \ + if (!(mask[e0] & mask[e1])) { \ + radeon_line_clip(&out, verts, mask, &next_vert, ormask, \ + interp); \ + } \ + } \ +} while (0) + +#define CLIP_TRIANGLE(e2, e1, e0) \ +do { \ + GLubyte ormask; \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + out += 3; \ + ormask = mask[e2] | mask[e1] | mask[e0]; \ + if (ormask) { \ + out -= 3; \ + if (!(mask[e2] & mask[e1] & mask[e0])) { \ + radeon_tri_clip(&out, verts, mask, &next_vert, ormask, \ + interp); \ + } \ + } \ +} while (0) + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ +#define LOCAL_VARS \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(VB->ctx); \ + radeonVertexBufferPtr radeon_vb = RADEON_DRIVER_DATA(VB); \ + GLuint *elt = VB->EltPtr->data; \ + radeonVertex *verts = radeon_vb->verts; \ + GLuint next_vert = radeon_vb->last_vert; \ + GLuint *out = radeon_vb->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + radeon_interp_func interp = radeon_ctx->interp; \ + (void) interp; (void) verts; + +#define POSTFIX \ + radeon_vb->clipped_elements.count = \ + out - radeon_vb->clipped_elements.data; \ + radeon_vb->last_vert = next_vert; + + +#define INIT(x) + +#define RENDER_POINTS(start, count) \ +do { \ + GLuint i; \ + for (i = start; i < count; i++) \ + CLIP_POINT(elt[i]); \ +} while (0) + +#define RENDER_LINE(i1, i0) \ +do { \ + CLIP_LINE(elt[i1], elt[i0]); \ +} while (0) + +#define RENDER_TRI(i2, i1, i0, pv, parity) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if (parity) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE(e2, e1, e0); \ +} while (0) + +#define RENDER_QUAD(i3, i2, i1, i0, pv) \ +do { \ + CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ + CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]); \ +} while (0) + +#define TAG(x) radeon_##x##_clip_elt +#include "render_tmp.h" + + +/* Pack rgba and/or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_UBYTE_COLOR 4 +#define CLIP_UBYTE_B 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_R 2 +#define CLIP_UBYTE_A 3 +#define CLIP_S0 6 +#define CLIP_T0 7 +#define CLIP_S1 8 +#define CLIP_T1 9 + +#define TYPE (0) +#define TAG(x) x +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "radeon_fasttmp.h" + +/* This one *could* get away with sneaking TEX1 into the color and + * specular slots, thus fitting inside a cache line. Would be even + * better to switch to a smaller vertex. + */ +#define TYPE (RADEON_TEX0_BIT | RADEON_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "radeon_fasttmp.h" + + + +/* Render elements directly from original list of vertices. */ +static void radeon_render_elements_direct( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = radeon_render_tab_smooth_indirect[prim]; + GLuint p = 0; + + if ( radeon_ctx->new_state ) + radeonDDUpdateHWState( ctx ); + + do { + func( VB, 0, nr, 0 ); + } while ( ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc( VB, ++p ) ); +} + +/* Project vertices from clip to device space */ +static void radeon_project_vertices( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + radeonVertexBufferPtr radeon_vb = RADEON_DRIVER_DATA(VB); + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY] + radeon_ctx->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * radeon_ctx->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * radeon_ctx->depth_scale; + + gl_project_v16( radeon_vb->verts[VB->CopyStart].f, + radeon_vb->verts[radeon_vb->last_vert].f, + m, + 16 * 4 ); +} + +/* Project clipped vertices from clip to device space */ +static void radeon_project_clipped_vertices( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + radeonVertexBufferPtr radeon_vb = RADEON_DRIVER_DATA(VB); + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY] + radeon_ctx->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * radeon_ctx->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * radeon_ctx->depth_scale; + + gl_project_clipped_v16( radeon_vb->verts[VB->CopyStart].f, + radeon_vb->verts[radeon_vb->last_vert].f, + m, + 16 * 4, + VB->ClipMask + VB->CopyStart ); +} + +static struct radeon_fast_tab radeonFastTab[0x80]; + +/* Initialize the table of fast path support functions */ +void radeonDDFastPathInit( void ) +{ + radeon_render_init_clip_elt(); + radeon_render_init_smooth_indirect(); + + radeon_init_fastpath( &radeonFastTab[0] ); + radeon_init_fastpath_RGBA( &radeonFastTab[RADEON_RGBA_BIT] ); + radeon_init_fastpath_TEX0( &radeonFastTab[RADEON_TEX0_BIT] ); + radeon_init_fastpath_RGBA_TEX0( &radeonFastTab[RADEON_RGBA_BIT | + RADEON_TEX0_BIT] ); + radeon_init_fastpath_TEX0_TEX1( &radeonFastTab[RADEON_TEX0_BIT | + RADEON_TEX1_BIT] ); + radeon_init_fastpath_RGBA_TEX0_TEX1( &radeonFastTab[RADEON_RGBA_BIT | + RADEON_TEX0_BIT | + RADEON_TEX1_BIT] ); +} + +#define VALID_SETUP (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT) + +void radeonDDFastPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + struct radeon_fast_tab *tab = + &radeonFastTab[radeon_ctx->SetupIndex & VALID_SETUP]; + GLuint do_cliptest = 1; + + gl_prepare_arrays_cva( VB ); /* still need this */ + +#if 0 + if ( ( gl_reduce_prim[prim] == GL_TRIANGLES ) && + ( VB->Count < (RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) ) && + ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL| + MAT_FLAG_PERSPECTIVE) ) ) + { + radeonDDEltPath( VB ); + return; + } +#endif + + /* Reserve enough space for the pathological case */ + if ( VB->EltPtr->count * 12 > RADEON_DRIVER_DATA(VB)->size ) { + radeonDDResizeVB( VB, VB->EltPtr->count * 12 ); + do_cliptest = 1; + } + + tab->build_vertices( VB, do_cliptest ); /* object->clip space */ + + if ( radeon_ctx->new_state ) + radeonDDUpdateHWState( ctx ); + + if ( VB->ClipOrMask ) { + if ( !VB->ClipAndMask ) { + render_func *clip = radeon_render_tab_clip_elt; + + radeon_ctx->interp = tab->interp; + + clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ + + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(RADEON_DRIVER_DATA(VB)->clipped_elements); + + radeon_project_clipped_vertices( VB ); /* clip->device space */ + radeon_render_elements_direct( VB ); /* render using new list */ + } + } else { + radeon_project_vertices( VB ); /* clip->device space */ + radeon_render_elements_direct( VB ); /* render using orig list */ + } + + /* This indicates that there is no cached data to reuse */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h new file mode 100644 index 000000000..303be0bd0 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h @@ -0,0 +1,196 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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 + * Kevin E. Martin + * Gareth Hughes + * + */ + +/* FIXME: These routines were copied from the i810 driver, and were only + slightly modified for the Radeon. They still need to be optmizied + and cleaned up. Also, support for USE_RHW2 needs to be added. */ + +/* The first part of setup is applied to all vertices, clipped or + * unclipped. This data w!ill be used for clipping, and then all + * vertices with a zero clipmask will be projected to device space. + * + * This could be split into several loops, but - it seems that the + * large stride of the fxVertices makes cache issues the big + * performance factor, and that multiple loops mean multiple cache + * misses.... + */ +static void TAG(radeon_setup_full)(struct vertex_buffer *VB, + GLuint do_cliptest) +{ + GLcontext *ctx = VB->ctx; + radeonVertexBufferPtr radeon_vb = RADEON_DRIVER_DATA(VB); + const GLfloat *m = ctx->ModelProjectMatrix.m; + GLuint start = VB->CopyStart; + GLuint count = VB->Count; + + gl_xform_points3_v16_general(radeon_vb->verts[start].f, + m, + VB->ObjPtr->start, + VB->ObjPtr->stride, + count - start); + + if (do_cliptest) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16(radeon_vb->verts[start].f, + radeon_vb->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), + VB->ClipMask + start); + } + + /* These branches are all resolved at compile time. Hopefully all + * the pointers are valid addresses even when not enabled. + */ + if (TYPE) { + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = radeon_vb->verts[start].f; + GLfloat *end = f + (16 * (count - start)); + + while (f != end) { + if (TYPE & RADEON_RGBA_BIT) { +#if defined(USE_X86_ASM) + /* GTH: I'd like to get some accurate timing data on the + * bswap instruction, but it gives a nice speedup anyway. + */ + __asm__ ("movl (%%edx),%%eax \n" + "bswap %%eax \n" + "rorl $8,%%eax \n" + "movl %%eax,16(%%edi) \n" + : + : "d" (color), "D" (f) + : "%eax"); +#else + GLubyte *col = color; + GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; + b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_R] = col[0]; + b[CLIP_UBYTE_A] = col[3]; +#endif + } + if (TYPE & RADEON_TEX0_BIT) { +#if defined (USE_X86_ASM) + __asm__ ("movl (%%ecx), %%eax \n" + "movl %%eax, 24(%%edi) \n" + "movl 4(%%ecx), %%eax \n" + "movl %%eax, 28(%%edi)" + : + : "c" (tex0_data), "D" (f) + : "%eax"); +#else + *(unsigned int *)(f+CLIP_S0) = *(unsigned int *)tex0_data; + *(unsigned int *)(f+CLIP_T0) = *(unsigned int *)(tex0_data+1); +#endif + } + if (TYPE & RADEON_TEX1_BIT) { + /* Hits a second cache line. + */ +#if defined (USE_X86_ASM) + __asm__ ("movl (%%esi), %%eax \n" + "movl %%eax, 32(%%edi) \n" + "movl 4(%%esi), %%eax \n" + "movl %%eax, 36(%%edi)" + : + : "S" (tex1_data), "D" (f) + : "%eax"); +#else + *(unsigned int *)(f+CLIP_S1) = *(unsigned int *)tex1_data; + *(unsigned int *)(f+CLIP_T1) = *(unsigned int *)(tex1_data+1); +#endif + } + if (TYPE & RADEON_RGBA_BIT) color += color_stride; + if (TYPE & RADEON_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); + if (TYPE & RADEON_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); + f += 16; + } + } + + radeon_vb->clipped_elements.count = start; + radeon_vb->last_vert = count; +} + + +/* Changed to just put the interp func instead of the whole clip + * routine into the header. Less code and better chance of doing some + * of this stuff in assembly. + */ +static void TAG(radeon_interp_vert)(GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J) +{ + O[0] = LINTERP(t, I[0], J[0]); + O[1] = LINTERP(t, I[1], J[1]); + O[2] = LINTERP(t, I[2], J[2]); + O[3] = LINTERP(t, I[3], J[3]); + + if (TYPE & RADEON_RGBA_BIT) { + INTERP_RGBA(t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4]))); + } + + if (TYPE & RADEON_TEX0_BIT) { + O[6] = LINTERP(t, I[6], J[6]); + O[7] = LINTERP(t, I[7], J[7]); + } + + if (TYPE & RADEON_TEX1_BIT) { + O[8] = LINTERP(t, I[8], J[8]); + O[9] = LINTERP(t, I[9], J[9]); + } +} + + +static void TAG(radeon_init_fastpath)(struct radeon_fast_tab *tab) +{ + tab->build_vertices = TAG(radeon_setup_full); + tab->interp = TAG(radeon_interp_vert); +} + +#undef TYPE +#undef TAG +#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c new file mode 100644 index 000000000..3a02d78a3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -0,0 +1,613 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" + +#include "mem.h" + +#define RADEON_TIMEOUT 2000000 + + +/* ============================================================= + * Hardware vertex buffer handling + */ + +/* Get a new VB from the pool of vertex buffers in AGP space. + */ +drmBufPtr radeonGetBufferLocked( radeonContextPtr radeon_ctx ) +{ + int fd = radeon_ctx->radeonScreen->driScreen->fd; + int index = 0; + int size = 0; + drmDMAReq dma; + drmBufPtr buf = NULL; + int to = 0; + int ret; + + dma.context = radeon_ctx->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = RADEON_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; + + while ( !buf && ( to++ < radeon_ctx->CPtimeout ) ) { + ret = drmDMA( fd, &dma ); + + if ( ret == 0 ) { + buf = &radeon_ctx->radeonScreen->buffers->list[index]; + buf->used = 0; +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + radeon_ctx->c_vertexBuffers++; +#endif + return buf; + } + fprintf( stderr, "hmmmm... trying again\n" ); + } + + if ( !buf ) { + drmRadeonEngineReset( fd ); + fprintf( stderr, "Error: Could not get new VB... exiting\n" ); + exit( -1 ); + } + + return buf; +} + +void radeonFlushVerticesLocked( radeonContextPtr radeon_ctx ) +{ + XF86DRIClipRectPtr pbox = radeon_ctx->pClipRects; + int nbox = radeon_ctx->numClipRects; + drmBufPtr buffer = radeon_ctx->vert_buf; + int count = radeon_ctx->num_verts; + int prim = RADEON_TRIANGLES; + int fd = radeon_ctx->driScreen->fd; + int i; + + radeon_ctx->num_verts = 0; + radeon_ctx->vert_buf = NULL; + + if ( !buffer ) { + return; + } + + if ( radeon_ctx->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeonEmitHwStateLocked( radeon_ctx ); + } + + if ( !nbox ) { + count = 0; + } + if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) { + radeon_ctx->dirty |= RADEON_UPLOAD_CLIPRECTS; + } + + if ( !count || !(radeon_ctx->dirty & RADEON_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + radeon_ctx->sarea->nbox = 0; + } else { + radeon_ctx->sarea->nbox = nbox; + } + + drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = radeon_ctx->sarea->boxes; + int discard = 0; + + radeon_ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + discard = 1; + } + + radeon_ctx->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, discard ); + } + } + + radeon_ctx->dirty &= ~RADEON_UPLOAD_CLIPRECTS; +} + + + +/* ================================================================ + * Indexed vertex buffer handling + */ + +void radeonGetEltBufLocked( radeonContextPtr radeon_ctx ) +{ + radeon_ctx->elt_buf = radeonGetBufferLocked( radeon_ctx ); +} + +void radeonFireEltsLocked( radeonContextPtr radeon_ctx, + GLuint start, GLuint end, + GLuint discard ) +{ + XF86DRIClipRectPtr pbox = radeon_ctx->pClipRects; + int nbox = radeon_ctx->numClipRects; + drmBufPtr buffer = radeon_ctx->elt_buf; + int prim = RADEON_TRIANGLES; + int fd = radeon_ctx->driScreen->fd; + int i; + + fprintf( stderr, "%s: start=%d end=%d discard=%d\n", + __FUNCTION__, start, end, discard ); + + if ( !buffer ) { + return; + } + + if ( radeon_ctx->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeonEmitHwStateLocked( radeon_ctx ); + } + + if ( !nbox ) { + end = start; + } + if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) { + radeon_ctx->dirty |= RADEON_UPLOAD_CLIPRECTS; + } + + if ( start == end || !(radeon_ctx->dirty & RADEON_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + radeon_ctx->sarea->nbox = 0; + } else { + radeon_ctx->sarea->nbox = nbox; + } + + drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = radeon_ctx->sarea->boxes; + int d = 0; + + radeon_ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + d = discard; + } + + radeon_ctx->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + } + + radeon_ctx->dirty &= ~RADEON_UPLOAD_CLIPRECTS; +} + +void radeonFlushEltsLocked( radeonContextPtr radeon_ctx ) +{ + if ( radeon_ctx->first_elt != radeon_ctx->next_elt ) { + radeonFireEltsLocked( radeon_ctx, + ((GLuint)radeon_ctx->first_elt - + (GLuint)radeon_ctx->elt_buf->address), + ((GLuint)radeon_ctx->next_elt - + (GLuint)radeon_ctx->elt_buf->address), + 0 ); + radeon_ctx->first_elt = radeon_ctx->next_elt; + } +} + +void radeonReleaseBufLocked( radeonContextPtr radeon_ctx, drmBufPtr buffer ) +{ + int fd = radeon_ctx->driScreen->fd; + + if ( !buffer ) + return; + + drmRadeonFlushVertexBuffer( fd, RADEON_TRIANGLES, buffer->idx, 0, 1 ); +} + + +/* Allocate some space in the current vertex buffer. If the current + * buffer is full, flush it and grab another one. + */ +CARD32 *radeonAllocVertices( radeonContextPtr radeon_ctx, int count ) +{ + return radeonAllocVerticesInline( radeon_ctx, count ); +} + + + +/* ================================================================ + * Texture uploads + */ +static int blit_index[RADEON_MAX_BLIT_BUFFERS]; +static int blit_sizes[RADEON_MAX_BLIT_BUFFERS]; + +void radeonGetBlitBuffersLocked( radeonContextPtr radeon_ctx, GLint count ) +{ + int fd = radeon_ctx->radeonScreen->driScreen->fd; + drmDMAReq dma; + drmBufPtr buf = NULL; + int i, to = 0; + int ret; + + dma.context = radeon_ctx->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = count; + dma.request_size = RADEON_BUFFER_SIZE; + dma.request_list = blit_index; + dma.request_sizes = blit_sizes; + dma.granted_count = 0; + + while ( to++ < radeon_ctx->CPtimeout ) { + ret = drmDMA( fd, &dma ); + + if ( ret == 0 ) { + for ( i = 0 ; i < dma.granted_count ; i++ ) { + buf = &radeon_ctx->radeonScreen->buffers->list[blit_index[i]]; + buf->used = 0; + + radeon_ctx->BlitRects[i].index = blit_index[i]; + radeon_ctx->BlitRects[i].x = 0; + radeon_ctx->BlitRects[i].y = 0; + radeon_ctx->BlitRects[i].width = 0; + radeon_ctx->BlitRects[i].height = 0; + + radeon_ctx->BlitBuffers[i] = buf; + } + radeon_ctx->numBlitBuffers = dma.granted_count; + return; + } + } + + drmRadeonEngineReset( fd ); + fprintf( stderr, "Error: Could not get blit buffers... exiting\n" ); + exit( -1 ); +} + +void radeonFireBlitLocked( radeonContextPtr radeon_ctx, + GLint offset, GLint pitch, GLint format ) +{ + GLint ret; + + ret = drmRadeonTextureBlit( radeon_ctx->driFd, offset, pitch, format, + radeon_ctx->BlitRects, + radeon_ctx->numBlitBuffers ); + + if ( ret ) { + fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); + exit( 1 ); + } +} + + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +static void delay( void ) { +/* Prevent an optimizing compiler from removing a spin loop */ +} + +#define RADEON_MAX_OUTSTANDING 4 + +/* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + * GH: We probably don't want a timeout here, as we can wait as + * long as we want for a frame to complete. If it never does, then + * the card has locked. + */ +static int radeonWaitForFrameCompletion( radeonContextPtr radeon_ctx ) +{ + unsigned char *RADEONMMIO = radeon_ctx->radeonScreen->mmio; + CARD32 frame; + int i; + int wait = 0; + + while ( 1 ) { + frame = INREG( RADEON_LAST_FRAME_REG ); + if ( radeon_ctx->sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) { + break; + } + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, "%s: frame = %d last_frame = %d\n", + __FUNCTION__, frame, radeon_ctx->sarea->last_frame ); + } + + /* Spin in place a bit so we aren't hammering the register */ + wait++; + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } + + return wait; +} + +/* Copy the back color buffer to the front color buffer */ +void radeonSwapBuffers( radeonContextPtr radeon_ctx ) +{ + GLint nbox = radeon_ctx->numClipRects; + GLint i; + GLint ret; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, radeon_ctx->glCtx ); + } + + /* Flush any outstanding vertex buffers */ + FLUSH_BATCH( radeon_ctx ); + + LOCK_HARDWARE( radeon_ctx ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !radeonWaitForFrameCompletion( radeon_ctx ) ) { + radeon_ctx->hardwareWentIdle = 1; + } else { + radeon_ctx->hardwareWentIdle = 0; + } + + for ( i = 0 ; i < nbox ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); + XF86DRIClipRectPtr box = radeon_ctx->pClipRects; + XF86DRIClipRectPtr b = radeon_ctx->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + radeon_ctx->sarea->nbox = n; + + ret = drmRadeonSwapBuffers( radeon_ctx->driFd ); + + if ( ret ) { + fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( radeon_ctx ); + + radeon_ctx->new_state |= RADEON_NEW_CONTEXT; + radeon_ctx->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + radeonPerformanceCounters( radeon_ctx ); +#endif +} + + +/* ================================================================ + * Buffer clear + */ + +static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = radeon_ctx->driDrawable; + GLuint flags = 0; + GLint i; + GLint ret; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s:\n", __FUNCTION__ ); + } + + FLUSH_BATCH( radeon_ctx ); + + /* Update and emit any new state. We need to do this here to catch + * changes to the masks. + * FIXME: Just update the masks? + */ + if ( radeon_ctx->new_state ) + radeonDDUpdateHWState( ctx ); + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= DRM_RADEON_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= DRM_RADEON_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) { + flags |= DRM_RADEON_DEPTH; + mask &= ~DD_DEPTH_BIT; + } +#if 0 + /* FIXME: Add stencil support */ + if ( mask & DD_STENCIL_BIT ) { + flags |= DRM_RADEON_DEPTH; + mask &= ~DD_STENCIL_BIT; + } +#endif + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( radeon_ctx ); + + if ( radeon_ctx->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeonEmitHwStateLocked( radeon_ctx ); + } + + for ( i = 0 ; i < radeon_ctx->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, + radeon_ctx->numClipRects ); + XF86DRIClipRectPtr box = radeon_ctx->pClipRects; + XF86DRIClipRectPtr b = radeon_ctx->sarea->boxes; + GLint n = 0; + + if ( !all ) { + for ( ; i < nr ; i++ ) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if ( x < cx ) w -= cx - x, x = cx; + if ( y < cy ) h -= cy - y, y = cy; + if ( x + w > cx + cw ) w = cx + cw - x; + if ( y + h > cy + ch ) h = cy + ch - y; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + } + + radeon_ctx->sarea->nbox = n; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) { + fprintf( stderr, + "drmRadeonClear: flag 0x%x color %x depth %x nbox %d\n", + flags, + (GLuint)radeon_ctx->ClearColor, + (GLuint)radeon_ctx->ClearDepth, + radeon_ctx->sarea->nbox ); + } + + ret = drmRadeonClear( radeon_ctx->driFd, flags, + cx, cy, cw, ch, + radeon_ctx->ClearColor, radeon_ctx->ClearDepth, + 0xffffffff, 0xffffffff ); + + if ( ret ) { + fprintf( stderr, "drmRadeonClear: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( radeon_ctx ); + + radeon_ctx->dirty |= RADEON_UPLOAD_CLIPRECTS; + + return mask; +} + + + +/* ================================================================ + * Deprecated function... + */ +void radeonSubmitPacketLocked( radeonContextPtr radeon_ctx, + CARD32 *buf, GLuint count ) +{ + CARD32 *b; + int c = count; + int fd = radeon_ctx->radeonScreen->driScreen->fd; + int to = 0; + int ret; + + do { + b = buf + (count - c); + ret = drmRadeonSubmitPacket( fd, b, &c, 0 ); + } while ( ( ret == -EBUSY ) && ( to++ < radeon_ctx->CPtimeout ) ); + + if ( ret < 0 ) { + drmRadeonEngineReset( fd ); + fprintf( stderr, "Error: Could not submit packet... exiting\n" ); + exit( -1 ); + } +} + + + +void radeonWaitForIdleLocked( radeonContextPtr radeon_ctx ) +{ + int fd = radeon_ctx->radeonScreen->driScreen->fd; + int to = 0; + int ret; + + do { + ret = drmRadeonWaitForIdleCP( fd ); + } while ( ( ret == -EBUSY ) && ( to++ < radeon_ctx->CPtimeout ) ); + + if ( ret < 0 ) { + drmRadeonEngineReset( fd ); + fprintf( stderr, "Error: Radeon timed out... exiting\n" ); + exit( -1 ); + } +} + + +void radeonDDInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = radeonDDClear; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h new file mode 100644 index 000000000..3610cc345 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h @@ -0,0 +1,195 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#ifndef __RADEON_IOCTL_H__ +#define __RADEON_IOCTL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_dri.h" +#include "radeon_lock.h" + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +#define RADEON_DEFAULT_TOTAL_CP_TIMEOUT 1000000 /* usecs */ + +#define RADEON_MAX_BLIT_BUFFERS ((2048 * 2048 * 4) / RADEON_BUFFER_SIZE) + + +#define FLUSH_BATCH( radeon_ctx ) \ +do { \ + if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) \ + fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ + if ( radeon_ctx->vert_buf ) { \ + radeonFlushVertices( radeon_ctx ); \ + } else if ( radeon_ctx->next_elt != radeon_ctx->first_elt ) { \ + radeonFlushElts( radeon_ctx ); \ + } \ +} while (0) + +#define radeonFlushVertices( radeon_ctx ) \ +do { \ + LOCK_HARDWARE( radeon_ctx ); \ + radeonFlushVerticesLocked( radeon_ctx ); \ + UNLOCK_HARDWARE( radeon_ctx ); \ +} while (0) + + +extern drmBufPtr radeonGetBufferLocked( radeonContextPtr radeon_ctx ); +extern void radeonFlushVerticesLocked( radeonContextPtr radeon_ctx ); + + +#define radeonFlushElts( radeon_ctx ) \ +do { \ + LOCK_HARDWARE( radeon_ctx ); \ + radeonFlushEltsLocked( radeon_ctx ); \ + UNLOCK_HARDWARE( radeon_ctx ); \ +} while (0) + +extern void radeonGetEltBufLocked( radeonContextPtr radeon_ctx ); +extern void radeonFlushEltsLocked( radeonContextPtr radeon_ctx ); +extern void radeonFireEltsLocked( radeonContextPtr radeon_ctx, + GLuint start, GLuint end, + GLuint discard ); +extern void radeonReleaseBufLocked( radeonContextPtr radeon_ctx, + drmBufPtr buffer ); + + +/* Make this available as both a regular and an inline function. + */ +extern CARD32 *radeonAllocVertices( radeonContextPtr radeon_ctx, int count ); + +static __inline CARD32 *radeonAllocVerticesInline( radeonContextPtr radeon_ctx, + int count ) +{ + int bytes = count * radeon_ctx->vertsize * 4; + CARD32 *head; + + if ( !radeon_ctx->vert_buf ) { + LOCK_HARDWARE( radeon_ctx ); + + if ( radeon_ctx->first_elt != radeon_ctx->next_elt ) { + radeonFlushEltsLocked( radeon_ctx ); + } + + radeon_ctx->vert_buf = radeonGetBufferLocked( radeon_ctx ); + + UNLOCK_HARDWARE( radeon_ctx ); + } else if ( radeon_ctx->vert_buf->used + bytes + > radeon_ctx->vert_buf->total ) { + LOCK_HARDWARE( radeon_ctx ); + + radeonFlushVerticesLocked( radeon_ctx ); + radeon_ctx->vert_buf = radeonGetBufferLocked( radeon_ctx ); + + UNLOCK_HARDWARE( radeon_ctx ); + } + + head = (CARD32 *)((char *)radeon_ctx->vert_buf->address + + radeon_ctx->vert_buf->used); + + radeon_ctx->num_verts += count; + radeon_ctx->vert_buf->used += bytes; + return head; +} + + +extern void radeonGetBlitBuffersLocked( radeonContextPtr radeon_ctx, + GLint count ); +extern void radeonFireBlitLocked( radeonContextPtr radeon_ctx, + GLint offset, GLint pitch, GLint format ); + +extern void radeonSwapBuffers( radeonContextPtr radeon_ctx ); + + +#define radeonWaitForIdle( radeon_ctx ) \ +do { \ + LOCK_HARDWARE( radeon_ctx ); \ + radeonWaitForIdleLocked( radeon_ctx ); \ + UNLOCK_HARDWARE( radeon_ctx ); \ +} while (0) + +extern void radeonWaitForIdleLocked( radeonContextPtr radeon_ctx ); + + +extern void radeonDDInitIoctlFuncs( GLcontext *ctx ); + + + +/* ================================================================ + * Deprecated functions: + */ + +typedef union { + float f; + int i; +} floatTOint; + +/* Insert an integer value into the CP ring buffer. */ +#define RADEONCP(v) \ +do { \ + radeon_ctx->CPbuf[radeon_ctx->CPcount] = (v); \ + radeon_ctx->CPcount++; \ +} while (0) + +/* Insert an floating point value into the CP ring buffer. */ +#define RADEONCPF(v) \ +do { \ + floatTOint fTi; \ + fTi.f = (v); \ + radeon_ctx->CPbuf[radeon_ctx->CPcount] = fTi.i; \ + radeon_ctx->CPcount++; \ +} while (0) + +/* Insert a type-[0123] packet header into the ring buffer */ +#define RADEONCP0(p,r,n) RADEONCP((p) | ((n) << 16) | ((r) >> 2)) +#define RADEONCP1(p,r1,r2) RADEONCP((p) | (((r2) >> 2) << 11) | ((r1) >> 2)) +#define RADEONCP2(p) RADEONCP((p)) +#define RADEONCP3(p,n) RADEONCP((p) | ((n) << 16)) + +#define RADEONCP_SUBMIT_PACKET() \ +do { \ + radeonSubmitPacketLocked( radeon_ctx, radeon_ctx->CPbuf, \ + radeon_ctx->CPcount ); \ + radeon_ctx->CPcount = 0; \ +} while (0) + +extern void radeonSubmitPacketLocked( radeonContextPtr radeon_ctx, + CARD32 *buf, GLuint count ); + +#endif +#endif /* __RADEON_IOCTL_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c new file mode 100644 index 000000000..c67c079a9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c @@ -0,0 +1,94 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#include "radeon_context.h" +#include "radeon_lock.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void radeonGetLock( radeonContextPtr radeon_ctx, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = radeon_ctx->driDrawable; + __DRIscreenPrivate *sPriv = radeon_ctx->driScreen; + RADEONSAREAPriv *sarea = radeon_ctx->sarea; + int stamp = dPriv->lastStamp; + int i; + + drmGetLock( radeon_ctx->driFd, radeon_ctx->hHWContext, flags ); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + XMESA_VALIDATE_DRAWABLE_INFO( radeon_ctx->display, sPriv, dPriv ); + + if ( stamp != dPriv->lastStamp ) { + radeon_ctx->new_state |= RADEON_NEW_WINDOW; + radeon_ctx->SetupDone = 0; + } + + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_CLIPRECTS; + + radeon_ctx->numClipRects = dPriv->numClipRects; + radeon_ctx->pClipRects = dPriv->pClipRects; + + if ( sarea->ctxOwner != radeon_ctx->hHWContext ) { + sarea->ctxOwner = radeon_ctx->hHWContext; + radeon_ctx->dirty = RADEON_UPLOAD_ALL; + } + + for ( i = 0 ; i < radeon_ctx->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != radeon_ctx->lastTexAge[i] ) { + radeonAgeTextures( radeon_ctx, i ); + } + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h new file mode 100644 index 000000000..ab3a7ae2c --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h @@ -0,0 +1,110 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_LOCK_H_ +#define _RADEON_LOCK_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonGetLock( radeonContextPtr radeon_ctx, GLuint flags ); + + +/* Turn DEBUG_LOCKING on to find locking conflicts (see radeon_init.h) */ +#if 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 + +/* + * !!! 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 !!! + */ + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( radeon_ctx ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( radeon_ctx->driHwLock, radeon_ctx->hHWContext, \ + (DRM_LOCK_HELD | radeon_ctx->hHWContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( radeon_ctx, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware. + */ +#define UNLOCK_HARDWARE( radeon_ctx ) \ + do { \ + DRM_UNLOCK( radeon_ctx->driFd, \ + radeon_ctx->driHwLock, \ + radeon_ctx->hHWContext ); \ + DEBUG_RESET(); \ + } while (0) + +#endif +#endif /* _RADEON_LOCK_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c new file mode 100644 index 000000000..da9cf9b14 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c @@ -0,0 +1,169 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_context.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "types.h" +#include "fog.h" + +static struct gl_pipeline_stage radeon_fast_stage = { + "Radeon Fast Path", + (PIPE_OP_VERT_XFORM | + PIPE_OP_RAST_SETUP_0 | + PIPE_OP_RAST_SETUP_1 | + PIPE_OP_RENDER), + PIPE_PRECALC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + radeonDDFastPath +}; + +#define ILLEGAL_ENABLES (TEXTURE0_3D | \ + TEXTURE1_3D | \ + ENABLE_TEXMAT0 | \ + ENABLE_TEXMAT1 | \ + ENABLE_TEXGEN0 | \ + ENABLE_TEXGEN1 | \ + ENABLE_USERCLIP | \ + ENABLE_LIGHT | \ + ENABLE_FOG) + +/* Build the PRECALC pipeline with our stage, if possible. Otherwise, + * return GL_FALSE. + */ +GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + struct gl_pipeline *pipe = &ctx->CVA.pre; + + if ( radeon_ctx->RenderIndex == 0 && + (ctx->Enabled & ILLEGAL_ENABLES) == 0 && + (ctx->Array.Flags & (VERT_OBJ_234 | + VERT_TEX0_4 | + VERT_TEX1_4 | + VERT_ELT)) == (VERT_OBJ_23 | VERT_ELT) ) + { + pipe->stages[0] = &radeon_fast_stage; + pipe->stages[1] = 0; + pipe->new_inputs = ctx->RenderFlags & VERT_DATA; + pipe->ops = pipe->stages[0]->ops; + + radeon_ctx->useFastPath = GL_TRUE; + return GL_TRUE; + } + + if ( radeon_ctx->useFastPath ) { + radeon_ctx->useFastPath = GL_FALSE; + + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->Array.NewArrayState |= ctx->Array.Summary; + } + + return GL_FALSE; +} + + +/* Still do the normal fixup and copy-to-current, so this isn't so + * bad. + */ +#define ILLEGAL_INPUTS_IMM (VERT_OBJ_4 | \ + VERT_TEX0_4 | \ + VERT_TEX1_4 | \ + VERT_MATERIAL) + +static void radeonDDCheckRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *d ) +{ + d->type = PIPE_IMMEDIATE | PIPE_PRECALC; + d->inputs = ctx->RenderFlags; + + /* radeon requires an extra input: + */ + if ( ctx->FogMode == FOG_FRAGMENT ) + d->inputs |= VERT_FOG_COORD; + + d->outputs = VERT_SETUP_FULL; + + if ( ctx->IndirectTriangles & DD_SW_SETUP ) + d->type = PIPE_IMMEDIATE; +} + + +/* Register the pipeline with our stages included */ +GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr ) +{ + int i, o; + + for ( i = o = 0 ; i < nr ; i++ ) { + switch ( in[i].ops ) { + /* Completely replace Mesa's fog processing to generate fog + * coordinates instead of messing with colors. + */ + case PIPE_OP_FOG: + out[o] = gl_fog_coord_stage; + o++; + break; + + case PIPE_OP_RAST_SETUP_0: + out[o] = in[i]; + out[o].cva_state_change = (NEW_LIGHTING | + NEW_TEXTURING | + NEW_RASTER_OPS); + out[o].state_change = ~0; + out[o].check = radeonDDCheckPartialRasterSetup; + out[o].run = radeonDDPartialRasterSetup; + o++; + break; + + case PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1: + out[o] = in[i]; + out[o].check = radeonDDCheckRasterSetup; + out[o].run = radeonDDDoRasterSetup; + o++; + break; + + default: + out[o++] = in[i]; + break; + } + } + + return o; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h new file mode 100644 index 000000000..22b7185b4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h @@ -0,0 +1,51 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_PIPELINE_H_ +#define _RADEON_PIPELINE_H_ + +extern GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx ); +extern GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr ); + +extern void radeonDDFastPathInit( void ); +extern void radeonDDFastPath( struct vertex_buffer *VB ); + +extern void radeonDDEltPathInit( void ); +extern void radeonDDEltPath( struct vertex_buffer *VB ); + +#endif /* _RADEON_PIPELINE_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c new file mode 100644 index 000000000..99e54e15d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -0,0 +1,280 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_dri.h" + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include + +#if 1 +/* Including xf86PciInfo.h introduces a bunch of errors... + */ +#define PCI_CHIP_RADEON_QD 0x5144 +#define PCI_CHIP_RADEON_QE 0x5145 +#define PCI_CHIP_RADEON_QF 0x5146 +#define PCI_CHIP_RADEON_QG 0x5147 +#endif + + +/* Create the device specific screen private data struct */ +radeonScreenPtr radeonCreateScreen(__DRIscreenPrivate *sPriv) +{ + radeonScreenPtr radeonScreen; + RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; + int cpp; + + /* Allocate the private area */ + radeonScreen = (radeonScreenPtr)Xmalloc(sizeof(*radeonScreen)); + if (!radeonScreen) return NULL; + + /* This is first since which regions we map depends on whether or + not we are using a PCI card */ + radeonScreen->IsPCI = radeonDRIPriv->IsPCI; + + radeonScreen->mmioRgn.handle = radeonDRIPriv->registerHandle; + radeonScreen->mmioRgn.size = radeonDRIPriv->registerSize; + if (drmMap(sPriv->fd, + radeonScreen->mmioRgn.handle, + radeonScreen->mmioRgn.size, + (drmAddressPtr)&radeonScreen->mmio)) { + Xfree(radeonScreen); + return NULL; + } + + if (!radeonScreen->IsPCI) { + radeonScreen->ringRgn.handle = radeonDRIPriv->ringHandle; + radeonScreen->ringRgn.size = radeonDRIPriv->ringMapSize; + if (drmMap(sPriv->fd, + radeonScreen->ringRgn.handle, + radeonScreen->ringRgn.size, + (drmAddressPtr)&radeonScreen->ring)) { + drmUnmap((drmAddress)radeonScreen->mmio, + radeonScreen->mmioRgn.size); + Xfree(radeonScreen); + return NULL; + } + + radeonScreen->ringReadRgn.handle = radeonDRIPriv->ringReadPtrHandle; + radeonScreen->ringReadRgn.size = radeonDRIPriv->ringReadMapSize; + if (drmMap(sPriv->fd, + radeonScreen->ringReadRgn.handle, + radeonScreen->ringReadRgn.size, + (drmAddressPtr)&radeonScreen->ringReadPtr)) { + drmUnmap((drmAddress)radeonScreen->ring, + radeonScreen->ringRgn.size); + drmUnmap((drmAddress)radeonScreen->mmio, + radeonScreen->mmioRgn.size); + Xfree(radeonScreen); + return NULL; + } + + radeonScreen->bufRgn.handle = radeonDRIPriv->bufHandle; + radeonScreen->bufRgn.size = radeonDRIPriv->bufMapSize; + if (drmMap(sPriv->fd, + radeonScreen->bufRgn.handle, + radeonScreen->bufRgn.size, + (drmAddressPtr)&radeonScreen->buf)) { + drmUnmap((drmAddress)radeonScreen->ringReadPtr, + radeonScreen->ringReadRgn.size); + drmUnmap((drmAddress)radeonScreen->ring, + radeonScreen->ringRgn.size); + drmUnmap((drmAddress)radeonScreen->mmio, + radeonScreen->mmioRgn.size); + Xfree(radeonScreen); + return NULL; + } + radeonScreen->bufOffset = radeonDRIPriv->bufOffset; + + radeonScreen->agpTexRgn.handle = radeonDRIPriv->agpTexHandle; + radeonScreen->agpTexRgn.size = radeonDRIPriv->agpTexMapSize; + if (drmMap(sPriv->fd, + radeonScreen->agpTexRgn.handle, + radeonScreen->agpTexRgn.size, + (drmAddressPtr)&radeonScreen->agpTex)) { + drmUnmap((drmAddress)radeonScreen->buf, + radeonScreen->bufRgn.size); + drmUnmap((drmAddress)radeonScreen->ringReadPtr, + radeonScreen->ringReadRgn.size); + drmUnmap((drmAddress)radeonScreen->ring, + radeonScreen->ringRgn.size); + drmUnmap((drmAddress)radeonScreen->mmio, + radeonScreen->mmioRgn.size); + Xfree(radeonScreen); + return NULL; + } + radeonScreen->agpTexOffset = radeonDRIPriv->agpTexOffset; + + if (!(radeonScreen->buffers = drmMapBufs(sPriv->fd))) { + drmUnmap((drmAddress)radeonScreen->agpTex, + radeonScreen->agpTexRgn.size); + drmUnmap((drmAddress)radeonScreen->buf, + radeonScreen->bufRgn.size); + drmUnmap((drmAddress)radeonScreen->ringReadPtr, + radeonScreen->ringReadRgn.size); + drmUnmap((drmAddress)radeonScreen->ring, + radeonScreen->ringRgn.size); + drmUnmap((drmAddress)radeonScreen->mmio, + radeonScreen->mmioRgn.size); + Xfree(radeonScreen); + return NULL; + } + } + + /* Allow both AGP and PCI cards to use vertex buffers. PCI cards use + * the ring walker method, ie. the vertex buffer data is actually part + * of the command stream. + */ + radeonScreen->bufMapSize = radeonDRIPriv->bufMapSize; + + radeonScreen->deviceID = radeonDRIPriv->deviceID; + + radeonScreen->depth = radeonDRIPriv->depth; + radeonScreen->bpp = radeonDRIPriv->bpp; + radeonScreen->pixel_code = (radeonScreen->bpp != 16 ? + radeonScreen->bpp : + radeonScreen->depth); + + cpp = radeonScreen->bpp / 8; + + radeonScreen->fb = sPriv->pFB; + radeonScreen->fbOffset = sPriv->fbOrigin; + radeonScreen->fbStride = sPriv->fbStride; + radeonScreen->fbSize = sPriv->fbSize; + + radeonScreen->frontX = radeonDRIPriv->fbX; + radeonScreen->frontY = radeonDRIPriv->fbY; + radeonScreen->frontOffset = (radeonDRIPriv->fbY * + radeonScreen->fbStride + + radeonDRIPriv->fbX * cpp); + radeonScreen->frontPitch = radeonScreen->fbStride / cpp; + + radeonScreen->backX = radeonDRIPriv->backX; + radeonScreen->backY = radeonDRIPriv->backY; + radeonScreen->backOffset = (radeonDRIPriv->backY * + radeonScreen->fbStride + + radeonScreen->backX * cpp); + radeonScreen->backPitch = radeonScreen->fbStride / cpp; + + radeonScreen->depthX = radeonDRIPriv->depthX; + radeonScreen->depthY = radeonDRIPriv->depthY; + radeonScreen->depthOffset = (radeonDRIPriv->depthY * + radeonScreen->fbStride + + radeonScreen->depthX * cpp); + radeonScreen->depthPitch = radeonScreen->fbStride / cpp; + + radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP] = + (radeonDRIPriv->textureY * radeonScreen->fbStride + + radeonDRIPriv->textureX * (radeonScreen->bpp/8)); + radeonScreen->texSize[RADEON_LOCAL_TEX_HEAP] = + radeonDRIPriv->textureSize; + radeonScreen->log2TexGran[RADEON_LOCAL_TEX_HEAP] = + radeonDRIPriv->log2TexGran; + + if (radeonScreen->IsPCI) { + radeonScreen->texOffset[RADEON_AGP_TEX_HEAP] = 0; + radeonScreen->texSize[RADEON_AGP_TEX_HEAP] = 0; + radeonScreen->log2TexGran[RADEON_AGP_TEX_HEAP] = 0; + radeonScreen->NRTexHeaps = RADEON_NR_TEX_HEAPS-1; + } else { + radeonScreen->texOffset[RADEON_AGP_TEX_HEAP] = 0; + radeonScreen->texSize[RADEON_AGP_TEX_HEAP] = + radeonDRIPriv->agpTexMapSize; + radeonScreen->log2TexGran[RADEON_AGP_TEX_HEAP] = + radeonDRIPriv->log2AGPTexGran; + radeonScreen->NRTexHeaps = RADEON_NR_TEX_HEAPS; + } + + radeonScreen->AGPMode = radeonDRIPriv->AGPMode; + + radeonScreen->CPMode = radeonDRIPriv->CPMode; + + radeonScreen->ringEntries = radeonDRIPriv->ringSize/sizeof(CARD32); + if (!radeonScreen->IsPCI) { + radeonScreen->ringStartPtr = (int *)radeonScreen->ring; + radeonScreen->ringEndPtr = (int *)(radeonScreen->ring + + radeonDRIPriv->ringSize); + } + + radeonScreen->driScreen = sPriv; + + switch ( radeonDRIPriv->deviceID ) { + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + break; + default: + radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + break; + } + + radeonDDFastPathInit(); + radeonDDEltPathInit(); + radeonDDTriangleFuncsInit(); + radeonDDSetupInit(); + + return radeonScreen; +} + +/* Destroy the device specific screen private data struct */ +void radeonDestroyScreen(__DRIscreenPrivate *sPriv) +{ + radeonScreenPtr radeonScreen = (radeonScreenPtr)sPriv->private; + + if (!radeonScreen->IsPCI) { + drmUnmapBufs(radeonScreen->buffers); + + drmUnmap((drmAddress)radeonScreen->agpTex, + radeonScreen->agpTexRgn.size); + drmUnmap((drmAddress)radeonScreen->buf, + radeonScreen->bufRgn.size); + drmUnmap((drmAddress)radeonScreen->ringReadPtr, + radeonScreen->ringReadRgn.size); + drmUnmap((drmAddress)radeonScreen->ring, + radeonScreen->ringRgn.size); + } + drmUnmap((drmAddress)radeonScreen->mmio, + radeonScreen->mmioRgn.size); + + Xfree(radeonScreen); + sPriv->private = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h new file mode 100644 index 000000000..2a130742b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -0,0 +1,118 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_SCREEN_H_ +#define _RADEON_SCREEN_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_sarea.h" + +typedef struct { + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ +} radeonRegionRec, *radeonRegionPtr; + +typedef struct { + /* MMIO register data */ + radeonRegionRec mmioRgn; + unsigned char *mmio; + + /* CP ring buffer data */ + radeonRegionRec ringRgn; + unsigned char *ring; + + /* CP ring read pointer data */ + radeonRegionRec ringReadRgn; + + /* CP vertex/indirect buffer data */ + radeonRegionRec bufRgn; + unsigned char *buf; + int bufOffset; + int bufMapSize; + drmBufMapPtr buffers; + + /* CP AGP Texture data */ + radeonRegionRec agpTexRgn; + unsigned char *agpTex; + int agpTexOffset; + + /* Frame buffer data */ + unsigned char *fb; + unsigned long fbOffset; + int fbStride; + int fbSize; + + unsigned int frontX, frontY; /* Start of front buffer */ + unsigned int frontOffset, frontPitch; + unsigned int backX, backY; /* Start of shared back buffer */ + unsigned int backOffset, backPitch; + unsigned int depthX, depthY; /* Start of shared depth buffer */ + unsigned int depthOffset, depthPitch; + + int chipset; + int IsPCI; /* Current card is a PCI card */ + int AGPMode; + + int CPMode; /* CP mode that server/clients use */ + + /* CP ring buffer data */ + int ringEntries; + + volatile int *ringReadPtr; /* Pointer to current read addr */ + int *ringStartPtr; /* Pointer to end of ring buffer */ + int *ringEndPtr; /* Pointer to end of ring buffer */ + + /* DRI screen private data */ + int deviceID; /* PCI device ID */ + int depth; /* Depth of display (8, 15, 16, 24) */ + int bpp; /* Bit depth of disp (8, 16, 24, 32) */ + int pixel_code; /* 8, 15, 16, 24, 32 */ + + /* Shared texture data */ + int NRTexHeaps; + int texOffset[RADEON_NR_TEX_HEAPS]; + int texSize[RADEON_NR_TEX_HEAPS]; + int log2TexGran[RADEON_NR_TEX_HEAPS]; + + __DRIscreenPrivate *driScreen; +} radeonScreenRec, *radeonScreenPtr; + +radeonScreenPtr radeonCreateScreen(__DRIscreenPrivate *sPriv); +void radeonDestroyScreen(__DRIscreenPrivate *sPriv); + +#endif +#endif /* _RADEON_SCREEN_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c new file mode 100644 index 000000000..7466fac72 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c @@ -0,0 +1,340 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Keith Whitwell + * Gareth Hughes + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_span.h" + +#define DBG 0 + +#define LOCAL_VARS \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); \ + radeonScreenPtr radeon_scrn = radeon_ctx->radeonScreen; \ + __DRIdrawablePrivate *dPriv = radeon_ctx->driDrawable; \ + GLuint pitch = radeon_scrn->fbStride; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(radeon_scrn->fb + \ + radeon_ctx->drawOffset + \ + (dPriv->x * radeon_scrn->bpp/8) + \ + (dPriv->y * pitch)); \ + char *read_buf = (char *)(radeon_scrn->fb + \ + radeon_ctx->readOffset + \ + (dPriv->x * radeon_scrn->bpp/8) + \ + (dPriv->y * pitch)); \ + GLushort p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); \ + radeonScreenPtr radeon_scrn = radeon_ctx->radeonScreen; \ + __DRIdrawablePrivate *dPriv = radeon_ctx->driDrawable; \ + GLuint pitch = radeon_scrn->fbStride; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(radeon_scrn->fb + \ + radeon_scrn->depthOffset + \ + (dPriv->x * radeon_scrn->bpp/8) + \ + (dPriv->y * pitch)); \ + (void) buf + +#define INIT_MONO_PIXEL( p ) \ + p = RADEON_CONTEXT(ctx)->Color + +#define CLIPPIXEL( _x, _y ) \ + ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) + + +#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; \ + } + +#define Y_FLIP( _y ) (height - _y - 1) + + +#define HW_LOCK() \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); \ + FLUSH_BATCH( radeon_ctx ); \ + LOCK_HARDWARE( radeon_ctx ); \ + radeonWaitForIdleLocked( radeon_ctx ); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = radeon_ctx->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( radeon_ctx ) \ + + + +/* 16 bit, RGB565 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] = 0xff; \ + } while (0) + +#define TAG(x) radeon##x##_RGB565 +#include "spantmp.h" + + + +/* 15 bit, ARGB1555 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) << 2) | \ + ((b & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#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 >> 2) & 0xf8; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = (p & 0x8000) ? 0xff : 0; \ + } while (0) + +#define TAG(x) radeon##x##_ARGB1555 +#include "spantmp.h" + + + +/* 24 bit, RGB888 color spanline and pixel functions */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = 0xff; \ +} while (0) + +#define TAG(x) radeon##x##_RGB888 +#include "spantmp.h" + + + +/* 32 bit, ARGB8888 color spanline and pixel functions */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16) | \ + (a << 24) ) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ +} while (0) + +#define TAG(x) radeon##x##_ARGB8888 +#include "spantmp.h" + + + +/* 16 bit depthbuffer functions */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*2 + _y*pitch) + +#define TAG(x) radeon##x##_16 +#include "depthtmp.h" + + + +/* 24 bit depth, 8 bit stencil depthbuffer functions */ +#define WRITE_DEPTH( _x, _y, d ) \ +do { \ + GLuint _d = *(GLuint *)(buf + _x*4 + _y*pitch); \ + _d &= 0xff000000; \ + _d |= (d & 0x00ffffff); \ + *(GLuint *)(buf + _x*4 + _y*pitch) = _d; \ +} while (0) + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0x00ffffff; + +#define TAG(x) radeon##x##_24_8 +#include "depthtmp.h" + + + +/* 32 bit depthbuffer functions */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = d + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch) + +#define TAG(x) radeon##x##_32 +#include "depthtmp.h" + + + +void radeonDDInitSpanFuncs( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + switch ( radeon_ctx->BufferSize ) { + case 8: /* Color Index mode not supported */ + break; + + case 15: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_ARGB1555; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_ARGB1555; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB1555; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_ARGB1555; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB1555; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_ARGB1555; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_ARGB1555; + break; + + case 16: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_RGB565; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_RGB565; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB565; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_RGB565; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB565; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_RGB565; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_RGB565; + break; + + case 24: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_RGB888; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_RGB888; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB888; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_RGB888; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB888; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_RGB888; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_RGB888; + break; + + case 32: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_ARGB8888; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_ARGB8888; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB8888; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_ARGB8888; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB8888; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_ARGB8888; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_ARGB8888; + break; + + default: + break; + } + + switch ( radeon_ctx->DepthSize ) { + case 16: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_16; + break; + + case 24: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_24_8; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_24_8; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_24_8; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_24_8; + break; + + case 32: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_32; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_32; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_32; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_32; + break; + + default: + break; + } + + 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/radeon/radeon_span.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h new file mode 100644 index 000000000..6d99cca70 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h @@ -0,0 +1,45 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_SPAN_H_ +#define _RADEON_SPAN_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonDDInitSpanFuncs(GLcontext *ctx); + +#endif +#endif /* _RADEON_SPAN_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c new file mode 100644 index 000000000..07928e8ca --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -0,0 +1,1343 @@ +/* $XFree86$ */ /* -*- c-basic-offset: 4 -*- */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * Keith Whitwell + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "pb.h" +#include "enums.h" + +/* ============================================================= + * Alpha blending + */ + +static void radeonUpdateAlphaMode( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 a = radeon_ctx->setup.pp_misc; + CARD32 p = radeon_ctx->setup.pp_cntl; + CARD32 b = radeon_ctx->setup.rb3d_blendcntl; + CARD32 c = radeon_ctx->setup.rb3d_cntl; + + if ( ctx->Color.AlphaEnabled ) { + GLubyte ref = ctx->Color.AlphaRef; + + a &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK); + + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: + a |= RADEON_ALPHA_TEST_FAIL; + ref = 0; + break; + case GL_LESS: + a |= RADEON_ALPHA_TEST_LESS; + break; + case GL_LEQUAL: + a |= RADEON_ALPHA_TEST_LEQUAL; + break; + case GL_EQUAL: + a |= RADEON_ALPHA_TEST_EQUAL; + break; + case GL_GEQUAL: + a |= RADEON_ALPHA_TEST_GEQUAL; + break; + case GL_GREATER: + a |= RADEON_ALPHA_TEST_GREATER; + break; + case GL_NOTEQUAL: + a |= RADEON_ALPHA_TEST_NEQUAL; + break; + case GL_ALWAYS: + a |= RADEON_ALPHA_TEST_PASS; + break; + } + + a |= ref & RADEON_REF_ALPHA_MASK; + p |= RADEON_ALPHA_TEST_ENABLE; + } else { + p &= ~RADEON_ALPHA_TEST_ENABLE; + } + + if ( ctx->Color.BlendEnabled ) { + b &= ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK); + + switch ( ctx->Color.BlendSrcRGB ) { + case GL_ZERO: + b |= RADEON_SRC_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= RADEON_SRC_BLEND_GL_ONE; + break; + case GL_DST_COLOR: + b |= RADEON_SRC_BLEND_GL_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA: + b |= RADEON_SRC_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= RADEON_SRC_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + case GL_SRC_ALPHA_SATURATE: + b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE; + break; + } + + switch ( ctx->Color.BlendDstRGB ) { + case GL_ZERO: + b |= RADEON_DST_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= RADEON_DST_BLEND_GL_ONE; + break; + case GL_SRC_COLOR: + b |= RADEON_DST_BLEND_GL_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + b |= RADEON_DST_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= RADEON_DST_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + } + + c |= RADEON_ALPHA_BLEND_ENABLE; + } else { + c &= ~RADEON_ALPHA_BLEND_ENABLE; + } + + if ( radeon_ctx->setup.pp_misc != a ) { + radeon_ctx->setup.pp_misc = a; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( radeon_ctx->setup.pp_cntl != p ) { + radeon_ctx->setup.pp_cntl = p; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( radeon_ctx->setup.rb3d_blendcntl != b ) { + radeon_ctx->setup.rb3d_blendcntl = b; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( radeon_ctx->setup.rb3d_cntl != c ) { + radeon_ctx->setup.rb3d_cntl = c; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } +} + +static void radeonDDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendEquation( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_ALPHA; +} + + +/* ============================================================= + * Depth testing + */ + +static void radeonUpdateZMode( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 z = radeon_ctx->setup.rb3d_zstencilcntl; + CARD32 c = radeon_ctx->setup.rb3d_cntl; + + if ( ctx->Depth.Test ) { + z &= ~RADEON_Z_TEST_MASK; + + switch ( ctx->Depth.Func ) { + case GL_NEVER: + z |= RADEON_Z_TEST_NEVER; + break; + case GL_ALWAYS: + z |= RADEON_Z_TEST_ALWAYS; + break; + case GL_LESS: + z |= RADEON_Z_TEST_LESS; + break; + case GL_LEQUAL: + z |= RADEON_Z_TEST_LEQUAL; + break; + case GL_EQUAL: + z |= RADEON_Z_TEST_EQUAL; + break; + case GL_GEQUAL: + z |= RADEON_Z_TEST_GEQUAL; + break; + case GL_GREATER: + z |= RADEON_Z_TEST_GREATER; + break; + case GL_NOTEQUAL: + z |= RADEON_Z_TEST_NEQUAL; + break; + } + + c |= RADEON_Z_ENABLE; + } else { + c &= ~RADEON_Z_ENABLE; + } + + if ( ctx->Depth.Mask ) { + z |= RADEON_Z_WRITE_ENABLE; + } else { + z &= ~RADEON_Z_WRITE_ENABLE; + } + + if ( radeon_ctx->setup.rb3d_zstencilcntl != z ) { + radeon_ctx->setup.rb3d_zstencilcntl = z; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( radeon_ctx->setup.rb3d_cntl != c ) { + radeon_ctx->setup.rb3d_cntl = c; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDDepthFunc( GLcontext *ctx, GLenum func ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_DEPTH; +} + +static void radeonDDDepthMask( GLcontext *ctx, GLboolean flag ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_DEPTH; +} + +static void radeonDDClearDepth( GLcontext *ctx, GLclampd d ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + switch ( radeon_ctx->DepthSize ) { + case 16: + radeon_ctx->ClearDepth = d * 0x0000ffff; + break; + case 24: + radeon_ctx->ClearDepth = d * 0x00ffffff; + break; + case 32: + radeon_ctx->ClearDepth = d * 0xffffffff; + break; + } +} + + +/* ============================================================= + * Fog + */ + +static void radeonUpdateFogAttrib( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 p = radeon_ctx->setup.pp_cntl; + GLubyte c[4]; + CARD32 col; + + if ( ctx->FogMode == FOG_FRAGMENT ) { + p |= RADEON_FOG_ENABLE; + } else { + p &= ~RADEON_FOG_ENABLE; + } + + FLOAT_RGBA_TO_UBYTE_RGBA( c, ctx->Fog.Color ); + col = radeonPackColor( 32, c[0], c[1], c[2], c[3] ); + + if ( radeon_ctx->setup.pp_fog_color != col ) { + radeon_ctx->setup.pp_fog_color = col; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( radeon_ctx->setup.pp_cntl != p ) { + radeon_ctx->setup.pp_cntl = p; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_FOG; +} + + +/* ============================================================= + * Clipping + */ + +static void radeonUpdateClipping( GLcontext *ctx ) +{ +#if 0 + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + /* FIXME: This is broken... */ + if ( radeon_ctx->driDrawable ) { + int x1 = radeon_ctx->driDrawable->x; + int y1 = radeon_ctx->driDrawable->y; + + int x2 = radeon_ctx->driDrawable->x + radeon_ctx->driDrawable->w - 1; + int y2 = radeon_ctx->driDrawable->y + radeon_ctx->driDrawable->h - 1; + + if ( x1 < 0 ) x1 = 0; + if ( y1 < 0 ) y1 = 0; + if ( x2 < 0 ) x2 = 0; + if ( y2 < 0 ) y2 = 0; + + radeon_ctx->setup.sc_top_left_c = ((x1 << 0) | + (y1 << 16)); + radeon_ctx->setup.sc_bottom_right_c = ((x2 << 0) | + (y2 << 16)); + + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } +#endif +} + +static void radeonDDScissor( GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_CLIP; +} + + +/* ============================================================= + * Culling + */ + +static void radeonUpdateCull( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 s = radeon_ctx->setup.se_cntl; + + s &= ~RADEON_FFACE_CULL_DIR_MASK; + + switch ( ctx->Polygon.FrontFace ) { + case GL_CW: + s |= RADEON_FFACE_CULL_CW; + break; + case GL_CCW: + s |= RADEON_FFACE_CULL_CCW; + break; + } + + s &= ~(RADEON_FFACE_CULL_MASK | RADEON_BFACE_CULL_MASK); + s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~RADEON_FFACE_CULL_MASK; + s |= RADEON_FFACE_CULL; + break; + case GL_BACK: + s &= ~RADEON_BFACE_CULL_MASK; + s |= RADEON_BFACE_CULL; + break; + case GL_FRONT_AND_BACK: + s &= ~(RADEON_FFACE_CULL_MASK | RADEON_BFACE_CULL_MASK); + s |= RADEON_FFACE_CULL | RADEON_BFACE_CULL; + break; + } + } + + if ( radeon_ctx->setup.se_cntl != s ) { + radeon_ctx->setup.se_cntl = s; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_SETUP; + } +} + +static void radeonDDCullFace( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_CULL; +} + +static void radeonDDFrontFace( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_CULL; +} + + +/* ============================================================= + * Masks + */ + +static void radeonUpdateMasks( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + GLuint mask = radeonPackColor( radeon_ctx->BufferSize, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); + + if ( radeon_ctx->setup.rb3d_planemask != mask ) { + radeon_ctx->setup.rb3d_planemask = mask; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } +} + +static GLboolean radeonDDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_MASKS; + + return GL_TRUE; +} + + +/* ============================================================= + * Rendering attributes + * + * We really don't want to recalculate all this every time we bind a + * texture. These things shouldn't change all that often, so it makes + * sense to break them out of the core texture state update routines. + */ + +static void radeonUpdateRenderAttrib( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 p = radeon_ctx->setup.pp_cntl; + CARD32 r = radeon_ctx->setup.rb3d_cntl; + +#if 0 + /* This is stored in the PP_TEXFILTER_# register and should go in + radeon_tex.c */ + CARD32 bias = radeon_ctx->lod_bias & 0xff;; + + p &= ~RADEON_LOD_BIAS_MASK; + p |= (bias << RADEON_LOD_BIAS_SHIFT); +#endif + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + p |= RADEON_SPECULAR_ENABLE; + } else { + p &= ~RADEON_SPECULAR_ENABLE; + } + + if ( ctx->Color.DitherFlag ) { + r |= RADEON_DITHER_ENABLE; + } else { + r &= ~RADEON_DITHER_ENABLE; + } + + if ( radeon_ctx->setup.pp_cntl != p ) { + radeon_ctx->setup.pp_cntl = p; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( radeon_ctx->setup.rb3d_cntl != r ) { + radeon_ctx->setup.rb3d_cntl = r; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDLightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_RENDER; + } +} + +static void radeonDDShadeModel( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 s = radeon_ctx->setup.se_cntl; + + s &= ~RADEON_DIFFUSE_SHADE_MASK; + + switch ( mode ) { + case GL_FLAT: + s |= RADEON_DIFFUSE_SHADE_FLAT; + break; + case GL_SMOOTH: + s |= RADEON_DIFFUSE_SHADE_GOURAUD; + break; + default: + return; + } + + if ( radeon_ctx->setup.se_cntl != s ) { + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->setup.se_cntl = s; + + radeon_ctx->new_state |= RADEON_NEW_CONTEXT; + radeon_ctx->dirty |= RADEON_UPLOAD_SETUP; + } +} + + +/* ============================================================= + * Window position + */ + +void radeonUpdateWindow( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); +#if 0 + int x = radeon_ctx->driDrawable->x; + int y = radeon_ctx->driDrawable->y; + + /* FIXME: Enable and use VPORT offset */ + radeon_ctx->setup.window_xy_offset = ((y << RADEON_WINDOW_Y_SHIFT) | + (x << RADEON_WINDOW_X_SHIFT)); +#endif + + radeon_ctx->setup.rb3d_depthoffset = radeon_ctx->radeonScreen->depthOffset; + + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; +} + + +/* ============================================================= + * Miscellaneous + */ + +static void radeonDDClearColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + radeon_ctx->ClearColor = radeonPackColor( radeon_ctx->radeonScreen->depth, + r, g, b, a ); +} + +static void radeonDDColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + radeon_ctx->Color = radeonPackColor( radeon_ctx->radeonScreen->depth, + r, g, b, a ); +} + +#if 0 +static void radeonDDDither( GLcontext *ctx, GLboolean enable ) +{ +} +#endif + +static void radeonDDLogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + if ( ctx->Color.ColorLogicOpEnabled ) { + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + FLUSH_BATCH( radeon_ctx ); + + if ( opcode == GL_COPY ) { + radeon_ctx->Fallback &= ~RADEON_FALLBACK_LOGICOP; + } else { + radeon_ctx->Fallback |= RADEON_FALLBACK_LOGICOP; + } + } +} + +static GLboolean radeonDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + int found = GL_TRUE; + + FLUSH_BATCH( radeon_ctx ); + + if ( radeon_ctx->DrawBuffer != mode ) { + radeon_ctx->DrawBuffer = mode; + radeon_ctx->Fallback &= ~RADEON_FALLBACK_DRAW_BUFFER; + + switch ( mode ) { + case GL_FRONT_LEFT: + radeon_ctx->drawX = radeon_ctx->radeonScreen->frontX; + radeon_ctx->drawY = radeon_ctx->radeonScreen->frontY; + radeon_ctx->drawOffset = radeon_ctx->radeonScreen->frontOffset; + radeon_ctx->drawPitch = radeon_ctx->radeonScreen->frontPitch; + radeon_ctx->readX = radeon_ctx->radeonScreen->frontX; + radeon_ctx->readY = radeon_ctx->radeonScreen->frontY; + break; + case GL_BACK_LEFT: + radeon_ctx->drawX = radeon_ctx->radeonScreen->backX; + radeon_ctx->drawY = radeon_ctx->radeonScreen->backY; + radeon_ctx->drawOffset = radeon_ctx->radeonScreen->backOffset; + radeon_ctx->drawPitch = radeon_ctx->radeonScreen->backPitch; + radeon_ctx->readX = radeon_ctx->radeonScreen->backX; + radeon_ctx->readY = radeon_ctx->radeonScreen->backY; + break; + default: + radeon_ctx->Fallback |= RADEON_FALLBACK_DRAW_BUFFER; + found = GL_FALSE; + break; + } + + radeon_ctx->setup.rb3d_coloroffset = + (radeon_ctx->drawOffset & RADEON_COLOROFFSET_MASK); + radeon_ctx->setup.rb3d_colorpitch |= + (radeon_ctx->drawPitch & RADEON_COLORPITCH_MASK); + radeon_ctx->new_state |= RADEON_NEW_WINDOW; + } + + return found; +} + +static void radeonDDSetReadBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLenum mode ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + radeon_ctx->Fallback &= ~RADEON_FALLBACK_READ_BUFFER; + + switch ( mode ) { + case GL_FRONT_LEFT: + radeon_ctx->readOffset = radeon_ctx->radeonScreen->frontOffset; + radeon_ctx->readPitch = radeon_ctx->radeonScreen->frontPitch; + radeon_ctx->readX = radeon_ctx->radeonScreen->frontX; + radeon_ctx->readY = radeon_ctx->radeonScreen->frontY; + break; + case GL_BACK_LEFT: + radeon_ctx->readOffset = radeon_ctx->radeonScreen->backOffset; + radeon_ctx->readPitch = radeon_ctx->radeonScreen->backPitch; + radeon_ctx->readX = radeon_ctx->radeonScreen->backX; + radeon_ctx->readY = radeon_ctx->radeonScreen->backY; + break; + default: + radeon_ctx->Fallback |= RADEON_FALLBACK_READ_BUFFER; + break; + } +} + + +/* ============================================================= + * Polygon stipple + */ + +static void radeonDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); +#if 0 + CARD32 *stipple = (CARD32 *)mask; + GLuint i; +#endif + + FLUSH_BATCH( radeon_ctx ); + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + +#if 0 + /* FIXME: Implement polygon stipple support */ + radeon_ctx->setup.dp_gui_master_cntl_c &= ~RADEON_GMC_BRUSH_NONE; + + if ( ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON ) { + radeon_ctx->setup.dp_gui_master_cntl_c |= + RADEON_GMC_BRUSH_32x32_MONO_FG_LA; + } else { + radeon_ctx->setup.dp_gui_master_cntl_c |= + RADEON_GMC_BRUSH_SOLID_COLOR; + } + + LOCK_HARDWARE( radeon_ctx ); + + RADEONCP0( RADEON_CP_PACKET0, RADEON_BRUSH_DATA0, 31 ); + for ( i = 0 ; i < 32 ; i++ ) { + RADEONCP( stipple[i] ); + } + RADEONCP_SUBMIT_PACKET(); + + UNLOCK_HARDWARE( radeon_ctx ); +#endif + + radeon_ctx->new_state |= RADEON_NEW_CONTEXT; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; +} + + +/* ============================================================= + * State enable/disable + */ + +static void radeonDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + switch ( cap ) { + case GL_ALPHA_TEST: + case GL_BLEND: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_ALPHA; + break; + + case GL_CULL_FACE: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_CULL; + break; + + case GL_DEPTH_TEST: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_DEPTH; + break; + + case GL_DITHER: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_RENDER; + break; + + case GL_FOG: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_FOG; + break; + + case GL_INDEX_LOGIC_OP: + case GL_COLOR_LOGIC_OP: + FLUSH_BATCH( radeon_ctx ); + if ( state && ctx->Color.LogicOp != GL_COPY ) { + radeon_ctx->Fallback |= RADEON_FALLBACK_LOGICOP; + } else { + radeon_ctx->Fallback &= ~RADEON_FALLBACK_LOGICOP; + } + break; + + case GL_SCISSOR_TEST: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->scissor = state; + radeon_ctx->new_state |= RADEON_NEW_CLIP; + break; + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; + break; + + case GL_POLYGON_STIPPLE: + if ( (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && + ctx->PB->primitive == GL_POLYGON ) + { + FLUSH_BATCH( radeon_ctx ); +#if 0 + /* FIXME: Implement polygon stipple support */ + radeon_ctx->setup.dp_gui_master_cntl_c &= ~RADEON_GMC_BRUSH_NONE; + if ( state ) { + radeon_ctx->setup.dp_gui_master_cntl_c |= + RADEON_GMC_BRUSH_32x32_MONO_FG_LA; + } else { + radeon_ctx->setup.dp_gui_master_cntl_c |= + RADEON_GMC_BRUSH_SOLID_COLOR; + } +#endif + radeon_ctx->new_state |= RADEON_NEW_CONTEXT; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } + break; + + default: + return; + } +} + + +/* ============================================================= + * State initialization, management + */ + +static void radeonDDPrintDirty( const char *msg, GLuint state ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & RADEON_UPLOAD_CONTEXT) ? "context, " : "", + (state & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", + (state & RADEON_UPLOAD_LINE) ? "line, " : "", + (state & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", + (state & RADEON_UPLOAD_MASKS) ? "masks, " : "", + (state & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", + (state & RADEON_UPLOAD_SETUP) ? "setup, " : "", + (state & RADEON_UPLOAD_TCL) ? "tcl, " : "", + (state & RADEON_UPLOAD_MISC) ? "misc, " : "", + (state & RADEON_UPLOAD_TEX0) ? "tex0, " : "", + (state & RADEON_UPLOAD_TEX1) ? "tex1, " : "", + (state & RADEON_UPLOAD_TEX2) ? "tex2, " : "", + (state & RADEON_UPLOAD_TEX0IMAGES) ? "tex0 images, " : "", + (state & RADEON_UPLOAD_TEX1IMAGES) ? "tex1 images, " : "", + (state & RADEON_UPLOAD_TEX2IMAGES) ? "tex2 images, " : "", + (state & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (state & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); +} + +/* + * Load the current context's state into the hardware. + * + * NOTE: Be VERY careful about ensuring the context state is marked for + * upload, the only place it shouldn't be uploaded is when the setup + * state has changed in ReducedPrimitiveChange as this comes right after + * a state update. + * + * Blits of any type should always upload the context and masks after + * they are done. + */ +void radeonEmitHwStateLocked( radeonContextPtr radeon_ctx ) +{ + RADEONSAREAPrivPtr sarea = radeon_ctx->sarea; + radeon_context_regs_t *regs = &(radeon_ctx->setup); + radeonTexObjPtr t0 = radeon_ctx->CurrentTexObj[0]; + radeonTexObjPtr t1 = radeon_ctx->CurrentTexObj[1]; + + if ( 0 ) { + radeonDDPrintDirty( "radeonEmitHwStateLocked", radeon_ctx->dirty ); + } + + if ( (radeon_ctx->dirty & RADEON_UPLOAD_TEX0IMAGES) && t0 ) { + radeonUploadTexImages( radeon_ctx, t0 ); + } + if ( (radeon_ctx->dirty & RADEON_UPLOAD_TEX1IMAGES) && t1 ) { + radeonUploadTexImages( radeon_ctx, t1 ); + } + + if ( radeon_ctx->dirty & (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_VERTFMT | + RADEON_UPLOAD_LINE | + RADEON_UPLOAD_BUMPMAP | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_VIEWPORT | + RADEON_UPLOAD_SETUP | + RADEON_UPLOAD_TCL | + RADEON_UPLOAD_MISC | + RADEON_UPLOAD_TEX0) ) { + memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); + } + + if ( (radeon_ctx->dirty & RADEON_UPLOAD_TEX0) && t0 ) { + memcpy( &sarea->TexState[0], &t0->setup, sizeof(sarea->TexState[0]) ); + } + + if ( (radeon_ctx->dirty & RADEON_UPLOAD_TEX1) && t1 ) { + memcpy( &sarea->TexState[1], &t1->setup, sizeof(sarea->TexState[1]) ); + } + + sarea->vertsize = radeon_ctx->vertsize; + sarea->vc_format = radeon_ctx->vc_format; + +#if 0 + /* Turn off the texture cache flushing */ + radeon_ctx->setup.tex_cntl_c &= ~RADEON_TEX_CACHE_FLUSH; +#endif + + sarea->dirty |= radeon_ctx->dirty; + radeon_ctx->dirty &= RADEON_UPLOAD_CLIPRECTS; +} + +static void radeonDDPrintState( const char *msg, GLuint flags ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & RADEON_NEW_CONTEXT) ? "context, " : "", + (flags & RADEON_NEW_ALPHA) ? "alpha, " : "", + (flags & RADEON_NEW_DEPTH) ? "depth, " : "", + (flags & RADEON_NEW_FOG) ? "fog, " : "", + (flags & RADEON_NEW_CLIP) ? "clip, " : "", + (flags & RADEON_NEW_TEXTURE) ? "texture, " : "", + (flags & RADEON_NEW_CULL) ? "cull, " : "", + (flags & RADEON_NEW_MASKS) ? "masks, " : "", + (flags & RADEON_NEW_WINDOW) ? "window, " : "" ); +} + +/* Update the hardware state */ +void radeonDDUpdateHWState( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + int new_state = radeon_ctx->new_state; + + if ( new_state ) { + FLUSH_BATCH( radeon_ctx ); + + radeon_ctx->new_state = 0; + + if ( 0 ) + radeonDDPrintState( "radeonUpdateHwState", new_state ); + + /* Update the various parts of the context's state */ + if ( new_state & RADEON_NEW_ALPHA ) + radeonUpdateAlphaMode( ctx ); + + if ( new_state & RADEON_NEW_DEPTH ) + radeonUpdateZMode( ctx ); + + if ( new_state & RADEON_NEW_FOG ) + radeonUpdateFogAttrib( ctx ); + + if ( new_state & RADEON_NEW_CLIP ) + radeonUpdateClipping( ctx ); + + if ( new_state & RADEON_NEW_CULL ) + radeonUpdateCull( ctx ); + + if ( new_state & RADEON_NEW_MASKS ) + radeonUpdateMasks( ctx ); + + if ( new_state & RADEON_NEW_RENDER ) + radeonUpdateRenderAttrib( ctx ); + + if ( new_state & RADEON_NEW_WINDOW ) + radeonUpdateWindow( ctx ); + + if ( new_state & RADEON_NEW_TEXTURE ) + radeonUpdateTextureState( ctx ); + } +} + +/* This is called when Mesa switches between rendering triangle + * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc), + * and lines, points and bitmaps. + * + * As the radeon uses triangles to render lines and points, it is + * necessary to turn off hardware culling when rendering these + * primitives. + */ +static void radeonDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + CARD32 s = radeon_ctx->setup.se_cntl; + + s &= ~(RADEON_FFACE_CULL_MASK | RADEON_BFACE_CULL_MASK); + s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~RADEON_FFACE_CULL_MASK; + s |= RADEON_FFACE_CULL; + break; + case GL_BACK: + s &= ~RADEON_BFACE_CULL_MASK; + s |= RADEON_BFACE_CULL; + break; + case GL_FRONT_AND_BACK: + s &= ~(RADEON_FFACE_CULL_MASK | RADEON_BFACE_CULL_MASK); + s |= RADEON_FFACE_CULL | RADEON_BFACE_CULL; + break; + } + } + + if ( radeon_ctx->setup.se_cntl != s ) { + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->setup.se_cntl = s; + + /* NOTE: Only upload the setup state, everything else has been + * uploaded by the usual means already. Also, note that this is + * an optimization (see comment in the kernel's radeon_state.c), + * which will not be necessary when/if we use the Radeon's + * native point/line support. + */ + radeon_ctx->dirty |= RADEON_UPLOAD_SETUP; + } +} + + +#define INTERESTED (~(NEW_MODELVIEW | \ + NEW_PROJECTION | \ + NEW_TEXTURE_MATRIX | \ + NEW_USER_CLIP | \ + NEW_CLIENT_STATE | \ + NEW_TEXTURE_ENABLE)) + +void radeonDDUpdateState( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + /* Need to do this here to detect texture fallbacks before + * setting triangle functions. + */ + if ( radeon_ctx->new_state & RADEON_NEW_TEXTURE ) { + radeonDDUpdateHWState( ctx ); + } + + if ( 1 /*ctx->NewState & INTERESTED*/ ) { + radeonDDChooseRenderState( ctx ); + radeonDDChooseRasterSetupFunc( ctx ); + } + + if ( !radeon_ctx->Fallback ) { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= radeon_ctx->IndirectTriangles; + + ctx->Driver.PointsFunc = radeon_ctx->PointsFunc; + ctx->Driver.LineFunc = radeon_ctx->LineFunc; + ctx->Driver.TriangleFunc = radeon_ctx->TriangleFunc; + ctx->Driver.QuadFunc = radeon_ctx->QuadFunc; + } +} + + +/* Initialize the context's hardware state */ +void radeonDDInitState( radeonContextPtr radeon_ctx ) +{ + int color_fmt, depth_fmt; + float f; + + switch ( radeon_ctx->BufferSize ) { + case 8: color_fmt = RADEON_COLOR_FORMAT_RGB332; break; + case 15: color_fmt = RADEON_COLOR_FORMAT_ARGB1555; break; + case 16: color_fmt = RADEON_COLOR_FORMAT_RGB565; break; + case 24: color_fmt = RADEON_COLOR_FORMAT_RGB8; break; + case 32: color_fmt = RADEON_COLOR_FORMAT_ARGB8888; break; + default: + fprintf( stderr, "Error: Unsupported pixel depth %d... exiting\n", + radeon_ctx->BufferSize ); + exit( -1 ); + } + + switch ( radeon_ctx->DepthSize ) { + case 16: + radeon_ctx->ClearDepth = 0x0000ffff; + depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + radeon_ctx->depth_scale = 1.0 / 65536.0; + break; + case 24: + radeon_ctx->ClearDepth = 0x00ffffff; + depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + radeon_ctx->depth_scale = 1.0 / 16777216.0; + break; + case 32: + radeon_ctx->ClearDepth = 0xffffffff; + depth_fmt = RADEON_DEPTH_FORMAT_32BIT_INT_Z; + radeon_ctx->depth_scale = 1.0 / 4294967296.0; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + radeon_ctx->DepthSize ); + exit( -1 ); + } + + radeon_ctx->ClearColor = 0x00000000; + + radeon_ctx->RenderIndex = RADEON_FALLBACK_BIT; + radeon_ctx->PointsFunc = NULL; + radeon_ctx->LineFunc = NULL; + radeon_ctx->TriangleFunc = NULL; + radeon_ctx->QuadFunc = NULL; + + radeon_ctx->IndirectTriangles = 0; + radeon_ctx->Fallback = 0; + + if ( radeon_ctx->glCtx->Visual->DBflag ) { + radeon_ctx->DrawBuffer = GL_BACK_LEFT; + radeon_ctx->drawOffset = radeon_ctx->readOffset = + radeon_ctx->radeonScreen->backOffset; + radeon_ctx->drawPitch = radeon_ctx->readPitch = + radeon_ctx->radeonScreen->backPitch; + } else { + radeon_ctx->DrawBuffer = GL_FRONT_LEFT; + radeon_ctx->drawOffset = radeon_ctx->readOffset = + radeon_ctx->radeonScreen->frontOffset; + radeon_ctx->drawPitch = radeon_ctx->readPitch = + radeon_ctx->radeonScreen->frontPitch; + } + + /* Harware state: */ + radeon_ctx->setup.pp_misc = + RADEON_ALPHA_TEST_PASS | + RADEON_CHROMA_FUNC_FAIL | + RADEON_CHROMA_KEY_NEAREST | + RADEON_SHADOW_FUNC_EQUAL | + RADEON_SHADOW_PASS_1 | + RADEON_RIGHT_HAND_CUBE_OGL; + radeon_ctx->setup.pp_fog_color = + (0x00000000 & RADEON_FOG_COLOR_MASK) | + RADEON_FOG_VERTEX | + RADEON_FOG_USE_DEPTH; + radeon_ctx->setup.re_solid_color = 0x00000000; + radeon_ctx->setup.rb3d_blendcntl = + RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO; + radeon_ctx->setup.rb3d_depthoffset = 0x00000000; + radeon_ctx->setup.rb3d_depthpitch = + (radeon_ctx->radeonScreen->depthPitch & RADEON_DEPTHPITCH_MASK) | + RADEON_DEPTH_ENDIAN_NO_SWAP; + radeon_ctx->setup.rb3d_zstencilcntl = + depth_fmt | + RADEON_Z_TEST_LESS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE; + + radeon_ctx->setup.pp_cntl = RADEON_ANTI_ALIAS_NONE; + radeon_ctx->setup.rb3d_cntl = + RADEON_Z_ENABLE | + color_fmt | + RADEON_ZBLOCK8; + radeon_ctx->setup.rb3d_coloroffset = + (radeon_ctx->drawOffset & RADEON_COLOROFFSET_MASK); + radeon_ctx->setup.re_width_height = + (2047 << RADEON_RE_WIDTH_SHIFT) | + (2047 << RADEON_RE_HEIGHT_SHIFT); + radeon_ctx->setup.rb3d_colorpitch = + (radeon_ctx->drawPitch & RADEON_COLORPITCH_MASK) | + RADEON_COLOR_ENDIAN_NO_SWAP; + radeon_ctx->setup.se_cntl = + RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD | + /* RADEON_VPORT_XY_XFORM_ENABLE | */ + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_16TH_PIX; + + radeon_ctx->setup.se_coord_fmt = + RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | + RADEON_VTX_ST0_PRE_MULT_1_OVER_W0 | + RADEON_VTX_ST1_PRE_MULT_1_OVER_W0 | + RADEON_VTX_ST2_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1; + + radeon_ctx->setup.re_line_pattern = + (0x0000 & RADEON_LINE_PATTERN_MASK) | + (0 << RADEON_LINE_REPEAT_COUNT_SHIFT) | + (0 << RADEON_LINE_PATTERN_START_SHIFT) | + RADEON_LINE_PATTERN_LITTLE_BIT_ORDER; + radeon_ctx->setup.re_line_state = + (0 << RADEON_LINE_CURRENT_PTR_SHIFT) | + (0 << RADEON_LINE_CURRENT_COUNT_SHIFT); + + radeon_ctx->setup.se_line_width = 0x00000000; + + radeon_ctx->setup.pp_lum_matrix = 0x00000000; + + radeon_ctx->setup.pp_rot_matrix_0 = 0x00000000; + radeon_ctx->setup.pp_rot_matrix_1 = 0x00000000; + + radeon_ctx->setup.rb3d_stencilrefmask = + (0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT); + radeon_ctx->setup.rb3d_ropcntl = 0x00000000; + radeon_ctx->setup.rb3d_planemask = 0xffffffff; + + f = 0.0; + radeon_ctx->setup.se_vport_xscale = RADEON_FLOAT_TO_DWORD(f); + radeon_ctx->setup.se_vport_xoffset = RADEON_FLOAT_TO_DWORD(f); + radeon_ctx->setup.se_vport_yscale = RADEON_FLOAT_TO_DWORD(f); + radeon_ctx->setup.se_vport_yoffset = RADEON_FLOAT_TO_DWORD(f); + radeon_ctx->setup.se_vport_zscale = RADEON_FLOAT_TO_DWORD(f); + radeon_ctx->setup.se_vport_zoffset = RADEON_FLOAT_TO_DWORD(f); + + radeon_ctx->setup.se_cntl_status = + RADEON_VC_NO_SWAP; + /* | RADEON_TCL_BYPASS;*/ + +#ifdef TCL_ENABLE + /* FIXME: Obviously these need to be properly initialized */ + radeon_ctx->setup.se_tcl_material_emmissive.red = 0x00000000; + radeon_ctx->setup.se_tcl_material_emmissive.green = 0x00000000; + radeon_ctx->setup.se_tcl_material_emmissive.blue = 0x00000000; + radeon_ctx->setup.se_tcl_material_emmissive.alpha = 0x00000000; + + radeon_ctx->setup.se_tcl_material_ambient.red = 0x00000000; + radeon_ctx->setup.se_tcl_material_ambient.green = 0x00000000; + radeon_ctx->setup.se_tcl_material_ambient.blue = 0x00000000; + radeon_ctx->setup.se_tcl_material_ambient.alpha = 0x00000000; + + radeon_ctx->setup.se_tcl_material_diffuse.red = 0x00000000; + radeon_ctx->setup.se_tcl_material_diffuse.green = 0x00000000; + radeon_ctx->setup.se_tcl_material_diffuse.blue = 0x00000000; + radeon_ctx->setup.se_tcl_material_diffuse.alpha = 0x00000000; + + radeon_ctx->setup.se_tcl_material_specular.red = 0x00000000; + radeon_ctx->setup.se_tcl_material_specular.green = 0x00000000; + radeon_ctx->setup.se_tcl_material_specular.blue = 0x00000000; + radeon_ctx->setup.se_tcl_material_specular.alpha = 0x00000000; + + radeon_ctx->setup.se_tcl_shininess = 0x00000000; + radeon_ctx->setup.se_tcl_output_vtx_fmt = 0x00000000; + radeon_ctx->setup.se_tcl_output_vtx_sel = 0x00000000; + radeon_ctx->setup.se_tcl_matrix_select_0 = 0x00000000; + radeon_ctx->setup.se_tcl_matrix_select_1 = 0x00000000; + radeon_ctx->setup.se_tcl_ucp_vert_blend_ctl = 0x00000000; + radeon_ctx->setup.se_tcl_texture_proc_ctl = 0x00000000; + radeon_ctx->setup.se_tcl_light_model_ctl = 0x00000000; + for (i = 0; i < 4; i++) + radeon_ctx->setup.se_tcl_per_light_ctl[i] = 0x00000000; +#endif + + radeon_ctx->setup.re_top_left = + (0 << RADEON_RE_LEFT_SHIFT) | + (0 << RADEON_RE_TOP_SHIFT); + radeon_ctx->setup.re_misc = + (0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | + RADEON_STIPPLE_LITTLE_BIT_ORDER; + + radeon_ctx->new_state = RADEON_NEW_ALL; +} + +/* Initialize the driver's state functions */ +void radeonDDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = radeonDDUpdateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = radeonDDClearColor; + ctx->Driver.Index = NULL; + ctx->Driver.Color = radeonDDColor; + ctx->Driver.SetDrawBuffer = radeonDDSetDrawBuffer; + ctx->Driver.SetReadBuffer = radeonDDSetReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = radeonDDColorMask; + ctx->Driver.LogicOp = NULL; +#if 0 + ctx->Driver.Dither = radeonDDDither; +#else + ctx->Driver.Dither = NULL; +#endif + + ctx->Driver.NearFar = NULL; + + ctx->Driver.RenderStart = radeonDDUpdateHWState; + ctx->Driver.RenderFinish = NULL; + ctx->Driver.RasterSetup = NULL; + + ctx->Driver.RenderVBClippedTab = NULL; + ctx->Driver.RenderVBCulledTab = NULL; + ctx->Driver.RenderVBRawTab = NULL; + + ctx->Driver.ReducedPrimitiveChange = radeonDDReducedPrimitiveChange; + ctx->Driver.MultipassFunc = NULL; + + ctx->Driver.AlphaFunc = radeonDDAlphaFunc; + ctx->Driver.BlendEquation = radeonDDBlendEquation; + ctx->Driver.BlendFunc = radeonDDBlendFunc; + ctx->Driver.BlendFuncSeparate = radeonDDBlendFuncSeparate; + ctx->Driver.ClearDepth = radeonDDClearDepth; + ctx->Driver.CullFace = radeonDDCullFace; + ctx->Driver.FrontFace = radeonDDFrontFace; + ctx->Driver.DepthFunc = radeonDDDepthFunc; + ctx->Driver.DepthMask = radeonDDDepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = radeonDDEnable; + ctx->Driver.Fogfv = radeonDDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = radeonDDLightModelfv; + ctx->Driver.LogicOpcode = radeonDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = radeonDDPolygonStipple; + ctx->Driver.Scissor = radeonDDScissor; + ctx->Driver.ShadeModel = radeonDDShadeModel; + ctx->Driver.ClearStencil = NULL; + ctx->Driver.StencilFunc = NULL; + ctx->Driver.StencilMask = NULL; + ctx->Driver.StencilOp = NULL; + ctx->Driver.Viewport = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h new file mode 100644 index 000000000..2fadc4973 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h @@ -0,0 +1,57 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_STATE_H_ +#define _RADEON_STATE_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_context.h" + +extern void radeonDDInitState( radeonContextPtr radeon_ctx ); +extern void radeonDDInitStateFuncs( GLcontext *ctx ); + +extern void radeonDDUpdateState( GLcontext *ctx ); +extern void radeonDDUpdateHWState( GLcontext *ctx ); + +extern void radeonUpdateWindow( GLcontext *ctx ); +extern void radeonSetClipRects( radeonContextPtr radeon_ctx, + XF86DRIClipRectPtr pc, int nc ); + +extern void radeonEmitHwStateLocked( radeonContextPtr radeon_ctx ); + +#endif +#endif /* _RADEON_STATE_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c new file mode 100644 index 000000000..055811073 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -0,0 +1,1663 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "simple_list.h" +#include "enums.h" +#include "mem.h" + +#define RADEON_BLIT_BUFFER_SHIFT 11 + + +static void radeonSetTexWrap(radeonTexObjPtr t, GLenum srwap, GLenum twrap); +static void radeonSetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf); +static void radeonSetTexBorderColor(radeonTexObjPtr t, GLubyte c[4]); + +/* Allocate and initialize hardware state associated with texture `t' */ +/* NOTE: This function is only called while holding the hardware lock */ +static radeonTexObjPtr radeonCreateTexObj( radeonContextPtr radeon_ctx, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t; + struct gl_texture_image *image; + int log2Pitch, log2Height, log2Size, log2MinSize; + int totalSize; + int i; + + image = tObj->Image[0]; + if ( !image ) + return NULL; + + t = (radeonTexObjPtr)CALLOC( sizeof(*t) ); + if ( !t ) + return NULL; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj ); + + switch ( image->Format ) { + case GL_RGBA: + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + if ( radeon_ctx->radeonScreen->bpp == 32 ) { + t->texelBytes = 4; +#if 0 + t->textureFormat = RADEON_DATATYPE_ARGB8888; +#endif + } else { + t->texelBytes = 2; +#if 0 + t->textureFormat = RADEON_DATATYPE_ARGB4444; +#endif + } + break; + + case GL_RGB: + if ( radeon_ctx->radeonScreen->bpp == 32 ) { + t->texelBytes = 4; +#if 0 + t->textureFormat = RADEON_DATATYPE_ARGB8888; +#endif + } else { + t->texelBytes = 2; +#if 0 + t->textureFormat = RADEON_DATATYPE_RGB565; +#endif + } + break; + + case GL_LUMINANCE: + if ( radeon_ctx->radeonScreen->bpp == 32 ) { + t->texelBytes = 4; +#if 0 + t->textureFormat = RADEON_DATATYPE_ARGB8888; +#endif + } else { + t->texelBytes = 2; + /* Use this to get true greys */ +#if 0 + t->textureFormat = RADEON_DATATYPE_ARGB1555; +#endif + } + break; + + case GL_COLOR_INDEX: + t->texelBytes = 1; +#if 0 + t->textureFormat = RADEON_DATATYPE_CI8; +#endif + break; + + default: + fprintf( stderr, "%s: bad image->Format\n", __FUNCTION__ ); + FREE( t ); + return NULL; + } + + /* Calculate dimensions in log domain */ + for ( i = 1, log2Height = 0 ; i < image->Height ; i *= 2 ) { + log2Height++; + } + for ( i = 1, log2Pitch = 0 ; i < image->Width ; i *= 2 ) { + log2Pitch++; + } + if ( image->Width > image->Height ) { + log2Size = log2Pitch; + } else { + log2Size = log2Height; + } + + t->dirty_images = 0; + + /* Calculate mipmap offsets and dimensions */ + totalSize = 0; + for ( i = 0 ; i <= log2Size && tObj->Image[i] ; i++ ) { + t->image[i].offset = totalSize; + t->image[i].width = tObj->Image[i]->Width; + t->image[i].height = tObj->Image[i]->Height; + + t->dirty_images |= (1 << i); + + totalSize += (tObj->Image[i]->Height * + tObj->Image[i]->Width * + t->texelBytes); + + /* Offsets must be 32-byte aligned for host data blits */ + totalSize = (totalSize + 31) & ~31; + } + log2MinSize = log2Size - i + 1; + + t->totalSize = totalSize; + t->internFormat = image->IntFormat; + + t->bound = 0; + t->heap = 0; + t->tObj = tObj; + + t->memBlock = NULL; + t->bufAddr = NULL; + + /* Hardware state: + */ +#if 0 + t->setup.tex_cntl = (RADEON_MIN_BLEND_NEAREST | + RADEON_MAG_BLEND_NEAREST | + RADEON_TEX_CLAMP_S_WRAP | + RADEON_TEX_CLAMP_T_WRAP | + t->textureFormat); + + t->setup.tex_combine_cntl = 0x00000000; + + t->setup.tex_size_pitch = ((log2Pitch << RADEON_TEX_PITCH_SHIFT) | + (log2Size << RADEON_TEX_SIZE_SHIFT) | + (log2Height << RADEON_TEX_HEIGHT_SHIFT) | + (log2MinSize << RADEON_TEX_MIN_SIZE_SHIFT)); + + for ( i = 0 ; i < RADEON_TEX_MAXLEVELS ; i++ ) { + t->setup.tex_offset[i] = 0x00000000; + } + t->setup.tex_border_color = 0x00000000; + + if ( ( log2MinSize == log2Size ) || ( log2MinSize != 0 ) ) { + t->setup.tex_cntl |= RADEON_MIP_MAP_DISABLE; + } +#endif + + radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); + radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + radeonSetTexBorderColor( t, tObj->BorderColor ); + + tObj->DriverData = t; + + make_empty_list( t ); + + return t; +} + +/* Destroy hardware state associated with texture `t' */ +void radeonDestroyTexObj( radeonContextPtr radeon_ctx, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + radeon_ctx->c_textureSwaps++; +#endif + if ( !t ) return; + + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + if ( t->tObj ) + t->tObj->DriverData = NULL; + if ( t->bound ) + radeon_ctx->CurrentTexObj[t->bound-1] = NULL; + + remove_from_list( t ); + FREE( t ); +} + +/* Keep track of swapped out texture objects */ +static void radeonSwapOutTexObj( radeonContextPtr radeon_ctx, + radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + radeon_ctx->c_textureSwaps++; +#endif + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + t->dirty_images = ~0; + move_to_tail( &radeon_ctx->SwappedOut, t ); +} + +/* Print out debugging information about texture LRU */ +void radeonPrintLocalLRU( radeonContextPtr radeon_ctx, int heap ) +{ + radeonTexObjPtr t; + int sz = 1 << (radeon_ctx->radeonScreen->log2TexGran[heap]); + + foreach(t, &radeon_ctx->TexObjList[heap]) { + if (!t->tObj) { + fprintf(stderr, "Placeholder %d at 0x%x sz 0x%x\n", + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size); + } else { + fprintf(stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", + t->bound, + t->memBlock->ofs, + t->memBlock->size); + } + } +} + +void radeonPrintGlobalLRU( radeonContextPtr radeon_ctx, int heap ) +{ + radeon_tex_region_t *list = radeon_ctx->sarea->texList[heap]; + int i, j; + + for (i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_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 == RADEON_NR_TEX_REGIONS) break; + } + + if (j != RADEON_NR_TEX_REGIONS) { + fprintf(stderr, "Loop detected in global LRU\n"); + } +} + +/* Reset the global texture LRU */ +/* NOTE: This function is only called while holding the hardware lock */ +static void radeonResetGlobalLRU(radeonContextPtr radeon_ctx, int heap) +{ + radeon_tex_region_t *list = radeon_ctx->sarea->texList[heap]; + int log2sz = 1 << radeon_ctx->radeonScreen->log2TexGran[heap]; + int i; + + /* + * (Re)initialize the global circular LRU list. The last element in + * the array (RADEON_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) * log2sz <= radeon_ctx->radeonScreen->texSize[heap]; + i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = RADEON_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = RADEON_NR_TEX_REGIONS; + list[RADEON_NR_TEX_REGIONS].prev = i; + list[RADEON_NR_TEX_REGIONS].next = 0; + radeon_ctx->sarea->texAge[heap] = 0; +} + +/* Update the local and glock texture LRUs */ +/* NOTE: This function is only called while holding the hardware lock */ +static void radeonUpdateTexLRU(radeonContextPtr radeon_ctx, radeonTexObjPtr t) +{ + int heap = t->heap; + radeon_tex_region_t *list = radeon_ctx->sarea->texList[heap]; + int log2sz = radeon_ctx->radeonScreen->log2TexGran[heap]; + + int start = t->memBlock->ofs >> log2sz; + int end = (t->memBlock->ofs + t->memBlock->size-1) >> log2sz; + int i; + + radeon_ctx->lastTexAge[heap] = ++radeon_ctx->sarea->texAge[heap]; + + /* Update our local LRU */ + move_to_head(&radeon_ctx->TexObjList[heap], t); + + /* Update the global LRU */ + for (i = start ; i <= end ; i++) { + list[i].in_use = 1; + list[i].age = radeon_ctx->lastTexAge[heap]; + + /* remove_from_list(i) */ + list[(CARD32)list[i].next].prev = list[i].prev; + list[(CARD32)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) */ + list[i].prev = RADEON_NR_TEX_REGIONS; + list[i].next = list[RADEON_NR_TEX_REGIONS].next; + list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; + list[RADEON_NR_TEX_REGIONS].next = i; + } +} + +/* Update our notion of what textures have been changed since we last + held the lock. This pertains to both our local textures and the + textures belonging to other clients. Keep track of other client's + textures by pushing a placeholder texture onto the LRU list -- these + are denoted by (tObj == NULL). */ +/* NOTE: This function is only called while holding the hardware lock */ +static void radeonTexturesGone(radeonContextPtr radeon_ctx, int heap, + int offset, int size, int in_use) +{ + radeonTexObjPtr t, tmp; + + foreach_s (t, tmp, &radeon_ctx->TexObjList[heap]) { + if (t->memBlock->ofs >= offset + size || + t->memBlock->ofs + t->memBlock->size <= offset) + continue; + + /* It overlaps - kick it out. Need to hold onto the currently + bound objects, however. */ + if (t->bound) radeonSwapOutTexObj(radeon_ctx, t); + else radeonDestroyTexObj(radeon_ctx, t); + } + + if (in_use) { + t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); + if (!t) return; + + t->memBlock = mmAllocMem(radeon_ctx->texHeap[heap], size, 0, offset); + insert_at_head(&radeon_ctx->TexObjList[heap], t); + } +} + +/* Update our client's shared texture state. If another client has + modified a region in which we have textures, then we need to figure + out which of our textures has been removed, and update our global + LRU. */ +void radeonAgeTextures(radeonContextPtr radeon_ctx, int heap) +{ + RADEONSAREAPriv *sarea = radeon_ctx->sarea; + + if (sarea->texAge[heap] != radeon_ctx->lastTexAge[heap]) { + int log2sz = 1 << radeon_ctx->radeonScreen->log2TexGran[heap]; + int nr = 0; + int idx; + + for (idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev; + idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS; + idx = sarea->texList[heap][idx].prev, nr++) { + + /* If switching texturing schemes, then the SAREA might not + have been properly cleared, so we need to reset the + global texture LRU. */ + if (idx * log2sz > radeon_ctx->radeonScreen->texSize[heap]) { + nr = RADEON_NR_TEX_REGIONS; + break; + } + + if (sarea->texList[heap][idx].age > radeon_ctx->lastTexAge[heap]) + radeonTexturesGone(radeon_ctx, heap, idx * log2sz, log2sz, + sarea->texList[heap][idx].in_use); + } + + if (nr == RADEON_NR_TEX_REGIONS) { + radeonTexturesGone(radeon_ctx, heap, + 0, radeon_ctx->radeonScreen->texSize[heap], 0); + radeonResetGlobalLRU(radeon_ctx, heap); + } + + radeon_ctx->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES); + radeon_ctx->lastTexAge[heap] = sarea->texAge[heap]; + } +} + +/* Convert a block of Mesa-formatted texture to an 8bpp hardware format */ +static void radeonConvertTexture8bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + switch ( image->Format ) { + case GL_RGB: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width >> 2 ; j ; j-- ) { + *dst++= ((RADEONPACKCOLOR332( src[0], src[1], src[2] )) | + (RADEONPACKCOLOR332( src[3], src[4], src[5] ) << 8) | + (RADEONPACKCOLOR332( src[6], src[7], src[8] ) << 16) | + (RADEONPACKCOLOR332( src[9], src[10], src[11] ) << 24)); + src += 12; + } + } + break; + + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_COLOR_INDEX: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 2 ; j ; j-- ) { + *dst++ = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + src += 4; + } + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} + +/* Convert a block of Mesa-formatted texture to a 16bpp hardware format */ +static void radeonConvertTexture16bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s: %d,%d at %d,%d\n", + __FUNCTION__, width, height, x, y ); + } + + + switch ( image->Format ) { + case GL_RGB: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR565( src[0], src[1], src[2] )) | + (RADEONPACKCOLOR565( src[3], src[4], src[5] ) << 16)); + src += 6; + } + } + break; + + case GL_RGBA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR4444( src[0], src[1], src[2], src[3] )) | + (RADEONPACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16)); + src += 8; + } + } + break; + + case GL_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) | + (RADEONPACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16)); + src += 2; + } + } + break; + + case GL_LUMINANCE: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR1555( src[0], src[0], src[0], 0xff )) | + (RADEONPACKCOLOR1555( src[1], src[1], src[1], 0xff ) << 16)); + src += 2; + } + } + break; + + case GL_LUMINANCE_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR4444( src[0], src[0], src[0], src[1] )) | + (RADEONPACKCOLOR4444( src[2], src[2], src[2], src[3] ) << 16)); + src += 4; + } + } + break; + + case GL_INTENSITY: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR4444( src[0], src[0], src[0], src[0] )) | + (RADEONPACKCOLOR4444( src[1], src[1], src[1], src[1] ) << 16)); + src += 2; + } + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} + +/* Convert a block of Mesa-formatted texture to a 32bpp hardware format */ +static void radeonConvertTexture32bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + switch ( image->Format ) { + case GL_RGB: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], 0xff ); + src += 3; + } + } + break; + + case GL_RGBA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], src[3] ); + src += 4; + } + } + break; + + case GL_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( 0xff, 0xff, 0xff, src[0] ); + src += 1; + } + } + break; + + case GL_LUMINANCE: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[0], src[0], 0xff ); + src += 1; + } + } + break; + + case GL_LUMINANCE_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[0], src[0], src[1] ); + src += 2; + } + } + break; + + case GL_INTENSITY: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[0], src[0], src[0] ); + src += 1; + } + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} + +/* Upload the texture image associated with texture `t' at level `level' + at the address relative to `start'. */ +/* NOTE: This function is only called while holding the hardware lock */ +static void radeonUploadSubImage( radeonContextPtr radeon_ctx, + radeonTexObjPtr t, int level, + int x, int y, int width, int height ) +{ + struct gl_texture_image *image; + int texelsPerDword = 0; + int imageWidth, imageHeight; + int remaining, rows; + int format, dwords, buffers; + CARD32 pitch, offset; + drmBufPtr buffer; + drmRadeonBlitRectPtr blit; + CARD32 *dst; + int i; + + /* Ensure we have a valid texture to upload */ + if ( ( level < 0 ) || ( level > RADEON_TEX_MAXLEVELS ) ) + return; + + image = t->tObj->Image[level]; + if ( !image ) + return; + + switch ( t->texelBytes ) { + case 1: texelsPerDword = 4; break; + case 2: texelsPerDword = 2; break; + case 4: texelsPerDword = 1; break; + } + +#if 1 + /* FIXME: The subimage index calcs are wrong - who changed them? */ + x = 0; + y = 0; + width = image->Width; + height = image->Height; +#endif + + imageWidth = image->Width; + imageHeight = image->Height; + + format = t->textureFormat >> 16; + + /* The texel upload routines have a minimum width, so force the size + * if needed. + */ + if ( imageWidth < texelsPerDword ) { + int factor; + + factor = texelsPerDword / imageWidth; + imageWidth = texelsPerDword; + imageHeight /= factor; + if ( imageHeight == 0 ) { + /* In this case, the texel converter will actually walk a + * texel or two off the end of the image, but normal malloc + * alignment should prevent it from ever causing a fault. + */ + imageHeight = 1; + } + } + + /* We can't upload to a pitch less than 8 texels so we will need to + * linearly upload all modified rows for textures smaller than this. + * This makes the x/y/width/height different for the blitter and the + * texture walker. + */ + if ( imageWidth >= 8 ) { + /* The texture walker and the blitter look identical */ + pitch = imageWidth >> 3; + } else { + int factor; + int y2; + int start, end; + + start = (y * imageWidth) & ~7; + end = (y + height) * imageWidth; + + if ( end - start < 8 ) { + /* Handle the case where the total number of texels + * uploaded is < 8. + */ + x = 0; + y = start / 8; + width = end - start; + height = 1; + } else { + /* Upload some number of full 8 texel blit rows */ + factor = 8 / imageWidth; + + y2 = y + height - 1; + y /= factor; + y2 /= factor; + + x = 0; + width = 8; + height = y2 - y + 1; + } + + /* Fixed pitch of 8 */ + pitch = 1; + } + + dwords = width * height / texelsPerDword; + offset = (CARD32)(t->bufAddr + t->image[level].offset); + + /* Fix offset for AGP textures */ + if ( t->heap == RADEON_AGP_TEX_HEAP ) { + offset += RADEON_AGP_TEX_OFFSET + radeon_ctx->radeonScreen->agpTexOffset; + } + +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + radeon_ctx->c_textureBytes += (dwords << 2); +#endif + + /* Grab the indirect buffers for the texture blit */ + buffers = ((dwords + (1 << RADEON_BLIT_BUFFER_SHIFT) - 1) >> + RADEON_BLIT_BUFFER_SHIFT); + radeonGetBlitBuffersLocked( radeon_ctx, buffers ); + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "radeonUploadSubImage: %d,%d of %d,%d at %d,%d\n", + width, height, image->Width, image->Height, x, y ); + fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d " + "level: %d format: %x\n", + (int)offset, pitch, dwords, level, format ); + } + + /* Subdivide the texture if required */ + if ( dwords <= RADEON_CP_PACKET_MAX_DWORDS / 2 ) { + rows = height; + } else { + rows = (RADEON_CP_PACKET_MAX_DWORDS * texelsPerDword) / (2 * width); + } + + for ( i = 0, remaining = height ; + remaining > 0 ; + remaining -= rows, y += rows, i++ ) + { + height = (remaining >= rows) ? rows : remaining; + dwords = width * height / texelsPerDword; + + buffer = radeon_ctx->BlitBuffers[i]; + blit = (drmRadeonBlitRectPtr) &radeon_ctx->BlitRects[i]; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, " blitting: %d,%d at %d,%d - %d dwords\n", + width, height, x, y, dwords ); + } + + blit->x = x; + blit->y = y; + blit->width = width; + blit->height = height; + + dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET); + + /* Actually do the texture conversion */ + switch ( t->texelBytes ) { + case 1: + radeonConvertTexture8bpp( dst, image, + x, y, width, height, width ); + break; + case 2: + radeonConvertTexture16bpp( dst, image, + x, y, width, height, width ); + break; + case 4: + radeonConvertTexture32bpp( dst, image, + x, y, width, height, width ); + break; + } + } + + radeonFireBlitLocked( radeon_ctx, offset, pitch, format ); + + radeon_ctx->new_state |= RADEON_NEW_CONTEXT; + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; +} + +/* Upload the texture images associated with texture `t'. This might + * require removing our own and/or other client's texture objects to + * make room for these images. + */ +/* NOTE: This function is only called while holding the hardware lock */ +int radeonUploadTexImages( radeonContextPtr radeon_ctx, radeonTexObjPtr t ) +{ + int i; + int minLevel; + int maxLevel; + int heap; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %p )\n", + __FUNCTION__, radeon_ctx->glCtx, t ); + } + + if ( !t ) return 0; + + /* Choose the heap appropriately */ + heap = t->heap = RADEON_LOCAL_TEX_HEAP; + if ( !radeon_ctx->radeonScreen->IsPCI && + t->totalSize > radeon_ctx->radeonScreen->texSize[heap] ) { + heap = t->heap = RADEON_AGP_TEX_HEAP; + } + + /* Do we need to eject LRU texture objects? */ + if ( !t->memBlock ) { + /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ + t->memBlock = mmAllocMem( radeon_ctx->texHeap[heap], + t->totalSize, 12, 0 ); + + /* Try AGP before kicking anything out of local mem */ + if ( !t->memBlock && heap == RADEON_LOCAL_TEX_HEAP ) { + t->memBlock = mmAllocMem( radeon_ctx->texHeap[RADEON_AGP_TEX_HEAP], + t->totalSize, 12, 0 ); + + if ( t->memBlock ) + heap = t->heap = RADEON_AGP_TEX_HEAP; + } + + /* Kick out textures until the requested texture fits */ + while ( !t->memBlock ) { + if ( radeon_ctx->TexObjList[heap].prev->bound ) { + fprintf( stderr, + "radeonUploadTexImages: ran into bound texture\n" ); + return -1; + } + if ( radeon_ctx->TexObjList[heap].prev == + &radeon_ctx->TexObjList[heap] ) { + if ( radeon_ctx->radeonScreen->IsPCI ) { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on local texture heaps, sz=%d\n", + t->totalSize ); + return -1; + } else if ( heap == RADEON_LOCAL_TEX_HEAP ) { + heap = t->heap = RADEON_AGP_TEX_HEAP; + continue; + } else { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize ); + return -1; + } + } + + radeonDestroyTexObj( radeon_ctx, radeon_ctx->TexObjList[heap].prev ); + + t->memBlock = mmAllocMem( radeon_ctx->texHeap[heap], + t->totalSize, 12, 0 ); + } + + /* Set the base offset of the texture image */ + t->bufAddr = (unsigned char *)radeon_ctx->radeonScreen->texOffset[heap]; + t->bufAddr += t->memBlock->ofs; + +#if 0 + maxLevel = ((t->setup.tex_size_pitch & RADEON_TEX_SIZE_MASK) >> + RADEON_TEX_SIZE_SHIFT); + minLevel = ((t->setup.tex_size_pitch & RADEON_TEX_MIN_SIZE_MASK) >> + RADEON_TEX_MIN_SIZE_SHIFT); + + /* Set texture offsets */ + if ( t->setup.tex_cntl & RADEON_MIP_MAP_DISABLE ) { + for ( i = 0 ; i < RADEON_TEX_MAXLEVELS ; i++ ) { + t->setup.tex_offset[i] = (CARD32)t->bufAddr; + } + } else { + for ( i = maxLevel ; i >= minLevel ; i-- ) { + t->setup.tex_offset[i] = + t->image[maxLevel-i].offset + (CARD32)t->bufAddr; + } + } + /* Fix AGP texture offsets */ + if ( heap == RADEON_AGP_TEX_HEAP ) { + for ( i = 0 ; i < RADEON_TEX_MAXLEVELS ; i++ ) { + t->setup.tex_offset[i] += RADEON_AGP_TEX_OFFSET + + radeon_ctx->radeonScreen->agpTexOffset; + } + } +#endif + + /* Force loading the new state into the hardware */ + switch ( t->bound ) { + case 1: + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0; + break; + + case 2: + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1; + break; + + default: + return -1; + } + } + + /* Let the world know we've used this memory recently */ + radeonUpdateTexLRU( radeon_ctx, t ); + + /* Upload any images that are new */ + if ( t->dirty_images ) { +#if 0 + int num_levels = (((t->setup.tex_size_pitch & RADEON_TEX_SIZE_MASK) >> + RADEON_TEX_SIZE_SHIFT) - + ((t->setup.tex_size_pitch & RADEON_TEX_MIN_SIZE_MASK) >> + RADEON_TEX_MIN_SIZE_SHIFT)); + + for ( i = 0 ; i <= num_levels ; i++ ) { + if ( t->dirty_images & (1 << i) ) { + radeonUploadSubImage( radeon_ctx, t, i, 0, 0, + t->image[i].width, t->image[i].height ); + } + } + + radeon_ctx->setup.tex_cntl_c |= RADEON_TEX_CACHE_FLUSH; +#endif + + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT; + } + + t->dirty_images = 0; + return 0; +} + + +/* + * Texture combiners: + */ + +#if 1 +#define COLOR_COMB_DISABLE 0 +#define COLOR_COMB_COPY_INPUT 0 +#define COLOR_COMB_MODULATE 0 +#define COLOR_COMB_MODULATE_NTEX 0 +#define COLOR_COMB_ADD 0 +#define COLOR_COMB_BLEND_TEX 0 +#define ALPHA_COMB_DISABLE 0 +#define ALPHA_COMB_COPY_INPUT 0 +#define ALPHA_COMB_MODULATE 0 +#define ALPHA_COMB_MODULATE_NTEX 0 +#define INPUT_INTERP 0 +#define INPUT_PREVIOUS 0 +#else +#define COLOR_COMB_DISABLE (RADEON_COMB_DIS | \ + RADEON_COLOR_FACTOR_TEX) +#define COLOR_COMB_COPY_INPUT (RADEON_COMB_COPY_INP | \ + RADEON_COLOR_FACTOR_TEX) +#define COLOR_COMB_MODULATE (RADEON_COMB_MODULATE | \ + RADEON_COLOR_FACTOR_TEX) +#define COLOR_COMB_MODULATE_NTEX (RADEON_COMB_MODULATE | \ + RADEON_COLOR_FACTOR_NTEX) +#define COLOR_COMB_ADD (RADEON_COMB_ADD | \ + RADEON_COLOR_FACTOR_TEX) +#define COLOR_COMB_BLEND_TEX (RADEON_COMB_BLEND_TEXTURE | \ + RADEON_COLOR_FACTOR_TEX) + +#define ALPHA_COMB_DISABLE (RADEON_COMB_ALPHA_DIS | \ + RADEON_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_COPY_INPUT (RADEON_COMB_ALPHA_COPY_INP | \ + RADEON_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_MODULATE (RADEON_COMB_ALPHA_MODULATE | \ + RADEON_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_MODULATE_NTEX (RADEON_COMB_ALPHA_MODULATE | \ + RADEON_ALPHA_FACTOR_NTEX_ALPHA) + +#define INPUT_INTERP (RADEON_INPUT_FACTOR_INT_COLOR | \ + RADEON_INP_FACTOR_A_INT_ALPHA) +#define INPUT_PREVIOUS (RADEON_INPUT_FACTOR_PREV_COLOR | \ + RADEON_INP_FACTOR_A_PREV_ALPHA) +#endif + +static void radeonUpdateTextureStage( GLcontext *ctx, int unit ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + int source = radeon_ctx->tmu_source[unit]; + struct gl_texture_object *tObj; + radeonTexObjPtr t; + GLuint enabled; + CARD32 combine; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) + return; + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + tObj = ctx->Texture.Unit[source].Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && + ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) + return; + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + if ( unit == 0 ) { + combine = INPUT_INTERP; + } else { + combine = INPUT_PREVIOUS; + } + + /* Set the texture environment state */ + switch ( ctx->Texture.Unit[source].EnvMode ) { + case GL_REPLACE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_DISABLE | + ALPHA_COMB_DISABLE); + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_DISABLE | + ALPHA_COMB_COPY_INPUT); + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | + ALPHA_COMB_DISABLE); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_MODULATE | + ALPHA_COMB_MODULATE); + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_MODULATE | + ALPHA_COMB_COPY_INPUT); + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | + ALPHA_COMB_MODULATE); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + combine |= (COLOR_COMB_BLEND_TEX | + ALPHA_COMB_COPY_INPUT); + break; + case GL_RGB: + combine |= (COLOR_COMB_DISABLE | + ALPHA_COMB_COPY_INPUT); + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + /* Undefined behaviour - just copy the incoming fragment */ + combine |= (COLOR_COMB_COPY_INPUT | + ALPHA_COMB_COPY_INPUT); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + switch ( radeon_ctx->envcolor ) { + case 0x00000000: + case 0xffffffff: + combine |= (COLOR_COMB_MODULATE_NTEX | + ALPHA_COMB_MODULATE); + break; + default: + combine |= (COLOR_COMB_MODULATE | + ALPHA_COMB_MODULATE); + radeon_ctx->Fallback |= RADEON_FALLBACK_TEXTURE; + break; + } + break; + case GL_RGB: + case GL_LUMINANCE: + switch ( radeon_ctx->envcolor ) { + case 0x00000000: + case 0xffffffff: + combine |= (COLOR_COMB_MODULATE_NTEX | + ALPHA_COMB_COPY_INPUT); + break; + default: + combine |= (COLOR_COMB_MODULATE | + ALPHA_COMB_COPY_INPUT); + radeon_ctx->Fallback |= RADEON_FALLBACK_TEXTURE; + break; + } + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | + ALPHA_COMB_MODULATE); + break; + case GL_INTENSITY: + switch ( radeon_ctx->envcolor ) { + case 0x00000000: + case 0xffffffff: + combine |= (COLOR_COMB_MODULATE_NTEX | + ALPHA_COMB_MODULATE_NTEX); + break; + default: + combine |= (COLOR_COMB_MODULATE | + ALPHA_COMB_MODULATE); + radeon_ctx->Fallback |= RADEON_FALLBACK_TEXTURE; + break; + } + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_ADD | + ALPHA_COMB_MODULATE); + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_ADD | + ALPHA_COMB_COPY_INPUT); + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | + ALPHA_COMB_MODULATE); + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + default: + return; + } + +#if 0 + t->setup.tex_combine_cntl = combine; +#endif +} + +static void radeonUpdateTextureObject( GLcontext *ctx, int unit ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + int source = radeon_ctx->tmu_source[unit]; + struct gl_texture_object *tObj; + radeonTexObjPtr t; + GLuint enabled; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + /* Disable all texturing until it is known to be good */ +#if 0 + radeon_ctx->setup.tex_cntl_c &= ~(RADEON_TEXMAP_ENABLE | + RADEON_SEC_TEXMAP_ENABLE); +#endif + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { + if ( enabled ) + radeon_ctx->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + tObj = ctx->Texture.Unit[source].Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && + ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) + return; + + if ( !tObj->DriverData ) { + /* If this is the first time the texture has been used, then create + * a new texture object for it. + */ + radeonCreateTexObj( radeon_ctx, tObj ); + + if ( !tObj->DriverData ) { + /* Can't create a texture object... */ + fprintf( stderr, "%s: texture object creation failed!\n", + __FUNCTION__ ); + radeon_ctx->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + } + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + /* Force the texture unit state to be loaded into the hardware */ + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit); + + /* Force any texture images to be loaded into the hardware */ + if ( t->dirty_images ) + radeon_ctx->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit); + + /* Bind to the given texture unit */ + radeon_ctx->CurrentTexObj[unit] = t; + t->bound = unit + 1; + + if ( t->memBlock ) + radeonUpdateTexLRU( radeon_ctx, t ); + +#if 0 + if ( unit == 0 ) { + radeon_ctx->setup.tex_cntl_c |= RADEON_TEXMAP_ENABLE; + radeon_ctx->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; + radeon_ctx->setup.scale_3d_cntl &= ~RADEON_TEX_CACHE_SPLIT; + + t->setup.tex_cntl &= ~RADEON_SEC_SELECT_SEC_ST; + } else { + t->setup.tex_cntl |= RADEON_SEC_SELECT_SEC_ST; + + radeon_ctx->setup.tex_cntl_c |= (RADEON_TEXMAP_ENABLE | + RADEON_SEC_TEXMAP_ENABLE) ; + radeon_ctx->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; + radeon_ctx->setup.scale_3d_cntl |= RADEON_TEX_CACHE_SPLIT; + } +#endif +} + +/* Update the hardware texture state */ +void radeonUpdateTextureState( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) en=0x%x\n", + __FUNCTION__, ctx, ctx->Texture.ReallyEnabled ); + } + + /* Clear any texturing fallbacks */ + radeon_ctx->Fallback &= ~RADEON_FALLBACK_TEXTURE; + + /* Unbind any currently bound textures */ + if ( radeon_ctx->CurrentTexObj[0] ) radeon_ctx->CurrentTexObj[0]->bound = 0; + if ( radeon_ctx->CurrentTexObj[1] ) radeon_ctx->CurrentTexObj[1]->bound = 0; + radeon_ctx->CurrentTexObj[0] = NULL; + radeon_ctx->CurrentTexObj[1] = NULL; + + if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) ) + radeon_ctx->Fallback |= RADEON_FALLBACK_TEXTURE; + +#if 0 + radeon_ctx->setup.tex_size_pitch_c = 0x00000000; +#endif + + radeonUpdateTextureObject( ctx, 0 ); + radeonUpdateTextureStage( ctx, 0 ); + + if ( radeon_ctx->multitex ) { + radeonUpdateTextureObject( ctx, 1 ); + radeonUpdateTextureStage( ctx, 1 ); + } +} + + +/* Set the texture wrap mode */ +static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) +{ +#if 0 + t->setup.tex_cntl &= ~(RADEON_TEX_CLAMP_S_MASK | RADEON_TEX_CLAMP_T_MASK); + + switch ( swrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= RADEON_TEX_CLAMP_S_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= RADEON_TEX_CLAMP_S_WRAP; + break; + } + + switch ( twrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= RADEON_TEX_CLAMP_T_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= RADEON_TEX_CLAMP_T_WRAP; + break; + } +#endif +} + +/* Set the texture filter mode */ +static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) +{ +#if 0 + t->setup.tex_cntl &= ~(RADEON_MIN_BLEND_MASK | RADEON_MAG_BLEND_MASK); + + switch ( minf ) { + case GL_NEAREST: + t->setup.tex_cntl |= RADEON_MIN_BLEND_NEAREST; + break; + case GL_LINEAR: + t->setup.tex_cntl |= RADEON_MIN_BLEND_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->setup.tex_cntl |= RADEON_MIN_BLEND_MIPNEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->setup.tex_cntl |= RADEON_MIN_BLEND_LINEARMIPNEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->setup.tex_cntl |= RADEON_MIN_BLEND_MIPLINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->setup.tex_cntl |= RADEON_MIN_BLEND_LINEARMIPLINEAR; + break; + } + + switch ( magf ) { + case GL_NEAREST: + t->setup.tex_cntl |= RADEON_MAG_BLEND_NEAREST; + break; + case GL_LINEAR: + t->setup.tex_cntl |= RADEON_MAG_BLEND_LINEAR; + break; + } +#endif +} + +/* Set the texture border color */ +static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) +{ +#if 0 + t->setup.tex_border_color = radeonPackColor( 32, c[0], c[1], c[2], c[3] ); +#endif +} + + +/* +============================================================================ + +Driver functions called directly from mesa + +============================================================================ +*/ + + +/* Set the texture environment state */ +static void radeonDDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + struct gl_texture_unit *texUnit; + GLubyte c[4]; + CARD32 col; + int bias; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + switch ( pname ) { + case GL_TEXTURE_ENV_MODE: + /* TexEnv modes are handled in UpdateTextureState */ + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->new_state |= RADEON_NEW_TEXTURE | RADEON_NEW_ALPHA; + break; + + case GL_TEXTURE_ENV_COLOR: + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + FLOAT_RGBA_TO_UBYTE_RGBA( texUnit->EnvColor, c ); + col = radeonPackColor( 32, c[0], c[1], c[2], c[3] ); +#if 0 + if ( radeon_ctx->setup.constant_color_c != col ) { + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->setup.constant_color_c = col; + + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; + } +#endif + break; + + case GL_TEXTURE_LOD_BIAS_EXT: + /* GTH: This isn't exactly correct, but gives good results up to a + * certain point. It is better than completely ignoring the LOD + * bias. Unfortunately there isn't much range in the bias, the + * spec mentions strides that vary between 0.5 and 2.0 but these + * numbers don't seem to relate the the GL LOD bias value at all. + */ + if ( param[0] >= 1.0 ) { + bias = -128; + } else if ( param[0] >= 0.5 ) { + bias = -64; + } else if ( param[0] >= 0.25 ) { + bias = 0; + } else if ( param[0] >= 0.0 ) { + bias = 63; + } else { + bias = 127; + } + if ( radeon_ctx->lod_bias != bias ) { + FLUSH_BATCH( radeon_ctx ); + radeon_ctx->lod_bias = bias; + + radeon_ctx->new_state |= RADEON_NEW_RENDER; + } + break; + + default: + return; + } +} + +/* Upload a new texture image */ +static void radeonDDTexImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint internalFormat, + const struct gl_texture_image *image ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + radeonTexObjPtr t; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level ); + + if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; + if ( level >= RADEON_TEX_MAXLEVELS ) return; + + t = (radeonTexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( radeon_ctx ); + + /* Destroy the old texture, and upload a new one. The actual + * uploading of the texture image occurs in the UploadSubImage + * function. + */ + radeonDestroyTexObj( radeon_ctx, t ); + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; + } +} + +/* Upload a new texture sub-image */ +static void radeonDDTexSubImage( 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 ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + radeonTexObjPtr t; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, level %d ) size: %d,%d of %d,%d\n", + __FUNCTION__, tObj, level, width, height, + image->Width, image->Height ); + } + + if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; + if ( level >= RADEON_TEX_MAXLEVELS ) return; + + t = (radeonTexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( radeon_ctx ); + + LOCK_HARDWARE( radeon_ctx ); + radeonUploadSubImage( radeon_ctx, t, level, + xoffset, yoffset, width, height ); + UNLOCK_HARDWARE( radeon_ctx ); + + /* Update the context state */ +#if 0 + radeon_ctx->setup.tex_cntl_c |= RADEON_TEX_CACHE_FLUSH; +#endif + + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; + } +} + +/* Set the texture parameter state */ +static void radeonDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + if ( !t ) return; + if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; + + switch ( pname ) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + if ( t->bound ) FLUSH_BATCH( radeon_ctx ); + radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if ( t->bound ) FLUSH_BATCH( radeon_ctx ); + radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + if ( t->bound ) FLUSH_BATCH( radeon_ctx ); + radeonSetTexBorderColor( t, tObj->BorderColor ); + break; + + default: + return; + } + + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; +} + +/* Bind a texture to the currently active texture unit */ +static void radeonDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) unit=%d\n", + __FUNCTION__, tObj, ctx->Texture.CurrentUnit ); + } + + FLUSH_BATCH( radeon_ctx ); + + /* Unbind the old texture */ + if ( radeon_ctx->CurrentTexObj[ctx->Texture.CurrentUnit] ) { + radeon_ctx->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; + radeon_ctx->CurrentTexObj[ctx->Texture.CurrentUnit] = NULL; + } + + /* The actualy binding occurs in the Tex[01]UpdateState function */ + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; +} + +/* Remove texture from AGP/local texture memory */ +static void radeonDDDeleteTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + if ( t ) { + if ( t->bound ) { + FLUSH_BATCH( radeon_ctx ); + + radeon_ctx->CurrentTexObj[t->bound-1] = 0; + radeon_ctx->new_state|= RADEON_NEW_TEXTURE; + } + + radeonDestroyTexObj( radeon_ctx, t ); + tObj->DriverData = NULL; + } +} + +/* Determine if a texture is currently residing in either AGP/local + * texture memory. + */ +static GLboolean radeonDDIsTextureResident( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + return t && t->memBlock; +} + +/* Initialize the driver's texture functions */ +void radeonDDInitTextureFuncs( GLcontext *ctx ) +{ + ctx->Driver.TexEnv = radeonDDTexEnv; + ctx->Driver.TexImage = radeonDDTexImage; + ctx->Driver.TexSubImage = radeonDDTexSubImage; + ctx->Driver.TexParameter = radeonDDTexParameter; + ctx->Driver.BindTexture = radeonDDBindTexture; + ctx->Driver.DeleteTexture = radeonDDDeleteTexture; + ctx->Driver.UpdateTexturePalette = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.IsTextureResident = radeonDDIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h new file mode 100644 index 000000000..1f753fdc3 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h @@ -0,0 +1,91 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_TEX_H_ +#define _RADEON_TEX_H_ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonUpdateTextureState( GLcontext *ctx ); + +extern int radeonUploadTexImages( radeonContextPtr radeon_ctx, + radeonTexObjPtr t ); + +extern void radeonAgeTextures( radeonContextPtr radeon_ctx, int heap ); +extern void radeonDestroyTexObj( radeonContextPtr radeon_ctx, + radeonTexObjPtr t ); + +extern void radeonPrintLocalLRU( radeonContextPtr radeon_ctx, int heap ); +extern void radeonPrintGlobalLRU( radeonContextPtr radeon_ctx, int heap ); + +extern void radeonDDInitTextureFuncs( GLcontext *ctx ); + + +#define RADEONPACKCOLOR332(r, g, b) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) + +#define RADEONPACKCOLOR1555(r, g, b, a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define RADEONPACKCOLOR565(r, g, b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define RADEONPACKCOLOR888(r, g, b) \ + (((r) << 16) | ((g) << 8) | (b)) + +#define RADEONPACKCOLOR8888(r, g, b, a) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define RADEONPACKCOLOR4444(r, g, b, a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +static __inline__ CARD32 radeonPackColor( GLuint depth, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + switch ( depth ) { + case 8: return RADEONPACKCOLOR332( r, g, b ); + case 15: return RADEONPACKCOLOR1555( r, g, b, a ); + case 16: return RADEONPACKCOLOR565( r, g, b ); + case 24: return RADEONPACKCOLOR888( r, g, b ); + case 32: return RADEONPACKCOLOR8888( r, g, b, a ); + default: return 0; + } +} + +#endif +#endif /* _RADEON_TEX_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h new file mode 100644 index 000000000..200c86848 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h @@ -0,0 +1,82 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_TEXOBJ_H_ +#define _RADEON_TEXOBJ_H_ + +#include "radeon_sarea.h" +#include "mm.h" + +/* Individual texture image information */ +typedef struct { + GLuint offset; /* Offset into locally shared texture space (i.e., + relative to bufAddr (below) */ + GLuint width; /* Width of texture image */ + GLuint height; /* Height of texture image */ +} radeonTexImage; + +typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; + +/* Texture object in locally shared texture space */ +struct radeon_tex_obj { + radeonTexObjPtr next, prev; + + struct gl_texture_object *tObj; /* Mesa texture object */ + + PMemBlock memBlock; /* Memory block containing texture */ + unsigned char *bufAddr; /* Offset to start of locally + shared texture block */ + + CARD32 dirty_images; /* Flags for whether or not + images need to be uploaded to + local or AGP texture space */ + + GLint bound; /* Texture unit currently bound to */ + GLint heap; /* Texture heap currently stored in */ + radeonTexImage image[RADEON_TEX_MAXLEVELS]; /* Image data for all + mipmap levels */ + + GLint totalSize; /* Total size of the texture + including all mipmap levels */ + GLuint internFormat; /* Internal GL format used to store + texture on card */ + CARD32 textureFormat; /* Actual hardware format */ + GLint texelBytes; /* Number of bytes per texel */ + + radeon_texture_regs_t setup; /* Setup regs for texture */ +}; + +#endif /* _RADEON_TEXOBJ_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c new file mode 100644 index 000000000..1063d5a44 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c @@ -0,0 +1,210 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tris.h" +#include "radeon_state.h" + +#include "pipeline.h" +#include "vbindirect.h" + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[RADEON_MAX_TRIFUNC]; + +#define RADEON_COLOR(to, from) \ +do { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ + (to)[3] = (from)[3]; \ +} while (0) + + +static void radeon_null_quad( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint v3, GLuint pv ) { +} +static void radeon_null_triangle( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint pv ) { +} +static void radeon_null_line( GLcontext *ctx, + GLuint v1, GLuint v2, GLuint pv ) { +} + +static void radeon_null_points( GLcontext *ctx, GLuint first, GLuint last ) { +} + +static void radeonPrintRenderState( const char *msg, GLuint state ) +{ + fprintf( stderr, "%s: (0x%x) %s%s%s%s%s\n", + msg, state, + (state & RADEON_FLAT_BIT) ? "flat, " : "", + (state & RADEON_OFFSET_BIT) ? "offset, " : "", + (state & RADEON_TWOSIDE_BIT) ? "twoside, " : "", + (state & RADEON_NODRAW_BIT) ? "no-draw, " : "", + (state & RADEON_FALLBACK_BIT) ? "fallback" : "" ); +} + +#define IND (0) +#define TAG(x) x +#include "radeon_tritmp.h" + +#define IND (RADEON_FLAT_BIT) +#define TAG(x) x##_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_OFFSET_BIT) +#define TAG(x) x##_offset +#include "radeon_tritmp.h" + +#define IND (RADEON_OFFSET_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "radeon_tritmp.h" + + +/* Initialize the table of points, line and triangle drawing functions */ +void radeonDDTriangleFuncsInit( void ) +{ + int i; + + init(); + init_flat(); + init_offset(); + init_offset_flat(); + init_twoside(); + init_twoside_flat(); + init_twoside_offset(); + init_twoside_offset_flat(); + + for ( i = 0 ; i < 0x20 ; i++ ) { + if ( (i & (RADEON_NODRAW_BIT | RADEON_FALLBACK_BIT)) == + RADEON_NODRAW_BIT ) { + rast_tab[i].points = radeon_null_points; + rast_tab[i].line = radeon_null_line; + rast_tab[i].triangle = radeon_null_triangle; + rast_tab[i].quad = radeon_null_quad; + } + } +} + + +/* FIXME: Only enable software fallback for stencil in 16 bpp mode after + * we have hardware stencil support. + */ +#define ALL_FALLBACK (DD_MULTIDRAW | DD_SELECT | DD_FEEDBACK | DD_STENCIL) +#define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH | DD_POINT_ATTEN) +#define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) +#define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_STIPPLE | DD_TRI_UNFILLED) +#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) +#define ANY_RASTER_FLAGS (/*DD_FLATSHADE |*/ DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) + +/* Setup the Point, Line, Triangle and Quad functions based on the + * current rendering state. Wherever possible, use the hardware to + * render the primitive. Otherwise, fallback to software rendering. + */ +void radeonDDChooseRenderState( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + GLuint flags = ctx->TriangleCaps; + CARD32 index = 0; + + if ( radeon_ctx->Fallback ) { + radeon_ctx->RenderIndex = RADEON_FALLBACK_BIT; + return; + } + + if ( flags & ANY_RASTER_FLAGS ) { + if ( flags & DD_FLATSHADE ) index |= RADEON_FLAT_BIT; + if ( flags & DD_TRI_LIGHT_TWOSIDE ) index |= RADEON_TWOSIDE_BIT; + if ( flags & DD_TRI_OFFSET ) index |= RADEON_OFFSET_BIT; + if ( flags & DD_Z_NEVER ) index |= RADEON_NODRAW_BIT; + } + + radeon_ctx->PointsFunc = rast_tab[index].points; + radeon_ctx->LineFunc = rast_tab[index].line; + radeon_ctx->TriangleFunc = rast_tab[index].triangle; + radeon_ctx->QuadFunc = rast_tab[index].quad; + + radeon_ctx->RenderIndex = index; + radeon_ctx->IndirectTriangles = 0; + + if ( flags & ANY_FALLBACK ) { + radeon_ctx->RenderIndex |= RADEON_FALLBACK_BIT; + + if ( flags & POINT_FALLBACK ) { + radeon_ctx->PointsFunc = 0; + radeon_ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + } + + if ( flags & LINE_FALLBACK ) { + radeon_ctx->LineFunc = 0; + radeon_ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + } + + if ( flags & TRI_FALLBACK ) { + radeon_ctx->TriangleFunc = 0; + radeon_ctx->QuadFunc = 0; + radeon_ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); + } + } + + if ( 0 ) { + gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); + radeonPrintRenderState( "radeon render state", radeon_ctx->RenderIndex ); + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h new file mode 100644 index 000000000..b306d4901 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h @@ -0,0 +1,321 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_TRIS_H_ +#define _RADEON_TRIS_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_vb.h" + +extern void radeonDDChooseRenderState(GLcontext *ctx); +extern void radeonDDTriangleFuncsInit(void); + +#define RADEON_ANTIALIAS_BIT 0x00 /* Ignored for now */ +#define RADEON_FLAT_BIT 0x01 +#define RADEON_OFFSET_BIT 0x02 +#define RADEON_TWOSIDE_BIT 0x04 +#define RADEON_NODRAW_BIT 0x08 +#define RADEON_FALLBACK_BIT 0x10 +#define RADEON_MAX_TRIFUNC 0x20 + +/* Draw a triangle from the vertices in the vertex buffer */ +static __inline void radeon_draw_triangle( radeonContextPtr radeon_ctx, + radeonVertex *v0, + radeonVertex *v1, + radeonVertex *v2 ) +{ + int vertsize = radeon_ctx->vertsize; + CARD32 *vb = radeonAllocVerticesInline( radeon_ctx, 3 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v2) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v2->ui[j]; +#endif +} + +/* Draw a quad from the vertices in the vertex buffer */ +static __inline void radeon_draw_quad( radeonContextPtr radeon_ctx, + radeonVertex *v0, + radeonVertex *v1, + radeonVertex *v2, + radeonVertex *v3 ) +{ + int vertsize = radeon_ctx->vertsize; + CARD32 *vb = radeonAllocVerticesInline( radeon_ctx, 6 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v3) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v2) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v3) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v3->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v2->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v3->ui[j]; +#endif +} + +/* Draw a line from the vertices in the vertex buffer */ +static __inline void radeon_draw_line( radeonContextPtr radeon_ctx, + radeonVertex *tmp0, + radeonVertex *tmp1, + float width ) +{ +#if 1 + int vertsize = radeon_ctx->vertsize; + CARD32 *vb = radeonAllocVerticesInline( radeon_ctx, 6 ); + float dx, dy, ix, iy; + int j; + + dx = tmp0->v.x - tmp1->v.x; + dy = tmp0->v.y - tmp1->v.y; + + ix = width * .5; iy = 0; + + if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width + 0.5 also */ + + if (dx * dx > dy * dy) { + iy = ix; ix = 0; + } + + *(float *)&vb[0] = tmp0->v.x - ix; + *(float *)&vb[1] = tmp0->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x + ix; + *(float *)&vb[1] = tmp1->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp0->v.x + ix; + *(float *)&vb[1] = tmp0->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp0->v.x - ix; + *(float *)&vb[1] = tmp0->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x - ix; + *(float *)&vb[1] = tmp1->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x + ix; + *(float *)&vb[1] = tmp1->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + +#else + + int vertsize = radeon_ctx->vertsize; + CARD32 *vb = radeonAllocVerticesInline( radeon_ctx, 2 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)tmp1) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp1->ui[j]; +#endif +#endif +} + +/* Draw a point from the vertices in the vertex buffer */ +static __inline void radeon_draw_point( radeonContextPtr radeon_ctx, + radeonVertex *tmp, float sz ) +{ +#if 1 + int vertsize = radeon_ctx->vertsize; + CARD32 *vb = radeonAllocVerticesInline( radeon_ctx, 6 ); + int j; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; +#else + + int vertsize = radeon_ctx->vertsize; + CARD32 *vb = radeonAllocVerticesInline( radeon_ctx, 1 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp->ui[j]; +#endif +#endif +} + +#endif +#endif /* _RADEON_TRIS_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h new file mode 100644 index 000000000..c298d8cd8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h @@ -0,0 +1,384 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#if !defined(TAG) || !defined(IND) +this is an error +#endif + +/* Draw a single triangle. Note that the device-dependent vertex data + might need to be changed based on the render state. */ +static __inline void TAG(triangle)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, + GLuint pv ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr radeon_verts = RADEON_DRIVER_DATA(VB)->verts; + radeonVertex *v[3]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[3]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + GLuint c[3]; +#endif + + v[0] = &radeon_verts[e0]; + v[1] = &radeon_verts[e1]; + v[2] = &radeon_verts[e2]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; +#endif + +#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)) + { + GLfloat ex = v[0]->v.x - v[2]->v.x; + GLfloat ey = v[0]->v.y - v[2]->v.y; + GLfloat fx = v[1]->v.x - v[2]->v.x; + GLfloat fy = v[1]->v.y - v[2]->v.y; + GLfloat cc = ex*fy - ey*fx; + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if (IND & RADEON_FLAT_BIT) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits * radeon_ctx->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + z[2] = v[2]->v.z; + if (cc * cc > 1e-16) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if (ac < 0.0f) ac = -ac; + if (bc < 0.0f) bc = -bc; + offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + } + v[0]->v.z += offset; + v[1]->v.z += offset; + v[2]->v.z += offset; + } +#endif + } +#endif + + radeon_draw_triangle( radeon_ctx, v[0], v[1], v[2] ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; + v[2]->ui[4] = c[2]; +#endif +} + + +static void TAG(quad)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, GLuint e3, + GLuint pv ) +{ +#if 0 + TAG(triangle)( ctx, e0, e1, e3, pv ); + TAG(triangle)( ctx, e1, e2, e3, pv ); +#else + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr radeon_verts = RADEON_DRIVER_DATA(VB)->verts; + radeonVertex *v[4]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[4]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + int c[4]; +#endif + + v[0] = &radeon_verts[e0]; + v[1] = &radeon_verts[e1]; + v[2] = &radeon_verts[e2]; + v[3] = &radeon_verts[e3]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; + c[3] = v[3]->ui[4]; +#endif + +#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)) + { + GLfloat ex = v[0]->v.x - v[2]->v.x; + GLfloat ey = v[0]->v.y - v[2]->v.y; + GLfloat fx = v[1]->v.x - v[2]->v.x; + GLfloat fy = v[1]->v.y - v[2]->v.y; + GLfloat cc = ex*fy - ey*fx; + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if (IND & RADEON_FLAT_BIT) { + RADEON_COLOR((char *)&v[0]->ui[4], vbcolor[pv]); + v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR((char *)&v[0]->ui[4], vbcolor[e0]); + RADEON_COLOR((char *)&v[1]->ui[4], vbcolor[e1]); + RADEON_COLOR((char *)&v[2]->ui[4], vbcolor[e2]); + RADEON_COLOR((char *)&v[3]->ui[4], vbcolor[e3]); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits * radeon_ctx->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + z[2] = v[2]->v.z; + z[3] = v[3]->v.z; + if (cc * cc > 1e-16) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if (ac < 0.0f) ac = -ac; + if (bc < 0.0f) bc = -bc; + offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + } + v[0]->v.z += offset; + v[1]->v.z += offset; + v[2]->v.z += offset; + v[3]->v.z += offset; + } +#endif + } +#endif + + radeon_draw_quad( radeon_ctx, v[0], v[1], v[2], v[3] ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; + v[3]->v.z = z[3]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; + v[2]->ui[4] = c[2]; + v[3]->ui[4] = c[3]; +#endif +#endif +} + + +/* Draw a single line. Note that the device-dependent vertex data + * might need to be changed based on the render state. + * + * Polygon offset for GL_LINE triangles is dependent on a harness in + * core mesa setting up LineZoffset on a per-triangle basis. + * + * Twosided lighting for GL_LINE triangles is dependent on the same + * harness. + */ +static void TAG(line)( GLcontext *ctx, + GLuint e0, GLuint e1, + GLuint pv ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + radeonVertexPtr radeon_verts = RADEON_DRIVER_DATA(ctx->VB)->verts; + GLfloat width = ctx->Line.Width; + radeonVertex *v[2]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[2]; +#endif +#if (IND & RADEON_TWOSIDE_BIT) + int c[2]; +#endif + + v[0] = &radeon_verts[e0]; + v[1] = &radeon_verts[e1]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + if (IND & RADEON_FLAT_BIT) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + offset = ctx->LineZoffset * radeon_ctx->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + v[0]->v.z += offset; + v[1]->v.z += offset; +#endif + + radeon_draw_line( radeon_ctx, v[0], v[1], width ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; +#endif + +#if 0 + if (IND & (RADEON_TWOSIDE_BIT|RADEON_FLAT_BIT|RADEON_OFFSET_BIT)) { + radeonVertex tmp0 = radeon_verts[e0]; + radeonVertex tmp1 = radeon_verts[e1]; + + if (IND & RADEON_TWOSIDE_BIT) { + GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + + if (IND & RADEON_FLAT_BIT) { + RADEON_COLOR((char *)&tmp0.v.color, vbcolor[pv]); + *(int *)&tmp1.v.color = *(int *)&tmp0.v.color; + } else { + RADEON_COLOR((char *)&tmp0.v.color, vbcolor[e0]); + RADEON_COLOR((char *)&tmp1.v.color, vbcolor[e1]); + } + } else if (IND & RADEON_FLAT_BIT) { + *(int *)&tmp0.v.color = *(int *)&radeon_verts[pv].v.color; + *(int *)&tmp1.v.color = *(int *)&radeon_verts[pv].v.color; + } + + if (IND & RADEON_OFFSET_BIT) { + GLfloat offset = ctx->LineZoffset * radeon_ctx->depth_scale; + tmp0.v.z += offset; + tmp1.v.z += offset; + } + + radeon_draw_line( radeon_ctx, &tmp0, &tmp1, width ); + } else { + radeon_draw_line( radeon_ctx, &radeon_verts[e0], &radeon_verts[e1], + width ); + } +#endif +} + +/* Draw a set of points. Note that the device-dependent vertex data + might need to be changed based on the render state. */ +static void TAG(points)(GLcontext *ctx, + GLuint first, GLuint last) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr radeon_verts = RADEON_DRIVER_DATA(VB)->verts; + GLfloat size = ctx->Point.Size * 0.5; + int i; + + + for(i = first; i <= last; i++) { + if(VB->ClipMask[i] == 0) { + if (IND & (RADEON_TWOSIDE_BIT|RADEON_OFFSET_BIT)) { + radeonVertex tmp0 = radeon_verts[i]; + + if (IND & RADEON_TWOSIDE_BIT) { + GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + RADEON_COLOR((char *)&tmp0.v.color, vbcolor[i]); + } + if (IND & RADEON_OFFSET_BIT) { + GLfloat offset = ctx->PointZoffset * radeon_ctx->depth_scale; + tmp0.v.z += offset; + } + radeon_draw_point( radeon_ctx, &tmp0, size ); + } else + radeon_draw_point( radeon_ctx, &radeon_verts[i], size ); + } + } +} + +/* Initialize the table of primitives to render. */ +static void TAG(init)(void) +{ + rast_tab[IND].triangle = TAG(triangle); + rast_tab[IND].quad = TAG(quad); + rast_tab[IND].line = TAG(line); + rast_tab[IND].points = TAG(points); +} + +#undef IND +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c new file mode 100644 index 000000000..bf7446e87 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c @@ -0,0 +1,484 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_vb.h" + +#include "mem.h" +#include "stages.h" + +#define TEX0 \ +do { \ + v->v.tu0 = tc0[i][0]; \ + v->v.tv0 = tc0[i][1]; \ +} while (0) + +#define TEX1 \ +do { \ + v->v.tu1 = tc1[i][0]; \ + v->v.tv1 = tc1[i][1]; \ +} while (0) + +#define SPC \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.blue = spec[2]; \ + v->v.specular.green = spec[1]; \ + v->v.specular.red = spec[0]; \ +} while (0) + +#define FOG \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.alpha = spec[3]; \ +} while (0) + +#define COL \ +do { \ + GLubyte *col = &(VB->Color[0]->data[i][0]); \ + v->v.color.blue = col[2]; \ + v->v.color.green = col[1]; \ + v->v.color.red = col[0]; \ + v->v.color.alpha = col[3]; \ +} while (0) + +#define TEX0_4 \ +do { \ + if (VB->TexCoordPtr[0]->size == 4) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + for (i = start; i < end; i++, v++) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ + v->v.tu0 *= oow; \ + v->v.tv0 *= oow; \ + } \ + } \ +} while (0) + +#if USE_RHW2 + +#define TEX1_4 \ +do { \ + if (VB->TexCoordPtr[1]->size == 4) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + for (i = start; i < end; i++, v++) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw2 *= tc[i][3]; \ + v->v.tu1 *= oow; \ + v->v.tv1 *= oow; \ + } \ + } \ +} while (0) + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = radeon_height - win[1]; \ + v->v.z = scale * win[2]; \ + v->v.rhw = v->v.rhw2 = win[3]; \ +} while (0) + +#else /* USE_RHW2 */ + +#define TEX1_4 + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = radeon_height - win[1]; \ + v->v.z = scale * win[2]; \ + v->v.rhw = win[3]; \ +} while (0) \ + +#endif /* USE_RHW2 */ + +#define NOP + +/* Setup the Radeon vertex buffer entries */ +#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ +static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ +{ \ + radeonContextPtr radeon_ctx = RADEON_CONTEXT(VB->ctx); \ + __DRIdrawablePrivate *dPriv = radeon_ctx->driDrawable; \ + radeonVertexPtr v; \ + GLfloat (*tc0)[4]; \ + GLfloat (*tc1)[4]; \ + GLfloat radeon_height = dPriv->h; \ + GLfloat scale = radeon_ctx->depth_scale; \ + int i; \ + \ + (void) radeon_height; (void) radeon_ctx; (void) scale; \ + \ + gl_import_client_data(VB, VB->ctx->RenderFlags, \ + (VB->ClipOrMask \ + ? VEC_WRITABLE | VEC_GOOD_STRIDE \ + : VEC_GOOD_STRIDE)); \ + \ + tc0 = VB->TexCoordPtr[radeon_ctx->tmu_source[0]]->data; \ + tc1 = VB->TexCoordPtr[radeon_ctx->tmu_source[1]]->data; \ + \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + \ + if (VB->ClipOrMask == 0) { \ + for (i = start; i < end; i++, v++) { \ + win; \ + col; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + } else { \ + for (i = start; i < end; i++, v++) { \ + if (VB->ClipMask[i] == 0) { \ + win; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + col; \ + } \ + } \ + tex0_4; \ + tex1_4; \ +} + + +SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + +SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + + +static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end ) +{ + fprintf(stderr, "radeonRasterSetup(): invalid setup function\n"); +} + +typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint); +static setupFunc setup_func[0x40]; + +/* Initialize the table of vertex buffer setup functions */ +void radeonDDSetupInit( void ) +{ + int i; + + for (i = 0; i < 0x20; i++) setup_func[i] = rs_invalid; + + /* Functions to build vertices from scratch */ + setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT] = rs_wt0; + setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wt0t1; + setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wft0; + setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wft0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT] = rs_wg; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_wgs; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_wgt0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgt0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgst0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgst0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_wgf; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_wgfs; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wgft0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgft0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgfst0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgfst0t1; + + /* Repair functions */ + setup_func[RADEON_TEX0_BIT] = rs_t0; + setup_func[RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_t0t1; + setup_func[RADEON_FOG_BIT] = rs_f; + setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_ft0; + setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_ft0t1; + setup_func[RADEON_RGBA_BIT] = rs_g; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_gs; + setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_gt0; + setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gt0t1; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gst0; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gst0t1; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_gf; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_gfs; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_gft0; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gft0t1; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gfst0; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gfst0t1; +} + +void radeonPrintSetupFlags( char *msg, GLuint flags ) +{ + fprintf( stderr, "%s: %d %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & RADEON_WIN_BIT) ? " xyzw," : "", + (flags & RADEON_RGBA_BIT) ? " rgba," : "", + (flags & RADEON_SPEC_BIT) ? " spec," : "", + (flags & RADEON_FOG_BIT) ? " fog," : "", + (flags & RADEON_TEX0_BIT) ? " tex-0," : "", + (flags & RADEON_TEX1_BIT) ? " tex-1," : "" ); +} + +/* Initialize the vertex buffer setup functions based on the current + rendering state */ +void radeonDDChooseRasterSetupFunc( GLcontext *ctx ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + int index = RADEON_WIN_BIT | RADEON_RGBA_BIT; + + radeon_ctx->vertsize = 8; + radeon_ctx->vc_format = RADEON_TEX0_VERTEX_FORMAT; + radeon_ctx->tmu_source[0] = 0; + radeon_ctx->tmu_source[1] = 1; + radeon_ctx->tex_dest[0] = RADEON_TEX0_BIT; + radeon_ctx->tex_dest[1] = RADEON_TEX1_BIT; + radeon_ctx->multitex = 0; + + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { + index |= RADEON_TEX0_BIT; + } + + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) { + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { + radeon_ctx->multitex = 1; + radeon_ctx->vertsize = 10; + radeon_ctx->vc_format = RADEON_TEX1_VERTEX_FORMAT; + index |= RADEON_TEX1_BIT; + } else { + /* Just a funny way of doing single texturing. + */ + radeon_ctx->tmu_source[0] = 1; + radeon_ctx->tex_dest[1] = RADEON_TEX0_BIT; + index |= RADEON_TEX0_BIT; + } + } + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) + index |= RADEON_SPEC_BIT; + + if ( ctx->Fog.Enabled ) + index |= RADEON_FOG_BIT; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, "\n" ); + radeonPrintSetupFlags( "full setup function", index ); + } + + radeon_ctx->new_state |= RADEON_NEW_TEXTURE; + radeon_ctx->SetupIndex = index; + + ctx->Driver.RasterSetup = setup_func[index]; +} + +/* Check to see if any updates of the vertex buffer entries are needed */ +void radeonDDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( ctx ); + int tmp = radeon_ctx->SetupDone; + + s->type = 0; + radeon_ctx->SetupDone = GL_FALSE; + + if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return; + if (ctx->IndirectTriangles) return; + + radeon_ctx->SetupDone = tmp; +} + + +/* Update the vertex buffer entries, if necessary */ +void radeonDDPartialRasterSetup( struct vertex_buffer *VB ) +{ + radeonContextPtr radeon_ctx = RADEON_CONTEXT( VB->ctx ); + int new = VB->pipeline->new_outputs; + int available = VB->pipeline->outputs; + int index = 0; + + if (new & VERT_WIN) { + new = available; + index |= RADEON_WIN_BIT | RADEON_FOG_BIT; + } + + if (new & VERT_RGBA) + index |= RADEON_RGBA_BIT | RADEON_SPEC_BIT; + + if (new & VERT_TEX0_ANY) + index |= RADEON_TEX0_BIT; + + if (new & VERT_TEX1_ANY) + index |= radeon_ctx->tex_dest[1]; + + if (new & VERT_FOG_COORD) + index |= RADEON_FOG_BIT; + + radeon_ctx->SetupDone &= ~index; + index &= radeon_ctx->SetupIndex; + radeon_ctx->SetupDone |= index; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) + radeonPrintSetupFlags( "partial setup function", index ); + + if ( index ) + setup_func[index]( VB, VB->Start, VB->Count ); +} + +/* Perform the raster setup for the fast path, if using CVA */ +void radeonDDDoRasterSetup( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + + if ( VB->Type == VB_CVA_PRECALC ) { + radeonDDPartialRasterSetup( VB ); + } else if ( ctx->Driver.RasterSetup ) { + ctx->Driver.RasterSetup( VB, + VB->CopyStart, + VB->Count ); + } +} + +/* Resize an existing vertex buffer */ +void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size ) +{ + radeonVertexBufferPtr radeon_vb = RADEON_DRIVER_DATA(VB); + + while ( radeon_vb->size < size ) + radeon_vb->size *= 2; + + ALIGN_FREE( radeon_vb->vert_store ); + radeon_vb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * radeon_vb->size, 32 ); + if ( !radeon_vb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + radeon_vb->verts = (radeonVertexPtr)radeon_vb->vert_store; + + gl_vector1ui_free( &radeon_vb->clipped_elements ); + gl_vector1ui_alloc( &radeon_vb->clipped_elements, + VEC_WRITABLE, radeon_vb->size, 32 ); + if ( !radeon_vb->clipped_elements.start ) { + fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); + exit( 1 ); + } + + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * radeon_vb->size, 32 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } +} + +/* Create a new device-dependent vertex buffer */ +void radeonDDRegisterVB( struct vertex_buffer *VB ) +{ + radeonVertexBufferPtr radeon_vb; + + radeon_vb = (radeonVertexBufferPtr)CALLOC( sizeof(*radeon_vb) ); + + radeon_vb->size = VB->Size * 2; + radeon_vb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * radeon_vb->size, 32 ); + if ( !radeon_vb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + radeon_vb->verts = (radeonVertexPtr)radeon_vb->vert_store; + + gl_vector1ui_alloc( &radeon_vb->clipped_elements, + VEC_WRITABLE, radeon_vb->size, 32 ); + if ( !radeon_vb->clipped_elements.start ) { + fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); + exit( 1 ); + } + + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * radeon_vb->size, 32 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } + + VB->driver_data = radeon_vb; +} + +/* Destroy a device-dependent vertex buffer */ +void radeonDDUnregisterVB( struct vertex_buffer *VB ) +{ + radeonVertexBufferPtr radeon_vb = RADEON_DRIVER_DATA(VB); + + if ( radeon_vb ) { + if ( radeon_vb->vert_store ) ALIGN_FREE( radeon_vb->vert_store ); + gl_vector1ui_free( &radeon_vb->clipped_elements ); + FREE( radeon_vb ); + VB->driver_data = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h new file mode 100644 index 000000000..b184a07c5 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h @@ -0,0 +1,137 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _RADEON_VB_H_ +#define _RADEON_VB_H_ + +#ifdef GLX_DIRECT_RENDERING + +/* FIXME: This is endian-specific */ +typedef struct { + GLubyte blue; + GLubyte green; + GLubyte red; + GLubyte alpha; +} radeon_color_t; + +/* The vertex structure. The final tu1/tv1 values are only used in + * multitexture modes, and the rhw2 value is currently never used. + */ +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + radeon_color_t color; /* Diffuse color */ + radeon_color_t specular; /* Specular color (alpha is fog) */ + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ + GLfloat rhw2; /* Reciprocal homogeneous w2 */ +} radeon_vertex; + +/* Format of vertices in radeon_vertex struct */ +#define RADEON_TEX0_VERTEX_FORMAT \ + RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 + +#define RADEON_TEX1_VERTEX_FORMAT \ + RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1 + +#if 0 +#define RADEON_PROJ_TEX1_VERTEX_FORMAT \ + RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1 | \ + RADEON_CP_VC_FRMT_Q1 +#endif + + +/* FIXME: We currently only have assembly for 16-stride vertices */ +union radeon_vertex_t { + radeon_vertex v; + GLfloat f[16]; + CARD32 ui[16]; +}; + +typedef union radeon_vertex_t radeonVertex; +typedef union radeon_vertex_t *radeonVertexPtr; + +/* Vertex buffer for use when on the fast path */ +typedef struct { + GLuint size; /* Number of vertices in store */ + void *vert_store; /* Storage for vertex buffer */ + radeonVertexPtr verts; /* Aligned start of verts in storage */ + int last_vert; /* Index of last vertex used */ + GLvector1ui clipped_elements; /* List of clipped elements */ +} *radeonVertexBufferPtr; + +#define RADEON_DRIVER_DATA(vb) ((radeonVertexBufferPtr)((vb)->driver_data)) + +#define RADEON_WIN_BIT 0x01 +#define RADEON_RGBA_BIT 0x02 +#define RADEON_FOG_BIT 0x04 +#define RADEON_SPEC_BIT 0x08 +#define RADEON_TEX0_BIT 0x10 +#define RADEON_TEX1_BIT 0x20 + +extern void radeonDDSetupInit( void ); + +extern void radeonDDChooseRasterSetupFunc( GLcontext *ctx ); +extern void radeonPrintSetupFlags( char *msg, GLuint flags ); + +extern void radeonDDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ); +extern void radeonDDPartialRasterSetup(struct vertex_buffer *VB); +extern void radeonDDDoRasterSetup(struct vertex_buffer *VB); + +extern void radeonDDResizeVB(struct vertex_buffer *VB, GLuint size); +extern void radeonDDRegisterVB(struct vertex_buffer *VB); +extern void radeonDDUnregisterVB(struct vertex_buffer *VB); + +#endif +#endif /* _RADEON_VB_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c new file mode 100644 index 000000000..aae67d617 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c @@ -0,0 +1,284 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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 +on 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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifdef GLX_DIRECT_RENDERING + +/* Radeon Mesa driver includes */ +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_tex.h" + +/* Mesa src includes */ +#include "context.h" +#include "simple_list.h" +#include "mmath.h" + +extern void __driRegisterExtensions( void ); + +#ifndef RADEON_DEBUG +int RADEON_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ + | DEBUG_VERBOSE_API + | DEBUG_VERBOSE_MSG + | DEBUG_VERBOSE_LRU + | DEBUG_VERBOSE_DRI + | DEBUG_VERBOSE_IOCTL + | DEBUG_VERBOSE_2D + ); +#endif + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + +static radeonContextPtr radeonContext = NULL; + + +/* Initialize the driver specific screen private data */ +GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) +{ + sPriv->private = (void *)radeonCreateScreen(sPriv); + if (!sPriv->private) { + radeonDestroyScreen(sPriv); + return GL_FALSE; + } + + return GL_TRUE; +} + +/* Reset the driver specific screen private data */ +void XMesaResetDriver(__DRIscreenPrivate *sPriv) +{ + radeonDestroyScreen(sPriv); +} + +/* Create and initialize the Mesa and driver specific visual data */ +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) +{ + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual(config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */); +} + +/* Create and initialize the Mesa and driver specific context data */ +GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv) +{ + return radeonCreateContext(dpy, mesaVis, driContextPriv); +} + +/* Destroy the Mesa and driver specific context data */ +void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) +{ + radeonContextPtr radeon_ctx = + (radeonContextPtr)driContextPriv->driverPrivate; + + if (radeon_ctx == (void *)radeonContext) radeonContext = NULL; + radeonDestroyContext(radeon_ctx); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer data */ +GLframebuffer *XMesaCreateWindowBuffer(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) +{ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 + ); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer data */ +GLframebuffer *XMesaCreatePixmapBuffer(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis) +{ +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0); +#else + return NULL; /* not implemented yet */ +#endif +} + +/* Copy the back color buffer to the front color buffer */ +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) +{ + /* FIXME: This assumes buffer is currently bound to a context. This + needs to be able to swap buffers when not currently bound. Also, + this needs to swap according to buffer, and NOT according to + context! */ + if (radeonContext == NULL) return; + + /* Only swap buffers when a back buffer exists */ + if (RADEON_MESACTX(radeonContext)->Visual->DBflag) { + FLUSH_VB(RADEON_MESACTX(radeonContext), "swap buffers"); + radeonSwapBuffers(radeonContext); + } +} + +/* Force the context `c' to be the current context and associate with it + buffer `b' */ +GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (driContextPriv) { + radeonContextPtr radeon_ctx = + (radeonContextPtr)driContextPriv->driverPrivate; + + if (radeonContext && + radeon_ctx == (void *)radeonContext && + driDrawPriv == RADEON_DRIDRAWABLE(radeonContext)) + return GL_TRUE; + + radeonContext = radeonMakeCurrent(radeonContext, radeon_ctx, + driDrawPriv); + + gl_make_current2(RADEON_MESACTX(radeonContext), + driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); + + if (radeonContext->driDrawable != driDrawPriv) { + radeonContext->driDrawable = driDrawPriv; + radeonContext->dirty = RADEON_UPLOAD_ALL; + } + + if (!RADEON_MESACTX(radeonContext)->Viewport.Width) { + gl_Viewport(RADEON_MESACTX(radeonContext), 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + } else { + gl_make_current(0,0); + radeonContext = NULL; + } + + return GL_TRUE; +} + +/* Force the context `c' to be unbound from its buffer */ +GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void __driRegisterExtensions( void ) +{ +} + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void radeonGetLock( radeonContextPtr radeon_ctx, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = radeon_ctx->driDrawable; + __DRIscreenPrivate *sPriv = radeon_ctx->driScreen; + RADEONSAREAPriv *sarea = radeon_ctx->sarea; + int stamp = dPriv->lastStamp; + int i; + + drmGetLock( radeon_ctx->driFd, radeon_ctx->hHWContext, flags ); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + XMESA_VALIDATE_DRAWABLE_INFO( radeon_ctx->display, sPriv, dPriv ); + + if ( stamp != dPriv->lastStamp ) { + radeon_ctx->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + radeon_ctx->SetupDone = 0; + } + + radeon_ctx->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_CLIPRECTS; + + radeon_ctx->numClipRects = dPriv->numClipRects; + radeon_ctx->pClipRects = dPriv->pClipRects; + + if ( sarea->ctxOwner != radeon_ctx->hHWContext ) { + sarea->ctxOwner = radeon_ctx->hHWContext; + radeon_ctx->dirty = RADEON_UPLOAD_ALL; + } + + for ( i = 0 ; i < radeon_ctx->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != radeon_ctx->lastTexAge[i] ) { + radeonAgeTextures( radeon_ctx, i ); + } + } +} + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c index d6ff85db4..fb3dac720 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c @@ -370,14 +370,14 @@ static void R128SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, R128InfoPtr info = R128PTR(pScrn); unsigned char *R128MMIO = info->MMIO; - R128WaitForFifo(pScrn, 1); - OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT - | R128_DST_Y_TOP_TO_BOTTOM)); - #ifdef XF86DRI R128CCE_TO_MMIO(pScrn, info); #endif + R128WaitForFifo(pScrn, 1); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); + if (dir == DEGREES_0) { R128SubsequentSolidFillRect(pScrn, x, y, len, 1); } else { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c index 350487c12..fe0067f10 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -327,7 +327,7 @@ static void RADEONEngineInit(ScrnInfoPtr pScrn) info->CurrentLayout.pixel_code, info->CurrentLayout.bitsPerPixel)); - OUTREG(RADEON_SCALE_3D_CNTL, 0); + OUTREG(RADEON_RB3D_CNTL, 0); RADEONEngineReset(pScrn); switch (info->CurrentLayout.pixel_code) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c index becc6f6a4..ee501790c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -329,11 +329,6 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) int nbox, nboxSave; int depth; -#if 0 - /* FIXME: This should work now.....test */ - if (info->CP2D) return; -#endif - /* FIXME: This should be based on the __GLXvisualConfig info */ switch (pScrn->bitsPerPixel) { case 8: depth = 0x000000ff; break; @@ -410,11 +405,6 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, int dx = pParent->drawable.x - ptOldOrg.x; int dy = pParent->drawable.y - ptOldOrg.y; -#if 0 - /* FIXME: This should work now.....test */ - if (info->CP2D) return; -#endif - /* If the copy will overlap in Y, reverse the order */ if (dy > 0) { ydir = -1; @@ -760,9 +750,10 @@ static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen) /* Initialize the kernel data structures. */ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - int pitch = pScrn->virtualX; - int cpp = info->CurrentLayout.pixel_bytes; + unsigned char *RADEONMMIO = info->MMIO; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int pitch = pScrn->virtualX; + int cpp = info->CurrentLayout.pixel_bytes; drmRadeonInit drmInfo; drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); @@ -813,6 +804,8 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) drmInfo.buffers_offset = info->bufHandle; drmInfo.agp_textures_offset = info->agpTexHandle; + drmInfo.agp_vm_start = INREG(RADEON_CONFIG_APER_SIZE); /* FIXME */ + if (drmRadeonInitCP(info->drmFD, &drmInfo) < 0) return FALSE; /* drmRadeonInitCP does an engine reset, which resets some engine @@ -1134,7 +1127,6 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) pRADEONDRI->AGPMode = info->agpMode; pRADEONDRI->CPMode = info->CPMode; - pRADEONDRI->CPFifoSize = info->CPFifoSize; return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h index aa6aede2a..bbc79e287 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -53,6 +53,8 @@ #define RADEON_AGP_MAX_MODE 4 +#define RADEON_CARD_TYPE_RADEON 1 + #define RADEONCP_USE_RING_BUFFER(m) \ (((m) == RADEON_CSQ_PRIBM_INDDIS) || \ ((m) == RADEON_CSQ_PRIBM_INDBM)) @@ -104,7 +106,6 @@ typedef struct { int AGPMode; int CPMode; /* CP mode that server/clients use */ - int CPFifoSize; /* Size of the CP command FIFO */ } RADEONDRIRec, *RADEONDRIPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h index b7024e885..0dae54ff4 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h @@ -932,6 +932,319 @@ #define RADEON_XDLL_CNTL 0x000c /* PLL */ #define RADEON_XPLL_CNTL 0x000b /* PLL */ + /* Registers for 3D/TCL */ +#define RADEON_PP_CNTL 0x1c38 +# define RADEON_STIPPLE_ENABLE (1 << 0) +# define RADEON_SCISSOR_ENABLE (1 << 1) +# define RADEON_PATTERN_ENABLE (1 << 2) +# define RADEON_SHADOW_ENABLE (1 << 3) +# define RADEON_TEX_0_ENABLE (1 << 4) +# define RADEON_TEX_1_ENABLE (1 << 5) +# define RADEON_TEX_2_ENABLE (1 << 6) +# define RADEON_TEX_3_ENABLE (1 << 7) +# define RADEON_TEX_BLEND_0_ENABLE (1 << 12) +# define RADEON_TEX_BLEND_1_ENABLE (1 << 13) +# define RADEON_TEX_BLEND_2_ENABLE (1 << 14) +# define RADEON_TEX_BLEND_3_ENABLE (1 << 15) +# define RADEON_PLANAR_YUV_ENABLE (1 << 20) +# define RADEON_SPECULAR_ENABLE (1 << 21) +# define RADEON_FOG_ENABLE (1 << 22) +# define RADEON_ALPHA_TEST_ENABLE (1 << 23) +# define RADEON_ANTI_ALIAS_NONE (0 << 24) +# define RADEON_ANTI_ALIAS_LINE (1 << 24) +# define RADEON_ANTI_ALIAS_POLY (2 << 24) +# define RADEON_ANTI_ALIAS_LINE_POLY (3 << 24) +# define RADEON_BUMP_MAP_ENABLE (1 << 26) +# define RADEON_BUMPED_MAP_T0 (0 << 27) +# define RADEON_BUMPED_MAP_T1 (1 << 27) +# define RADEON_BUMPED_MAP_T2 (2 << 27) +# define RADEON_TEX_3D_ENABLE_0 (1 << 29) +# define RADEON_TEX_3D_ENABLE_1 (1 << 30) +# define RADEON_MC_ENABLE (1 << 31) +#define RADEON_PP_FOG_COLOR 0x1c18 +# define RADEON_FOG_COLOR_MASK 0x00ffffff +# define RADEON_FOG_VERTEX (0 << 24) +# define RADEON_FOG_TABLE (1 << 24) +# define RADEON_FOG_USE_DEPTH (0 << 25) +# define RADEON_FOG_USE_DIFFUSE_ALPHA (2 << 25) +# define RADEON_FOG_USE_SPEC_ALPHA (3 << 25) +#define RADEON_PP_LUM_MATRIX 0x1d00 +#define RADEON_PP_MISC 0x1c14 +# define RADEON_REF_ALPHA_MASK 0x000000ff +# define RADEON_ALPHA_TEST_FAIL (0 << 8) +# define RADEON_ALPHA_TEST_LESS (1 << 8) +# define RADEON_ALPHA_TEST_LEQUAL (2 << 8) +# define RADEON_ALPHA_TEST_EQUAL (3 << 8) +# define RADEON_ALPHA_TEST_GEQUAL (4 << 8) +# define RADEON_ALPHA_TEST_GREATER (5 << 8) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 8) +# define RADEON_ALPHA_TEST_PASS (7 << 8) +# define RADEON_ALPHA_TEST_OP_MASK (7 << 8) +# define RADEON_CHROMA_FUNC_FAIL (0 << 16) +# define RADEON_CHROMA_FUNC_PASS (1 << 16) +# define RADEON_CHROMA_FUNC_NEQUAL (2 << 16) +# define RADEON_CHROMA_FUNC_EQUAL (3 << 16) +# define RADEON_CHROMA_KEY_NEAREST (0 << 18) +# define RADEON_CHROMA_KEY_ZERO (1 << 18) +# define RADEON_SHADOW_ID_AUTO_INC (1 << 20) +# define RADEON_SHADOW_FUNC_EQUAL (0 << 21) +# define RADEON_SHADOW_FUNC_NEQUAL (1 << 21) +# define RADEON_SHADOW_PASS_1 (0 << 22) +# define RADEON_SHADOW_PASS_2 (1 << 22) +# define RADEON_RIGHT_HAND_CUBE_D3D (0 << 24) +# define RADEON_RIGHT_HAND_CUBE_OGL (1 << 24) +#define RADEON_PP_ROT_MATRIX_0 0x1d58 +#define RADEON_PP_ROT_MATRIX_1 0x1d5c + +#define RADEON_RB3D_BLENDCNTL 0x1c20 +# define RADEON_COMB_FCN_ADD_CLAMP (0 << 12) +# define RADEON_COMB_FCN_ADD_NOCLAMP (1 << 12) +# define RADEON_COMB_FCN_SUB_CLAMP (2 << 12) +# define RADEON_COMB_FCN_SUB_NOCLAMP (3 << 12) +# define RADEON_SRC_BLEND_GL_ZERO (32 << 16) +# define RADEON_SRC_BLEND_GL_ONE (33 << 16) +# define RADEON_SRC_BLEND_GL_SRC_COLOR (34 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) +# define RADEON_SRC_BLEND_GL_DST_COLOR (36 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) +# define RADEON_SRC_BLEND_GL_SRC_ALPHA (38 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) +# define RADEON_SRC_BLEND_GL_DST_ALPHA (40 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) +# define RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) +# define RADEON_SRC_BLEND_MASK (63 << 16) +# define RADEON_DST_BLEND_GL_ZERO (32 << 24) +# define RADEON_DST_BLEND_GL_ONE (33 << 24) +# define RADEON_DST_BLEND_GL_SRC_COLOR (34 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) +# define RADEON_DST_BLEND_GL_DST_COLOR (36 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) +# define RADEON_DST_BLEND_GL_SRC_ALPHA (38 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) +# define RADEON_DST_BLEND_GL_DST_ALPHA (40 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) +# define RADEON_DST_BLEND_MASK (63 << 24) +#define RADEON_RB3D_CNTL 0x1c3c +# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) +# define RADEON_PLANE_MASK_ENABLE (1 << 1) +# define RADEON_DITHER_ENABLE (1 << 2) +# define RADEON_ROUND_ENABLE (1 << 3) +# define RADEON_SCALE_DITHER_ENABLE (1 << 4) +# define RADEON_DITHER_INIT (1 << 5) +# define RADEON_ROP_ENABLE (1 << 6) +# define RADEON_STENCIL_ENABLE (1 << 7) +# define RADEON_Z_ENABLE (1 << 8) +# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) +# define RADEON_COLOR_FORMAT_ARGB1555 (3 << 10) +# define RADEON_COLOR_FORMAT_RGB565 (4 << 10) +# define RADEON_COLOR_FORMAT_ARGB8888 (6 << 10) +# define RADEON_COLOR_FORMAT_RGB332 (7 << 10) +# define RADEON_COLOR_FORMAT_Y8 (8 << 10) +# define RADEON_COLOR_FORMAT_RGB8 (9 << 10) +# define RADEON_COLOR_FORMAT_YUV422_VYUY (11 << 10) +# define RADEON_COLOR_FORMAT_YUV422_YVYU (12 << 10) +# define RADEON_COLOR_FORMAT_aYUV444 (14 << 10) +# define RADEON_COLOR_FORMAT_ARGB4444 (15 << 10) +# define RADEON_CLRCMP_FLIP_ENABLE (1 << 14) +# define RADEON_ZBLOCK8 (0 << 15) +# define RADEON_ZBLOCK16 (1 << 15) +#define RADEON_RB3D_COLOROFFSET 0x1c40 +# define RADEON_COLOROFFSET_MASK 0xfffffff0 +#define RADEON_RB3D_COLORPITCH 0x1c48 +# define RADEON_COLORPITCH_MASK 0x000001ff8 +# define RADEON_COLOR_TILE_ENABLE (1 << 16) +# define RADEON_COLOR_MICROTILE_ENABLE (1 << 17) +# define RADEON_COLOR_ENDIAN_NO_SWAP (0 << 18) +# define RADEON_COLOR_ENDIAN_WORD_SWAP (1 << 18) +# define RADEON_COLOR_ENDIAN_DWORD_SWAP (2 << 18) +#define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_DEPTHPITCH 0x1c28 +# define RADEON_DEPTHPITCH_MASK 0x00001ff8 +# define RADEON_DEPTH_ENDIAN_NO_SWAP (0 << 18) +# define RADEON_DEPTH_ENDIAN_WORD_SWAP (1 << 18) +# define RADEON_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) +#define RADEON_RB3D_PLANEMASK 0x1d84 +#define RADEON_RB3D_ROPCNTL 0x1d80 +#define RADEON_RB3D_STENCILREFMASK 0x1d7c +# define RADEON_STENCIL_REF_SHIFT 0 +# define RADEON_STENCIL_MASK_SHIFT 16 +# define RADEON_STENCIL_WRITEMASK_SHIFT 24 +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) +# define RADEON_DEPTH_FORMAT_16BIT_FLOAT_W (7 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) +# define RADEON_Z_TEST_NEVER (0 << 4) +# define RADEON_Z_TEST_LESS (1 << 4) +# define RADEON_Z_TEST_LEQUAL (2 << 4) +# define RADEON_Z_TEST_EQUAL (3 << 4) +# define RADEON_Z_TEST_GEQUAL (4 << 4) +# define RADEON_Z_TEST_GREATER (5 << 4) +# define RADEON_Z_TEST_NEQUAL (6 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_HIERARCHICAL_Z_ENABLE (1 << 8) +# define RADEON_STENCIL_TEST_NEVER (0 << 12) +# define RADEON_STENCIL_TEST_LESS (1 << 12) +# define RADEON_STENCIL_TEST_LEQUAL (2 << 12) +# define RADEON_STENCIL_TEST_EQUAL (3 << 12) +# define RADEON_STENCIL_TEST_GEQUAL (4 << 12) +# define RADEON_STENCIL_TEST_GREATER (5 << 12) +# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) +# define RADEON_STENCIL_S_FAIL_ZERO (1 << 16) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_S_FAIL_INC (3 << 16) +# define RADEON_STENCIL_S_FAIL_DEC (4 << 16) +# define RADEON_STENCIL_S_FAIL_INVERT (5 << 16) +# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) +# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZPASS_INC (3 << 20) +# define RADEON_STENCIL_ZPASS_DEC (4 << 20) +# define RADEON_STENCIL_ZPASS_INVERT (5 << 20) +# define RADEON_STENCIL_ZFAIL_KEEP (0 << 20) +# define RADEON_STENCIL_ZFAIL_ZERO (1 << 20) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 20) +# define RADEON_STENCIL_ZFAIL_INC (3 << 20) +# define RADEON_STENCIL_ZFAIL_DEC (4 << 20) +# define RADEON_STENCIL_ZFAIL_INVERT (5 << 20) +# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) +# define RADEON_FORCE_Z_DIRTY (1 << 29) +# define RADEON_Z_WRITE_ENABLE (1 << 30) +# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) +#define RADEON_RE_LINE_PATTERN 0x1cd0 +# define RADEON_LINE_PATTERN_MASK 0x0000ffff +# define RADEON_LINE_REPEAT_COUNT_SHIFT 16 +# define RADEON_LINE_PATTERN_START_SHIFT 24 +# define RADEON_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) +# define RADEON_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) +# define RADEON_LINE_PATTERN_AUTO_RESET (1 << 29) +#define RADEON_RE_LINE_STATE 0x1cd4 +# define RADEON_LINE_CURRENT_PTR_SHIFT 0 +# define RADEON_LINE_CURRENT_COUNT_SHIFT 8 +#define RADEON_RE_MISC 0x26c4 +# define RADEON_STIPPLE_X_OFFSET_SHIFT 0 +# define RADEON_STIPPLE_Y_OFFSET_SHIFT 8 +# define RADEON_STIPPLE_LITTLE_BIT_ORDER (0 << 16) +# define RADEON_STIPPLE_BIG_BIT_ORDER (1 << 16) +#define RADEON_RE_SOLID_COLOR 0x1c1c +#define RADEON_RE_TOP_LEFT 0x26c0 +# define RADEON_RE_LEFT_SHIFT 0 +# define RADEON_RE_TOP_SHIFT 16 +#define RADEON_RE_WIDTH_HEIGHT 0x1c44 +# define RADEON_RE_WIDTH_SHIFT 0 +# define RADEON_RE_HEIGHT_SHIFT 16 + +#define RADEON_SE_CNTL 0x1c4c +# define RADEON_FFACE_CULL_CW (0 << 0) +# define RADEON_FFACE_CULL_CCW (1 << 0) +# define RADEON_FFACE_CULL_DIR_MASK (1 << 0) +# define RADEON_BFACE_CULL (0 << 1) +# define RADEON_BFACE_SOLID (3 << 1) +# define RADEON_BFACE_CULL_MASK (3 << 1) +# define RADEON_FFACE_CULL (0 << 3) +# define RADEON_FFACE_SOLID (3 << 3) +# define RADEON_FFACE_CULL_MASK (3 << 3) +# define RADEON_BADVTX_CULL_DISABLE (1 << 5) +# define RADEON_FLAT_SHADE_VTX_0 (0 << 6) +# define RADEON_FLAT_SHADE_VTX_1 (1 << 6) +# define RADEON_FLAT_SHADE_VTX_2 (2 << 6) +# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) +# define RADEON_DIFFUSE_SHADE_SOLID (0 << 8) +# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) +# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) +# define RADEON_DIFFUSE_SHADE_MASK (3 << 8) +# define RADEON_ALPHA_SHADE_SOLID (0 << 10) +# define RADEON_ALPHA_SHADE_FLAT (1 << 10) +# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) +# define RADEON_ALPHA_SHADE_MASK (3 << 10) +# define RADEON_SPECULAR_SHADE_SOLID (0 << 12) +# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) +# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) +# define RADEON_SPECULAR_SHADE_MASK (3 << 12) +# define RADEON_FOG_SHADE_SOLID (0 << 14) +# define RADEON_FOG_SHADE_FLAT (1 << 14) +# define RADEON_FOG_SHADE_GOURAUD (2 << 14) +# define RADEON_FOG_SHADE_MASK (3 << 14) +# define RADEON_ZBIAS_ENABLE_POINT (1 << 16) +# define RADEON_ZBIAS_ENABLE_LINE (1 << 17) +# define RADEON_ZBIAS_ENABLE_TRI (1 << 18) +# define RADEON_WIDELINE_ENABLE (1 << 20) +# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) +# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) +# define RADEON_VTX_PIX_CENTER_D3D (0 << 27) +# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) +# define RADEON_ROUND_MODE_TRUNC (0 << 28) +# define RADEON_ROUND_MODE_ROUND (1 << 28) +# define RADEON_ROUND_MODE_ROUND_EVEN (2 << 28) +# define RADEON_ROUND_MODE_ROUND_ODD (3 << 28) +# define RADEON_ROUND_PREC_16TH_PIX (0 << 30) +# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) +# define RADEON_ROUND_PREC_4TH_PIX (2 << 30) +# define RADEON_ROUND_PREC_HALF_PIX (3 << 30) +#define RADEON_SE_CNTL_STATUS 0x2140 +# define RADEON_VC_NO_SWAP (0 << 0) +# define RADEON_VC_16BIT_SWAP (1 << 0) +# define RADEON_VC_32BIT_SWAP (2 << 0) +# define RADEON_VC_HALF_DWORD_SWAP (3 << 0) +# define RADEON_TCL_BYPASS (1 << 8) +#define RADEON_SE_COORD_FMT 0x15c0 +# define RADEON_VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0) +# define RADEON_VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1) +# define RADEON_VTX_ST0_NONPARAMETRIC (1 << 8) +# define RADEON_VTX_ST1_NONPARAMETRIC (1 << 9) +# define RADEON_VTX_ST2_NONPARAMETRIC (1 << 10) +# define RADEON_VTX_ST3_NONPARAMETRIC (1 << 11) +# define RADEON_VTX_W0_NORMALIZE (1 << 12) +# define RADEON_VTX_W0_IS_NOT_1_OVER_W0 (1 << 16) +# define RADEON_VTX_ST0_PRE_MULT_1_OVER_W0 (1 << 17) +# define RADEON_VTX_ST1_PRE_MULT_1_OVER_W0 (1 << 19) +# define RADEON_VTX_ST2_PRE_MULT_1_OVER_W0 (1 << 21) +# define RADEON_VTX_ST3_PRE_MULT_1_OVER_W0 (1 << 23) +# define RADEON_TEX1_W_ROUTING_USE_W0 (0 << 26) +# define RADEON_TEX1_W_ROUTING_USE_Q1 (1 << 26) +#define RADEON_SE_LINE_WIDTH 0x1db8 +#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c +#define RADEON_SE_TCL_MATERIAL_AMBIENT_RED 0x2220 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA 0x222c +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_RED 0x2230 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN 0x2234 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE 0x2238 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA 0x223c +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN 0x2214 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE 0x2218 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA 0x221c +#define RADEON_SE_TCL_MATERIAL_SPECULAR_RED 0x2240 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c +#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c +#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260 +#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 +#define RADEON_SE_TCL_OUTPUT_VTX_SEL 0x2258 +#define RADEON_SE_TCL_PER_LIGHT_CTL_0 0x2270 +#define RADEON_SE_TCL_PER_LIGHT_CTL_1 0x2274 +#define RADEON_SE_TCL_PER_LIGHT_CTL_2 0x2278 +#define RADEON_SE_TCL_PER_LIGHT_CTL_3 0x227c +#define RADEON_SE_TCL_SHININESS 0x2250 +#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268 +#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264 +#define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SE_VPORT_XOFFSET 0x1d9c +#define RADEON_SE_VPORT_YSCALE 0x1da0 +#define RADEON_SE_VPORT_YOFFSET 0x1da4 +#define RADEON_SE_VPORT_ZSCALE 0x1da8 +#define RADEON_SE_VPORT_ZOFFSET 0x1dac + /* Registers for CP and Microcode Engine */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 #define RADEON_CP_ME_RAM_RADDR 0x07d8 @@ -972,519 +1285,93 @@ #define RADEON_AIC_CNTL 0x01d0 # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -#define RADEON_PM4_VC_FPU_SETUP 0x071c -# define RADEON_FRONT_DIR_CW (0 << 0) -# define RADEON_FRONT_DIR_CCW (1 << 0) -# define RADEON_FRONT_DIR_MASK (1 << 0) -# define RADEON_BACKFACE_CULL (0 << 1) -# define RADEON_BACKFACE_POINTS (1 << 1) -# define RADEON_BACKFACE_LINES (2 << 1) -# define RADEON_BACKFACE_SOLID (3 << 1) -# define RADEON_BACKFACE_MASK (3 << 1) -# define RADEON_FRONTFACE_CULL (0 << 3) -# define RADEON_FRONTFACE_POINTS (1 << 3) -# define RADEON_FRONTFACE_LINES (2 << 3) -# define RADEON_FRONTFACE_SOLID (3 << 3) -# define RADEON_FRONTFACE_MASK (3 << 3) -# define RADEON_FPU_COLOR_SOLID (0 << 5) -# define RADEON_FPU_COLOR_FLAT (1 << 5) -# define RADEON_FPU_COLOR_GOURAUD (2 << 5) -# define RADEON_FPU_COLOR_GOURAUD2 (3 << 5) -# define RADEON_FPU_COLOR_MASK (3 << 5) -# define RADEON_FPU_SUB_PIX_2BITS (0 << 7) -# define RADEON_FPU_SUB_PIX_4BITS (1 << 7) -# define RADEON_FPU_MODE_2D (0 << 8) -# define RADEON_FPU_MODE_3D (1 << 8) -# define RADEON_TRAP_BITS_DISABLE (1 << 9) -# define RADEON_EDGE_ANTIALIAS (1 << 10) -# define RADEON_SUPERSAMPLE (1 << 11) -# define RADEON_XFACTOR_2 (0 << 12) -# define RADEON_XFACTOR_4 (1 << 12) -# define RADEON_YFACTOR_2 (0 << 13) -# define RADEON_YFACTOR_4 (1 << 13) -# define RADEON_FLAT_SHADE_VERTEX_D3D (0 << 14) -# define RADEON_FLAT_SHADE_VERTEX_OGL (1 << 14) -# define RADEON_FPU_ROUND_TRUNCATE (0 << 15) -# define RADEON_FPU_ROUND_NEAREST (1 << 15) -# define RADEON_WM_SEL_8DW (0 << 16) -# define RADEON_WM_SEL_16DW (1 << 16) -# define RADEON_WM_SEL_32DW (2 << 16) -#define RADEON_PM4_VC_DEBUG_CONFIG 0x07a4 -#define RADEON_PM4_VC_STAT 0x07a8 -#define RADEON_PM4_VC_TIMESTAMP0 0x07b0 -#define RADEON_PM4_VC_TIMESTAMP1 0x07b4 -#define RADEON_PM4_STAT 0x07b8 -# define RADEON_PM4_FIFOCNT_MASK 0x0fff -# define RADEON_PM4_BUSY (1 << 16) -# define RADEON_PM4_GUI_ACTIVE (1 << 31) -#define RADEON_PM4_BUFFER_ADDR 0x07f0 -#define RADEON_CP_ME_CNTL 0x07d0 -# define RADEON_CP_ME_FREERUN (1 << 30) -#define RADEON_PM4_FIFO_DATA_EVEN 0x1000 -#define RADEON_PM4_FIFO_DATA_ODD 0x1004 - -#define RADEON_SCALE_3D_CNTL 0x1a00 -# define RADEON_SCALE_DITHER_ERR_DIFF (0 << 1) -# define RADEON_SCALE_DITHER_TABLE (1 << 1) -# define RADEON_TEX_CACHE_SIZE_FULL (0 << 2) -# define RADEON_TEX_CACHE_SIZE_HALF (1 << 2) -# define RADEON_DITHER_INIT_CURR (0 << 3) -# define RADEON_DITHER_INIT_RESET (1 << 3) -# define RADEON_ROUND_24BIT (1 << 4) -# define RADEON_TEX_CACHE_DISABLE (1 << 5) -# define RADEON_SCALE_3D_NOOP (0 << 6) -# define RADEON_SCALE_3D_SCALE (1 << 6) -# define RADEON_SCALE_3D_TEXMAP_SHADE (2 << 6) -# define RADEON_SCALE_PIX_BLEND (0 << 8) -# define RADEON_SCALE_PIX_REPLICATE (1 << 8) -# define RADEON_TEX_CACHE_SPLIT (1 << 9) -# define RADEON_APPLE_YUV_MODE (1 << 10) -# define RADEON_TEX_CACHE_PALLETE_MODE (1 << 11) -# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) -# define RADEON_ALPHA_COMB_ADD_NCLAMP (1 << 12) -# define RADEON_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) -# define RADEON_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) -# define RADEON_FOG_TABLE (1 << 14) -# define RADEON_SIGNED_DST_CLAMP (1 << 15) -# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) -# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) -# define RADEON_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) -# define RADEON_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) -# define RADEON_ALPHA_BLEND_SRC_SAT (10 << 16) -# define RADEON_ALPHA_BLEND_SRC_BLEND (11 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVBLEND (12 << 16) -# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) -# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) -# define RADEON_ALPHA_BLEND_DST_DSTALPHA (6 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) -# define RADEON_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) -# define RADEON_ALPHA_TEST_NEVER (0 << 24) -# define RADEON_ALPHA_TEST_LESS (1 << 24) -# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) -# define RADEON_ALPHA_TEST_EQUAL (3 << 24) -# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) -# define RADEON_ALPHA_TEST_GREATER (5 << 24) -# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) -# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) -# define RADEON_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) -# define RADEON_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) -# define RADEON_COMPOSITE_SHADOW (1 << 29) -# define RADEON_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) -# define RADEON_TEX_CACHE_LINE_SIZE_8QW (0 << 31) -# define RADEON_TEX_CACHE_LINE_SIZE_4QW (1 << 31) -#define RADEON_SCALE_3D_DATATYPE 0x1a20 - -#define RADEON_SETUP_CNTL 0x1bc4 -# define RADEON_DONT_START_TRIANGLE (1 << 0) -# define RADEON_Z_BIAS (0 << 1) -# define RADEON_DONT_START_ANY_ON (1 << 2) -# define RADEON_COLOR_SOLID_COLOR (0 << 3) -# define RADEON_COLOR_FLAT_VERT_1 (1 << 3) -# define RADEON_COLOR_FLAT_VERT_2 (2 << 3) -# define RADEON_COLOR_FLAT_VERT_3 (3 << 3) -# define RADEON_COLOR_GOURAUD (4 << 3) -# define RADEON_PRIM_TYPE_TRI (0 << 7) -# define RADEON_PRIM_TYPE_LINE (1 << 7) -# define RADEON_PRIM_TYPE_POINT (2 << 7) -# define RADEON_PRIM_TYPE_POLY_EDGE (3 << 7) -# define RADEON_TEXTURE_ST_MULT_W (0 << 9) -# define RADEON_TEXTURE_ST_DIRECT (1 << 9) -# define RADEON_STARTING_VERTEX_1 (1 << 14) -# define RADEON_STARTING_VERTEX_2 (2 << 14) -# define RADEON_STARTING_VERTEX_3 (3 << 14) -# define RADEON_ENDING_VERTEX_1 (1 << 16) -# define RADEON_ENDING_VERTEX_2 (2 << 16) -# define RADEON_ENDING_VERTEX_3 (3 << 16) -# define RADEON_SU_POLY_LINE_LAST (0 << 18) -# define RADEON_SU_POLY_LINE_NOT_LAST (1 << 18) -# define RADEON_SUB_PIX_2BITS (0 << 19) -# define RADEON_SUB_PIX_4BITS (1 << 19) -# define RADEON_SET_UP_CONTINUE (1 << 31) - -#define RADEON_WINDOW_XY_OFFSET 0x1bcc -# define RADEON_WINDOW_Y_SHIFT 4 -# define RADEON_WINDOW_X_SHIFT 20 - -#define RADEON_Z_OFFSET_C 0x1c90 -#define RADEON_Z_PITCH_C 0x1c94 -#define RADEON_Z_STEN_CNTL_C 0x1c98 -# define RADEON_Z_PIX_WIDTH_16 (0 << 1) -# define RADEON_Z_PIX_WIDTH_24 (1 << 1) -# define RADEON_Z_PIX_WIDTH_32 (2 << 1) -# define RADEON_Z_PIX_WIDTH_MASK (3 << 1) -# define RADEON_Z_TEST_NEVER (0 << 4) -# define RADEON_Z_TEST_LESS (1 << 4) -# define RADEON_Z_TEST_LESSEQUAL (2 << 4) -# define RADEON_Z_TEST_EQUAL (3 << 4) -# define RADEON_Z_TEST_GREATEREQUAL (4 << 4) -# define RADEON_Z_TEST_GREATER (5 << 4) -# define RADEON_Z_TEST_NEQUAL (6 << 4) -# define RADEON_Z_TEST_ALWAYS (7 << 4) -# define RADEON_Z_TEST_MASK (7 << 4) -# define RADEON_STENCIL_TEST_NEVER (0 << 12) -# define RADEON_STENCIL_TEST_LESS (1 << 12) -# define RADEON_STENCIL_TEST_LESSEQUAL (2 << 12) -# define RADEON_STENCIL_TEST_EQUAL (3 << 12) -# define RADEON_STENCIL_TEST_GREATEREQUAL (4 << 12) -# define RADEON_STENCIL_TEST_GREATER (5 << 12) -# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) -# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) -# define RADEON_STENCIL_S_FAIL_ZERO (1 << 16) -# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) -# define RADEON_STENCIL_S_FAIL_INC (3 << 16) -# define RADEON_STENCIL_S_FAIL_DEC (4 << 16) -# define RADEON_STENCIL_S_FAIL_INV (5 << 16) -# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) -# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) -# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) -# define RADEON_STENCIL_ZPASS_INC (3 << 20) -# define RADEON_STENCIL_ZPASS_DEC (4 << 20) -# define RADEON_STENCIL_ZPASS_INV (5 << 20) -# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) -# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) -# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) -# define RADEON_STENCIL_ZFAIL_INC (3 << 24) -# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) -# define RADEON_STENCIL_ZFAIL_INV (5 << 24) -#define RADEON_TEX_CNTL_C 0x1c9c -# define RADEON_Z_ENABLE (1 << 0) -# define RADEON_Z_WRITE_ENABLE (1 << 1) -# define RADEON_STENCIL_ENABLE (1 << 3) -# define RADEON_SHADE_ENABLE (0 << 4) -# define RADEON_TEXMAP_ENABLE (1 << 4) -# define RADEON_SEC_TEXMAP_ENABLE (1 << 5) -# define RADEON_FOG_ENABLE (1 << 7) -# define RADEON_DITHER_ENABLE (1 << 8) -# define RADEON_ALPHA_ENABLE (1 << 9) -# define RADEON_ALPHA_TEST_ENABLE (1 << 10) -# define RADEON_SPEC_LIGHT_ENABLE (1 << 11) -# define RADEON_TEX_CHROMA_KEY_ENABLE (1 << 12) -# define RADEON_ALPHA_IN_TEX_COMPLETE_A (0 << 13) -# define RADEON_ALPHA_IN_TEX_LSB_A (1 << 13) -# define RADEON_LIGHT_DIS (0 << 14) -# define RADEON_LIGHT_COPY (1 << 14) -# define RADEON_LIGHT_MODULATE (2 << 14) -# define RADEON_LIGHT_ADD (3 << 14) -# define RADEON_LIGHT_BLEND_CONSTANT (4 << 14) -# define RADEON_LIGHT_BLEND_TEXTURE (5 << 14) -# define RADEON_LIGHT_BLEND_VERTEX (6 << 14) -# define RADEON_LIGHT_BLEND_CONST_COLOR (7 << 14) -# define RADEON_ALPHA_LIGHT_DIS (0 << 18) -# define RADEON_ALPHA_LIGHT_COPY (1 << 18) -# define RADEON_ALPHA_LIGHT_MODULATE (2 << 18) -# define RADEON_ALPHA_LIGHT_ADD (3 << 18) -# define RADEON_ANTI_ALIAS (1 << 21) -# define RADEON_TEX_CACHE_FLUSH (1 << 23) -# define RADEON_LOD_BIAS_SHIFT 24 -# define RADEON_LOD_BIAS_MASK (0xff << 24) -#define RADEON_MISC_3D_STATE_CNTL_REG 0x1ca0 -# define RADEON_REF_ALPHA_MASK 0xff -# define RADEON_MISC_SCALE_3D_NOOP (0 << 8) -# define RADEON_MISC_SCALE_3D_SCALE (1 << 8) -# define RADEON_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) -# define RADEON_MISC_SCALE_PIX_BLEND (0 << 10) -# define RADEON_MISC_SCALE_PIX_REPLICATE (1 << 10) -# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) -# define RADEON_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) -# define RADEON_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) -# define RADEON_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) -# define RADEON_FOG_VERTEX (0 << 14) -# define RADEON_FOG_TABLE (1 << 14) -# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) -# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) -# define RADEON_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) -# define RADEON_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) -# define RADEON_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) -# define RADEON_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) -# define RADEON_ALPHA_BLEND_SRC_MASK (15 << 16) -# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) -# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) -# define RADEON_ALPHA_BLEND_DST_DESTALPHA (6 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) -# define RADEON_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) -# define RADEON_ALPHA_BLEND_DST_MASK (15 << 20) -# define RADEON_ALPHA_TEST_NEVER (0 << 24) -# define RADEON_ALPHA_TEST_LESS (1 << 24) -# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) -# define RADEON_ALPHA_TEST_EQUAL (3 << 24) -# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) -# define RADEON_ALPHA_TEST_GREATER (5 << 24) -# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) -# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) -# define RADEON_ALPHA_TEST_MASK (7 << 24) -#define RADEON_TEXTURE_CLR_CMP_CLR_C 0x1ca4 -#define RADEON_TEXTURE_CLR_CMP_MSK_C 0x1ca8 -#define RADEON_FOG_COLOR_C 0x1cac -# define RADEON_FOG_BLUE_SHIFT 0 -# define RADEON_FOG_GREEN_SHIFT 8 -# define RADEON_FOG_RED_SHIFT 16 -#define RADEON_PRIM_TEX_CNTL_C 0x1cb0 -# define RADEON_MIN_BLEND_NEAREST (0 << 1) -# define RADEON_MIN_BLEND_LINEAR (1 << 1) -# define RADEON_MIN_BLEND_MIPNEAREST (2 << 1) -# define RADEON_MIN_BLEND_MIPLINEAR (3 << 1) -# define RADEON_MIN_BLEND_LINEARMIPNEAREST (4 << 1) -# define RADEON_MIN_BLEND_LINEARMIPLINEAR (5 << 1) -# define RADEON_MIN_BLEND_MASK (7 << 1) -# define RADEON_MAG_BLEND_NEAREST (0 << 4) -# define RADEON_MAG_BLEND_LINEAR (1 << 4) -# define RADEON_MAG_BLEND_MASK (7 << 4) -# define RADEON_MIP_MAP_DISABLE (1 << 7) -# define RADEON_TEX_CLAMP_S_WRAP (0 << 8) -# define RADEON_TEX_CLAMP_S_MIRROR (1 << 8) -# define RADEON_TEX_CLAMP_S_CLAMP (2 << 8) -# define RADEON_TEX_CLAMP_S_BORDER_COLOR (3 << 8) -# define RADEON_TEX_CLAMP_S_MASK (3 << 8) -# define RADEON_TEX_WRAP_S (1 << 10) -# define RADEON_TEX_CLAMP_T_WRAP (0 << 11) -# define RADEON_TEX_CLAMP_T_MIRROR (1 << 11) -# define RADEON_TEX_CLAMP_T_CLAMP (2 << 11) -# define RADEON_TEX_CLAMP_T_BORDER_COLOR (3 << 11) -# define RADEON_TEX_CLAMP_T_MASK (3 << 11) -# define RADEON_TEX_WRAP_T (1 << 13) -# define RADEON_TEX_PERSPECTIVE_DISABLE (1 << 14) -# define RADEON_DATATYPE_VQ (0 << 16) -# define RADEON_DATATYPE_CI4 (1 << 16) -# define RADEON_DATATYPE_CI8 (2 << 16) -# define RADEON_DATATYPE_ARGB1555 (3 << 16) -# define RADEON_DATATYPE_RGB565 (4 << 16) -# define RADEON_DATATYPE_RGB888 (5 << 16) -# define RADEON_DATATYPE_ARGB8888 (6 << 16) -# define RADEON_DATATYPE_RGB332 (7 << 16) -# define RADEON_DATATYPE_Y8 (8 << 16) -# define RADEON_DATATYPE_RGB8 (9 << 16) -# define RADEON_DATATYPE_CI16 (10 << 16) -# define RADEON_DATATYPE_YUV422 (11 << 16) -# define RADEON_DATATYPE_YUV422_2 (12 << 16) -# define RADEON_DATATYPE_AYUV444 (14 << 16) -# define RADEON_DATATYPE_ARGB4444 (15 << 16) -# define RADEON_PALLETE_EITHER (0 << 20) -# define RADEON_PALLETE_1 (1 << 20) -# define RADEON_PALLETE_2 (2 << 20) -# define RADEON_PSEUDOCOLOR_DT_RGB565 (0 << 24) -# define RADEON_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) -# define RADEON_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) -#define RADEON_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 -# define RADEON_COMB_DIS (0 << 0) -# define RADEON_COMB_COPY (1 << 0) -# define RADEON_COMB_COPY_INP (2 << 0) -# define RADEON_COMB_MODULATE (3 << 0) -# define RADEON_COMB_MODULATE2X (4 << 0) -# define RADEON_COMB_MODULATE4X (5 << 0) -# define RADEON_COMB_ADD (6 << 0) -# define RADEON_COMB_ADD_SIGNED (7 << 0) -# define RADEON_COMB_BLEND_VERTEX (8 << 0) -# define RADEON_COMB_BLEND_TEXTURE (9 << 0) -# define RADEON_COMB_BLEND_CONST (10 << 0) -# define RADEON_COMB_BLEND_PREMULT (11 << 0) -# define RADEON_COMB_BLEND_PREV (12 << 0) -# define RADEON_COMB_BLEND_PREMULT_INV (13 << 0) -# define RADEON_COMB_ADD_SIGNED2X (14 << 0) -# define RADEON_COMB_BLEND_CONST_COLOR (15 << 0) -# define RADEON_COMB_MASK (15 << 0) -# define RADEON_COLOR_FACTOR_TEX (4 << 4) -# define RADEON_COLOR_FACTOR_NTEX (5 << 4) -# define RADEON_COLOR_FACTOR_ALPHA (6 << 4) -# define RADEON_COLOR_FACTOR_NALPHA (7 << 4) -# define RADEON_COLOR_FACTOR_MASK (15 << 4) -# define RADEON_INPUT_FACTOR_CONST_COLOR (2 << 10) -# define RADEON_INPUT_FACTOR_CONST_ALPHA (3 << 10) -# define RADEON_INPUT_FACTOR_INT_COLOR (4 << 10) -# define RADEON_INPUT_FACTOR_INT_ALPHA (5 << 10) -# define RADEON_INPUT_FACTOR_MASK (15 << 10) -# define RADEON_COMB_ALPHA_DIS (0 << 14) -# define RADEON_COMB_ALPHA_COPY (1 << 14) -# define RADEON_COMB_ALPHA_COPY_INP (2 << 14) -# define RADEON_COMB_ALPHA_MODULATE (3 << 14) -# define RADEON_COMB_ALPHA_MODULATE2X (4 << 14) -# define RADEON_COMB_ALPHA_MODULATE4X (5 << 14) -# define RADEON_COMB_ALPHA_ADD (6 << 14) -# define RADEON_COMB_ALPHA_ADD_SIGNED (7 << 14) -# define RADEON_COMB_ALPHA_ADD_SIGNED2X (14 << 14) -# define RADEON_COMB_ALPHA_MASK (15 << 14) -# define RADEON_ALPHA_FACTOR_TEX_ALPHA (6 << 18) -# define RADEON_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) -# define RADEON_ALPHA_FACTOR_MASK (15 << 18) -# define RADEON_INP_FACTOR_A_CONST_ALPHA (1 << 25) -# define RADEON_INP_FACTOR_A_INT_ALPHA (2 << 25) -# define RADEON_INP_FACTOR_A_MASK (7 << 25) -#define RADEON_TEX_SIZE_PITCH_C 0x1cb8 -# define RADEON_TEX_PITCH_SHIFT 0 -# define RADEON_TEX_SIZE_SHIFT 4 -# define RADEON_TEX_HEIGHT_SHIFT 8 -# define RADEON_TEX_MIN_SIZE_SHIFT 12 -# define RADEON_SEC_TEX_PITCH_SHIFT 16 -# define RADEON_SEC_TEX_SIZE_SHIFT 20 -# define RADEON_SEC_TEX_HEIGHT_SHIFT 24 -# define RADEON_SEC_TEX_MIN_SIZE_SHIFT 28 -# define RADEON_TEX_PITCH_MASK (0x0f << 0) -# define RADEON_TEX_SIZE_MASK (0x0f << 4) -# define RADEON_TEX_HEIGHT_MASK (0x0f << 8) -# define RADEON_TEX_MIN_SIZE_MASK (0x0f << 12) -# define RADEON_SEC_TEX_PITCH_MASK (0x0f << 16) -# define RADEON_SEC_TEX_SIZE_MASK (0x0f << 20) -# define RADEON_SEC_TEX_HEIGHT_MASK (0x0f << 24) -# define RADEON_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) -# define RADEON_TEX_SIZE_PITCH_SHIFT 0 -# define RADEON_SEC_TEX_SIZE_PITCH_SHIFT 16 -# define RADEON_TEX_SIZE_PITCH_MASK (0xffff << 0) -# define RADEON_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) -#define RADEON_PRIM_TEX_0_OFFSET_C 0x1cbc -#define RADEON_PRIM_TEX_1_OFFSET_C 0x1cc0 -#define RADEON_PRIM_TEX_2_OFFSET_C 0x1cc4 -#define RADEON_PRIM_TEX_3_OFFSET_C 0x1cc8 -#define RADEON_PRIM_TEX_4_OFFSET_C 0x1ccc -#define RADEON_PRIM_TEX_5_OFFSET_C 0x1cd0 -#define RADEON_PRIM_TEX_6_OFFSET_C 0x1cd4 -#define RADEON_PRIM_TEX_7_OFFSET_C 0x1cd8 -#define RADEON_PRIM_TEX_8_OFFSET_C 0x1cdc -#define RADEON_PRIM_TEX_9_OFFSET_C 0x1ce0 -#define RADEON_PRIM_TEX_10_OFFSET_C 0x1ce4 -# define RADEON_TEX_NO_TILE (0 << 30) -# define RADEON_TEX_TILED_BY_HOST (1 << 30) -# define RADEON_TEX_TILED_BY_STORAGE (2 << 30) -# define RADEON_TEX_TILED_BY_STORAGE2 (3 << 30) - -#define RADEON_SEC_TEX_CNTL_C 0x1d00 -# define RADEON_SEC_SELECT_PRIM_ST (0 << 0) -# define RADEON_SEC_SELECT_SEC_ST (1 << 0) -#define RADEON_SEC_TEX_COMBINE_CNTL_C 0x1d04 -# define RADEON_INPUT_FACTOR_PREV_COLOR (8 << 10) -# define RADEON_INPUT_FACTOR_PREV_ALPHA (9 << 10) -# define RADEON_INP_FACTOR_A_PREV_ALPHA (4 << 25) -#define RADEON_SEC_TEX_0_OFFSET_C 0x1d08 -#define RADEON_SEC_TEX_1_OFFSET_C 0x1d0c -#define RADEON_SEC_TEX_2_OFFSET_C 0x1d10 -#define RADEON_SEC_TEX_3_OFFSET_C 0x1d14 -#define RADEON_SEC_TEX_4_OFFSET_C 0x1d18 -#define RADEON_SEC_TEX_5_OFFSET_C 0x1d1c -#define RADEON_SEC_TEX_6_OFFSET_C 0x1d20 -#define RADEON_SEC_TEX_7_OFFSET_C 0x1d24 -#define RADEON_SEC_TEX_8_OFFSET_C 0x1d28 -#define RADEON_SEC_TEX_9_OFFSET_C 0x1d2c -#define RADEON_SEC_TEX_10_OFFSET_C 0x1d30 -#define RADEON_CONSTANT_COLOR_C 0x1d34 -# define RADEON_CONSTANT_BLUE_SHIFT 0 -# define RADEON_CONSTANT_GREEN_SHIFT 8 -# define RADEON_CONSTANT_RED_SHIFT 16 -# define RADEON_CONSTANT_ALPHA_SHIFT 24 -#define RADEON_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 -# define RADEON_PRIM_TEX_BORDER_BLUE_SHIFT 0 -# define RADEON_PRIM_TEX_BORDER_GREEN_SHIFT 8 -# define RADEON_PRIM_TEX_BORDER_RED_SHIFT 16 -# define RADEON_PRIM_TEX_BORDER_ALPHA_SHIFT 24 -#define RADEON_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c -# define RADEON_SEC_TEX_BORDER_BLUE_SHIFT 0 -# define RADEON_SEC_TEX_BORDER_GREEN_SHIFT 8 -# define RADEON_SEC_TEX_BORDER_RED_SHIFT 16 -# define RADEON_SEC_TEX_BORDER_ALPHA_SHIFT 24 -#define RADEON_STEN_REF_MASK_C 0x1d40 -# define RADEON_STEN_REFERENCE_SHIFT 0 -# define RADEON_STEN_MASK_SHIFT 16 -# define RADEON_STEN_WRITE_MASK_SHIFT 24 -#define RADEON_PLANE_3D_MASK_C 0x1d44 -#define RADEON_TEX_CACHE_STAT_COUNT 0x1974 - - /* Constants */ #define RADEON_AGP_TEX_OFFSET 0x02000000 #define RADEON_LAST_FRAME_REG RADEON_GUI_SCRATCH_REG0 /* CP packet types */ -#define RADEON_CP_PACKET0 0x00000000 -#define RADEON_CP_PACKET0_ONE_REG_WR 0x00008000 -#define RADEON_CP_PACKET1 0x40000000 -#define RADEON_CP_PACKET2 0x80000000 -#define RADEON_CP_PACKET3 0xC0000000 -#define RADEON_CP_PACKET3_NOP 0xC0001000 -#define RADEON_CP_PACKET3_PAINT 0xC0001100 -#define RADEON_CP_PACKET3_BITBLT 0xC0001200 -#define RADEON_CP_PACKET3_SMALLTEXT 0xC0001300 -#define RADEON_CP_PACKET3_HOSTDATA_BLT 0xC0001400 -#define RADEON_CP_PACKET3_POLYLINE 0xC0001500 -#define RADEON_CP_PACKET3_SCALING 0xC0001600 -#define RADEON_CP_PACKET3_TRANS_SCALING 0xC0001700 -#define RADEON_CP_PACKET3_POLYSCANLINES 0xC0001800 -#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 -#define RADEON_CP_PACKET3_PAINT_MULTI 0xC0001A00 -#define RADEON_CP_PACKET3_BITBLT_MULTI 0xC0001B00 -#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 -#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 -#define RADEON_CP_PACKET3_SET_MODE24BPP 0xC0001F00 -#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 -#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 -#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 -#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 -#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 -#define RADEON_CP_PACKET3_CNTL_SCALING 0xC0009600 -#define RADEON_CP_PACKET3_CNTL_TRANS_SCALING 0xC0009700 -#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 -#define RADEON_CP_PACKET3_CNTL_NEXT_CHAR 0xC0009900 -#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 -#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 -#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 -#define RADEON_CP_PACKET3_3D_SAVE_CONTEXT 0xC0002000 -#define RADEON_CP_PACKET3_3D_PLAY_CONTEXT 0xC0002100 -#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 -#define RADEON_CP_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 -#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 -#define RADEON_CP_PACKET3_PURGE 0xC0002D00 -#define RADEON_CP_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 -# define RADEON_CP_PACKET_MASK 0xC0000000 -# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 -# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) -# define RADEON_CP_PACKET0_REG_MASK 0x000007ff -# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff -# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 +#define RADEON_CP_PACKET0 0x00000000 +#define RADEON_CP_PACKET1 0x40000000 +#define RADEON_CP_PACKET2 0x80000000 +#define RADEON_CP_PACKET3 0xC0000000 +# define RADEON_CP_PACKET_MASK 0xC0000000 +# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 +# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) +# define RADEON_CP_PACKET0_REG_MASK 0x000007ff +# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff +# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 + +#define RADEON_CP_PACKET0_ONE_REG_WR 0x00008000 + +#define RADEON_CP_PACKET3_NOP 0xC0001000 +#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 +#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 +#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 +#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 +#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 +#define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003200 +#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 + -#define RADEON_CP_VC_FRMT_RHW 0x00000001 -#define RADEON_CP_VC_FRMT_DIFFUSE_BGR 0x00000002 -#define RADEON_CP_VC_FRMT_DIFFUSE_A 0x00000004 -#define RADEON_CP_VC_FRMT_DIFFUSE_ARGB 0x00000008 -#define RADEON_CP_VC_FRMT_SPEC_BGR 0x00000010 -#define RADEON_CP_VC_FRMT_SPEC_F 0x00000020 -#define RADEON_CP_VC_FRMT_SPEC_FRGB 0x00000040 -#define RADEON_CP_VC_FRMT_S_T 0x00000080 -#define RADEON_CP_VC_FRMT_S2_T2 0x00000100 -#define RADEON_CP_VC_FRMT_RHW2 0x00000200 +#define RADEON_CP_VC_FRMT_XY 0x00000000 +#define RADEON_CP_VC_FRMT_W0 0x00000001 +#define RADEON_CP_VC_FRMT_FPCOLOR 0x00000002 +#define RADEON_CP_VC_FRMT_FPALPHA 0x00000004 +#define RADEON_CP_VC_FRMT_PKCOLOR 0x00000008 +#define RADEON_CP_VC_FRMT_FPSPEC 0x00000010 +#define RADEON_CP_VC_FRMT_FPFOG 0x00000020 +#define RADEON_CP_VC_FRMT_PKSPEC 0x00000040 +#define RADEON_CP_VC_FRMT_ST0 0x00000080 +#define RADEON_CP_VC_FRMT_ST1 0x00000100 +#define RADEON_CP_VC_FRMT_Q1 0x00000200 +#define RADEON_CP_VC_FRMT_ST2 0x00000400 +#define RADEON_CP_VC_FRMT_Q2 0x00000800 +#define RADEON_CP_VC_FRMT_ST3 0x00001000 +#define RADEON_CP_VC_FRMT_Q3 0x00002000 +#define RADEON_CP_VC_FRMT_Q0 0x00004000 +#define RADEON_CP_VC_FRMT_BLND_WEIGHT_CNT_MASK 0x00038000 +#define RADEON_CP_VC_FRMT_N0 0x00040000 +#define RADEON_CP_VC_FRMT_XY1 0x08000000 +#define RADEON_CP_VC_FRMT_Z1 0x10000000 +#define RADEON_CP_VC_FRMT_W1 0x20000000 +#define RADEON_CP_VC_FRMT_N1 0x40000000 +#define RADEON_CP_VC_FRMT_Z 0x80000000 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 -#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 -#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 -#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 -#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a +#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 +#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080 +#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000 +#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100 +#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h index 90ba97de8..8ca507355 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h @@ -42,18 +42,24 @@ #define __RADEON_SAREA_DEFINES__ /* What needs to be changed for the current vertex buffer? */ -#define RADEON_UPLOAD_CONTEXT 0x001 -#define RADEON_UPLOAD_SETUP 0x002 -#define RADEON_UPLOAD_TEX0 0x004 -#define RADEON_UPLOAD_TEX1 0x008 -#define RADEON_UPLOAD_TEX0IMAGES 0x010 -#define RADEON_UPLOAD_TEX1IMAGES 0x020 -#define RADEON_UPLOAD_CORE 0x040 -#define RADEON_UPLOAD_MASKS 0x080 -#define RADEON_UPLOAD_WINDOW 0x100 -#define RADEON_UPLOAD_CLIPRECTS 0x200 /* handled client-side */ -#define RADEON_REQUIRE_QUIESCENCE 0x400 -#define RADEON_UPLOAD_ALL 0x7ff +#define RADEON_UPLOAD_CONTEXT 0x00000001 +#define RADEON_UPLOAD_VERTFMT 0x00000002 +#define RADEON_UPLOAD_LINE 0x00000004 +#define RADEON_UPLOAD_BUMPMAP 0x00000008 +#define RADEON_UPLOAD_MASKS 0x00000010 +#define RADEON_UPLOAD_VIEWPORT 0x00000020 +#define RADEON_UPLOAD_SETUP 0x00000040 +#define RADEON_UPLOAD_TCL 0x00000080 +#define RADEON_UPLOAD_MISC 0x00000100 +#define RADEON_UPLOAD_TEX0 0x00000200 +#define RADEON_UPLOAD_TEX1 0x00000400 +#define RADEON_UPLOAD_TEX2 0x00000800 +#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 +#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 +#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_REQUIRE_QUIESCENCE 0x00010000 +#define RADEON_UPLOAD_ALL 0x0001ffff #define RADEON_FRONT 0x1 #define RADEON_BACK 0x2 @@ -94,48 +100,99 @@ #endif /* __RADEON_SAREA_DEFINES__ */ +#define RADEON_FLOAT_TO_DWORD(f) *((unsigned int *)(&(f))) + typedef struct { - /* Context state - can be written in one large chunk */ - unsigned long dst_pitch_offset_c; - unsigned long dp_gui_master_cntl_c; - unsigned long sc_top_left_c; - unsigned long sc_bottom_right_c; - unsigned long z_offset_c; - unsigned long z_pitch_c; - unsigned long z_sten_cntl_c; - unsigned long tex_cntl_c; - unsigned long misc_3d_state_cntl_reg; - unsigned long texture_clr_cmp_clr_c; - unsigned long texture_clr_cmp_msk_c; - unsigned long fog_color_c; - - /* Texture state */ - unsigned long tex_size_pitch_c; - unsigned long constant_color_c; + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int alpha; +} radeon_color_regs_t; - /* Setup state */ - unsigned long pm4_vc_fpu_setup; - unsigned long setup_cntl; +typedef struct { + /* Context state */ + unsigned int pp_misc; + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + + unsigned int pp_cntl; + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + unsigned int se_cntl; + + /* Vertex format state */ + unsigned int se_coord_fmt; + + /* Line state */ + unsigned int re_line_pattern; + unsigned int re_line_state; + + unsigned int se_line_width; + + /* Bumpmap state */ + unsigned int pp_lum_matrix; + + unsigned int pp_rot_matrix_0; + unsigned int pp_rot_matrix_1; /* Mask state */ - unsigned long dp_write_mask; - unsigned long sten_ref_mask_c; - unsigned long plane_3d_mask_c; + unsigned int rb3d_stencilrefmask; + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + + /* Viewport state */ + unsigned int se_vport_xscale; + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; - /* Window state */ - unsigned long window_xy_offset; + /* Setup state */ + unsigned int se_cntl_status; + +#ifdef TCL_ENABLE + /* TCL state */ + radeon_color_regs_t se_tcl_material_emmissive; + radeon_color_regs_t se_tcl_material_ambient; + radeon_color_regs_t se_tcl_material_diffuse; + radeon_color_regs_t se_tcl_material_specular; + unsigned int se_tcl_shininess; + unsigned int se_tcl_output_vtx_fmt; + unsigned int se_tcl_output_vtx_sel; + unsigned int se_tcl_matrix_select_0; + unsigned int se_tcl_matrix_select_1; + unsigned int se_tcl_ucp_vert_blend_ctl; + unsigned int se_tcl_texture_proc_ctl; + unsigned int se_tcl_light_model_ctl; + unsigned int se_tcl_per_light_ctl[4]; +#endif - /* Core state */ - unsigned long scale_3d_cntl; + /* Misc state */ + unsigned int re_top_left; + unsigned int re_misc; } radeon_context_regs_t; /* Setup registers for each texture unit */ typedef struct { - unsigned long tex_cntl; - unsigned long tex_combine_cntl; - unsigned long tex_size_pitch; - unsigned long tex_offset[RADEON_TEX_MAXLEVELS]; - unsigned long tex_border_color; + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + + unsigned int pp_cubic_faces; + + unsigned int pp_border_color; + + unsigned int pp_cubic_offset[5]; } radeon_texture_regs_t; typedef struct { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c index 3dd69ba5a..3c31f65d3 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c @@ -445,30 +445,7 @@ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) */ static int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) { -#if 1 return radeon_do_wait_for_idle( dev_priv ); -#else - int i; - - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( *dev_priv->ring.head == dev_priv->ring.tail ) { - int pm4stat = RADEON_READ( RADEON_PM4_STAT ); - if ( ( (pm4stat & RADEON_PM4_FIFOCNT_MASK) >= - dev_priv->cp_fifo_size ) && - !(pm4stat & (RADEON_PM4_BUSY | - RADEON_PM4_GUI_ACTIVE)) ) { - return radeon_do_pixcache_flush( dev_priv ); - } - } - udelay( 1 ); - } - -#if 0 - DRM_ERROR( "failed!\n" ); - radeon_status( dev_priv ); -#endif - return -EBUSY; -#endif } /* Start the Concurrent Command Engine. @@ -565,21 +542,20 @@ static int radeon_do_engine_reset( drm_device_t *dev ) static void radeon_cp_init_ring_buffer( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; - u32 ring_start, agp_vm_start, cur_read_ptr; + u32 ring_start, cur_read_ptr; u32 tmp; - agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ); - /* Initialize the memory controller */ RADEON_WRITE( RADEON_MC_FB_LOCATION, - ( agp_vm_start-1 ) & 0xffff0000); + ( dev_priv->agp_vm_start-1 ) & 0xffff0000); RADEON_WRITE( RADEON_MC_AGP_LOCATION, - ( ( ( agp_vm_start-1 + dev_priv->agp_size ) & 0xffff0000) - | ( agp_vm_start >> 16 ) ) ); + ( ( ( dev_priv->agp_vm_start-1 + + dev_priv->agp_size ) & 0xffff0000) + | ( dev_priv->agp_vm_start >> 16 ) ) ); ring_start = dev_priv->cp_ring->offset - dev->agp->base; - RADEON_WRITE( RADEON_CP_RB_BASE, ring_start + agp_vm_start ); + RADEON_WRITE( RADEON_CP_RB_BASE, ring_start + dev_priv->agp_vm_start ); /* Set the write pointer delay */ RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); @@ -706,6 +682,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) } #endif + dev_priv->agp_vm_start = init->agp_vm_start; dev_priv->agp_size = init->agp_size; dev_priv->ring.head = ((__volatile__ u32 *) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h index 5066b5206..b758660f1 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h @@ -38,27 +38,31 @@ #ifndef __RADEON_SAREA_DEFINES__ #define __RADEON_SAREA_DEFINES__ -/* What needs to be changed for the current vertex buffer? - */ -#define RADEON_UPLOAD_CONTEXT 0x001 -#define RADEON_UPLOAD_SETUP 0x002 -#define RADEON_UPLOAD_TEX0 0x004 -#define RADEON_UPLOAD_TEX1 0x008 -#define RADEON_UPLOAD_TEX0IMAGES 0x010 -#define RADEON_UPLOAD_TEX1IMAGES 0x020 -#define RADEON_UPLOAD_CORE 0x040 -#define RADEON_UPLOAD_MASKS 0x080 -#define RADEON_UPLOAD_WINDOW 0x100 -#define RADEON_UPLOAD_CLIPRECTS 0x200 /* handled client-side */ -#define RADEON_REQUIRE_QUIESCENCE 0x400 -#define RADEON_UPLOAD_ALL 0x7ff +/* What needs to be changed for the current vertex buffer? */ +#define RADEON_UPLOAD_CONTEXT 0x00000001 +#define RADEON_UPLOAD_VERTFMT 0x00000002 +#define RADEON_UPLOAD_LINE 0x00000004 +#define RADEON_UPLOAD_BUMPMAP 0x00000008 +#define RADEON_UPLOAD_MASKS 0x00000010 +#define RADEON_UPLOAD_VIEWPORT 0x00000020 +#define RADEON_UPLOAD_SETUP 0x00000040 +#define RADEON_UPLOAD_TCL 0x00000080 +#define RADEON_UPLOAD_MISC 0x00000100 +#define RADEON_UPLOAD_TEX0 0x00000200 +#define RADEON_UPLOAD_TEX1 0x00000400 +#define RADEON_UPLOAD_TEX2 0x00000800 +#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 +#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 +#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_REQUIRE_QUIESCENCE 0x00010000 +#define RADEON_UPLOAD_ALL 0x0001ffff #define RADEON_FRONT 0x1 #define RADEON_BACK 0x2 #define RADEON_DEPTH 0x4 -/* Primitive types - */ +/* Primitive types */ #define RADEON_POINTS 0x1 #define RADEON_LINES 0x2 #define RADEON_LINE_STRIP 0x3 @@ -66,29 +70,25 @@ #define RADEON_TRIANGLE_FAN 0x5 #define RADEON_TRIANGLE_STRIP 0x6 -/* Vertex/indirect buffer size - */ +/* Vertex/indirect buffer size */ #if 1 #define RADEON_BUFFER_SIZE 16384 #else #define RADEON_BUFFER_SIZE (128 * 1024) #endif -/* Byte offsets for indirect buffer data - */ +/* Byte offsets for indirect buffer data */ #define RADEON_INDEX_PRIM_OFFSET 20 #define RADEON_HOSTDATA_BLIT_OFFSET 32 -/* 2048x2048 @ 32bpp texture requires this many indirect buffers - */ +/* 2048x2048 @ 32bpp texture requires this many indirect buffers */ #define RADEON_MAX_BLIT_BUFFERS ((2048 * 2048 * 4)/RADEON_BUFFER_SIZE) -/* Keep these small for testing. - */ +/* Keep these small for testing. */ #define RADEON_NR_SAREA_CLIPRECTS 12 /* There are 2 heaps (local/AGP). Each region within a heap is a - * minimum of 64k, and there are at most 64 of them per heap. + * minimum of 64k, and there are at most 64 of them per heap. */ #define RADEON_LOCAL_TEX_HEAP 0 #define RADEON_AGP_TEX_HEAP 1 @@ -102,57 +102,105 @@ #endif /* __RADEON_SAREA_DEFINES__ */ typedef struct { - /* Context state - can be written in one large chunk */ - unsigned int dst_pitch_offset_c; - unsigned int dp_gui_master_cntl_c; - unsigned int sc_top_left_c; - unsigned int sc_bottom_right_c; - unsigned int z_offset_c; - unsigned int z_pitch_c; - unsigned int z_sten_cntl_c; - unsigned int tex_cntl_c; - unsigned int misc_3d_state_cntl_reg; - unsigned int texture_clr_cmp_clr_c; - unsigned int texture_clr_cmp_msk_c; - unsigned int fog_color_c; - - /* Texture state */ - unsigned int tex_size_pitch_c; - unsigned int constant_color_c; + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int alpha; +} radeon_color_regs_t; - /* Setup state */ - unsigned int pm4_vc_fpu_setup; - unsigned int setup_cntl; +typedef struct { + /* Context state */ + unsigned int pp_misc; /* 0x1c14 */ + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + + unsigned int pp_cntl; /* 0x1c38 */ + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + unsigned int se_cntl; + + /* Vertex format state */ + unsigned int se_coord_fmt; /* 0x1c50 */ + + /* Line state */ + unsigned int re_line_pattern; /* 0x1cd0 */ + unsigned int re_line_state; + + unsigned int se_line_width; /* 0x1db8 */ + + /* Bumpmap state */ + unsigned int pp_lum_matrix; /* 0x1d00 */ + + unsigned int pp_rot_matrix_0; /* 0x1d58 */ + unsigned int pp_rot_matrix_1; /* Mask state */ - unsigned int dp_write_mask; - unsigned int sten_ref_mask_c; - unsigned int plane_3d_mask_c; + unsigned int rb3d_stencilrefmask; /* 0x1d7c */ + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + + /* Viewport state */ + unsigned int se_vport_xscale; /* 0x1d98 */ + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; - /* Window state */ - unsigned int window_xy_offset; + /* Setup state */ + unsigned int se_cntl_status; /* 0x2140 */ + +#ifdef TCL_ENABLE + /* TCL state */ + radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */ + radeon_color_regs_t se_tcl_material_ambient; + radeon_color_regs_t se_tcl_material_diffuse; + radeon_color_regs_t se_tcl_material_specular; + unsigned int se_tcl_shininess; + unsigned int se_tcl_output_vtx_fmt; + unsigned int se_tcl_output_vtx_sel; + unsigned int se_tcl_matrix_select_0; + unsigned int se_tcl_matrix_select_1; + unsigned int se_tcl_ucp_vert_blend_ctl; + unsigned int se_tcl_texture_proc_ctl; + unsigned int se_tcl_light_model_ctl; + unsigned int se_tcl_per_light_ctl[4]; +#endif - /* Core state */ - unsigned int scale_3d_cntl; + /* Misc state */ + unsigned int re_top_left; /* 0x26c0 */ + unsigned int re_misc; } drm_radeon_context_regs_t; /* Setup registers for each texture unit */ typedef struct { - unsigned int tex_cntl; - unsigned int tex_combine_cntl; - unsigned int tex_size_pitch; - unsigned int tex_offset[RADEON_TEX_MAXLEVELS]; - unsigned int tex_border_color; -} drm_radeon_texture_regs_t; + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + + unsigned int pp_cubic_faces; + unsigned int pp_border_color; -typedef struct drm_radeon_tex_region { + unsigned int pp_cubic_offset[5]; +} drm_radeon_texture_regs_t; + +typedef struct { unsigned char next, prev; unsigned char in_use; int age; } drm_radeon_tex_region_t; -typedef struct drm_radeon_sarea { +typedef struct { /* The channel for communication of state information to the kernel * on firing a vertex buffer. */ @@ -179,7 +227,7 @@ typedef struct drm_radeon_sarea { /* WARNING: If you change any of these defines, make sure to change the - * defines in the Xserver file (xf86drmRADEON.h) + * defines in the Xserver file (xf86drmRadeon.h) */ typedef struct drm_radeon_init { enum { @@ -209,6 +257,8 @@ typedef struct drm_radeon_init { unsigned int ring_rptr_offset; unsigned int buffers_offset; unsigned int agp_textures_offset; + + unsigned int agp_vm_start; } drm_radeon_init_t; typedef struct drm_radeon_cp_stop { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c index d74405239..9cbb1264f 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c @@ -110,7 +110,7 @@ static drm_ioctl_desc_t radeon_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_SWAP)] = { radeon_cp_swap, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_CLEAR)] = { radeon_cp_clear, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_VERTEX)] = { radeon_cp_vertex, 1, 0 }, diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h index 6fb21ca20..2e27398b3 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h @@ -56,6 +56,7 @@ typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; drm_radeon_sarea_t *sarea_priv; + u32 agp_vm_start; int agp_size; int cp_mode; @@ -181,31 +182,6 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); * for Radeon kernel driver. */ -#if 0 -#define RADEON_AUX_SC_CNTL 0x1660 -# define RADEON_AUX1_SC_EN (1 << 0) -# define RADEON_AUX1_SC_MODE_OR (0 << 1) -# define RADEON_AUX1_SC_MODE_NAND (1 << 1) -# define RADEON_AUX2_SC_EN (1 << 2) -# define RADEON_AUX2_SC_MODE_OR (0 << 3) -# define RADEON_AUX2_SC_MODE_NAND (1 << 3) -# define RADEON_AUX3_SC_EN (1 << 4) -# define RADEON_AUX3_SC_MODE_OR (0 << 5) -# define RADEON_AUX3_SC_MODE_NAND (1 << 5) -#define RADEON_AUX1_SC_LEFT 0x1664 -#define RADEON_AUX1_SC_RIGHT 0x1668 -#define RADEON_AUX1_SC_TOP 0x166c -#define RADEON_AUX1_SC_BOTTOM 0x1670 -#define RADEON_AUX2_SC_LEFT 0x1674 -#define RADEON_AUX2_SC_RIGHT 0x1678 -#define RADEON_AUX2_SC_TOP 0x167c -#define RADEON_AUX2_SC_BOTTOM 0x1680 -#define RADEON_AUX3_SC_LEFT 0x1684 -#define RADEON_AUX3_SC_RIGHT 0x1688 -#define RADEON_AUX3_SC_TOP 0x168c -#define RADEON_AUX3_SC_BOTTOM 0x1690 -#endif - #define RADEON_BUS_CNTL 0x0030 # define RADEON_BUS_MASTER_DIS (1 << 6) @@ -214,11 +190,7 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); #define RADEON_CLOCK_CNTL_INDEX 0x0008 #define RADEON_CONFIG_APER_SIZE 0x0108 -#if 0 -#define RADEON_CONSTANT_COLOR_C 0x1d34 -#endif -#if 0 #define RADEON_DP_GUI_MASTER_CNTL 0x146c # define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) # define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) @@ -232,18 +204,10 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); # define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) # define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) # define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) -# define RADEON_GMC_AUX_CLIP_DIS (1 << 29) # define RADEON_GMC_WR_MSK_DIS (1 << 30) # define RADEON_ROP3_S 0x00cc0000 # define RADEON_ROP3_P 0x00f00000 #define RADEON_DP_WRITE_MASK 0x16cc -#define RADEON_DST_PITCH_OFFSET_C 0x1c80 -#endif - -#if 0 -#define RADEON_GEN_RESET_CNTL 0x00f0 -# define RADEON_SOFT_RESET_GUI (1 << 0) -#endif #define RADEON_GUI_SCRATCH_REG0 0x15e0 #define RADEON_GUI_SCRATCH_REG1 0x15e4 @@ -252,29 +216,28 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); #define RADEON_GUI_SCRATCH_REG4 0x15f0 #define RADEON_GUI_SCRATCH_REG5 0x15f4 -#if 0 -#define RADEON_GUI_STAT 0x1740 -# define RADEON_GUI_FIFOCNT_MASK 0x0fff -# define RADEON_GUI_ACTIVE (1 << 31) -#endif - #define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_MCLK_CNTL 0x0012 -#if 0 -#define RADEON_PC_GUI_CTLSTAT 0x1748 -#define RADEON_PC_NGUI_CTLSTAT 0x0184 -# define RADEON_PC_FLUSH_GUI (3 << 0) -# define RADEON_PC_RI_GUI (1 << 2) -# define RADEON_PC_FLUSH_ALL 0x00ff -# define RADEON_PC_BUSY (1 << 31) -#define RADEON_PRIM_TEX_CNTL_C 0x1cb0 -#endif +#define RADEON_PP_CNTL 0x1c38 +#define RADEON_PP_LUM_MATRIX 0x1d00 +#define RADEON_PP_MISC 0x1c14 +#define RADEON_PP_ROT_MATRIX_0 0x1d58 #define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c # define RADEON_RB2D_DC_FLUSH_ALL 0xf # define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_RB3D_CNTL 0x1c3c +# define RADEON_PLANE_MASK_ENABLE (1 << 1) +# define RADEON_Z_ENABLE (1 << 8) +#define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_PLANEMASK 0x1d84 +#define RADEON_RB3D_STENCILREFMASK 0x1d7c +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_Z_WRITE_ENABLE (1 << 30) #define RADEON_RBBM_SOFT_RESET 0x00f0 # define RADEON_SOFT_RESET_CP (1 << 0) # define RADEON_SOFT_RESET_HI (1 << 1) @@ -287,23 +250,20 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); #define RADEON_RBBM_STATUS 0x0e40 # define RADEON_RBBM_FIFOCNT_MASK 0x007f # define RADEON_RBBM_ACTIVE (1 << 31) - -#if 0 -#define RADEON_SCALE_3D_CNTL 0x1a00 -#define RADEON_SEC_TEX_CNTL_C 0x1d00 -#define RADEON_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c -#define RADEON_SETUP_CNTL 0x1bc4 -#define RADEON_STEN_REF_MASK_C 0x1d40 -#endif - -#if 0 -#define RADEON_TEX_CNTL_C 0x1c9c -# define RADEON_TEX_CACHE_FLUSH (1 << 23) -#endif - -#if 0 -#define RADEON_WINDOW_XY_OFFSET 0x1bcc -#endif +#define RADEON_RE_LINE_PATTERN 0x1cd0 +#define RADEON_RE_TOP_LEFT 0x26c0 + +#define RADEON_SE_COORD_FMT 0x1c50 +#define RADEON_SE_CNTL 0x1c4c +# define RADEON_BFACE_SOLID (3 << 1) +# define RADEON_BFACE_CULL_MASK (3 << 1) +# define RADEON_FFACE_SOLID (3 << 3) +# define RADEON_FFACE_CULL_MASK (3 << 3) +# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) +# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) +#define RADEON_SE_CNTL_STATUS 0x2140 +#define RADEON_SE_LINE_WIDTH 0x1db8 +#define RADEON_SE_VPORT_XSCALE 0x1d98 /* CP registers */ @@ -322,6 +282,8 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); # define RADEON_PRE_WRITE_TIMER_SHIFT 0 # define RADEON_PRE_WRITE_LIMIT_SHIFT 23 +#define RADEON_CP_IB_BASE 0x0738 + #define RADEON_CP_CSQ_CNTL 0x0740 # define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) # define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) @@ -334,16 +296,16 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); #define RADEON_AIC_CNTL 0x01d0 # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -#if 0 /* CP command packets */ #define RADEON_CP_PACKET0 0x00000000 #define RADEON_CP_PACKET1 0x40000000 #define RADEON_CP_PACKET2 0x80000000 #define RADEON_CP_PACKET3 0xC0000000 +# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 +# define RADEON_3D_DRAW_IMMD 0x00002900 # define RADEON_CNTL_HOSTDATA_BLT 0x00009400 # define RADEON_CNTL_PAINT_MULTI 0x00009A00 # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 -# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 #define RADEON_CP_PACKET_MASK 0xC0000000 #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 @@ -351,28 +313,40 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new); #define RADEON_CP_PACKET1_REG0_MASK 0x000007ff #define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 -#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 -#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 -#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 -#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 - -#define RADEON_DATATYPE_CI8 2 -#define RADEON_DATATYPE_ARGB1555 3 -#define RADEON_DATATYPE_RGB565 4 -#define RADEON_DATATYPE_RGB888 5 -#define RADEON_DATATYPE_ARGB8888 6 -#define RADEON_DATATYPE_RGB332 7 -#define RADEON_DATATYPE_RGB8 9 -#define RADEON_DATATYPE_ARGB4444 15 -#endif +#define RADEON_CP_VC_FRMT_XY 0x00000000 +#define RADEON_CP_VC_FRMT_Z 0x80000000 + +#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a +#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 +#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080 +#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000 +#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100 +#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 + +#define RADEON_COLOR_FORMAT_ARGB1555 3 +#define RADEON_COLOR_FORMAT_RGB565 4 +#define RADEON_COLOR_FORMAT_ARGB8888 6 +#define RADEON_COLOR_FORMAT_RGB332 7 +#define RADEON_COLOR_FORMAT_Y8 8 +#define RADEON_COLOR_FORMAT_RGB8 9 +#define RADEON_COLOR_FORMAT_YUV422_VYUY 11 +#define RADEON_COLOR_FORMAT_YUV422_YVYU 12 +#define RADEON_COLOR_FORMAT_aYUV444 14 +#define RADEON_COLOR_FORMAT_ARGB4444 15 /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c index 0284c4f8d..30949ee27 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c @@ -33,6 +33,7 @@ #include "radeon_drv.h" #include "drm.h" +/* This must be defined to 1 for now */ #define USE_OLD_BLITS 1 static drm_radeon_blit_rect_t rects[RADEON_MAX_BLIT_BUFFERS]; @@ -87,9 +88,37 @@ static void radeon_emit_clip_rects( drm_radeon_private_t *dev_priv, #endif } -static inline void radeon_emit_core( drm_radeon_private_t *dev_priv ) +static inline void radeon_emit_context( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 15 ); + + OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); + OUT_RING( ctx->pp_misc ); + OUT_RING( ctx->pp_fog_color ); + OUT_RING( ctx->re_solid_color ); + OUT_RING( ctx->rb3d_blendcntl ); + OUT_RING( ctx->rb3d_depthoffset ); + OUT_RING( ctx->rb3d_depthpitch ); + OUT_RING( ctx->rb3d_zstencilcntl ); + + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 5 ) ); + OUT_RING( ctx->pp_cntl ); + OUT_RING( ctx->rb3d_cntl ); + OUT_RING( ctx->rb3d_coloroffset ); + OUT_RING( ctx->re_width_height ); + OUT_RING( ctx->rb3d_colorpitch ); + OUT_RING( ctx->se_cntl ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv ) { -#if 0 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; @@ -97,95 +126,175 @@ static inline void radeon_emit_core( drm_radeon_private_t *dev_priv ) BEGIN_RING( 2 ); - OUT_RING( CP_PACKET0( RADEON_SCALE_3D_CNTL, 0 ) ); - OUT_RING( ctx->scale_3d_cntl ); + OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); + OUT_RING( ctx->se_coord_fmt ); ADVANCE_RING(); -#endif } -static inline void radeon_emit_context( drm_radeon_private_t *dev_priv ) +static inline void radeon_emit_line( drm_radeon_private_t *dev_priv ) { -#if 0 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 13 ); - - OUT_RING( CP_PACKET0( RADEON_DST_PITCH_OFFSET_C, 11 ) ); - OUT_RING( ctx->dst_pitch_offset_c ); - OUT_RING( ctx->dp_gui_master_cntl_c ); - OUT_RING( ctx->sc_top_left_c ); - OUT_RING( ctx->sc_bottom_right_c ); - OUT_RING( ctx->z_offset_c ); - OUT_RING( ctx->z_pitch_c ); - OUT_RING( ctx->z_sten_cntl_c ); - OUT_RING( ctx->tex_cntl_c ); - OUT_RING( ctx->misc_3d_state_cntl_reg ); - OUT_RING( ctx->texture_clr_cmp_clr_c ); - OUT_RING( ctx->texture_clr_cmp_msk_c ); - OUT_RING( ctx->fog_color_c ); + BEGIN_RING( 5 ); + + OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); + OUT_RING( ctx->re_line_pattern ); + OUT_RING( ctx->re_line_state ); + + OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); + OUT_RING( ctx->se_line_width ); ADVANCE_RING(); -#endif } -static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv ) +static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv ) { -#if 0 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 3 ); + BEGIN_RING( 5 ); - OUT_RING( CP_PACKET1( RADEON_SETUP_CNTL, RADEON_PM4_VC_FPU_SETUP ) ); - OUT_RING( ctx->setup_cntl ); - OUT_RING( ctx->pm4_vc_fpu_setup ); + OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); + OUT_RING( ctx->pp_lum_matrix ); + + OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); + OUT_RING( ctx->pp_rot_matrix_0 ); + OUT_RING( ctx->pp_rot_matrix_1 ); ADVANCE_RING(); -#endif } static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv ) { -#if 0 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 5 ); + BEGIN_RING( 4 ); - OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( ctx->dp_write_mask ); + OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); + OUT_RING( ctx->rb3d_stencilrefmask ); + OUT_RING( ctx->rb3d_ropcntl ); + OUT_RING( ctx->rb3d_planemask ); - OUT_RING( CP_PACKET0( RADEON_STEN_REF_MASK_C, 1 ) ); - OUT_RING( ctx->sten_ref_mask_c ); - OUT_RING( ctx->plane_3d_mask_c ); + ADVANCE_RING(); +} + +static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 7 ); + + OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); + OUT_RING( ctx->se_vport_xscale ); + OUT_RING( ctx->se_vport_xoffset ); + OUT_RING( ctx->se_vport_yscale ); + OUT_RING( ctx->se_vport_yoffset ); + OUT_RING( ctx->se_vport_zscale ); + OUT_RING( ctx->se_vport_zoffset ); ADVANCE_RING(); -#endif } -static inline void radeon_emit_window( drm_radeon_private_t *dev_priv ) +static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv ) { -#if 0 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 2 ); + /* Note this duplicates the uploading of se_cntl, which is part + of the context, but adding it here optimizes the reduced + primitive change since we currently render points and lines + with triangles. In the future, we probably won't need this + optimization. */ + +#if 0 + /* Why doesn't CP_PACKET1 work? */ + BEGIN_RING( 3 ); + + OUT_RING( CP_PACKET1( RADEON_SE_CNTL, RADEON_SE_CNTL_STATUS ) ); + OUT_RING( ctx->se_cntl ); + OUT_RING( ctx->se_cntl_status ); +#else + BEGIN_RING( 4 ); + + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( ctx->se_cntl ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); + OUT_RING( ctx->se_cntl_status ); +#endif + + ADVANCE_RING(); +} + +#ifdef TCL_ENABLE +static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); - OUT_RING( CP_PACKET0( RADEON_WINDOW_XY_OFFSET, 0 ) ); - OUT_RING( ctx->window_xy_offset ); + BEGIN_RING( 29 ); + + OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) ); + OUT_RING( ctx->se_tcl_material_emmissive.red ); + OUT_RING( ctx->se_tcl_material_emmissive.green ); + OUT_RING( ctx->se_tcl_material_emmissive.blue ); + OUT_RING( ctx->se_tcl_material_emmissive.alpha ); + OUT_RING( ctx->se_tcl_material_ambient.red ); + OUT_RING( ctx->se_tcl_material_ambient.green ); + OUT_RING( ctx->se_tcl_material_ambient.blue ); + OUT_RING( ctx->se_tcl_material_ambient.alpha ); + OUT_RING( ctx->se_tcl_material_diffuse.red ); + OUT_RING( ctx->se_tcl_material_diffuse.green ); + OUT_RING( ctx->se_tcl_material_diffuse.blue ); + OUT_RING( ctx->se_tcl_material_diffuse.alpha ); + OUT_RING( ctx->se_tcl_material_specular.red ); + OUT_RING( ctx->se_tcl_material_specular.green ); + OUT_RING( ctx->se_tcl_material_specular.blue ); + OUT_RING( ctx->se_tcl_material_specular.alpha ); + OUT_RING( ctx->se_tcl_shininess ); + OUT_RING( ctx->se_tcl_output_vtx_fmt ); + OUT_RING( ctx->se_tcl_output_vtx_sel ); + OUT_RING( ctx->se_tcl_matrix_select_0 ); + OUT_RING( ctx->se_tcl_matrix_select_1 ); + OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl ); + OUT_RING( ctx->se_tcl_texture_proc_ctl ); + OUT_RING( ctx->se_tcl_light_model_ctl ); + for (i = 0; i < 4; i++) + OUT_RING( ctx->se_tcl_per_light_ctl[i] ); ADVANCE_RING(); +} #endif + +static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 3 ); + + OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 1 ) ); + OUT_RING( ctx->re_top_left ); + OUT_RING( ctx->re_misc ); + + ADVANCE_RING(); } static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv ) @@ -243,6 +352,32 @@ static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv ) #endif } +static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv ) +{ +#if 0 + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2]; + int i; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 5 + RADEON_TEX_MAXLEVELS ); + + OUT_RING( CP_PACKET0( RADEON_SEC_TEX_CNTL_C, + 1 + RADEON_TEX_MAXLEVELS ) ); + OUT_RING( tex->tex_cntl ); + OUT_RING( tex->tex_combine_cntl ); + for ( i = 0 ; i < RADEON_TEX_MAXLEVELS ; i++ ) { + OUT_RING( tex->tex_offset[i] ); + } + + OUT_RING( CP_PACKET0( RADEON_SEC_TEXTURE_BORDER_COLOR_C, 0 ) ); + OUT_RING( tex->tex_border_color ); + + ADVANCE_RING(); +#endif +} + static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) { drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -250,19 +385,24 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); - if ( dirty & RADEON_UPLOAD_CORE ) { - radeon_emit_core( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_CORE; - } - if ( dirty & RADEON_UPLOAD_CONTEXT ) { radeon_emit_context( dev_priv ); sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT; } - if ( dirty & RADEON_UPLOAD_SETUP ) { - radeon_emit_setup( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP; + if ( dirty & RADEON_UPLOAD_VERTFMT ) { + radeon_emit_vertfmt( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT; + } + + if ( dirty & RADEON_UPLOAD_LINE ) { + radeon_emit_line( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_LINE; + } + + if ( dirty & RADEON_UPLOAD_BUMPMAP ) { + radeon_emit_bumpmap( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP; } if ( dirty & RADEON_UPLOAD_MASKS ) { @@ -270,9 +410,26 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS; } - if ( dirty & RADEON_UPLOAD_WINDOW ) { - radeon_emit_window( dev_priv ); - sarea_priv->dirty &= ~RADEON_UPLOAD_WINDOW; + if ( dirty & RADEON_UPLOAD_VIEWPORT ) { + radeon_emit_viewport( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT; + } + + if ( dirty & RADEON_UPLOAD_SETUP ) { + radeon_emit_setup( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP; + } + +#ifdef TCL_ENABLE + if ( dirty & RADEON_UPLOAD_TCL ) { + radeon_emit_tcl( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_TCL; + } +#endif + + if ( dirty & RADEON_UPLOAD_MISC ) { + radeon_emit_misc( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_MISC; } if ( dirty & RADEON_UPLOAD_TEX0 ) { @@ -285,6 +442,11 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1; } + if ( dirty & RADEON_UPLOAD_TEX2 ) { + radeon_emit_tex1( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1; + } + #if 0 /* Turn off the texture cache flushing */ sarea_priv->context_state.tex_cntl_c &= ~RADEON_TEX_CACHE_FLUSH; @@ -292,6 +454,7 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | RADEON_REQUIRE_QUIESCENCE); } @@ -305,7 +468,6 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv, int x, int y, int w, int h, int r, int g, int b ) { -#if 0 u32 pitch, offset; u32 fb_bpp, color; RING_LOCALS; @@ -317,10 +479,6 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv, ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); break; - case 24: - fb_bpp = RADEON_GMC_DST_24BPP; - color = ((r << 16) | (g << 8) | b); - break; case 32: default: fb_bpp = RADEON_GMC_DST_32BPP; @@ -339,17 +497,15 @@ static void radeon_clear_box( drm_radeon_private_t *dev_priv, | fb_bpp | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); + | RADEON_GMC_CLR_CMP_CNTL_DIS ); - OUT_RING( (pitch << 21) | (offset >> 5) ); + OUT_RING( (pitch << 22) | (offset >> 5) ); OUT_RING( color ); OUT_RING( (x << 16) | y ); OUT_RING( (w << 16) | h ); ADVANCE_RING(); -#endif } static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) @@ -370,16 +526,21 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) static void radeon_print_dirty( const char *msg, unsigned int flags ) { - DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", msg, flags, - (flags & RADEON_UPLOAD_CORE) ? "core, " : "", (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "", + (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", + (flags & RADEON_UPLOAD_LINE) ? "line, " : "", + (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", + (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "", + (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "", + (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "", + (flags & RADEON_UPLOAD_MISC) ? "misc, " : "", (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "", (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "", - (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "", - (flags & RADEON_UPLOAD_WINDOW) ? "window, " : "", + (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "", (flags & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); } @@ -392,7 +553,6 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, unsigned int color_mask, unsigned int depth_mask ) { -#if 0 drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; @@ -408,9 +568,6 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, case 16: fb_bpp = RADEON_GMC_DST_16BPP; break; - case 24: - fb_bpp = RADEON_GMC_DST_24BPP; - break; case 32: default: fb_bpp = RADEON_GMC_DST_32BPP; @@ -420,9 +577,6 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, case 16: depth_bpp = RADEON_GMC_DST_16BPP; break; - case 24: - depth_bpp = RADEON_GMC_DST_32BPP; - break; case 32: depth_bpp = RADEON_GMC_DST_32BPP; break; @@ -463,8 +617,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, | fb_bpp | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); + | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( clear_color ); OUT_RING( (fx << 16) | fy ); OUT_RING( (w << 16) | h ); @@ -485,8 +638,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, | fb_bpp | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); + | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( clear_color ); OUT_RING( (bx << 16) | by ); OUT_RING( (w << 16) | h ); @@ -495,26 +647,84 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, } if ( flags & RADEON_DEPTH ) { - int dx = x + dev_priv->depth_x; - int dy = y + dev_priv->depth_y; + int dx = x; + int dy = y; + drm_radeon_context_regs_t *ctx = + &sarea_priv->context_state; + u32 rb3d_cntl = ctx->rb3d_cntl; + u32 rb3d_zstencilcntl = ctx->rb3d_zstencilcntl; + u32 se_cntl = ctx->se_cntl; DRM_DEBUG( "clear depth: x=%d y=%d\n", dev_priv->depth_x, dev_priv->depth_y ); - BEGIN_RING( 7 ); - OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); - OUT_RING( depth_mask ); + rb3d_cntl |= ( RADEON_PLANE_MASK_ENABLE + | RADEON_Z_ENABLE ); + + rb3d_zstencilcntl &= ~RADEON_Z_TEST_MASK; + rb3d_zstencilcntl |= ( RADEON_Z_TEST_ALWAYS + | RADEON_Z_WRITE_ENABLE ); + + se_cntl &= ~( RADEON_VPORT_XY_XFORM_ENABLE + | RADEON_VPORT_Z_XFORM_ENABLE + | RADEON_FFACE_CULL_MASK + | RADEON_BFACE_CULL_MASK ); + se_cntl |= ( RADEON_FFACE_SOLID + | RADEON_BFACE_SOLID ); + + BEGIN_RING( 28 ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_CNTL, 0 ) ); + OUT_RING( rb3d_cntl ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); + OUT_RING( rb3d_zstencilcntl ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) ); + OUT_RING( 0x00000000 ); + + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( se_cntl ); + + /* Draw rectangle */ + OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) ); + OUT_RING( RADEON_CP_VC_FRMT_XY + | RADEON_CP_VC_FRMT_Z); + OUT_RING( RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE + | RADEON_CP_VC_CNTL_MAOS_ENABLE + | RADEON_CP_VC_CNTL_PRIM_WALK_RING + | RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST + | ( 3 << RADEON_CP_VC_CNTL_NUM_SHIFT ) ); + { + union { + float f; + u32 u; + } val; + + val.f = dx; OUT_RING( val.u ); + val.f = dy; OUT_RING( val.u ); + val.f = clear_depth; OUT_RING( val.u ); + + val.f = dx; OUT_RING( val.u ); + val.f = dy + h; OUT_RING( val.u ); + val.f = clear_depth; OUT_RING( val.u ); + + val.f = dx + w; OUT_RING( val.u ); + val.f = dy + h; OUT_RING( val.u ); + val.f = clear_depth; OUT_RING( val.u ); + } - OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 3 ) ); - OUT_RING( RADEON_GMC_BRUSH_SOLID_COLOR - | depth_bpp - | RADEON_GMC_SRC_DATATYPE_COLOR - | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); - OUT_RING( clear_depth ); - OUT_RING( (dx << 16) | dy ); - OUT_RING( (w << 16) | h ); + OUT_RING( CP_PACKET0( RADEON_RB3D_CNTL, 0 ) ); + OUT_RING( ctx->rb3d_cntl ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); + OUT_RING( ctx->rb3d_zstencilcntl ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) ); + OUT_RING( ctx->rb3d_planemask ); + + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( ctx->se_cntl ); ADVANCE_RING(); } @@ -528,8 +738,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, | fb_bpp | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); + | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( ((dev_priv->front_pitch/8) << 21) | (dev_priv->front_offset >> 5) ); @@ -550,8 +759,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, | fb_bpp | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); + | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( ((dev_priv->back_pitch/8) << 21) | (dev_priv->back_offset >> 5) ); @@ -575,8 +783,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, | depth_bpp | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P - | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS ); + | RADEON_GMC_CLR_CMP_CNTL_DIS ); OUT_RING( ((dev_priv->depth_pitch/8) << 21) | (dev_priv->depth_offset >> 5) ); @@ -589,12 +796,10 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, } #endif } -#endif } static void radeon_cp_dispatch_swap( drm_device_t *dev ) { -#if 0 drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; @@ -646,7 +851,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) | fb_bpp | RADEON_ROP3_S | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS | RADEON_GMC_WR_MSK_DIS ); OUT_RING( (bx << 16) | by ); @@ -666,7 +870,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) | fb_bpp | RADEON_ROP3_S | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS | RADEON_GMC_WR_MSK_DIS ); OUT_RING( ((dev_priv->back_pitch/8) << 21) | @@ -694,13 +897,11 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) OUT_RING( dev_priv->sarea_priv->last_frame ); ADVANCE_RING(); -#endif } static void radeon_cp_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) { -#if 0 drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -745,7 +946,7 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); - OUT_RING( offset ); + OUT_RING( offset + dev_priv->agp_vm_start ); OUT_RING( size ); OUT_RING( format ); OUT_RING( prim | RADEON_CP_VC_CNTL_PRIM_WALK_LIST | @@ -787,7 +988,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; -#endif } @@ -797,7 +997,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, drm_buf_t *buf, int start, int end ) { -#if 0 drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; @@ -842,7 +1041,7 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, /* Fire off the indirect buffer */ BEGIN_RING( 3 ); - OUT_RING( CP_PACKET0( RADEON_PM4_IW_INDOFF, 1 ) ); + OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) ); OUT_RING( offset ); OUT_RING( dwords ); @@ -875,14 +1074,12 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, radeon_freelist_reset( dev ); } #endif -#endif } static void radeon_cp_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, int start, int end ) { -#if 0 drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -922,7 +1119,7 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); - data[1] = offset; + data[1] = offset + dev_priv->agp_vm_start; data[2] = RADEON_MAX_VB_VERTS; data[3] = format; data[4] = (prim | RADEON_CP_VC_CNTL_PRIM_WALK_IND | @@ -984,7 +1181,6 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; -#endif } static int radeon_cp_dispatch_blit( drm_device_t *dev, @@ -1068,7 +1264,6 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev, | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_HOST_DATA | RADEON_GMC_CLR_CMP_CNTL_DIS - | RADEON_GMC_AUX_CLIP_DIS | RADEON_GMC_WR_MSK_DIS ); data[2] = (pitch << 21) | (offset >> 5); @@ -1201,13 +1396,11 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, vertex.idx, dma->buf_count - 1 ); return -EINVAL; } -#if 0 if ( vertex.prim < 0 || - vertex.prim > RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { + vertex.prim > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST ) { DRM_ERROR( "buffer prim %d\n", vertex.prim ); return -EINVAL; } -#endif buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; @@ -1265,13 +1458,11 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, elts.idx, dma->buf_count - 1 ); return -EINVAL; } -#if 0 if ( elts.prim < 0 || - elts.prim > RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { + elts.prim > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST ) { DRM_ERROR( "buffer prim %d\n", elts.prim ); return -EINVAL; } -#endif buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c index eeaebd846..44a4224df 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c @@ -120,6 +120,8 @@ int drmRadeonInitCP( int fd, drmRadeonInit *info ) init.buffers_offset = info->buffers_offset; init.agp_textures_offset = info->agp_textures_offset; + init.agp_vm_start = info->agp_vm_start; + if ( ioctl( fd, DRM_IOCTL_RADEON_CP_INIT, &init ) ) { return -errno; } else { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h index c6e0a3273..f140afe49 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h @@ -64,6 +64,8 @@ typedef struct { unsigned int ring_rptr_offset; unsigned int buffers_offset; unsigned int agp_textures_offset; + + unsigned int agp_vm_start; } drmRadeonInit; typedef struct { -- cgit v1.2.3