From cce70a18e5afe7b2b84f304f964051740362c75c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 20 Dec 2008 07:07:13 +0000 Subject: [PATCH] - Mesa rebase to upstream + new r300 bufmgr code (may need more work) --- .cvsignore | 2 +- depth-override-fix.patch | 25 - mesa.spec | 3 +- r300-bufmgr.patch | 7372 ++++++++++++++++++++++---------------- sources | 2 +- 5 files changed, 4225 insertions(+), 3179 deletions(-) delete mode 100644 depth-override-fix.patch diff --git a/.cvsignore b/.cvsignore index 728d9ce..8bd82eb 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,3 +1,3 @@ xdriinfo-1.0.2.tar.bz2 gl-manpages-1.0.1.tar.bz2 -mesa-20081001.tar.bz2 +mesa-20081220.tar.bz2 diff --git a/depth-override-fix.patch b/depth-override-fix.patch deleted file mode 100644 index 377743a..0000000 --- a/depth-override-fix.patch +++ /dev/null @@ -1,25 +0,0 @@ -From df6ae3f0a39f95cb1199ac16c98be2bf9a3bc96f Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 1 Oct 2008 14:14:06 -0700 -Subject: [PATCH] i965: Fix overwriting of depth override for SetTexOffset. - -Fixes black borders around windows in compiz. Bug #17233. ---- - src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) - -diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c -index 47127c0..3790b50 100644 ---- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c -+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c -@@ -274,7 +274,6 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) - key.width = firstImage->Width; - key.height = firstImage->Height; - key.cpp = intelObj->mt->cpp; -- key.depth = firstImage->Depth; - key.tiling = intelObj->mt->region->tiling; - - dri_bo_unreference(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]); --- -1.6.0.1 - diff --git a/mesa.spec b/mesa.spec index e0c8b9e..a3716c6 100644 --- a/mesa.spec +++ b/mesa.spec @@ -51,7 +51,6 @@ BuildRequires: kernel-headers >= 2.6.27-0.305.rc5.git6 BuildRequires: libXxf86vm-devel BuildRequires: expat-devel >= 2.0 BuildRequires: xorg-x11-proto-devel >= 7.1-10 -BuildRequires: dri2proto >= 1.1 BuildRequires: makedepend BuildRequires: libselinux-devel BuildRequires: libXext-devel @@ -189,7 +188,7 @@ sed -i 's,terrain.dat,%{_libdir}/mesa-demos-data/&,' progs/demos/terrain.c %build -autoreconf --install +autoreconf --install export CFLAGS="$RPM_OPT_FLAGS -fvisibility=hidden -Os" export CXXFLAGS="$RPM_OPT_FLAGS -fvisibility=hidden -Os" diff --git a/r300-bufmgr.patch b/r300-bufmgr.patch index 41c2b0f..644ea5f 100644 --- a/r300-bufmgr.patch +++ b/r300-bufmgr.patch @@ -1,506 +1,24 @@ -commit 576ee3db94bd79092fe7f69b4ac8293367b6dfb1 -Author: Dave Airlie -Date: Thu Oct 23 10:27:54 2008 +1000 - - r300: fallback to sw rendering if we can't fit textures into aperture - -commit bd018ad09b6225a6386c57d8ca8eb37f74025006 -Author: Dave Airlie -Date: Thu Oct 23 10:13:28 2008 +1000 - - r300: add bufmgr vram sizing to stop overflowing textures in VRAM - - a) needs to be redone for bufmgr in screen - b) need to add GART aperture sizing also. - -commit e768e7df0f6b7f61f82d70a55c7419c359b17cb2 -Author: Dave Airlie -Date: Sun Oct 19 18:56:56 2008 +1000 - - r300: fixup no kms case for map/unmap - -commit 6b6995112d3223496c04e7afc338ffc9bcc5093e -Author: Dave Airlie -Date: Sun Oct 19 18:42:24 2008 +1000 - - radeon: disable leak detection for now - -commit 445d367fed8b55a1351788dbf3e2e303e56095b5 -Author: Dave Airlie -Date: Sun Oct 19 18:28:45 2008 +1000 - - r300: only enable set tex offset for non-kernel mm systems - -commit 737b174d7e82cc277d877ff810ffe058e1aa4522 -Author: Dave Airlie -Date: Mon Oct 13 15:40:58 2008 +1000 - - radeon: fixup prototypes - -commit a4fa4aaf6754e2e35cee42924dc141738b7edc27 -Author: Dave Airlie -Date: Mon Oct 13 15:39:46 2008 +1000 - - radeon: fix rounding to avoid kernel EFAULT - -commit c6b6a65281b8e98f5050f142d284e6ba622bea1b -Author: Dave Airlie -Date: Mon Oct 13 15:39:20 2008 +1000 - - r300: with real buffers - sw fallbacks to hardcoded maps - - so don't screw with virtual - -commit c41a002914ab9cfd8f49199e4a4612a6aeecf0b5 -Author: Dave Airlie -Date: Tue Sep 30 16:51:04 2008 +1000 - - r300: make work again - - Conflicts: - - src/mesa/drivers/dri/r300/r300_mem.c - src/mesa/drivers/dri/r300/r300_mem.h - src/mesa/drivers/dri/r300/r300_texstate.c - src/mesa/drivers/dri/r300/radeon_context.c - src/mesa/drivers/dri/radeon/radeon_buffer.h - -commit 289b38b16b9e0aae4d51bac8c745359a36c0d54e -Author: Dave Airlie -Date: Fri Sep 5 14:11:25 2008 +1000 - - drop r300 use of ttm flags - -commit 1ca0e2ac03b4fd95ee9cd2dbe82bb7a0e9c1614d -Author: Nicolai Haehnle -Date: Mon Sep 29 09:40:50 2008 +0200 - - r300: Fix crash in r300ClearBuffer - - That function can currently be called without a radeon_renderbuffer - when only Z/stencil needs clearing. - -commit 4d19a9b9ac84a972d0807ff931df596418d9a7f4 -Author: Nicolai Haehnle -Date: Sun Sep 28 19:37:52 2008 +0200 - - r300_mem: Prefer using screen structures over context structures - - Eventually, bufmgr will have to live with only screen structures for - correctness. - -commit 8d42990244a196b85ceb1439ad2b5eef6c559d61 -Author: Nicolai Haehnle -Date: Sun Sep 28 19:20:40 2008 +0200 - - r300: Remove radeon_bufmgr - - Since the bufmgr is now driver-specific anyway, there's no point in having - the additional indirection around. - -commit 3dba9178ec5dbf8183a5ceee701c9a36606ad464 -Merge: 857362e... 2e5d717... -Author: Nicolai Haehnle -Date: Sun Sep 28 18:28:05 2008 +0200 - - Merge branch 'master' into develop - - Conflicts: - - src/mesa/drivers/dri/r300/r300_tex.c - src/mesa/drivers/dri/r300/r300_texstate.c - src/mesa/drivers/dri/r300/radeon_context.c - src/mesa/drivers/dri/r300/radeon_context.h - -commit 857362ef14fc4f175a9d425a74f9ca2b691971d6 -Author: Nicolai Haehnle -Date: Tue Aug 19 22:02:41 2008 +0200 - - r300: Reasonably hacked up texture images - -commit b3153fc6f7823b434ab82faec4e966c3311f8ce8 -Author: Nicolai Haehnle -Date: Fri Aug 29 17:55:37 2008 +0200 - - Call FreeTexImageData unconditionally during mipmap generation. - - When drivers override texture image storage, Data may be null even though - storage has been reserved, e.g. when the data is currently in video memory - but not mapped into CPU-accessible memory. - -commit d8d306220c19f0cc60d14876021543fe6e542775 -Author: Nicolai Haehnle -Date: Fri Aug 29 18:40:05 2008 +0200 - - r300: Remove some debug messages - -commit b179525a87b5bf510628918406e3562e2d138ce7 -Author: Nicolai Haehnle -Date: Tue Aug 26 23:21:24 2008 +0200 - - r300: Fix various software fallback regressions - - Renderbuffers are now mapped and unmapped properly for software rendering, - and various assorted fixes. - -commit ebf556644058c748c7c621b1e5ae12dc900a2dd0 -Author: Nicolai Haehnle -Date: Fri Aug 15 19:55:59 2008 +0200 - - r300: Remove unused field pitch in r300_tex_obj - -commit 7db556b55baa392a951f92074c058868ead2edb5 -Author: Nicolai Haehnle -Date: Tue Aug 26 19:02:14 2008 +0200 - - radeon: Add missing header radeon_buffer.h - -commit 093023518b81c11d0c3242a27b90def9a7e2e1c0 -Author: Adam Jackson -Date: Sun Aug 24 18:47:53 2008 +1000 - - r300: move color/depth buffers to using fake buffers - - Emit state for color/depth properly - - This also moves the bufmgr into the radeon struct, as we - need it from make current. It won't affect the other chips yet. - - can probably move fbLocation into the bufmgr soon - -commit 004100f123ca3ea4b35e16ae5d91911ad02b327f -Author: Dave Airlie -Date: Sun Aug 24 18:33:06 2008 +1000 - - r300: add static BO alloc to classic bufmgr - -commit 6827a4d742cf2b815d2651dd7ffe002f46a07b1b -Author: Nicolai Haehnle -Date: Fri Aug 8 18:37:37 2008 +0200 - - r300: Fix regression when redefining texture images - - We obviously have to destroy and recreate the miptree when incompatible - changes to the texture objects are made. - -commit b3b221caefbcbb749fea9dc1040e4313fc9ea717 -Author: Nicolai Haehnle -Date: Mon Aug 4 01:04:15 2008 +0200 - - r300: Texture memory managed by bufmgr - - The bufmgr makes use of the texture heap by wrapping the old texmem.c code. - - There are currently three copies of each texture image: - - Mesa's storage - - bufmgr backing store - - VRAM (if the texture has recently been used) - The first one should eventually be eliminated by making changes along the - lines of the Intel driver. - -commit 7eed94472049bba4e41bf7e51c51d0cc418cfc87 -Author: Nicolai Haehnle -Date: Sun Aug 3 21:59:52 2008 +0200 - - r300: Introduce r300_mipmap_tree - -commit 6d8ee45f31c11cae2424e987a0577f9b7e26762d -Author: Nicolai Haehnle -Date: Sun Aug 3 17:23:50 2008 +0200 - - r300: Start pushing driTextureObject down - -commit f403a51e2aedfb04f845d03c1aa1023c7e518e45 -Author: Nicolai Haehnle -Date: Sun Aug 3 15:59:04 2008 +0200 - - r300: Remove unused texture object variables - -commit 4e432ffb0a403c44898ea608a7a1d7a515b59a73 -Author: Nicolai Haehnle -Date: Sun Aug 3 14:28:59 2008 +0200 - - r300: Remove bo_use - - Validating buffers and marking them as pending is now done automatically - based on relocations. - -commit 604515f17698572be3a2ae61b6843b4acef02f2e -Author: Nicolai Haehnle -Date: Sun Aug 3 14:27:05 2008 +0200 - - r300: Remove last traces of r300_dma_region - -commit 656a1df66fbf5d2f748babf6be58524ee4b65bcc -Author: Nicolai Haehnle -Date: Sun Aug 3 14:18:42 2008 +0200 - - r300: No longer use r300_dma_region for dma.current buffer - -commit b1267a2c7b144f7286ae901cea02c4e81cb435ab -Author: Nicolai Haehnle -Date: Sun Aug 3 13:41:12 2008 +0200 - - r300: Stop using r300_dma_region for elt_dma - -commit 0ff9bcf22b7fc0c8a0fa55ec15c3c3ba176f2afd -Author: Nicolai Haehnle -Date: Sun Aug 3 12:37:51 2008 +0200 - - r300: Remove unused variable r300_state.Elts - -commit 723af37157ffa8be9be710c8e168386f02035909 -Author: Nicolai Haehnle -Date: Sun Aug 3 12:26:28 2008 +0200 - - r300: Fix interaction of ClearState emits with swtcl - -commit ecedb19db194721c6d2030287e346ca6b3d50168 -Author: Nicolai Haehnle -Date: Sun Aug 3 11:18:48 2008 +0200 - - r300: Fix Clear state emission - -commit e1bdd637c0740c8e3c00874ff3301a361df9c5b3 -Author: Nicolai Haehnle -Date: Sun Aug 3 10:41:17 2008 +0200 - - r300: Use explicit r300_aos structure instead of overloaded r300_dma_region - -commit fa63e5eea06d6ac709465ef2cfef4e1760ce0a62 -Author: Nicolai Haehnle -Date: Sun Aug 3 00:23:06 2008 +0200 - - r300: Remove unused variable - -commit 168b082ec48cb6aedb3d7a45538e65fa24d07f1a -Author: Nicolai Haehnle -Date: Sat Aug 2 23:50:15 2008 +0200 - - r300: Use relocations in texture blits - -commit 723a451b5ecc2862701f0b1f7c518902c4675fe1 -Author: Nicolai Haehnle -Date: Sat Aug 2 23:29:36 2008 +0200 - - r300: Remove old emit helpers - -commit 511a071823e58a5861f0afb9af086411fc3aa7eb -Author: Nicolai Haehnle -Date: Sat Aug 2 23:28:14 2008 +0200 - - r300: Convert swtcl to new emit system - -commit 4288e01990c66299830088942094772bb938e597 -Author: Nicolai Haehnle -Date: Sat Aug 2 23:27:18 2008 +0200 - - r300: Complete copnversion of r300ClearBuffer - -commit 3acc8c5ac2c8aed11a4196387db2016a399ef12a -Author: Nicolai Haehnle -Date: Sat Aug 2 23:15:23 2008 +0200 - - r300: Continue convering ClearState to new emit - -commit 5e49bf6abf82bee702b51248dea65404267b1856 -Author: Nicolai Haehnle -Date: Sat Aug 2 23:13:58 2008 +0200 - - r300: Continue convering ClearState to new emit - -commit b94bad12c3bc000e93e139cceaf761e0cb9805f6 -Author: Nicolai Haehnle -Date: Sat Aug 2 23:10:35 2008 +0200 - - r300: Convert ClearState to new emit - -commit 8937fcc3c100bdd16a26a3a91953e8bfded6a17b -Author: Nicolai Haehnle -Date: Sat Aug 2 23:07:33 2008 +0200 - - r300: Use new style emit in r300ClearBuffer - -commit e231031ece3ee08618b781cf4b9c29b60258a8c4 -Author: Nicolai Haehnle -Date: Sat Aug 2 23:05:15 2008 +0200 - - r300: Prepare Clear implementation for new style emit - -commit ed54357c566d7c7ed84cca33d45388d9986e1a75 -Author: Nicolai Haehnle -Date: Sat Aug 2 23:02:38 2008 +0200 - - r300: Rewrite cp_delay and cp_wait using new emit - -commit 8ab20decadddac4f16a906a8411d1ff64be2a03f -Author: Nicolai Haehnle -Date: Sat Aug 2 23:01:30 2008 +0200 - - r300: Rewrite end_3d using new emit - -commit 7316a87cb95375cc79bb957695fc39668c55ca26 -Author: Nicolai Haehnle -Date: Sat Aug 2 22:56:29 2008 +0200 - - r300: Use new emit for r300EmitBlit and get rid of redundant r300EmitWait - -commit e2e3062864f5fd7332e0ba3356f5047b66608ba6 -Author: Nicolai Haehnle -Date: Sat Aug 2 22:55:15 2008 +0200 - - r300: Use new emit in r300EmitCacheFlush - -commit 021d49403d259bb43982235f8e47f04f104545cd -Author: Nicolai Haehnle -Date: Sat Aug 2 22:54:01 2008 +0200 - - r300: Prepare texture blitting for new emit style - -commit e3640e75a22e1647b8a4237212fd9091516cc0d0 -Author: Nicolai Haehnle -Date: Sat Aug 2 22:48:59 2008 +0200 - - r300: Use new emit style for memory fencing - -commit 887c24496910df9d4efbb597a4e7abb3ad655f54 -Author: Nicolai Haehnle -Date: Sat Aug 2 22:46:48 2008 +0200 - - r300: Use new emit style in r300_render - -commit 196a156ed067f00a38ef24cd89084392dbe58e95 -Author: Nicolai Haehnle -Date: Sat Aug 2 22:41:31 2008 +0200 - - r300: Add additional helper macros for emit - -commit dad24c477db1db583cddfb407937e0f749e3a063 -Author: Nicolai Haehnle -Date: Sat Aug 2 22:39:52 2008 +0200 - - r300: Use new emit style for r300EmitAtoms - -commit ebb3329c089ad8db18998e85135fb0eabe3f547c -Author: Nicolai Haehnle -Date: Sat Aug 2 22:34:23 2008 +0200 - - r300: Start moving cmdbuf towards an emit system that is closer to DRM and DDX - -commit 296d81a420e0831b2c795a050442acf7e5eaa4d6 -Author: Nicolai Haehnle -Date: Sat Aug 2 20:01:27 2008 +0200 - - r300: Move r300EmitWait and r300EmitBlit to r300_emit.c - - These functions don't really fit into r300_cmdbuf.c. - -commit 3c7b7b60f5736698b0c68d1100baa3feba7dfa14 -Author: Nicolai Haehnle -Date: Sat Aug 2 19:15:19 2008 +0200 - - r300: Remove unused variable buf0_address - -commit 1a25eb30d6f7567946b920fa58d760959db6726d -Author: Nicolai Haehnle -Date: Sat Aug 2 19:12:50 2008 +0200 - - r300: Be more conservative about command buffer space allocation - - Having the main rendering sequence split up into separate command buffer is - probably one of the worst offenders for hardware lockups, so this might help. - It can't hurt in any case. - -commit 88d3539f3a6cc6d81ec91b901bbd1b76bf38ba67 -Author: Nicolai Haehnle -Date: Sat Aug 2 18:55:19 2008 +0200 - - r300: Manage cmdbuf via the r300_mem dri_bufmgr - - Relocation code isn't actually used yet. - -commit bab989ab8aba252b6a8a041a517308aeb22ed897 -Author: Nicolai Haehnle -Date: Sat Aug 2 15:43:07 2008 +0200 - - r300: Remove more GART-related legacy code - -commit ccd0bf4dbabeb57fc6a496a76aa7258d4451b190 -Author: Nicolai Haehnle -Date: Sat Aug 2 15:31:46 2008 +0200 - - r300: Eliminate Gart- and ClientStorage-related functions - - These functions will be incorrect with a new memory manager. Furthermore, - they seem to be no-ops right now, judging from the comments and a cursory - inspection. - - Actually, it's possible that applications out there have been using the - client_storage extension successfully, who knows - but they should continue - to work, just with client_storage turned into a no-op. - -commit 9fb9931fa7e4fe0d82d73b00f6347ea07f9afa32 -Author: Nicolai Haehnle -Date: Sat Aug 2 15:17:44 2008 +0200 - - r300: Start turning r300_mem into a dri_bufmgr-style manager - - This is only for DMA memory right now, textures do not go through this - manager yet. - -commit 990a685e1191b875ec7c7d2d481def37554877db -Author: Nicolai Haehnle -Date: Sat Aug 2 12:15:22 2008 +0200 - - r300: Remove unused variable r300_state.swtcl_dma - -commit 50ad5c9a8f1da5fdf51b1ca17259369f0a7dbab6 -Author: Nicolai Haehnle -Date: Sat Aug 2 11:30:42 2008 +0200 - - r300: Remove unused or ineffective and untested variables - -commit 8f71ab684448f5caa0c649e52bb6ea1d0bb86077 -Author: Nicolai Haehnle -Date: Sat Aug 2 11:09:36 2008 +0200 - - r300: Get rid of USER_BUFFERS define -diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile -index e9144ac..c26c43b 100644 ---- a/src/mesa/drivers/dri/r200/Makefile -+++ b/src/mesa/drivers/dri/r200/Makefile -@@ -48,7 +48,9 @@ SYMLINKS = \ - COMMON_SYMLINKS = \ - radeon_chipset.h \ - radeon_screen.c \ -- radeon_screen.h -+ radeon_screen.h \ -+ radeon_buffer.h \ -+ radeon_dri_bufmgr.h - - ##### TARGETS ##### - diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile -index 6ca9342..acadf1e 100644 +index 6ca9342..cbb09e6 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile -@@ -11,15 +11,6 @@ ifeq ($(USING_EGL), 1) - EGL_SOURCES = server/radeon_egl.c - endif +@@ -21,13 +21,14 @@ COMMON_SOURCES = \ + ../common/dri_util.c --COMMON_SOURCES = \ -- ../../common/driverfuncs.c \ -- ../common/mm.c \ -- ../common/utils.c \ -- ../common/texmem.c \ -- ../common/vblank.c \ -- ../common/xmlconfig.c \ -- ../common/dri_util.c -- DRIVER_SOURCES = \ ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ radeon_screen.c \ radeon_context.c \ -@@ -36,6 +27,7 @@ DRIVER_SOURCES = \ + radeon_ioctl.c \ + radeon_lock.c \ + radeon_span.c \ + radeon_state.c \ +- r300_mem.c \ + r300_context.c \ + r300_ioctl.c \ + r300_cmdbuf.c \ +@@ -36,6 +37,7 @@ DRIVER_SOURCES = \ r300_texmem.c \ r300_tex.c \ r300_texstate.c \ @@ -508,32 +26,35 @@ index 6ca9342..acadf1e 100644 radeon_program.c \ radeon_program_alu.c \ radeon_program_pair.c \ -@@ -49,9 +41,10 @@ DRIVER_SOURCES = \ - r300_shader.c \ - r300_emit.c \ - r300_swtcl.c \ -+ radeon_dri_bufmgr.c \ - $(EGL_SOURCES) - --C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -+C_SOURCES = $(COMMON_SOURCES) $(COMMON_BM_SOURCES) $(DRIVER_SOURCES) +@@ -54,7 +56,9 @@ DRIVER_SOURCES = \ + C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) DRIVER_DEFINES = -DCOMPILE_R300 -DR200_MERGED=0 \ - -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 -@@ -68,7 +61,10 @@ COMMON_SYMLINKS = \ +- -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 ++ -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 \ ++# -DRADEON_BO_TRACK \ ++ -Wall + + SYMLINKS = \ + server/radeon_dri.c \ +@@ -68,7 +72,14 @@ COMMON_SYMLINKS = \ radeon_chipset.h \ radeon_screen.c \ radeon_screen.h \ - radeon_span.h + radeon_span.h \ + radeon_buffer.h \ -+ radeon_dri_bufmgr.h \ -+ radeon_dri_bufmgr.c ++ radeon_bo_legacy.c \ ++ radeon_cs_legacy.c \ ++ radeon_bo_legacy.h \ ++ radeon_cs_legacy.h ++ ++DRI_LIB_DEPS += -ldrm-radeon ##### TARGETS ##### diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c -index c9e1dfe..421cb81 100644 +index c9e1dfe..ca9d36a 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -544,13 +65,18 @@ index c9e1dfe..421cb81 100644 #include "radeon_ioctl.h" #include "r300_context.h" #include "r300_ioctl.h" -@@ -51,11 +52,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -51,62 +52,41 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_reg.h" #include "r300_cmdbuf.h" #include "r300_emit.h" -+#include "r300_mem.h" +#include "r300_mipmap_tree.h" #include "r300_state.h" ++#include "radeon_cs_legacy.h" ++#include "radeon_cs_gem.h" ++#include "radeon_reg.h" ++ ++#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 ++# define RADEON_ONE_REG_WR (1 << 15) // Set this to 1 for extremely verbose debugging of command buffers #define DEBUG_CMDBUF 0 @@ -563,78 +89,69 @@ index c9e1dfe..421cb81 100644 /** * Send the current command buffer via ioctl to the hardware. */ -@@ -66,24 +74,42 @@ int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller) - drm_radeon_cmd_buffer_t cmd; - int start; + int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller) + { +- int ret; +- int i; +- drm_radeon_cmd_buffer_t cmd; +- int start; +- +- if (r300->radeon.lost_context) { +- start = 0; +- r300->radeon.lost_context = GL_FALSE; +- } else +- start = r300->cmdbuf.count_reemit; +- +- if (RADEON_DEBUG & DEBUG_IOCTL) { +- fprintf(stderr, "%s from %s - %i cliprects\n", +- __FUNCTION__, caller, r300->radeon.numClipRects); +- +- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE) +- for (i = start; i < r300->cmdbuf.count_used; ++i) +- fprintf(stderr, "%d: %08x\n", i, +- r300->cmdbuf.cmd_buf[i]); +- } +- +- cmd.buf = (char *)(r300->cmdbuf.cmd_buf + start); +- cmd.bufsz = (r300->cmdbuf.count_used - start) * 4; ++ int ret = 0; +- if (r300->radeon.state.scissor.enabled) { +- cmd.nbox = r300->radeon.state.scissor.numClipRects; +- cmd.boxes = +- (drm_clip_rect_t *) r300->radeon.state.scissor.pClipRects; +- } else { +- cmd.nbox = r300->radeon.numClipRects; +- cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects; + if (r300->cmdbuf.flushing) { + fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); + exit(-1); -+ } -+ r300->cmdbuf.flushing = 1; -+ - if (r300->radeon.lost_context) { - start = 0; - r300->radeon.lost_context = GL_FALSE; - } else -- start = r300->cmdbuf.count_reemit; -+ start = r300->cmdbuf.reemit; - - if (RADEON_DEBUG & DEBUG_IOCTL) { - fprintf(stderr, "%s from %s - %i cliprects\n", - __FUNCTION__, caller, r300->radeon.numClipRects); - -- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE) -- for (i = start; i < r300->cmdbuf.count_used; ++i) -+ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE) { -+ fprintf(stderr, "written: %d committed: %d\n", r300->cmdbuf.written, r300->cmdbuf.committed); -+ for (i = start; i < r300->cmdbuf.written; ++i) - fprintf(stderr, "%d: %08x\n", i, -- r300->cmdbuf.cmd_buf[i]); -+ ((uint32_t*)r300->cmdbuf.buf->virtual)[i]); -+ } } - -- cmd.buf = (char *)(r300->cmdbuf.cmd_buf + start); -- cmd.bufsz = (r300->cmdbuf.count_used - start) * 4; -+ if (r300->cmdbuf.written != r300->cmdbuf.committed) { -+ _mesa_problem(r300->radeon.glCtx, -+ "Command buffer contains %d uncommitted dwords\n" -+ "in r300FlushCmdBufLocked called from %s.\n", -+ r300->cmdbuf.written - r300->cmdbuf.committed, caller); -+ } -+ -+ dri_bo_unmap(r300->cmdbuf.buf); -+ dri_process_relocs(r300->cmdbuf.buf, 1); -+ -+ cmd.buf = (char *)r300->cmdbuf.buf->virtual + 4*start; -+ cmd.bufsz = (r300->cmdbuf.committed - start) * 4; - - if (r300->radeon.state.scissor.enabled) { - cmd.nbox = r300->radeon.state.scissor.numClipRects; -@@ -103,9 +129,19 @@ int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller) - radeonWaitForIdleLocked(&r300->radeon); - } - -+ dri_post_submit(r300->cmdbuf.buf, 0); -+ dri_bo_unreference(r300->cmdbuf.buf); -+ - r300->dma.nr_released_bufs = 0; +- +- ret = drmCommandWrite(r300->radeon.dri.fd, +- DRM_RADEON_CMDBUF, &cmd, sizeof(cmd)); +- +- if (RADEON_DEBUG & DEBUG_SYNC) { +- fprintf(stderr, "Syncing in %s (from %s)\n\n", +- __FUNCTION__, caller); +- radeonWaitForIdleLocked(&r300->radeon); +- } +- +- r300->dma.nr_released_bufs = 0; - r300->cmdbuf.count_used = 0; - r300->cmdbuf.count_reemit = 0; -+ r300->cmdbuf.buf = dri_bo_alloc(r300->radeon.bufmgr, "cmdbuf", -+ r300->cmdbuf.size*4, 16, DRM_BO_MEM_CMDBUF); -+ r300->cmdbuf.written = 0; -+ r300->cmdbuf.reserved = 0; -+ r300->cmdbuf.committed = 0; -+ r300->cmdbuf.reemit = 0; -+ dri_bo_map(r300->cmdbuf.buf, GL_TRUE); -+ +- ++ r300->cmdbuf.flushing = 1; ++ if (r300->cmdbuf.cs->cdw) { ++ ret = radeon_cs_emit(r300->cmdbuf.cs); ++ r300->hw.all_dirty = 1; ++ } ++ radeon_cs_erase(r300->cmdbuf.cs); + r300->cmdbuf.flushing = 0; - return ret; } -@@ -115,9 +151,7 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) + +@@ -115,9 +95,7 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) int ret; LOCK_HARDWARE(&r300->radeon); @@ -644,10 +161,11 @@ index c9e1dfe..421cb81 100644 UNLOCK_HARDWARE(&r300->radeon); if (ret) { -@@ -128,6 +162,44 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) +@@ -128,13 +106,42 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) return ret; } +-static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *state) +/** + * Make sure that enough space is available in the command buffer + * by flushing if necessary. @@ -656,40 +174,40 @@ index c9e1dfe..421cb81 100644 + */ +void r300EnsureCmdBufSpace(r300ContextPtr r300, int dwords, const char *caller) +{ -+ assert(dwords < r300->cmdbuf.size); -+ -+ if (!r300->cmdbuf.flushing) -+ dwords += SPACE_FOR_FLUSHING; -+ -+ if (r300->cmdbuf.written + dwords > r300->cmdbuf.size) ++ if ((r300->cmdbuf.cs->cdw + dwords + 128) > r300->cmdbuf.size || ++ radeon_cs_need_flush(r300->cmdbuf.cs)) { + r300FlushCmdBuf(r300, caller); ++ } +} + -+void r300BeginBatch(r300ContextPtr r300, int n, GLboolean autostate, const char* function, int line) ++void r300BeginBatch(r300ContextPtr r300, int n, ++ int dostate, ++ const char *file, ++ const char *function, ++ int line) +{ -+ assert(r300->cmdbuf.written == r300->cmdbuf.reserved); -+ + r300EnsureCmdBufSpace(r300, n, function); -+ -+ if (autostate && !r300->cmdbuf.written) { ++ if (!r300->cmdbuf.cs->cdw && dostate) { + if (RADEON_DEBUG & DEBUG_IOCTL) -+ fprintf(stderr, -+ "Reemit state after flush (from %s)\n", function); ++ fprintf(stderr, "Reemit state after flush (from %s)\n", function); + r300EmitState(r300); + } -+ -+ r300->cmdbuf.reserved += n; -+ assert(r300->cmdbuf.reserved < r300->cmdbuf.size); -+ -+ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_IOCTL) -+ fprintf(stderr, "BEGIN_BATCH(%d) at %d, from %s:%i\n", -+ n, r300->cmdbuf.written, function, line); ++ radeon_cs_begin(r300->cmdbuf.cs, n, file, function, line); +} + - static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *state) ++static void r300PrintStateAtom(r300ContextPtr r300, ++ struct r300_state_atom *state) { int i; -@@ -152,33 +224,18 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat + int dwords = (*state->check) (r300, state); + +- fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, +- state->cmd_size); ++ fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size); + + if (RADEON_DEBUG & DEBUG_VERBOSE) { + for (i = 0; i < dwords; i++) { +@@ -152,33 +159,18 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat */ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) { @@ -718,19 +236,19 @@ index c9e1dfe..421cb81 100644 - *dest = cmdpacify(); - dest++; - r300->cmdbuf.count_used++; -+ BEGIN_BATCH_NO_AUTOSTATE(4); -+ OUT_BATCH(cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN)); -+ OUT_BATCH(cmdpacket0(R300_TX_INVALTAGS, 1)); ++ cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN); ++ BEGIN_BATCH_NO_AUTOSTATE(2); ++ OUT_BATCH(cmdpacket0(r300->radeon.radeonScreen, R300_TX_INVALTAGS, 1)); + OUT_BATCH(R300_TX_FLUSH); -+ OUT_BATCH(cmdpacify()); + END_BATCH(); ++ end_3d(r300); /* Emit actual atoms */ - foreach(atom, &r300->hw.atomlist) { if ((atom->dirty || r300->hw.all_dirty) == dirty) { dwords = (*atom->check) (r300, atom); -@@ -186,9 +243,13 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) +@@ -186,9 +178,13 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { r300PrintStateAtom(r300, atom); } @@ -738,7 +256,7 @@ index c9e1dfe..421cb81 100644 - dest += dwords; - r300->cmdbuf.count_used += dwords; + if (atom->emit) { -+ (*atom->emit)(r300); ++ (*atom->emit)(r300, atom); + } else { + BEGIN_BATCH_NO_AUTOSTATE(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); @@ -747,7 +265,7 @@ index c9e1dfe..421cb81 100644 atom->dirty = GL_FALSE; } else { if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { -@@ -198,6 +259,8 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) +@@ -198,6 +194,8 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) } } } @@ -756,13 +274,13 @@ index c9e1dfe..421cb81 100644 } /** -@@ -211,22 +274,21 @@ void r300EmitState(r300ContextPtr r300) +@@ -211,39 +209,169 @@ void r300EmitState(r300ContextPtr r300) if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS)) fprintf(stderr, "%s\n", __FUNCTION__); - if (r300->cmdbuf.count_used && !r300->hw.is_dirty -+ if (r300->cmdbuf.written && !r300->hw.is_dirty - && !r300->hw.all_dirty) +- && !r300->hw.all_dirty) ++ if (r300->cmdbuf.cs->cdw && !r300->hw.is_dirty && !r300->hw.all_dirty) return; /* To avoid going across the entire set of states multiple times, just check @@ -773,83 +291,142 @@ index c9e1dfe..421cb81 100644 r300EnsureCmdBufSpace(r300, r300->hw.max_state_size, __FUNCTION__); - if (!r300->cmdbuf.count_used) { -+ if (!r300->cmdbuf.written) { ++ if (!r300->cmdbuf.cs->cdw) { if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "Begin reemit state\n"); r300EmitAtoms(r300, GL_FALSE); - r300->cmdbuf.count_reemit = r300->cmdbuf.count_used; -+ r300->cmdbuf.reemit = r300->cmdbuf.committed; } if (RADEON_DEBUG & DEBUG_STATE) -@@ -234,7 +296,7 @@ void r300EmitState(r300ContextPtr r300) + fprintf(stderr, "Begin dirty state\n"); r300EmitAtoms(r300, GL_TRUE); - +- - assert(r300->cmdbuf.count_used < r300->cmdbuf.size); -+ assert(r300->cmdbuf.written < r300->cmdbuf.size); - +- r300->hw.is_dirty = GL_FALSE; r300->hw.all_dirty = GL_FALSE; -@@ -244,6 +306,79 @@ void r300EmitState(r300ContextPtr r300) + } + +-#define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count) ++static unsigned packet0_count(r300ContextPtr r300, uint32_t *pkt) ++{ ++ if (r300->radeon.radeonScreen->kernel_mm) { ++ return ((((*pkt) >> 16) & 0x3FFF) + 1); ++ } else { ++ drm_r300_cmd_header_t *t = (drm_r300_cmd_header_t*)pkt; ++ return t->packet0.count; ++ } ++ return 0; ++} ++ #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count) #define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count) -+static void emit_tex_offsets(r300ContextPtr r300) ++void emit_vpu(r300ContextPtr r300, struct r300_state_atom * atom) +{ + BATCH_LOCALS(r300); -+ int numtmus = packet0_count(r300->hw.tex.offset.cmd); ++ drm_r300_cmd_header_t cmd; ++ uint32_t addr, ndw, i; ++ ++ if (!r300->radeon.radeonScreen->kernel_mm) { ++ uint32_t dwords; ++ dwords = (*atom->check) (r300, atom); ++ BEGIN_BATCH_NO_AUTOSTATE(dwords); ++ OUT_BATCH_TABLE(atom->cmd, dwords); ++ END_BATCH(); ++ return; ++ } ++ ++ cmd.u = atom->cmd[0]; ++ addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo; ++ ndw = cmd.vpu.count * 4; ++ if (ndw) { ++ /* flush processing vertices */ ++ OUT_BATCH(CP_PACKET0(R300_SC_SCREENDOOR, 0)); ++ OUT_BATCH(0x0); ++ OUT_BATCH(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); ++ OUT_BATCH((1 << 15) | (1 << 28)); ++ OUT_BATCH(CP_PACKET0(R300_SC_SCREENDOOR, 0)); ++ OUT_BATCH(0x00FFFFFF); ++ OUT_BATCH(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0)); ++ OUT_BATCH(1); ++ /* write vpu */ ++ OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_ADDRESS, 0)); ++ OUT_BATCH(addr); ++ OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR); ++ for (i = 0; i < ndw; i++) { ++ OUT_BATCH(atom->cmd[i+1]); ++ } ++ } ++} ++ ++static void emit_tex_offsets(r300ContextPtr r300, struct r300_state_atom * atom) ++{ ++ BATCH_LOCALS(r300); ++ int numtmus = packet0_count(r300, r300->hw.tex.offset.cmd); + + if (numtmus) { + int i; + -+ BEGIN_BATCH(numtmus + 1); -+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, numtmus); + for(i = 0; i < numtmus; ++i) { ++ BEGIN_BATCH(2); ++ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); + r300TexObj *t = r300->hw.textures[i]; + if (t && !t->image_override) { -+ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, DRM_RELOC_TXOFFSET); ++ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, ++ RADEON_GEM_DOMAIN_VRAM, 0, 0); + } else if (!t) { + OUT_BATCH(r300->radeon.radeonScreen->texOffset[0]); + } else { -+ OUT_BATCH(t->override_offset); ++ if (t->bo) { ++ OUT_BATCH_RELOC(t->tile_bits, t->bo, 0, ++ RADEON_GEM_DOMAIN_VRAM, 0, 0); ++ } else { ++ OUT_BATCH(t->override_offset); ++ } + } ++ END_BATCH(); + } -+ END_BATCH(); + } +} + -+static void emit_cb_offset(r300ContextPtr r300) ++static void emit_cb_offset(r300ContextPtr r300, struct r300_state_atom * atom) +{ + BATCH_LOCALS(r300); + struct radeon_renderbuffer *rrb; + uint32_t cbpitch; ++ GLframebuffer *fb = r300->radeon.dri.drawable->driverPrivate; + + rrb = r300->radeon.state.color.rrb; -+ if (!rrb) { ++ if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { ++ rrb = fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ } ++ if (!rrb || !rrb->bo) { + fprintf(stderr, "no rrb\n"); + return; + } + -+ cbpitch = rrb->pitch; ++ cbpitch = (rrb->pitch / rrb->cpp); + if (rrb->cpp == 4) + cbpitch |= R300_COLOR_FORMAT_ARGB8888; + else + cbpitch |= R300_COLOR_FORMAT_RGB565; + -+ if (r300->radeon.sarea->tiling_enabled) ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) + cbpitch |= R300_COLOR_TILE_ENABLE; + + BEGIN_BATCH(4); + OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1); -+ OUT_BATCH_RELOC(0, rrb->bo, 0, DRM_RELOC_TXOFFSET); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_REGSEQ(R300_RB3D_COLORPITCH0, 1); + OUT_BATCH(cbpitch); + END_BATCH(); +} + -+static void emit_zb_offset(r300ContextPtr r300) ++static void emit_zb_offset(r300ContextPtr r300, struct r300_state_atom * atom) +{ + BATCH_LOCALS(r300); + struct radeon_renderbuffer *rrb; @@ -859,80 +436,476 @@ index c9e1dfe..421cb81 100644 + if (!rrb) + return; + -+ zbpitch = rrb->pitch; ++ zbpitch = (rrb->pitch / rrb->cpp); ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ zbpitch |= R300_DEPTHMACROTILE_ENABLE; ++ } ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ ++ zbpitch |= R300_DEPTHMICROTILE_TILED; ++ } + -+ BEGIN_BATCH(3); -+ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 2); -+ OUT_BATCH_RELOC(0, rrb->bo, 0, DRM_RELOC_TXOFFSET); -+ OUT_BATCH(zbpitch); ++ BEGIN_BATCH(4); ++ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, zbpitch); + END_BATCH(); -+ +} + static int check_always(r300ContextPtr r300, struct r300_state_atom *atom) { return atom->cmd_size; -@@ -480,8 +615,7 @@ void r300InitCmdBuf(r300ContextPtr r300) +@@ -252,13 +380,17 @@ static int check_always(r300ContextPtr r300, struct r300_state_atom *atom) + static int check_variable(r300ContextPtr r300, struct r300_state_atom *atom) + { + int cnt; +- cnt = packet0_count(atom->cmd); ++ if (atom->cmd[0] == CP_PACKET2) { ++ return 0; ++ } ++ cnt = packet0_count(r300, atom->cmd); + return cnt ? cnt + 1 : 0; + } + +-static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) ++int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) + { + int cnt; ++ + cnt = vpu_count(atom->cmd); + return cnt ? (cnt * 4) + 1 : 0; + } +@@ -266,6 +398,7 @@ static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) + static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom) + { + int cnt; ++ + cnt = r500fp_count(atom->cmd); + return cnt ? (cnt * 6) + 1 : 0; + } +@@ -273,7 +406,8 @@ static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom) + static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom) + { + int cnt; +- cnt = r500fp_count(atom->cmd); ++ ++ cnt = r500fp_count(atom->cmd); + return cnt ? (cnt * 4) + 1 : 0; + } + +@@ -318,92 +452,92 @@ void r300InitCmdBuf(r300ContextPtr r300) + + /* Initialize state atoms */ + ALLOC_STATE(vpt, always, R300_VPT_CMDSIZE, 0); +- r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(R300_SE_VPORT_XSCALE, 6); ++ r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SE_VPORT_XSCALE, 6); + ALLOC_STATE(vap_cntl, always, R300_VAP_CNTL_SIZE, 0); +- r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(R300_VAP_PVS_STATE_FLUSH_REG, 1); ++ r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1); + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH_1] = 0; +- r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(R300_VAP_CNTL, 1); ++ r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL, 1); + if (is_r500) { + ALLOC_STATE(vap_index_offset, always, 2, 0); +- r300->hw.vap_index_offset.cmd[0] = cmdpacket0(R500_VAP_INDEX_OFFSET, 1); ++ r300->hw.vap_index_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_VAP_INDEX_OFFSET, 1); + r300->hw.vap_index_offset.cmd[1] = 0; + } + ALLOC_STATE(vte, always, 3, 0); +- r300->hw.vte.cmd[0] = cmdpacket0(R300_SE_VTE_CNTL, 2); ++ r300->hw.vte.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SE_VTE_CNTL, 2); + ALLOC_STATE(vap_vf_max_vtx_indx, always, 3, 0); +- r300->hw.vap_vf_max_vtx_indx.cmd[0] = cmdpacket0(R300_VAP_VF_MAX_VTX_INDX, 2); ++ r300->hw.vap_vf_max_vtx_indx.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_VF_MAX_VTX_INDX, 2); + ALLOC_STATE(vap_cntl_status, always, 2, 0); +- r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(R300_VAP_CNTL_STATUS, 1); ++ r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL_STATUS, 1); + ALLOC_STATE(vir[0], variable, R300_VIR_CMDSIZE, 0); + r300->hw.vir[0].cmd[R300_VIR_CMD_0] = +- cmdpacket0(R300_VAP_PROG_STREAM_CNTL_0, 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PROG_STREAM_CNTL_0, 1); + ALLOC_STATE(vir[1], variable, R300_VIR_CMDSIZE, 1); + r300->hw.vir[1].cmd[R300_VIR_CMD_0] = +- cmdpacket0(R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); + ALLOC_STATE(vic, always, R300_VIC_CMDSIZE, 0); +- r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(R300_VAP_VTX_STATE_CNTL, 2); ++ r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_VTX_STATE_CNTL, 2); + ALLOC_STATE(vap_psc_sgn_norm_cntl, always, 2, 0); +- r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); ++ r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); + + if (has_tcl) { + ALLOC_STATE(vap_clip_cntl, always, 2, 0); +- r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(R300_VAP_CLIP_CNTL, 1); ++ r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CLIP_CNTL, 1); + ALLOC_STATE(vap_clip, always, 5, 0); +- r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_GB_VERT_CLIP_ADJ, 4); ++ r300->hw.vap_clip.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_GB_VERT_CLIP_ADJ, 4); + ALLOC_STATE(vap_pvs_vtx_timeout_reg, always, 2, 0); +- r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(VAP_PVS_VTX_TIMEOUT_REG, 1); ++ r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, VAP_PVS_VTX_TIMEOUT_REG, 1); + } + + ALLOC_STATE(vof, always, R300_VOF_CMDSIZE, 0); + r300->hw.vof.cmd[R300_VOF_CMD_0] = +- cmdpacket0(R300_VAP_OUTPUT_VTX_FMT_0, 2); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_OUTPUT_VTX_FMT_0, 2); + + if (has_tcl) { + ALLOC_STATE(pvs, always, R300_PVS_CMDSIZE, 0); + r300->hw.pvs.cmd[R300_PVS_CMD_0] = +- cmdpacket0(R300_VAP_PVS_CODE_CNTL_0, 3); ++ cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_CODE_CNTL_0, 3); + } + + ALLOC_STATE(gb_enable, always, 2, 0); +- r300->hw.gb_enable.cmd[0] = cmdpacket0(R300_GB_ENABLE, 1); ++ r300->hw.gb_enable.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_ENABLE, 1); + ALLOC_STATE(gb_misc, always, R300_GB_MISC_CMDSIZE, 0); +- r300->hw.gb_misc.cmd[0] = cmdpacket0(R300_GB_MSPOS0, 5); ++ r300->hw.gb_misc.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_MSPOS0, 5); + ALLOC_STATE(txe, always, R300_TXE_CMDSIZE, 0); +- r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(R300_TX_ENABLE, 1); ++ r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_ENABLE, 1); + ALLOC_STATE(ga_point_s0, always, 5, 0); +- r300->hw.ga_point_s0.cmd[0] = cmdpacket0(R300_GA_POINT_S0, 4); ++ r300->hw.ga_point_s0.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_S0, 4); + ALLOC_STATE(ga_triangle_stipple, always, 2, 0); +- r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(R300_GA_TRIANGLE_STIPPLE, 1); ++ r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_TRIANGLE_STIPPLE, 1); + ALLOC_STATE(ps, always, R300_PS_CMDSIZE, 0); +- r300->hw.ps.cmd[0] = cmdpacket0(R300_GA_POINT_SIZE, 1); ++ r300->hw.ps.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_SIZE, 1); + ALLOC_STATE(ga_point_minmax, always, 4, 0); +- r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(R300_GA_POINT_MINMAX, 3); ++ r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_MINMAX, 3); + ALLOC_STATE(lcntl, always, 2, 0); +- r300->hw.lcntl.cmd[0] = cmdpacket0(R300_GA_LINE_CNTL, 1); ++ r300->hw.lcntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_CNTL, 1); + ALLOC_STATE(ga_line_stipple, always, 4, 0); +- r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE, 3); ++ r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_STIPPLE_VALUE, 3); + ALLOC_STATE(shade, always, 5, 0); +- r300->hw.shade.cmd[0] = cmdpacket0(R300_GA_ENHANCE, 4); ++ r300->hw.shade.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_ENHANCE, 4); + ALLOC_STATE(polygon_mode, always, 4, 0); +- r300->hw.polygon_mode.cmd[0] = cmdpacket0(R300_GA_POLY_MODE, 3); ++ r300->hw.polygon_mode.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POLY_MODE, 3); + ALLOC_STATE(fogp, always, 3, 0); +- r300->hw.fogp.cmd[0] = cmdpacket0(R300_GA_FOG_SCALE, 2); ++ r300->hw.fogp.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_FOG_SCALE, 2); + ALLOC_STATE(zbias_cntl, always, 2, 0); +- r300->hw.zbias_cntl.cmd[0] = cmdpacket0(R300_SU_TEX_WRAP, 1); ++ r300->hw.zbias_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_TEX_WRAP, 1); + ALLOC_STATE(zbs, always, R300_ZBS_CMDSIZE, 0); + r300->hw.zbs.cmd[R300_ZBS_CMD_0] = +- cmdpacket0(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); ++ cmdpacket0(r300->radeon.radeonScreen, R300_SU_POLY_OFFSET_FRONT_SCALE, 4); + ALLOC_STATE(occlusion_cntl, always, 2, 0); +- r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(R300_SU_POLY_OFFSET_ENABLE, 1); ++ r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_POLY_OFFSET_ENABLE, 1); + ALLOC_STATE(cul, always, R300_CUL_CMDSIZE, 0); +- r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(R300_SU_CULL_MODE, 1); ++ r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_CULL_MODE, 1); + ALLOC_STATE(su_depth_scale, always, 3, 0); +- r300->hw.su_depth_scale.cmd[0] = cmdpacket0(R300_SU_DEPTH_SCALE, 2); ++ r300->hw.su_depth_scale.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_DEPTH_SCALE, 2); + ALLOC_STATE(rc, always, R300_RC_CMDSIZE, 0); +- r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(R300_RS_COUNT, 2); ++ r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_COUNT, 2); + if (is_r500) { + ALLOC_STATE(ri, always, R500_RI_CMDSIZE, 0); +- r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R500_RS_IP_0, 16); ++ r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_IP_0, 16); + for (i = 0; i < 8; i++) { + r300->hw.ri.cmd[R300_RI_CMD_0 + i +1] = + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | +@@ -412,133 +546,144 @@ void r300InitCmdBuf(r300ContextPtr r300) + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); + } + ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, 1); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, 1); + } else { + ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); +- r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8); ++ r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_IP_0, 8); + ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, 1); + } + ALLOC_STATE(sc_hyperz, always, 3, 0); +- r300->hw.sc_hyperz.cmd[0] = cmdpacket0(R300_SC_HYPERZ, 2); ++ r300->hw.sc_hyperz.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_HYPERZ, 2); + ALLOC_STATE(sc_screendoor, always, 2, 0); +- r300->hw.sc_screendoor.cmd[0] = cmdpacket0(R300_SC_SCREENDOOR, 1); ++ r300->hw.sc_screendoor.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); + ALLOC_STATE(us_out_fmt, always, 6, 0); +- r300->hw.us_out_fmt.cmd[0] = cmdpacket0(R300_US_OUT_FMT, 5); ++ r300->hw.us_out_fmt.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_OUT_FMT, 5); + + if (is_r500) { + ALLOC_STATE(fp, always, R500_FP_CMDSIZE, 0); +- r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(R500_US_CONFIG, 2); ++ r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_US_CONFIG, 2); + r300->hw.fp.cmd[R500_FP_CNTL] = R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO; +- r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(R500_US_CODE_ADDR, 3); +- r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(R500_US_FC_CTRL, 1); ++ r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R500_US_CODE_ADDR, 3); ++ r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(r300->radeon.radeonScreen, R500_US_FC_CTRL, 1); + r300->hw.fp.cmd[R500_FP_FC_CNTL] = 0; /* FIXME when we add flow control */ + + ALLOC_STATE(r500fp, r500fp, R500_FPI_CMDSIZE, 0); +- r300->hw.r500fp.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 0, 0); ++ r300->hw.r500fp.cmd[R300_FPI_CMD_0] = ++ cmdr500fp(r300->radeon.radeonScreen, 0, 0, 0, 0); + ALLOC_STATE(r500fp_const, r500fp_const, R500_FPP_CMDSIZE, 0); +- r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 1, 0); ++ r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = ++ cmdr500fp(r300->radeon.radeonScreen, 0, 0, 1, 0); + } else { + ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0); +- r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(R300_US_CONFIG, 3); +- r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(R300_US_CODE_ADDR_0, 4); ++ r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CONFIG, 3); ++ r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CODE_ADDR_0, 4); ++ + ALLOC_STATE(fpt, variable, R300_FPT_CMDSIZE, 0); +- r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_US_TEX_INST_0, 0); ++ r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_TEX_INST_0, 0); + + ALLOC_STATE(fpi[0], variable, R300_FPI_CMDSIZE, 0); +- r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, 1); ++ r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_RGB_INST_0, 1); + ALLOC_STATE(fpi[1], variable, R300_FPI_CMDSIZE, 1); +- r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, 1); ++ r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_RGB_ADDR_0, 1); + ALLOC_STATE(fpi[2], variable, R300_FPI_CMDSIZE, 2); +- r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, 1); ++ r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, 1); + ALLOC_STATE(fpi[3], variable, R300_FPI_CMDSIZE, 3); +- r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, 1); ++ r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, 1); + ALLOC_STATE(fpp, variable, R300_FPP_CMDSIZE, 0); +- r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, 0); ++ r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_PFS_PARAM_0_X, 0); + } + ALLOC_STATE(fogs, always, R300_FOGS_CMDSIZE, 0); +- r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(R300_FG_FOG_BLEND, 1); ++ r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_FOG_BLEND, 1); + ALLOC_STATE(fogc, always, R300_FOGC_CMDSIZE, 0); +- r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(R300_FG_FOG_COLOR_R, 3); ++ r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_FOG_COLOR_R, 3); + ALLOC_STATE(at, always, R300_AT_CMDSIZE, 0); +- r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(R300_FG_ALPHA_FUNC, 2); ++ r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_ALPHA_FUNC, 2); + ALLOC_STATE(fg_depth_src, always, 2, 0); +- r300->hw.fg_depth_src.cmd[0] = cmdpacket0(R300_FG_DEPTH_SRC, 1); ++ r300->hw.fg_depth_src.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_DEPTH_SRC, 1); + ALLOC_STATE(rb3d_cctl, always, 2, 0); +- r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(R300_RB3D_CCTL, 1); ++ r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_CCTL, 1); + ALLOC_STATE(bld, always, R300_BLD_CMDSIZE, 0); +- r300->hw.bld.cmd[R300_BLD_CMD_0] = cmdpacket0(R300_RB3D_CBLEND, 2); ++ r300->hw.bld.cmd[R300_BLD_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_CBLEND, 2); + ALLOC_STATE(cmk, always, R300_CMK_CMDSIZE, 0); +- r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmdpacket0(RB3D_COLOR_CHANNEL_MASK, 1); ++ r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, RB3D_COLOR_CHANNEL_MASK, 1); + if (is_r500) { + ALLOC_STATE(blend_color, always, 3, 0); +- r300->hw.blend_color.cmd[0] = cmdpacket0(R500_RB3D_CONSTANT_COLOR_AR, 2); ++ r300->hw.blend_color.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_CONSTANT_COLOR_AR, 2); + } else { + ALLOC_STATE(blend_color, always, 2, 0); +- r300->hw.blend_color.cmd[0] = cmdpacket0(R300_RB3D_BLEND_COLOR, 1); ++ r300->hw.blend_color.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_BLEND_COLOR, 1); + } ALLOC_STATE(rop, always, 2, 0); - r300->hw.rop.cmd[0] = cmdpacket0(R300_RB3D_ROPCNTL, 1); +- r300->hw.rop.cmd[0] = cmdpacket0(R300_RB3D_ROPCNTL, 1); ++ r300->hw.rop.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_ROPCNTL, 1); ALLOC_STATE(cb, always, R300_CB_CMDSIZE, 0); - r300->hw.cb.cmd[R300_CB_CMD_0] = cmdpacket0(R300_RB3D_COLOROFFSET0, 1); - r300->hw.cb.cmd[R300_CB_CMD_1] = cmdpacket0(R300_RB3D_COLORPITCH0, 1); + r300->hw.cb.emit = &emit_cb_offset; ALLOC_STATE(rb3d_dither_ctl, always, 10, 0); - r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(R300_RB3D_DITHER_CTL, 9); +- r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(R300_RB3D_DITHER_CTL, 9); ++ r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DITHER_CTL, 9); ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0); -@@ -495,7 +629,7 @@ void r300InitCmdBuf(r300ContextPtr r300) +- r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(R300_RB3D_AARESOLVE_CTL, 1); ++ r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_AARESOLVE_CTL, 1); + ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0); +- r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); ++ r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); + ALLOC_STATE(zs, always, R300_ZS_CMDSIZE, 0); + r300->hw.zs.cmd[R300_ZS_CMD_0] = +- cmdpacket0(R300_ZB_CNTL, 3); ++ cmdpacket0(r300->radeon.radeonScreen, R300_ZB_CNTL, 3); + ALLOC_STATE(zstencil_format, always, 5, 0); r300->hw.zstencil_format.cmd[0] = - cmdpacket0(R300_ZB_FORMAT, 4); +- cmdpacket0(R300_ZB_FORMAT, 4); ++ cmdpacket0(r300->radeon.radeonScreen, R300_ZB_FORMAT, 4); ALLOC_STATE(zb, always, R300_ZB_CMDSIZE, 0); - r300->hw.zb.cmd[R300_ZB_CMD_0] = cmdpacket0(R300_ZB_DEPTHOFFSET, 2); + r300->hw.zb.emit = emit_zb_offset; ALLOC_STATE(zb_depthclearvalue, always, 2, 0); - r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(R300_ZB_DEPTHCLEARVALUE, 1); +- r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(R300_ZB_DEPTHCLEARVALUE, 1); ++ r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_DEPTHCLEARVALUE, 1); ALLOC_STATE(unk4F30, always, 3, 0); -@@ -562,9 +696,10 @@ void r300InitCmdBuf(r300ContextPtr r300) +- r300->hw.unk4F30.cmd[0] = cmdpacket0(0x4F30, 2); ++ r300->hw.unk4F30.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x4F30, 2); + ALLOC_STATE(zb_hiz_offset, always, 2, 0); +- r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(R300_ZB_HIZ_OFFSET, 1); ++ r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_OFFSET, 1); + ALLOC_STATE(zb_hiz_pitch, always, 2, 0); +- r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(R300_ZB_HIZ_PITCH, 1); ++ r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_PITCH, 1); + + /* VPU only on TCL */ + if (has_tcl) { + int i; + ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); +- r300->hw.vpi.cmd[R300_VPI_CMD_0] = +- cmdvpu(R300_PVS_CODE_START, 0); ++ r300->hw.vpi.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0); ++ r300->hw.vpi.emit = emit_vpu; + + if (is_r500) { + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); +- r300->hw.vpp.cmd[R300_VPP_CMD_0] = +- cmdvpu(R500_PVS_CONST_START, 0); ++ r300->hw.vpp.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0); ++ r300->hw.vpp.emit = emit_vpu; + + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); +- r300->hw.vps.cmd[R300_VPS_CMD_0] = +- cmdvpu(R500_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R500_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.emit = emit_vpu; + + for (i = 0; i < 6; i++) { + ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); +- r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = +- cmdvpu(R500_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, ++ R500_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].emit = emit_vpu; + } + } else { + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); +- r300->hw.vpp.cmd[R300_VPP_CMD_0] = +- cmdvpu(R300_PVS_CONST_START, 0); ++ r300->hw.vpp.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0); ++ r300->hw.vpp.emit = emit_vpu; + + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); +- r300->hw.vps.cmd[R300_VPS_CMD_0] = +- cmdvpu(R300_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, R300_POINT_VPORT_SCALE_OFFSET, 1); ++ r300->hw.vps.emit = emit_vpu; + + for (i = 0; i < 6; i++) { + ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); +- r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = +- cmdvpu(R300_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].cmd[0] = ++ cmdvpu(r300->radeon.radeonScreen, ++ R300_PVS_UCP_START + i, 1); ++ r300->hw.vpucp[i].emit = emit_vpu; + } + } + } +@@ -546,33 +691,34 @@ void r300InitCmdBuf(r300ContextPtr r300) + /* Textures */ + ALLOC_STATE(tex.filter, variable, mtu + 1, 0); + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER0_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 0); + + ALLOC_STATE(tex.filter_1, variable, mtu + 1, 0); + r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER1_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER1_0, 0); + + ALLOC_STATE(tex.size, variable, mtu + 1, 0); +- r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_SIZE_0, 0); ++ r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_SIZE_0, 0); + + ALLOC_STATE(tex.format, variable, mtu + 1, 0); + r300->hw.tex.format.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FORMAT_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT_0, 0); + ALLOC_STATE(tex.pitch, variable, mtu + 1, 0); - r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FORMAT2_0, 0); +- r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FORMAT2_0, 0); ++ r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, 0); - ALLOC_STATE(tex.offset, variable, mtu + 1, 0); + ALLOC_STATE(tex.offset, variable, 1, 0); r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_OFFSET_0, 0); +- cmdpacket0(R300_TX_OFFSET_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, 0); + r300->hw.tex.offset.emit = &emit_tex_offsets; ALLOC_STATE(tex.chroma_key, variable, mtu + 1, 0); r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = -@@ -597,10 +732,14 @@ void r300InitCmdBuf(r300ContextPtr r300) +- cmdpacket0(R300_TX_CHROMA_KEY_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_CHROMA_KEY_0, 0); + + ALLOC_STATE(tex.border_color, variable, mtu + 1, 0); + r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_BORDER_COLOR_0, 0); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, 0); + + r300->hw.is_dirty = GL_TRUE; + r300->hw.all_dirty = GL_TRUE; +@@ -587,6 +733,7 @@ void r300InitCmdBuf(r300ContextPtr r300) + if (size > 64 * 256) + size = 64 * 256; + ++ size = 64 * 1024 / 4; + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { + fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", + sizeof(drm_r300_cmd_header_t)); +@@ -597,10 +744,19 @@ void r300InitCmdBuf(r300ContextPtr r300) size * 4, r300->hw.max_state_size * 4); } -+ r300->cmdbuf.buf = dri_bo_alloc(r300->radeon.bufmgr, "cmdbuf", -+ size*4, 16, DRM_BO_MEM_CMDBUF); ++ if (r300->radeon.radeonScreen->kernel_mm) { ++ int fd = r300->radeon.radeonScreen->driScreen->fd; ++ r300->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); ++ } else { ++ r300->cmdbuf.csm = radeon_cs_manager_legacy_ctor(&r300->radeon); ++ } ++ if (r300->cmdbuf.csm == NULL) { ++ /* FIXME: fatal error */ ++ return; ++ } ++ r300->cmdbuf.cs = radeon_cs_create(r300->cmdbuf.csm, size); ++ assert(r300->cmdbuf.cs != NULL); r300->cmdbuf.size = size; - r300->cmdbuf.cmd_buf = (uint32_t *) CALLOC(size * 4); - r300->cmdbuf.count_used = 0; - r300->cmdbuf.count_reemit = 0; -+ r300->cmdbuf.written = 0; -+ r300->cmdbuf.reserved = 0; -+ r300->cmdbuf.committed = 0; -+ r300->cmdbuf.reemit = 0; -+ dri_bo_map(r300->cmdbuf.buf, GL_TRUE); } /** -@@ -610,66 +749,10 @@ void r300DestroyCmdBuf(r300ContextPtr r300) +@@ -610,66 +766,13 @@ void r300DestroyCmdBuf(r300ContextPtr r300) { struct r300_state_atom *atom; - FREE(r300->cmdbuf.cmd_buf); -+ dri_bo_unmap(r300->cmdbuf.buf); -+ dri_bo_unreference(r300->cmdbuf.buf); - +- ++ radeon_cs_destroy(r300->cmdbuf.cs); foreach(atom, &r300->hw.atomlist) { FREE(atom->cmd); } - } +-} - -void r300EmitBlit(r300ContextPtr rmesa, - GLuint color_fmt, @@ -989,18 +962,36 @@ index c9e1dfe..421cb81 100644 - cmd[0].u = 0; - cmd[0].wait.cmd_type = R300_CMD_WAIT; - cmd[0].wait.flags = flags; --} ++ if (r300->radeon.radeonScreen->driScreen->dri2.enabled || r300->radeon.radeonScreen->kernel_mm) { ++ radeon_cs_manager_gem_dtor(r300->cmdbuf.csm); ++ } else { ++ radeon_cs_manager_legacy_dtor(r300->cmdbuf.csm); ++ } + } diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h -index a8eaa58..4708a4c 100644 +index a8eaa58..1a249c8 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h -@@ -45,29 +45,88 @@ extern void r300EmitState(r300ContextPtr r300); +@@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define __R300_CMDBUF_H__ + + #include "r300_context.h" ++#include "radeon_cs.h" + + extern int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller); + extern int r300FlushCmdBuf(r300ContextPtr r300, const char *caller); +@@ -45,72 +46,90 @@ extern void r300EmitState(r300ContextPtr r300); extern void r300InitCmdBuf(r300ContextPtr r300); extern void r300DestroyCmdBuf(r300ContextPtr r300); +extern void r300EnsureCmdBufSpace(r300ContextPtr r300, int dwords, const char *caller); + -+extern void r300BeginBatch(r300ContextPtr r300, int n, GLboolean autostate, const char* function, int line); ++void r300BeginBatch(r300ContextPtr r300, ++ int n, ++ int dostate, ++ const char *file, ++ const char *function, ++ int line); /** - * Make sure that enough space is available in the command buffer @@ -1009,38 +1000,74 @@ index a8eaa58..4708a4c 100644 - * \param dwords The number of dwords we need to be free on the command buffer + * Every function writing to the command buffer needs to declare this + * to get the necessary local variables. - */ --static INLINE void r300EnsureCmdBufSpace(r300ContextPtr r300, -- int dwords, const char *caller) --{ -- assert(dwords < r300->cmdbuf.size); ++ */ +#define BATCH_LOCALS(r300) \ + const r300ContextPtr b_l_r300 = r300 - -- if (r300->cmdbuf.count_used + dwords > r300->cmdbuf.size) -- r300FlushCmdBuf(r300, caller); --} ++ +/** + * Prepare writing n dwords to the command buffer, + * including producing any necessary state emits on buffer wraparound. + */ -+#define BEGIN_BATCH(n) r300BeginBatch(b_l_r300, n, GL_TRUE, __FUNCTION__, __LINE__) ++#define BEGIN_BATCH(n) r300BeginBatch(b_l_r300, n, 1, __FILE__, __FUNCTION__, __LINE__) + +/** + * Same as BEGIN_BATCH, but do not cause automatic state emits. + */ -+#define BEGIN_BATCH_NO_AUTOSTATE(n) r300BeginBatch(b_l_r300, n, GL_FALSE, __FUNCTION__, __LINE__) ++#define BEGIN_BATCH_NO_AUTOSTATE(n) r300BeginBatch(b_l_r300, n, 0, __FILE__, __FUNCTION__, __LINE__) + +/** + * Write one dword to the command buffer. + */ +#define OUT_BATCH(data) \ + do { \ -+ if (b_l_r300->cmdbuf.written < b_l_r300->cmdbuf.reserved) { \ -+ ((uint32_t*)b_l_r300->cmdbuf.buf->virtual)[b_l_r300->cmdbuf.written++] = data; \ -+ } else { \ -+ _mesa_problem(b_l_r300->radeon.glCtx, "%s:%i: OUT_BATCH mismatch", __FUNCTION__, __LINE__); \ -+ } \ ++ radeon_cs_write_dword(b_l_r300->cmdbuf.cs, data);\ ++ } while(0) ++ ++/** ++ * Write a relocated dword to the command buffer. ++ */ ++#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ ++ do { \ ++ if (offset) {\ ++ fprintf(stderr, "(%s:%s:%d) offset : %d\n",\ ++ __FILE__, __FUNCTION__, __LINE__, offset);\ ++ }\ ++ radeon_cs_write_dword(b_l_r300->cmdbuf.cs, offset);\ ++ radeon_cs_write_reloc(b_l_r300->cmdbuf.cs, \ ++ bo, \ ++ offset, \ ++ (bo)->size, \ ++ rd, \ ++ wd, \ ++ flags);\ ++ } while(0) ++ ++/** ++ * Write n dwords from ptr to the command buffer. + */ +-static INLINE void r300EnsureCmdBufSpace(r300ContextPtr r300, +- int dwords, const char *caller) +-{ +- assert(dwords < r300->cmdbuf.size); ++#define OUT_BATCH_TABLE(ptr,n) \ ++ do { \ ++ int _i; \ ++ for (_i=0; _i < n; _i++) {\ ++ radeon_cs_write_dword(b_l_r300->cmdbuf.cs, ptr[_i]);\ ++ }\ ++ } while(0) + +- if (r300->cmdbuf.count_used + dwords > r300->cmdbuf.size) +- r300FlushCmdBuf(r300, caller); +-} ++/** ++ * Finish writing dwords to the command buffer. ++ * The number of (direct or indirect) OUT_BATCH calls between the previous ++ * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. ++ */ ++#define END_BATCH() \ ++ do { \ ++ radeon_cs_end(b_l_r300->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ + } while(0) /** @@ -1049,88 +1076,40 @@ index a8eaa58..4708a4c 100644 - * When necessary, these functions cause a flush. r300AllocCmdBuf() also - * causes state reemission after a flush. This is necessary to ensure - * correct hardware state after an unlock. -+ * Write a relocated dword to the command buffer. - */ -+#define OUT_BATCH_RELOC(data, bo, offset, flags) \ -+ do { \ -+ if (b_l_r300->cmdbuf.written < b_l_r300->cmdbuf.reserved) { \ -+ dri_emit_reloc(b_l_r300->cmdbuf.buf, flags, offset, 4*b_l_r300->cmdbuf.written, bo); \ -+ ((uint32_t*)b_l_r300->cmdbuf.buf->virtual)[b_l_r300->cmdbuf.written++] = data; \ -+ } else { \ -+ _mesa_problem(b_l_r300->radeon.glCtx, "%s:%i: OUT_BATCH mismatch", __FUNCTION__, __LINE__); \ -+ } \ -+ } while(0) -+ -+/** -+ * Write n dwords from ptr to the command buffer. -+ */ -+#define OUT_BATCH_TABLE(ptr,n) \ -+ do { \ -+ int _n = n; \ -+ if (b_l_r300->cmdbuf.written+_n <= b_l_r300->cmdbuf.reserved) { \ -+ memcpy((uint32_t*)b_l_r300->cmdbuf.buf->virtual + b_l_r300->cmdbuf.written, (ptr), 4*_n); \ -+ b_l_r300->cmdbuf.written += _n; \ -+ } else { \ -+ _mesa_problem(b_l_r300->radeon.glCtx, "%s:%i: OUT_BATCH_TABLE mismatch", __FUNCTION__, __LINE__); \ -+ } \ -+ } while(0) -+ -+/** -+ * Finish writing dwords to the command buffer. -+ * The number of (direct or indirect) OUT_BATCH calls between the previous -+ * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. -+ */ -+#define END_BATCH() \ -+ do { \ -+ if (b_l_r300->cmdbuf.written != b_l_r300->cmdbuf.reserved) \ -+ _mesa_problem(b_l_r300->radeon.glCtx, "%s:%i: END_BATCH mismatch", __FUNCTION__, __LINE__); \ -+ } while(0) -+ -+/** + * After the last END_BATCH() of rendering, this indicates that flushing + * the command buffer now is okay. -+ */ -+#define COMMIT_BATCH() \ -+ do { \ -+ assert(b_l_r300->cmdbuf.written == b_l_r300->cmdbuf.reserved); \ -+ b_l_r300->cmdbuf.committed = b_l_r300->cmdbuf.written; \ -+ } while(0) -+ - static INLINE uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, - int dwords, const char *caller) - { -@@ -75,8 +134,9 @@ static INLINE uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, - - r300EnsureCmdBufSpace(r300, dwords, caller); - + */ +-static INLINE uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, +- int dwords, const char *caller) +-{ +- uint32_t *ptr; +- +- r300EnsureCmdBufSpace(r300, dwords, caller); +- - ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used]; - r300->cmdbuf.count_used += dwords; -+ ptr = (uint32_t*)r300->cmdbuf.buf->virtual + r300->cmdbuf.written; -+ r300->cmdbuf.written += dwords; -+ r300->cmdbuf.reserved = r300->cmdbuf.committed = r300->cmdbuf.written; - return ptr; - } - -@@ -87,30 +147,17 @@ static INLINE uint32_t *r300AllocCmdBuf(r300ContextPtr r300, - - r300EnsureCmdBufSpace(r300, dwords, caller); - +- return ptr; +-} +- +-static INLINE uint32_t *r300AllocCmdBuf(r300ContextPtr r300, +- int dwords, const char *caller) +-{ +- uint32_t *ptr; +- +- r300EnsureCmdBufSpace(r300, dwords, caller); +- - if (!r300->cmdbuf.count_used) { -+ if (!r300->cmdbuf.written) { - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, - "Reemit state after flush (from %s)\n", caller); - r300EmitState(r300); - } - +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, +- "Reemit state after flush (from %s)\n", caller); +- r300EmitState(r300); +- } +- - ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used]; - r300->cmdbuf.count_used += dwords; -+ ptr = (uint32_t*)r300->cmdbuf.buf->virtual + r300->cmdbuf.written; -+ r300->cmdbuf.written += dwords; -+ r300->cmdbuf.reserved = r300->cmdbuf.committed = r300->cmdbuf.written; - return ptr; - } - +- return ptr; +-} +- -extern void r300EmitBlit(r300ContextPtr rmesa, - GLuint color_fmt, - GLuint src_pitch, @@ -1144,13 +1123,19 @@ index a8eaa58..4708a4c 100644 -extern void r300EmitLOAD_VBPNTR(r300ContextPtr rmesa, int start); -extern void r300EmitVertexShader(r300ContextPtr rmesa); -extern void r300EmitPixelShader(r300ContextPtr rmesa); -- ++#define COMMIT_BATCH() \ ++ do { \ ++ } while(0) ++ ++void emit_vpu(r300ContextPtr r300, struct r300_state_atom * atom); ++int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom); + #endif /* __R300_CMDBUF_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c -index ee4a69d..75cbebe 100644 +index 3743627..5fce841 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c -@@ -59,15 +59,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -59,15 +59,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_span.h" #include "r300_context.h" #include "r300_cmdbuf.h" @@ -1162,12 +1147,30 @@ index ee4a69d..75cbebe 100644 #include "r300_swtcl.h" -#ifdef USER_BUFFERS - #include "r300_mem.h" +-#include "r300_mem.h" -#endif #include "vblank.h" #include "utils.h" -@@ -190,7 +189,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, +@@ -178,6 +176,17 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = { + 0, + }; + ++static void r300RunPipeline(GLcontext * ctx) ++{ ++ _mesa_lock_context_textures(ctx); ++ ++ if (ctx->NewState) ++ _mesa_update_state_locked(ctx); ++ ++ _tnl_run_pipeline(ctx); ++ _mesa_unlock_context_textures(ctx); ++} ++ + /* Create the device specific rendering context. + */ + GLboolean r300CreateContext(const __GLcontextModes * glVisual, +@@ -189,7 +198,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, struct dd_function_table functions; r300ContextPtr r300; GLcontext *ctx; @@ -1176,7 +1179,7 @@ index ee4a69d..75cbebe 100644 assert(glVisual); assert(driContextPriv); -@@ -222,10 +221,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, +@@ -221,10 +230,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, r300InitTextureFuncs(&functions); r300InitShaderFuncs(&functions); @@ -1187,12 +1190,9 @@ index ee4a69d..75cbebe 100644 if (!radeonInitContext(&r300->radeon, &functions, glVisual, driContextPriv, sharedContextPrivate)) { -@@ -233,34 +228,9 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, - return GL_FALSE; +@@ -233,33 +238,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, } -+ r300->radeon.bufmgr = radeonBufmgrClassicInit(r300); -+ /* Init r300 context data */ - r300->dma.buf0_address = - r300->radeon.radeonScreen->buffers->list[0].address; @@ -1224,7 +1224,7 @@ index ee4a69d..75cbebe 100644 r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache, "texture_depth"); if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) -@@ -299,13 +269,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, +@@ -298,13 +276,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, ctx->Const.MaxLineWidth = R300_LINESIZE_MAX; ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX; @@ -1238,7 +1238,16 @@ index ee4a69d..75cbebe 100644 /* Initialize the software rasterizer and helper modules. */ -@@ -407,72 +375,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, +@@ -383,7 +359,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, + if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) + r300InitSwtcl(ctx); + +- TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; ++ TNL_CONTEXT(ctx)->Driver.RunPipeline = r300RunPipeline; + + tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode"); + if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) { +@@ -406,72 +382,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, return GL_TRUE; } @@ -1311,7 +1320,7 @@ index ee4a69d..75cbebe 100644 /* Destroy the device specific context. */ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) -@@ -496,23 +398,16 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) +@@ -495,23 +405,12 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) assert(r300); /* should never be null */ if (r300) { @@ -1330,16 +1339,13 @@ index ee4a69d..75cbebe 100644 -#ifndef USER_BUFFERS - r300FlushCmdBuf(r300, __FUNCTION__); -#endif -+ if (r300->dma.current) { -+ dri_bo_unreference(r300->dma.current); -+ r300->dma.current = 0; - } +- } - r300FreeGartAllocations(r300); + r300FlushCmdBuf(r300, __FUNCTION__); r300DestroyCmdBuf(r300); if (radeon->state.scissor.pClipRects) { -@@ -520,28 +415,13 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) +@@ -519,28 +418,11 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) radeon->state.scissor.pClipRects = NULL; } @@ -1365,24 +1371,20 @@ index ee4a69d..75cbebe 100644 */ - r300_mem_destroy(r300); -#endif -+ dri_bufmgr_destroy(r300->radeon.bufmgr); -+ r300->radeon.bufmgr = 0; /* free the option cache */ driDestroyOptionCache(&r300->radeon.optionCache); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h -index c15e9fa..037d0e6 100644 +index c15e9fa..30229ed 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h -@@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - #include "tnl/t_vertex.h" - #include "drm.h" +@@ -42,13 +42,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_drm.h" -+#include "radeon_dri_bufmgr.h" #include "dri_util.h" #include "texmem.h" ++#include "radeon_bo.h" -@@ -47,8 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "main/macros.h" #include "main/mtypes.h" #include "main/colormac.h" @@ -1391,7 +1393,7 @@ index c15e9fa..037d0e6 100644 struct r300_context; typedef struct r300_context r300ContextRec; typedef struct r300_context *r300ContextPtr; -@@ -122,68 +121,71 @@ static INLINE uint32_t r300PackFloat24(float f) +@@ -122,68 +121,51 @@ static INLINE uint32_t r300PackFloat24(float f) /************ DMA BUFFERS **************/ @@ -1421,42 +1423,25 @@ index c15e9fa..037d0e6 100644 - int aos_stride; /* distance between elements, in dwords */ - int aos_size; /* number of components (1-4) */ -}; -- - struct r300_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ -- struct r300_dma_region current; -+ dri_bo *current; /** Buffer that DMA memory is allocated from */ -+ int current_used; /** Number of bytes allocated and forgotten about */ -+ int current_vertexptr; /** End of active vertex region */ -+ /** -+ * If current_vertexptr != current_used then flush must be non-zero. -+ * flush must be called before non-active vertex allocations can be -+ * performed. -+ */ - void (*flush) (r300ContextPtr); +-struct r300_dma { +- /* Active dma region. Allocations for vertices and retained +- * regions come from here. Also used for emitting random vertices, +- * these may be flushed by calling flush_current(); +- */ +- struct r300_dma_region current; ++/* Texture related */ ++typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr; ++typedef struct _r300_texture_image r300_texture_image; + +- void (*flush) (r300ContextPtr); - char *buf0_address; /* start of buf[0], for index calcs */ -- - /* Number of "in-flight" DMA buffers, i.e. the number of buffers - * for which a DISCARD command is currently queued in the command buffer. - */ - GLuint nr_released_bufs; - }; - -- /* Texture related */ -- -+/* Texture related */ - typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr; -+typedef struct _r300_texture_image r300_texture_image; -+ -+ +struct _r300_texture_image { + struct gl_texture_image base; -+ + +- /* Number of "in-flight" DMA buffers, i.e. the number of buffers +- * for which a DISCARD command is currently queued in the command buffer. + /** + * If mt != 0, the image is stored in hardware format in the + * given mipmap tree. In this case, base.Data may point into the @@ -1464,18 +1449,22 @@ index c15e9fa..037d0e6 100644 + * + * If mt == 0, the image is stored in normal memory pointed to + * by base.Data. -+ */ + */ +- GLuint nr_released_bufs; + struct _r300_mipmap_tree *mt; ++ struct radeon_bo *bo; + + int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ + int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ -+}; -+ + }; + +- /* Texture related */ +static INLINE r300_texture_image *get_r300_texture_image(struct gl_texture_image *image) +{ + return (r300_texture_image*)image; +} -+ + +-typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr; /* Texture object in locally shared texture space. */ @@ -1502,7 +1491,7 @@ index c15e9fa..037d0e6 100644 /* hardware register values */ /* Note that R200 has 8 registers per texture and R300 only 7 */ GLuint filter; -@@ -191,30 +193,16 @@ struct r300_tex_obj { +@@ -191,30 +173,17 @@ struct r300_tex_obj { GLuint pitch_reg; GLuint size; /* npot only */ GLuint format; @@ -1524,6 +1513,7 @@ index c15e9fa..037d0e6 100644 + /* end hardware registers */ GLuint tile_bits; /* hw texture tile bits used on this texture */ ++ struct radeon_bo *bo; }; -struct r300_texture_env_state { @@ -1538,7 +1528,7 @@ index c15e9fa..037d0e6 100644 /* The blit width for texture uploads */ -@@ -222,7 +210,6 @@ struct r300_texture_env_state { +@@ -222,7 +191,6 @@ struct r300_texture_env_state { #define R300_MAX_TEXTURE_UNITS 8 struct r300_texture_state { @@ -1546,15 +1536,15 @@ index c15e9fa..037d0e6 100644 int tc_count; /* number of incoming texture coordinates from VAP */ }; -@@ -242,6 +229,7 @@ struct r300_state_atom { +@@ -242,6 +210,7 @@ struct r300_state_atom { GLboolean dirty; int (*check) (r300ContextPtr, struct r300_state_atom * atom); -+ void (*emit) (r300ContextPtr); ++ void (*emit) (r300ContextPtr, struct r300_state_atom * atom); }; #define R300_VPT_CMD_0 0 -@@ -549,6 +537,8 @@ struct r300_hw_state { +@@ -549,6 +518,8 @@ struct r300_hw_state { struct r300_state_atom border_color; } tex; struct r300_state_atom txe; /* tex enable (4104) */ @@ -1563,7 +1553,7 @@ index c15e9fa..037d0e6 100644 }; /** -@@ -559,10 +549,14 @@ struct r300_hw_state { +@@ -559,10 +530,10 @@ struct r300_hw_state { * otherwise. */ struct r300_cmdbuf { @@ -1571,23 +1561,19 @@ index c15e9fa..037d0e6 100644 - uint32_t *cmd_buf; - int count_used; /* DWORDs filled so far */ - int count_reemit; /* size of re-emission batch */ -+ dri_bo *buf; -+ int reemit; /** # of dwords in reemit sequence (is always <= committed) */ ++ struct radeon_cs_manager *csm; ++ struct radeon_cs *cs; + int size; /** # of dwords total */ -+ -+ int committed; /** # of dwords that we have committed to */ -+ int written; /** # of dwords written (is always >= committed) */ -+ int reserved; /** # of dwords reserved up to previous BEGIN_BATCH */ + unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ }; /** -@@ -811,18 +805,25 @@ struct r500_fragment_program { +@@ -811,18 +782,25 @@ struct r500_fragment_program { #define REG_COLOR0 1 #define REG_TEX0 2 +struct r300_aos { -+ dri_bo *bo; /** Buffer object where vertex data is stored */ ++ struct radeon_bo *bo; /** Buffer object where vertex data is stored */ + int offset; /** Offset into buffer object, in bytes */ + int components; /** Number of components per vertex */ + int stride; /** Stride in dwords (may be 0 for repeating) */ @@ -1605,31 +1591,33 @@ index c15e9fa..037d0e6 100644 - GLuint *Elts; - struct r300_dma_region elt_dma; -+ dri_bo *elt_dma_bo; /** Buffer object that contains element indices */ ++ struct radeon_bo *elt_dma_bo; /** Buffer object that contains element indices */ + int elt_dma_offset; /** Offset into this buffer object, in bytes */ - struct r300_dma_region swtcl_dma; DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for. They are the same as tnl->render_inputs for fixed pipeline */ -@@ -880,13 +881,6 @@ struct r300_swtcl_info { - * Offset of the 3UB specular color data within a hardware (swtcl) vertex. +@@ -881,12 +859,8 @@ struct r300_swtcl_info { */ GLuint specoffset; -- + - /** - * Should Mesa project vertex data or will the hardware do it? - */ - GLboolean needproj; - - struct r300_dma_region indexed_verts; ++ struct radeon_bo *bo; ++ void (*flush) (r300ContextPtr); }; -@@ -905,25 +899,11 @@ struct r300_context { +@@ -904,26 +878,11 @@ struct r300_context { + /* Vertex buffers */ - struct r300_dma dma; +- struct r300_dma dma; - GLboolean save_on_next_unlock; GLuint NewGLState; @@ -1653,20 +1641,20 @@ index c15e9fa..037d0e6 100644 GLvector4f *temp_attrib[_TNL_ATTRIB_MAX]; diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c -index 80bd338..6ed2638 100644 +index 80bd338..a984f55 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c -@@ -51,9 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -51,9 +51,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_emit.h" #include "r300_ioctl.h" -#ifdef USER_BUFFERS - #include "r300_mem.h" +-#include "r300_mem.h" -#endif #if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \ SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \ -@@ -86,11 +84,9 @@ do { \ +@@ -86,11 +83,9 @@ do { \ } while (0) #endif @@ -1679,7 +1667,7 @@ index 80bd338..6ed2638 100644 if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s count %d stride %d out %p data %p\n", -@@ -106,11 +102,9 @@ static void r300EmitVec4(GLcontext * ctx, struct r300_dma_region *rvb, +@@ -106,11 +101,9 @@ static void r300EmitVec4(GLcontext * ctx, struct r300_dma_region *rvb, } } @@ -1692,7 +1680,7 @@ index 80bd338..6ed2638 100644 if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s count %d stride %d out %p data %p\n", -@@ -127,11 +121,9 @@ static void r300EmitVec8(GLcontext * ctx, struct r300_dma_region *rvb, +@@ -127,18 +120,17 @@ static void r300EmitVec8(GLcontext * ctx, struct r300_dma_region *rvb, } } @@ -1705,6 +1693,15 @@ index 80bd338..6ed2638 100644 if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + +- if (stride == 12) ++ if (stride == 12) { + COPY_DWORDS(out, data, count * 3); ++ } + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; @@ -149,11 +141,9 @@ static void r300EmitVec12(GLcontext * ctx, struct r300_dma_region *rvb, } } @@ -1718,21 +1715,22 @@ index 80bd338..6ed2638 100644 if (RADEON_DEBUG & DEBUG_VERTS) fprintf(stderr, "%s count %d stride %d out %p data %p\n", -@@ -172,35 +162,31 @@ static void r300EmitVec16(GLcontext * ctx, struct r300_dma_region *rvb, +@@ -172,39 +162,40 @@ static void r300EmitVec16(GLcontext * ctx, struct r300_dma_region *rvb, } } -static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb, -+ +static void r300EmitVec(GLcontext * ctx, struct r300_aos *aos, GLvoid * data, int size, int stride, int count) { r300ContextPtr rmesa = R300_CONTEXT(ctx); + uint32_t *out; ++ uint32_t bo_size; ++ memset(aos, 0, sizeof(struct r300_aos)); if (stride == 0) { - r300AllocDmaRegion(rmesa, rvb, size * 4, 4); -+ r300AllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); ++ bo_size = size * 4; count = 1; - rvb->aos_offset = GET_START(rvb); - rvb->aos_stride = 0; @@ -1741,14 +1739,18 @@ index 80bd338..6ed2638 100644 - r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4); - rvb->aos_offset = GET_START(rvb); - rvb->aos_stride = size; -+ r300AllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); ++ bo_size = size * count * 4; + aos->stride = size; } - +- ++ aos->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, ++ 0, bo_size, 32, RADEON_GEM_DOMAIN_GTT, 0); ++ aos->offset = 0; + aos->components = size; + aos->count = count; + -+ out = (uint32_t*)((char*)aos->bo->virtual + aos->offset); ++ radeon_bo_map(aos->bo, 1); ++ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); switch (size) { - case 1: - r300EmitVec4(ctx, rvb, data, stride, count); @@ -1769,6 +1771,30 @@ index 80bd338..6ed2638 100644 default: assert(0); break; + } ++ radeon_bo_unmap(aos->bo); + } + + #define DW_SIZE(x) ((inputs[tab[(x)]] << R300_DST_VEC_LOC_SHIFT) | \ +@@ -314,10 +305,6 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten) + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; + +-#if 0 +- if (OutputsWritten & (1 << VERT_RESULT_FOGC)) ; +-#endif +- + if (OutputsWritten & (1 << VERT_RESULT_PSIZ)) + ret |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; + +@@ -371,7 +358,6 @@ int r300EmitArrays(GLcontext * ctx) + + assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)); + assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_NORMAL) == 0); +- //assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0)); + + if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) { + InputsRead |= 1 << VERT_ATTRIB_POS; @@ -433,7 +419,7 @@ int r300EmitArrays(GLcontext * ctx) } @@ -1778,10 +1804,11 @@ index 80bd338..6ed2638 100644 swizzle[i][0] = SWIZZLE_ZERO; swizzle[i][1] = SWIZZLE_ZERO; -@@ -444,48 +430,10 @@ int r300EmitArrays(GLcontext * ctx) +@@ -443,52 +429,25 @@ int r300EmitArrays(GLcontext * ctx) + for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) { swizzle[i][ci] = ci; } - +- - if (r300IsGartMemory(rmesa, vb->AttribPtr[tab[i]]->data, 4)) { - if (vb->AttribPtr[tab[i]]->stride % 4) { - return R300_FALLBACK_TCL; @@ -1831,7 +1858,30 @@ index 80bd338..6ed2638 100644 } /* Setup INPUT_ROUTE. */ -@@ -515,45 +463,76 @@ int r300EmitArrays(GLcontext * ctx) ++ if (rmesa->radeon.radeonScreen->kernel_mm) { ++ R300_STATECHANGE(rmesa, vir[0]); ++ rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; ++ rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; ++ rmesa->hw.vir[0].cmd[0] |= ++ (r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], ++ vb->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16; ++ R300_STATECHANGE(rmesa, vir[1]); ++ rmesa->hw.vir[1].cmd[0] |= ++ (r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, ++ nr) & 0x3FFF) << 16; ++ } else { + R300_STATECHANGE(rmesa, vir[0]); + ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = + r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], +@@ -497,6 +456,7 @@ int r300EmitArrays(GLcontext * ctx) + ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = + r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, + nr); ++ } + + /* Setup INPUT_CNTL. */ + R300_STATECHANGE(rmesa, vic); +@@ -515,45 +475,33 @@ int r300EmitArrays(GLcontext * ctx) return R300_FALLBACK_NONE; } @@ -1858,14 +1908,13 @@ index 80bd338..6ed2638 100644 - r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__); + if (rmesa->state.elt_dma_bo) { -+ dri_bo_unreference(rmesa->state.elt_dma_bo); ++ radeon_bo_unref(rmesa->state.elt_dma_bo); + rmesa->state.elt_dma_bo = 0; + } for (i = 0; i < rmesa->state.aos_count; i++) { - r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__); + if (rmesa->state.aos[i].bo) { -+ dri_bo_unreference(rmesa->state.aos[i].bo); -+ rmesa->state.aos[i].bo = 0; ++ rmesa->state.aos[i].bo = radeon_bo_unref(rmesa->state.aos[i].bo); + } } } @@ -1880,6 +1929,10 @@ index 80bd338..6ed2638 100644 - reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); - e32(R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | - R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); +- +- reg_start(R300_ZB_ZCACHE_CTLSTAT, 0); +- e32(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | +- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + BATCH_LOCALS(rmesa); + + BEGIN_BATCH(4); @@ -1891,57 +1944,102 @@ index 80bd338..6ed2638 100644 + R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + END_BATCH(); + COMMIT_BATCH(); -+} - -- reg_start(R300_ZB_ZCACHE_CTLSTAT, 0); -- e32(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | -- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); -+void r300EmitBlit(r300ContextPtr rmesa, -+ GLuint color_fmt, -+ GLuint src_pitch, -+ dri_bo *src_bo, int src_offset, -+ GLuint dst_pitch, -+ GLuint dst_offset, -+ GLint srcx, GLint srcy, -+ GLint dstx, GLint dsty, GLuint w, GLuint h) -+{ -+ BATCH_LOCALS(rmesa); -+ -+ if (RADEON_DEBUG & DEBUG_IOCTL) -+ fprintf(stderr, -+ "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", -+ __FUNCTION__, src_pitch, src_offset, srcx, srcy, -+ dst_pitch, dst_offset, dstx, dsty, w, h); -+ -+ assert((src_pitch & 63) == 0); -+ assert((dst_pitch & 63) == 0); -+ assert((src_offset & 1023) == 0); -+ assert((dst_offset & 1023) == 0); -+ assert(w < (1 << 16)); -+ assert(h < (1 << 16)); -+ -+ BEGIN_BATCH(8); -+ OUT_BATCH_PACKET3(R300_CP_CMD_BITBLT_MULTI, 5); -+ OUT_BATCH(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | -+ RADEON_GMC_DST_PITCH_OFFSET_CNTL | -+ RADEON_GMC_BRUSH_NONE | -+ (color_fmt << 8) | -+ RADEON_GMC_SRC_DATATYPE_COLOR | -+ RADEON_ROP3_S | -+ RADEON_DP_SRC_SOURCE_MEMORY | -+ RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); -+ OUT_BATCH_RELOC((src_pitch / 64) << 22, src_bo, src_offset, DRM_RELOC_BLITTER); -+ OUT_BATCH(((dst_pitch / 64) << 22) | (dst_offset >> 10)); -+ OUT_BATCH((srcx << 16) | srcy); -+ OUT_BATCH((dstx << 16) | dsty); -+ OUT_BATCH((w << 16) | h); -+ END_BATCH(); } diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h -index 89d7383..7e11604 100644 +index 89d7383..db43cc3 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h -@@ -127,130 +127,62 @@ static INLINE uint32_t cmdpacify(void) +@@ -46,23 +46,31 @@ + + /* TODO: move these defines (and the ones from DRM) into r300_reg.h and sync up + * with DRM */ ++#define CP_PACKET2 (2 << 30) + #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) + #define CP_PACKET3( pkt, n ) \ + (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + +-static INLINE uint32_t cmdpacket0(int reg, int count) ++static INLINE uint32_t cmdpacket0(struct radeon_screen *rscrn, ++ int reg, int count) + { +- drm_r300_cmd_header_t cmd; +- +- cmd.packet0.cmd_type = R300_CMD_PACKET0; +- cmd.packet0.count = count; +- cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; +- cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); +- +- return cmd.u; ++ if (!rscrn->kernel_mm) { ++ drm_r300_cmd_header_t cmd; ++ ++ cmd.packet0.cmd_type = R300_CMD_PACKET0; ++ cmd.packet0.count = count; ++ cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; ++ cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); ++ ++ return cmd.u; ++ } ++ if (count) { ++ return CP_PACKET0(reg, count - 1); ++ } ++ return CP_PACKET2; + } + +-static INLINE uint32_t cmdvpu(int addr, int count) ++static INLINE uint32_t cmdvpu(struct radeon_screen *rscrn, int addr, int count) + { + drm_r300_cmd_header_t cmd; + +@@ -74,7 +82,8 @@ static INLINE uint32_t cmdvpu(int addr, int count) + return cmd.u; + } + +-static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) ++static INLINE uint32_t cmdr500fp(struct radeon_screen *rscrn, ++ int addr, int count, int type, int clamp) + { + drm_r300_cmd_header_t cmd; + +@@ -88,7 +97,7 @@ static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) + return cmd.u; + } + +-static INLINE uint32_t cmdpacket3(int packet) ++static INLINE uint32_t cmdpacket3(struct radeon_screen *rscrn, int packet) + { + drm_r300_cmd_header_t cmd; + +@@ -98,7 +107,8 @@ static INLINE uint32_t cmdpacket3(int packet) + return cmd.u; + } + +-static INLINE uint32_t cmdcpdelay(unsigned short count) ++static INLINE uint32_t cmdcpdelay(struct radeon_screen *rscrn, ++ unsigned short count) + { + drm_r300_cmd_header_t cmd; + +@@ -108,7 +118,8 @@ static INLINE uint32_t cmdcpdelay(unsigned short count) + return cmd.u; + } + +-static INLINE uint32_t cmdwait(unsigned char flags) ++static INLINE uint32_t cmdwait(struct radeon_screen *rscrn, ++ unsigned char flags) + { + drm_r300_cmd_header_t cmd; + +@@ -118,7 +129,7 @@ static INLINE uint32_t cmdwait(unsigned char flags) + return cmd.u; + } + +-static INLINE uint32_t cmdpacify(void) ++static INLINE uint32_t cmdpacify(struct radeon_screen *rscrn) + { + drm_r300_cmd_header_t cmd; + +@@ -127,130 +138,100 @@ static INLINE uint32_t cmdpacify(void) return cmd.u; } @@ -1965,13 +2063,13 @@ index 89d7383..7e11604 100644 + +/** Single register write to command buffer; requires 2 dwords. */ +#define OUT_BATCH_REGVAL(reg, val) \ -+ OUT_BATCH(cmdpacket0((reg), 1)); \ ++ OUT_BATCH(cmdpacket0(b_l_r300->radeon.radeonScreen, (reg), 1)); \ + OUT_BATCH((val)) + +/** Continuous register range write to command buffer; requires 1 dword, + * expects count dwords afterwards for register contents. */ +#define OUT_BATCH_REGSEQ(reg, count) \ -+ OUT_BATCH(cmdpacket0((reg), (count))); ++ OUT_BATCH(cmdpacket0(b_l_r300->radeon.radeonScreen, (reg), (count))); + +/** Write a 32 bit float to the ring; requires 1 dword. */ +#define OUT_BATCH_FLOAT32(f) \ @@ -1998,7 +2096,10 @@ index 89d7383..7e11604 100644 - _mesa_exit(-1); \ - } \ +#define OUT_BATCH_PACKET3(packet, num_extra) do {\ -+ OUT_BATCH(cmdpacket3(R300_CMD_PACKET3_RAW)); \ ++ if (!b_l_r300->radeon.radeonScreen->kernel_mm) { \ ++ OUT_BATCH(cmdpacket3(b_l_r300->radeon.radeonScreen,\ ++ R300_CMD_PACKET3_RAW)); \ ++ }\ + OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ } while(0) @@ -2063,9 +2164,11 @@ index 89d7383..7e11604 100644 - cmd = - (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); - cmd[0].header.cmd_type = R300_CMD_END3D; -+ BEGIN_BATCH(1); -+ OUT_BATCH(cmdpacify()); -+ END_BATCH(); ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH(1); ++ OUT_BATCH(cmdpacify(rmesa->radeon.radeonScreen)); ++ END_BATCH(); ++ } } void static INLINE cp_delay(r300ContextPtr rmesa, unsigned short count) @@ -2076,22 +2179,56 @@ index 89d7383..7e11604 100644 - cmd = - (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); - cmd[0].i = cmdcpdelay(count); -+ BEGIN_BATCH(1); -+ OUT_BATCH(cmdcpdelay(count)); -+ END_BATCH(); ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH(1); ++ OUT_BATCH(cmdcpdelay(rmesa->radeon.radeonScreen, count)); ++ END_BATCH(); ++ } } void static INLINE cp_wait(r300ContextPtr rmesa, unsigned char flags) { - drm_radeon_cmd_header_t *cmd = NULL; -+ BATCH_LOCALS(rmesa); - +- - cmd = - (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); - cmd[0].i = cmdwait(flags); -+ BEGIN_BATCH(1); -+ OUT_BATCH(cmdwait(flags)); -+ END_BATCH(); ++ BATCH_LOCALS(rmesa); ++ uint32_t wait_until; ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH_NO_AUTOSTATE(1); ++ OUT_BATCH(cmdwait(rmesa->radeon.radeonScreen, flags)); ++ END_BATCH(); ++ } else { ++ switch(flags) { ++ case R300_WAIT_2D: ++ wait_until = (1 << 14); ++ break; ++ case R300_WAIT_3D: ++ wait_until = (1 << 15); ++ break; ++ case R300_NEW_WAIT_2D_3D: ++ wait_until = (1 << 14) | (1 << 15); ++ break; ++ case R300_NEW_WAIT_2D_2D_CLEAN: ++ wait_until = (1 << 14) | (1 << 16) | (1 << 18); ++ break; ++ case R300_NEW_WAIT_3D_3D_CLEAN: ++ wait_until = (1 << 15) | (1 << 17) | (1 << 18); ++ break; ++ case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN: ++ wait_until = (1 << 14) | (1 << 16) | (1 << 18); ++ wait_until |= (1 << 15) | (1 << 17) | (1 << 18); ++ break; ++ default: ++ return; ++ } ++ BEGIN_BATCH_NO_AUTOSTATE(2); ++ OUT_BATCH(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); ++ OUT_BATCH(wait_until); ++ END_BATCH(); ++ } } extern int r300EmitArrays(GLcontext * ctx); @@ -2103,22 +2240,8 @@ index 89d7383..7e11604 100644 extern void r300ReleaseArrays(GLcontext * ctx); extern int r300PrimitiveType(r300ContextPtr rmesa, int prim); extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim); -@@ -265,4 +197,13 @@ extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead); - extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten); - extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten); - -+extern void r300EmitBlit(r300ContextPtr rmesa, -+ GLuint color_fmt, -+ GLuint src_pitch, -+ dri_bo *src_bo, int src_offset, -+ GLuint dst_pitch, -+ GLuint dst_offset, -+ GLint srcx, GLint srcy, -+ GLint dstx, GLint dsty, GLuint w, GLuint h); -+ - #endif diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c -index ee85e22..c3d0d72 100644 +index ee85e22..a86841c 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -2129,21 +2252,24 @@ index ee85e22..c3d0d72 100644 #include "r300_context.h" #include "radeon_ioctl.h" #include "r300_ioctl.h" -@@ -55,6 +56,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -55,71 +56,83 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_reg.h" #include "r300_emit.h" #include "r300_fragprog.h" -+#include "r300_mem.h" ++#include "r300_context.h" #include "vblank.h" -@@ -62,64 +64,56 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++#define R200_3D_DRAW_IMMD_2 0xC0003500 ++ + #define CLEARBUFFER_COLOR 0x1 #define CLEARBUFFER_DEPTH 0x2 #define CLEARBUFFER_STENCIL 0x4 -static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) +static void r300ClearBuffer(r300ContextPtr r300, int flags, -+ struct radeon_renderbuffer *rrb) ++ struct radeon_renderbuffer *rrb, ++ struct radeon_renderbuffer *rrbd) { + BATCH_LOCALS(r300); GLcontext *ctx = r300->radeon.glCtx; @@ -2172,14 +2298,15 @@ index ee85e22..c3d0d72 100644 + dPriv->w, dPriv->h); + + if (rrb) { -+ cbpitch = rrb->pitch; ++ cbpitch = (rrb->pitch / rrb->cpp); + if (rrb->cpp == 4) + cbpitch |= R300_COLOR_FORMAT_ARGB8888; + else + cbpitch |= R300_COLOR_FORMAT_RGB565; + -+ if (r300->radeon.sarea->tiling_enabled) ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ + cbpitch |= R300_COLOR_TILE_ENABLE; ++ } } - cboffset += r300->radeon.radeonScreen->fbLocation; @@ -2205,22 +2332,39 @@ index ee85e22..c3d0d72 100644 - - R300_STATECHANGE(r300, cmk); - reg_start(RB3D_COLOR_CHANNEL_MASK, 0); -+ if (flags & CLEARBUFFER_COLOR) { -+ assert(rrb != 0); -+ BEGIN_BATCH(4); -+ OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1); -+ OUT_BATCH_RELOC(0, rrb->bo, 0, DRM_RELOC_TXOFFSET); -+ OUT_BATCH_REGVAL(R300_RB3D_COLORPITCH0, cbpitch); -+ END_BATCH(); -+ } - -+ BEGIN_BATCH(15); -+ OUT_BATCH_REGSEQ(RB3D_COLOR_CHANNEL_MASK, 1); +- if (flags & CLEARBUFFER_COLOR) { - e32((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | - (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | - (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | - (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0)); ++ assert(rrb != 0); ++ BEGIN_BATCH_NO_AUTOSTATE(4); ++ OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1); ++ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGVAL(R300_RB3D_COLORPITCH0, cbpitch); ++ END_BATCH(); ++ } ++#if 1 ++ if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) { ++ assert(rrbd != 0); ++ cbpitch = (rrbd->pitch / rrbd->cpp); ++ if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ ++ cbpitch |= R300_DEPTHMACROTILE_ENABLE; ++ } ++ if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ ++ cbpitch |= R300_DEPTHMICROTILE_TILED; ++ } ++ BEGIN_BATCH_NO_AUTOSTATE(4); ++ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1); ++ OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, cbpitch); ++ END_BATCH(); ++ } ++#endif ++ BEGIN_BATCH_NO_AUTOSTATE(6); ++ OUT_BATCH_REGSEQ(RB3D_COLOR_CHANNEL_MASK, 1); ++ if (flags & CLEARBUFFER_COLOR) { + OUT_BATCH((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | + (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | + (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | @@ -2232,11 +2376,10 @@ index ee85e22..c3d0d72 100644 - R300_STATECHANGE(r300, zs); - reg_start(R300_ZB_CNTL, 2); -+ OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3); { uint32_t t1, t2; -@@ -146,37 +140,37 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) +@@ -146,37 +159,55 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) R300_S_FRONT_ZFAIL_OP_SHIFT); } @@ -2244,10 +2387,13 @@ index ee85e22..c3d0d72 100644 - e32(t2); - e32(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << R300_STENCILWRITEMASK_SHIFT) | - (ctx->Stencil.Clear & R300_STENCILREF_MASK)); ++ OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3); + OUT_BATCH(t1); + OUT_BATCH(t2); -+ OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << R300_STENCILWRITEMASK_SHIFT) | ++ OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << ++ R300_STENCILWRITEMASK_SHIFT) | + (ctx->Stencil.Clear & R300_STENCILREF_MASK)); ++ END_BATCH(); } - cmd2 = (drm_r300_cmd_header_t *) r300AllocCmdBuf(r300, 9, __FUNCTION__); @@ -2261,16 +2407,31 @@ index ee85e22..c3d0d72 100644 - cmd2[6].u = r300PackFloat32(ctx->Color.ClearColor[1]); - cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]); - cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]); -+ OUT_BATCH(cmdpacket3(R300_CMD_PACKET3_CLEAR)); -+ OUT_BATCH_FLOAT32(dPriv->w / 2.0); -+ OUT_BATCH_FLOAT32(dPriv->h / 2.0); -+ OUT_BATCH_FLOAT32(ctx->Depth.Clear); -+ OUT_BATCH_FLOAT32(1.0); -+ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); -+ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); -+ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); -+ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); -+ END_BATCH(); ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ BEGIN_BATCH_NO_AUTOSTATE(9); ++ OUT_BATCH(cmdpacket3(r300->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR)); ++ OUT_BATCH_FLOAT32(dPriv->w / 2.0); ++ OUT_BATCH_FLOAT32(dPriv->h / 2.0); ++ OUT_BATCH_FLOAT32(ctx->Depth.Clear); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); ++ END_BATCH(); ++ } else { ++ OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); ++ OUT_BATCH(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | ++ (1 << R300_PRIM_NUM_VERTICES_SHIFT)); ++ OUT_BATCH_FLOAT32(dPriv->w / 2.0); ++ OUT_BATCH_FLOAT32(dPriv->h / 2.0); ++ OUT_BATCH_FLOAT32(ctx->Depth.Clear); ++ OUT_BATCH_FLOAT32(1.0); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); ++ OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); ++ } r300EmitCacheFlush(rmesa); cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN); @@ -2293,16 +2454,16 @@ index ee85e22..c3d0d72 100644 int has_tcl = 1; int is_r500 = 0; GLuint vap_cntl; -@@ -184,35 +178,37 @@ static void r300EmitClearState(GLcontext * ctx) +@@ -184,35 +215,37 @@ static void r300EmitClearState(GLcontext * ctx) if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) has_tcl = 0; - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) - is_r500 = 1; +- + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + is_r500 = 1; -- - /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and - * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are - * quite complex; see the functions in r300_emit.c. @@ -2352,7 +2513,7 @@ index ee85e22..c3d0d72 100644 (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) | (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) | (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) | -@@ -226,238 +222,246 @@ static void r300EmitClearState(GLcontext * ctx) +@@ -226,238 +259,267 @@ static void r300EmitClearState(GLcontext * ctx) << R300_SWIZZLE1_SHIFT))); /* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */ @@ -2636,7 +2797,7 @@ index ee85e22..c3d0d72 100644 + OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1)); + OUT_BATCH(R500_US_CODE_OFFSET_ADDR(0)); + -+ OUT_BATCH(cmdr500fp(0, 1, 0, 0)); ++ OUT_BATCH(cmdr500fp(r300->radeon.radeonScreen, 0, 1, 0, 0)); + OUT_BATCH(R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | + R500_INST_LAST | @@ -2728,6 +2889,8 @@ index ee85e22..c3d0d72 100644 + END_BATCH(); if (has_tcl) { ++ struct r300_state_atom vpu; ++ uint32_t _cmd[10]; R300_STATECHANGE(r300, pvs); - reg_start(R300_VAP_PVS_CODE_CNTL_0, 2); - @@ -2740,17 +2903,17 @@ index ee85e22..c3d0d72 100644 - R300_STATECHANGE(r300, vpi); - vsf_start_fragment(0x0, 8); - +- - e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 0, 0xf, PVS_DST_REG_OUT)); - e32(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - e32(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - e32(0x0); -- + - e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, PVS_DST_REG_OUT)); - e32(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - e32(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - e32(0x0); -+ BEGIN_BATCH(13); ++ BEGIN_BATCH(4); + OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3); + OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) | + (0 << R300_PVS_XYZW_VALID_INST_SHIFT) | @@ -2758,33 +2921,54 @@ index ee85e22..c3d0d72 100644 + OUT_BATCH((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | + (0 << R300_PVS_MAX_CONST_ADDR_SHIFT)); + OUT_BATCH(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT); -+ -+ OUT_BATCH(cmdvpu(0, 2)); -+ OUT_BATCH(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 0, 0xf, PVS_DST_REG_OUT)); -+ OUT_BATCH(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); -+ OUT_BATCH(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); -+ OUT_BATCH(0x0); -+ -+ OUT_BATCH(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, PVS_DST_REG_OUT)); -+ OUT_BATCH(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); -+ OUT_BATCH(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); -+ OUT_BATCH(0x0); + END_BATCH(); ++ ++ vpu.check = check_vpu; ++ vpu.cmd = _cmd; ++ vpu.cmd[0] = cmdvpu(r300->radeon.radeonScreen, 0, 2); ++ ++ vpu.cmd[1] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, ++ 0, 0xf, PVS_DST_REG_OUT); ++ vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, ++ PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, ++ PVS_SRC_REG_INPUT, VSF_FLAG_NONE); ++ vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_REG_INPUT, VSF_FLAG_NONE); ++ vpu.cmd[4] = 0x0; ++ ++ vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, ++ PVS_DST_REG_OUT); ++ vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, ++ PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, ++ PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, ++ VSF_FLAG_NONE); ++ vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_SELECT_FORCE_0, ++ PVS_SRC_REG_INPUT, VSF_FLAG_NONE); ++ vpu.cmd[8] = 0x0; ++ emit_vpu(r300, &vpu); } } -@@ -467,7 +471,10 @@ static void r300EmitClearState(GLcontext * ctx) - static void r300Clear(GLcontext * ctx, GLbitfield mask) +@@ -468,9 +530,11 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); -+ BATCH_LOCALS(r300); __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + GLframebuffer *fb = dPriv->driverPrivate; + struct radeon_renderbuffer *rrb; ++ struct radeon_renderbuffer *rrbd; int flags = 0; int bits = 0; - int swapped; -@@ -482,6 +489,12 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) +- int swapped; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "r300Clear\n"); +@@ -482,6 +546,12 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) return; } @@ -2797,7 +2981,7 @@ index ee85e22..c3d0d72 100644 if (mask & BUFFER_BIT_FRONT_LEFT) { flags |= BUFFER_BIT_FRONT_LEFT; mask &= ~BUFFER_BIT_FRONT_LEFT; -@@ -509,26 +522,27 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) +@@ -509,26 +579,28 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) _swrast_Clear(ctx, mask); } @@ -2807,63 +2991,69 @@ index ee85e22..c3d0d72 100644 r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); ++ rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; if (flags & BUFFER_BIT_FRONT_LEFT) { - r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped); + rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; -+ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb); ++ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); bits = 0; } if (flags & BUFFER_BIT_BACK_LEFT) { - r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1); + rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; -+ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb); ++ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); bits = 0; } if (bits) - r300ClearBuffer(r300, bits, 0); -+ r300ClearBuffer(r300, bits, NULL); ++ r300ClearBuffer(r300, bits, NULL, rrbd); + COMMIT_BATCH(); } void r300Flush(GLcontext * ctx) -@@ -541,16 +555,12 @@ void r300Flush(GLcontext * ctx) - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); +@@ -538,302 +610,13 @@ void r300Flush(GLcontext * ctx) + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + +- if (rmesa->dma.flush) +- rmesa->dma.flush( rmesa ); ++ if (rmesa->swtcl.flush) { ++ rmesa->swtcl.flush(rmesa); ++ } - if (rmesa->cmdbuf.count_used > rmesa->cmdbuf.count_reemit) -+ if (rmesa->cmdbuf.committed > rmesa->cmdbuf.reemit) ++ if (rmesa->cmdbuf.cs->cdw) { r300FlushCmdBuf(rmesa, __FUNCTION__); - } - +-} +- -#ifdef USER_BUFFERS -#include "r300_mem.h" - - void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) - { +-void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) +-{ - struct r300_dma_buffer *dmabuf; - size = MAX2(size, RADEON_BUFFER_SIZE * 16); - - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) -@@ -560,216 +570,24 @@ void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) - rmesa->dma.flush(rmesa); - } - +- size = MAX2(size, RADEON_BUFFER_SIZE * 16); +- +- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) +- fprintf(stderr, "%s\n", __FUNCTION__); +- +- if (rmesa->dma.flush) { +- rmesa->dma.flush(rmesa); +- } +- - if (rmesa->dma.current.buf) { -#ifdef USER_BUFFERS - r300_mem_use(rmesa, rmesa->dma.current.buf->id); -#endif - r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__); -+ if (rmesa->dma.current) { -+ dri_bo_unreference(rmesa->dma.current); -+ rmesa->dma.current = 0; - } - if (rmesa->dma.nr_released_bufs > 4) - r300FlushCmdBuf(rmesa, __FUNCTION__); - +- } +- if (rmesa->dma.nr_released_bufs > 4) +- r300FlushCmdBuf(rmesa, __FUNCTION__); +- - dmabuf = CALLOC_STRUCT(r300_dma_buffer); - dmabuf->buf = (void *)1; /* hack */ - dmabuf->refcount = 1; @@ -2909,7 +3099,7 @@ index ee85e22..c3d0d72 100644 - r300_mem_free(rmesa, region->buf->id); - FREE(region->buf); - rmesa->dma.nr_released_bufs++; -- } + } - - region->buf = 0; - region->start = 0; @@ -3058,30 +3248,25 @@ index ee85e22..c3d0d72 100644 - - region->buf = 0; - region->start = 0; -+ rmesa->dma.current = dri_bo_alloc(rmesa->radeon.bufmgr, "DMA regions", -+ size, 4, DRM_BO_MEM_DMA); -+ rmesa->dma.current_used = 0; -+ rmesa->dma.current_vertexptr = 0; - } - - /* Allocates a region from rmesa->dma.current. If there isn't enough - * space in current, grab a new buffer (and discard what was left of current) - */ - void r300AllocDmaRegion(r300ContextPtr rmesa, +-} +- +-/* Allocates a region from rmesa->dma.current. If there isn't enough +- * space in current, grab a new buffer (and discard what was left of current) +- */ +-void r300AllocDmaRegion(r300ContextPtr rmesa, - struct r300_dma_region *region, -+ dri_bo **pbo, int *poffset, - int bytes, int alignment) - { - if (RADEON_DEBUG & DEBUG_IOCTL) -@@ -778,62 +596,23 @@ void r300AllocDmaRegion(r300ContextPtr rmesa, - if (rmesa->dma.flush) - rmesa->dma.flush(rmesa); - +- int bytes, int alignment) +-{ +- if (RADEON_DEBUG & DEBUG_IOCTL) +- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); +- +- if (rmesa->dma.flush) +- rmesa->dma.flush(rmesa); +- - if (region->buf) - r300ReleaseDmaRegion(rmesa, region, __FUNCTION__); -+ assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); - - alignment--; +- +- alignment--; - rmesa->dma.current.start = rmesa->dma.current.ptr = - (rmesa->dma.current.ptr + alignment) & ~alignment; - @@ -3098,8 +3283,7 @@ index ee85e22..c3d0d72 100644 - rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ - rmesa->dma.current.start = - rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; -+ rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; - +- - assert(rmesa->dma.current.ptr <= rmesa->dma.current.end); -} - @@ -3118,24 +3302,16 @@ index ee85e22..c3d0d72 100644 - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer, - valid); -+ if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) -+ r300RefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); - +- - return valid; -} -+ *poffset = rmesa->dma.current_used; -+ *pbo = rmesa->dma.current; -+ dri_bo_reference(*pbo); - +- -GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer) -{ - int offset = - (char *)pointer - - (char *)rmesa->radeon.radeonScreen->gartTextures.map; -+ /* Always align to at least 16 bytes */ -+ rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; -+ rmesa->dma.current_vertexptr = rmesa->dma.current_used; - +- - //fprintf(stderr, "offset=%08x\n", offset); - - if (offset < 0 @@ -3143,12 +3319,11 @@ index ee85e22..c3d0d72 100644 - return ~0; - else - return rmesa->radeon.radeonScreen->gart_texture_offset + offset; -+ assert(rmesa->dma.current_used <= rmesa->dma.current->size); } void r300InitIoctlFuncs(struct dd_function_table *functions) diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h -index e1143fb..c743478 100644 +index e1143fb..5f00264 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.h +++ b/src/mesa/drivers/dri/r300/r300_ioctl.h @@ -39,20 +39,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -3169,379 +3344,141 @@ index e1143fb..c743478 100644 extern void r300AllocDmaRegion(r300ContextPtr rmesa, - struct r300_dma_region *region, int bytes, - int alignment); -+ dri_bo **pbo, int *poffset, ++ struct radeon_bo **pbo, int *poffset, + int bytes, int alignment); extern void r300InitIoctlFuncs(struct dd_function_table *functions); diff --git a/src/mesa/drivers/dri/r300/r300_mem.c b/src/mesa/drivers/dri/r300/r300_mem.c -index f8f9d4f..3c0b055 100644 +deleted file mode 100644 +index f8f9d4f..0000000 --- a/src/mesa/drivers/dri/r300/r300_mem.c -+++ b/src/mesa/drivers/dri/r300/r300_mem.c -@@ -27,359 +27,955 @@ - - /** - * \file -+ * Simulate a real memory manager for R300 in the old-style scheme. -+ * -+ * NOTE: Right now, this is DMA-only and really only a skeleton of a true bufmgr. - * - * \author Aapo Tahkola - */ - -+#include "r300_mem.h" -+ -+#include - #include - ++++ /dev/null +@@ -1,385 +0,0 @@ +-/* +- * Copyright (C) 2005 Aapo Tahkola. +- * +- * All Rights Reserved. +- * +- * Permission is hereby granted, free of charge, to any person obtaining +- * a copy of this software and associated documentation files (the +- * "Software"), to deal in the Software without restriction, including +- * without limitation the rights to use, copy, modify, merge, publish, +- * distribute, sublicense, and/or sell copies of the Software, and to +- * permit persons to whom the Software is furnished to do so, subject to +- * the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial +- * portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- * +- */ +- +-/** +- * \file +- * +- * \author Aapo Tahkola +- */ +- +-#include +- -#include "r300_context.h" -#include "r300_cmdbuf.h" -#include "r300_ioctl.h" -#include "r300_mem.h" -+#include "main/simple_list.h" -+ -+#include "radeon_buffer.h" - #include "radeon_ioctl.h" -+#include "r300_cmdbuf.h" - +-#include "radeon_ioctl.h" +- -#ifdef USER_BUFFERS -+typedef struct _radeon_bufmgr_classic radeon_bufmgr_classic; -+typedef struct _radeon_bo_classic radeon_bo_classic; -+typedef struct _radeon_bo_functions radeon_bo_functions; -+typedef struct _radeon_reloc radeon_reloc; -+typedef struct _radeon_bo_vram radeon_bo_vram; -+ -+struct _radeon_bufmgr_classic { -+ dri_bufmgr base; -+ radeonScreenPtr screen; -+ r300ContextPtr rmesa; -+ -+ radeon_bo_classic *buffers; /** Unsorted linked list of all buffer objects */ -+ -+ radeon_bo_classic *pending; /** Age-sorted linked list of pending buffer objects */ -+ radeon_bo_classic **pending_tail; -+ -+ /* Texture heap bookkeeping */ -+ driTexHeap *texture_heap; -+ GLuint texture_offset; -+ driTextureObject texture_swapped; -+ -+ GLuint total_vram_used; -+}; -+ -+struct _radeon_reloc { -+ uint64_t flags; -+ GLuint offset; /**< Offset (in bytes) into command buffer to relocated dword */ -+ radeon_bo_classic *target; -+ GLuint delta; -+}; -+ -+struct _radeon_bo_functions { -+ /** -+ * Free a buffer object. Caller has verified that the object is not -+ * referenced or pending. -+ */ -+ void (*free)(radeon_bo_classic*); -+ -+ /** -+ * Validate the given buffer. Must set the validated flag to 1. -+ * -+ * May be null for buffer objects that are always valid. -+ * Always called with lock held. -+ * return -1 to restart validation -+ */ -+ int (*validate)(radeon_bo_classic*); -+ -+ /** -+ * Map the buffer for CPU access. -+ * Only called when the buffer isn't already mapped. -+ * -+ * May be null. -+ */ -+ void (*map)(radeon_bo_classic*, GLboolean write); -+ -+ /** -+ * Unmap the buffer. -+ * Only called on final unmap. -+ * -+ * May be null. -+ */ -+ void (*unmap)(radeon_bo_classic*); -+ -+ /** -+ * Indicate that the buffer object is now used by the hardware. -+ * -+ * May be null. -+ */ -+ void (*bind)(radeon_bo_classic*); -+ -+ /** -+ * Indicate that the buffer object is no longer used by the hardware. -+ * -+ * May be null. -+ */ -+ void (*unbind)(radeon_bo_classic*); -+}; - +- -static void resize_u_list(r300ContextPtr rmesa) -{ - void *temp; - int nsize; -+/** -+ * A buffer object. There are three types of buffer objects: -+ * 1. cmdbuf: Ordinary malloc()ed memory, used for command buffers -+ * 2. dma: GART memory allocated via the DRM_RADEON_ALLOC ioctl. -+ * 3. vram: Objects with malloc()ed backing store that will be uploaded -+ * into VRAM on demand; used for textures. -+ * There is a @ref functions table for operations that depend on the -+ * buffer object type. -+ * -+ * Fencing is handled the same way all buffer objects. During command buffer -+ * submission, the pending flag and corresponding variables are set accordingly. -+ */ -+struct _radeon_bo_classic { -+ dri_bo base; - +- - temp = rmesa->rmm->u_list; - nsize = rmesa->rmm->u_size * 2; -+ const radeon_bo_functions *functions; - +- - rmesa->rmm->u_list = _mesa_malloc(nsize * sizeof(*rmesa->rmm->u_list)); - _mesa_memset(rmesa->rmm->u_list, 0, - nsize * sizeof(*rmesa->rmm->u_list)); -+ radeon_bo_classic *next; /** Unsorted linked list of all buffer objects */ -+ radeon_bo_classic **pprev; - +- - if (temp) { - r300FlushCmdBuf(rmesa, __FUNCTION__); -+ /** -+ * Number of software references to this buffer. -+ * A buffer is freed automatically as soon as its reference count reaches 0 -+ * *and* it is no longer pending. -+ */ -+ unsigned int refcount; -+ unsigned int mapcount; /** mmap count; mutually exclusive to being pending */ - +- - _mesa_memcpy(rmesa->rmm->u_list, temp, - rmesa->rmm->u_size * sizeof(*rmesa->rmm->u_list)); - _mesa_free(temp); - } -+ unsigned int validated:1; /** whether the buffer is validated for hardware use right now */ -+ unsigned int used:1; /* only for communication between process_relocs and post_submit */ -+ -+ unsigned int pending:1; -+ unsigned int space_accounted:1; -+ radeon_bo_classic *pending_next; /** Age-sorted linked list of pending buffer objects */ -+ radeon_bo_classic **pending_pprev; -+ -+ /* The following two variables are intricately linked to the DRM interface, -+ * and must be in this physical memory order, or else chaos ensues. -+ * See the DRM's implementation of R300_CMD_SCRATCH for details. -+ */ -+ uint32_t pending_age; /** Buffer object pending until this age is reached, written by the DRM */ -+ uint32_t pending_count; /** Number of pending R300_CMD_SCRATCH references to this object */ -+ -+ radeon_reloc *relocs; /** Array of relocations in this buffer */ -+ GLuint relocs_used; /** # of relocations in relocation array */ -+ GLuint relocs_size; /** # of reloc records reserved in relocation array */ -+}; -+ -+typedef struct _radeon_vram_wrapper radeon_vram_wrapper; -+ -+/** Wrapper around heap object */ -+struct _radeon_vram_wrapper { -+ driTextureObject base; -+ radeon_bo_vram *bo; -+}; -+ -+struct _radeon_bo_vram { -+ radeon_bo_classic base; -+ -+ unsigned int backing_store_dirty:1; /** Backing store has changed, block must be reuploaded */ -+ -+ radeon_vram_wrapper *vram; /** Block in VRAM (if any) */ -+}; -+ -+static radeon_bufmgr_classic* get_bufmgr_classic(dri_bufmgr *bufmgr_ctx) -+{ -+ return (radeon_bufmgr_classic*)bufmgr_ctx; -+} -+ -+static radeon_bo_classic* get_bo_classic(dri_bo *bo_base) -+{ -+ return (radeon_bo_classic*)bo_base; -+} - +- - rmesa->rmm->u_size = nsize; -+static radeon_bo_vram* get_bo_vram(radeon_bo_classic *bo_base) -+{ -+ return (radeon_bo_vram*)bo_base; - } - +-} +- -void r300_mem_init(r300ContextPtr rmesa) -+/** -+ * Really free a given buffer object. -+ */ -+static void bo_free(radeon_bo_classic *bo) - { +-{ - rmesa->rmm = malloc(sizeof(struct r300_memory_manager)); - memset(rmesa->rmm, 0, sizeof(struct r300_memory_manager)); -+ assert(!bo->refcount); -+ assert(!bo->pending); -+ assert(!bo->mapcount); -+ -+ if (bo->relocs) { -+ int i; -+ for(i = 0; i < bo->relocs_used; ++i) -+ dri_bo_unreference(&bo->relocs[i].target->base); -+ free(bo->relocs); -+ bo->relocs = 0; -+ } - +- - rmesa->rmm->u_size = 128; - resize_u_list(rmesa); -+ *bo->pprev = bo->next; -+ if (bo->next) -+ bo->next->pprev = bo->pprev; -+ -+ bo->functions->free(bo); - } - +-} +- -void r300_mem_destroy(r300ContextPtr rmesa) -+ -+/** -+ * Keep track of which buffer objects are still pending, i.e. waiting for -+ * some hardware operation to complete. -+ */ -+static void track_pending_buffers(radeon_bufmgr_classic *bufmgr) - { +-{ - _mesa_free(rmesa->rmm->u_list); - rmesa->rmm->u_list = NULL; -+ uint32_t currentage = radeonGetAge((radeonContextPtr)bufmgr->rmesa); -+ -+ while(bufmgr->pending) { -+ radeon_bo_classic *bo = bufmgr->pending; -+ -+ assert(bo->pending); - +- - _mesa_free(rmesa->rmm); - rmesa->rmm = NULL; -+ if (bo->pending_count || -+ bo->pending_age > currentage) // TODO: Age counter wraparound! -+ break; -+ -+ bo->pending = 0; -+ bufmgr->pending = bo->pending_next; -+ if (bufmgr->pending) -+ bufmgr->pending->pending_pprev = &bufmgr->pending; -+ else -+ bufmgr->pending_tail = &bufmgr->pending; -+ -+ if (bo->functions->unbind) -+ (*bo->functions->unbind)(bo); -+ if (!bo->refcount) -+ bo_free(bo); -+ } - } - +-} +- -void *r300_mem_ptr(r300ContextPtr rmesa, int id) -+/** -+ * Initialize common buffer object data. -+ */ -+static void init_buffer(radeon_bufmgr_classic *bufmgr, radeon_bo_classic *bo, unsigned long size) - { +-{ - assert(id <= rmesa->rmm->u_last); - return rmesa->rmm->u_list[id].ptr; -+ bo->base.bufmgr = &bufmgr->base; -+ bo->base.size = size; -+ bo->refcount = 1; -+ -+ bo->pprev = &bufmgr->buffers; -+ bo->next = bufmgr->buffers; -+ if (bo->next) -+ bo->next->pprev = &bo->next; -+ bufmgr->buffers = bo; - } - +-} +- -int r300_mem_find(r300ContextPtr rmesa, void *ptr) -+ -+/** -+ * Free a DMA-based buffer. -+ */ -+static void dma_free(radeon_bo_classic *bo) - { +-{ - int i; -+ radeon_bufmgr_classic* bufmgr = get_bufmgr_classic(bo->base.bufmgr); -+ drm_radeon_mem_free_t memfree; -+ int ret; - +- - for (i = 1; i < rmesa->rmm->u_size + 1; i++) - if (rmesa->rmm->u_list[i].ptr && - ptr >= rmesa->rmm->u_list[i].ptr && - ptr < - rmesa->rmm->u_list[i].ptr + rmesa->rmm->u_list[i].size) - break; -+ memfree.region = RADEON_MEM_REGION_GART; -+ memfree.region_offset = bo->base.offset; -+ memfree.region_offset -= bufmgr->screen->gart_texture_offset; - +- - if (i < rmesa->rmm->u_size + 1) - return i; -+ ret = drmCommandWrite(bufmgr->screen->driScreen->fd, -+ DRM_RADEON_FREE, &memfree, sizeof(memfree)); -+ if (ret) { -+ fprintf(stderr, "Failed to free bo[%p] at %08x\n", bo, memfree.region_offset); -+ fprintf(stderr, "ret = %s\n", strerror(-ret)); -+ exit(1); -+ } - +- - fprintf(stderr, "%p failed\n", ptr); - return 0; -+ free(bo); - } - +-} +- -//#define MM_DEBUG -int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size) -+static const radeon_bo_functions dma_bo_functions = { -+ .free = &dma_free -+}; -+ -+/** -+ * Call the DRM to allocate GART memory for the given (incomplete) -+ * buffer object. -+ */ -+static int try_dma_alloc(radeon_bufmgr_classic *bufmgr, radeon_bo_classic *bo, -+ unsigned long size, unsigned int alignment) - { - drm_radeon_mem_alloc_t alloc; +-{ +- drm_radeon_mem_alloc_t alloc; - int offset = 0, ret; - int i, free = -1; - int done_age; - drm_radeon_mem_free_t memfree; - int tries = 0; - static int bytes_wasted = 0, allocated = 0; -+ int baseoffset; -+ int ret; - +- - if (size < 4096) - bytes_wasted += 4096 - size; -+ alloc.region = RADEON_MEM_REGION_GART; -+ alloc.alignment = alignment; -+ alloc.size = size; -+ alloc.region_offset = &baseoffset; - +- - allocated += size; -+ ret = drmCommandWriteRead(bufmgr->screen->driScreen->fd, -+ DRM_RADEON_ALLOC, &alloc, sizeof(alloc)); -+ if (ret) { -+ if (RADEON_DEBUG & DEBUG_MEMORY) -+ fprintf(stderr, "DRM_RADEON_ALLOC failed: %d\n", ret); -+ return 0; -+ } -+ -+ bo->base.virtual = (char*)bufmgr->screen->gartTextures.map + baseoffset; -+ bo->base.offset = bufmgr->screen->gart_texture_offset + baseoffset; - +- -#if 0 - static int t = 0; - if (t != time(NULL)) { @@ -3549,76 +3486,24 @@ index f8f9d4f..3c0b055 100644 - fprintf(stderr, "slots used %d, wasted %d kb, allocated %d\n", - rmesa->rmm->u_last, bytes_wasted / 1024, - allocated / 1024); -+ return 1; -+} -+ -+/** -+ * Allocate a DMA buffer. -+ */ -+static dri_bo *dma_alloc(radeon_bufmgr_classic *bufmgr, const char *name, -+ unsigned long size, unsigned int alignment) -+{ -+ radeon_bo_classic* bo = (radeon_bo_classic*)calloc(1, sizeof(radeon_bo_classic)); -+ -+ bo->functions = &dma_bo_functions; -+ -+ track_pending_buffers(bufmgr); -+ if (!try_dma_alloc(bufmgr, bo, size, alignment)) { -+ if (RADEON_DEBUG & DEBUG_MEMORY) -+ fprintf(stderr, "Failed to allocate %ld bytes, finishing command buffer...\n", size); -+ radeonFinish(bufmgr->rmesa->radeon.glCtx); -+ track_pending_buffers(bufmgr); -+ if (!try_dma_alloc(bufmgr, bo, size, alignment)) { -+ WARN_ONCE( -+ "Ran out of GART memory (for %ld)!\n" -+ "Please consider adjusting GARTSize option.\n", -+ size); -+ free(bo); -+ return 0; -+ } - } +- } -#endif - +- - memfree.region = RADEON_MEM_REGION_GART; -+ init_buffer(bufmgr, bo, size); -+ bo->validated = 1; /* DMA buffer offsets are always valid */ - +- - again: -+ return &bo->base; -+} - +- - done_age = radeonGetAge((radeonContextPtr) rmesa); -+/** -+ * Free a command buffer -+ */ -+static void cmdbuf_free(radeon_bo_classic *bo) -+{ -+ free(bo->base.virtual); -+ free(bo); -+} - +- - if (rmesa->rmm->u_last + 1 >= rmesa->rmm->u_size) - resize_u_list(rmesa); -+static const radeon_bo_functions cmdbuf_bo_functions = { -+ .free = cmdbuf_free -+}; - +- - for (i = rmesa->rmm->u_last + 1; i > 0; i--) { - if (rmesa->rmm->u_list[i].ptr == NULL) { - free = i; - continue; - } -+/** -+ * Allocate a command buffer. -+ * -+ * Command buffers are really just malloc'ed buffers. They are managed by -+ * the bufmgr to enable relocations. -+ */ -+static dri_bo *cmdbuf_alloc(radeon_bufmgr_classic *bufmgr, const char *name, -+ unsigned long size) -+{ -+ radeon_bo_classic* bo = (radeon_bo_classic*)calloc(1, sizeof(radeon_bo_classic)); - +- - if (rmesa->rmm->u_list[i].h_pending == 0 && - rmesa->rmm->u_list[i].pending - && rmesa->rmm->u_list[i].age <= done_age) { @@ -3626,17 +3511,12 @@ index f8f9d4f..3c0b055 100644 - (char *)rmesa->rmm->u_list[i].ptr - - (char *)rmesa->radeon.radeonScreen->gartTextures. - map; -+ bo->functions = &cmdbuf_bo_functions; -+ bo->base.virtual = malloc(size); - +- - ret = - drmCommandWrite(rmesa->radeon.radeonScreen-> - driScreen->fd, DRM_RADEON_FREE, - &memfree, sizeof(memfree)); -+ init_buffer(bufmgr, bo, size); -+ return &bo->base; -+} - +- - if (ret) { - fprintf(stderr, "Failed to free at %p\n", - rmesa->rmm->u_list[i].ptr); @@ -3659,54 +3539,9 @@ index f8f9d4f..3c0b055 100644 - rmesa->rmm->u_list[i].pending = 0; - rmesa->rmm->u_list[i].ptr = NULL; - free = i; -+/** -+ * Free a VRAM-based buffer object. -+ */ -+static void vram_free(radeon_bo_classic *bo_base) -+{ -+ radeon_bo_vram *bo = get_bo_vram(bo_base); -+ -+ if (bo->vram) { -+ driDestroyTextureObject(&bo->vram->base); -+ bo->vram = 0; -+ } -+ -+ free(bo->base.base.virtual); -+ free(bo); -+} -+ -+/** -+ * Allocate/update the copy in vram. -+ * -+ * Note: Assume we're called with the DRI lock held. -+ */ -+static int vram_validate(radeon_bo_classic *bo_base) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo_base->base.bufmgr); -+ radeon_bo_vram *bo = get_bo_vram(bo_base); -+ int retry_count = 0, pending_retry = 0; -+ -+ track_pending_buffers(bufmgr); -+ if (!bo->vram) { -+ bo->backing_store_dirty = 1; -+ bo->vram = (radeon_vram_wrapper*)calloc(1, sizeof(radeon_vram_wrapper)); -+ bo->vram->bo = bo; -+ make_empty_list(&bo->vram->base); -+ bo->vram->base.totalSize = bo->base.base.size; -+retry: -+ if (driAllocateTexture(&bufmgr->texture_heap, 1, &bo->vram->base) < 0) { -+ pending_retry = 0; -+ while(bufmgr->pending && pending_retry++ < 10000) -+ track_pending_buffers(bufmgr); -+ retry_count++; -+ if (retry_count > 2) { -+ free(bo->vram); -+ bo->vram = NULL; -+ return -1; - } -+ goto retry; - } - } +- } +- } +- } - rmesa->rmm->u_head = i; - - if (free == -1) { @@ -3717,64 +3552,15 @@ index f8f9d4f..3c0b055 100644 - if (tries > 100) { - WARN_ONCE("Ran out of slots!\n"); - exit(1); -+ -+ assert(bo->vram->base.memBlock); -+ -+ bo->base.base.offset = bufmgr->texture_offset + bo->vram->base.memBlock->ofs; -+ -+ if (bo->backing_store_dirty) { -+ /* Copy to VRAM using a blit. -+ * All memory is 4K aligned. We're using 1024 pixels wide blits. -+ */ -+ drm_radeon_texture_t tex; -+ drm_radeon_tex_image_t tmp; -+ int ret; -+ -+ tex.offset = bo->base.base.offset; -+ tex.image = &tmp; -+ -+ assert(!(tex.offset & 1023)); -+ -+ tmp.x = 0; -+ tmp.y = 0; -+ if (bo->base.base.size < 4096) { -+ tmp.width = (bo->base.base.size + 3) / 4; -+ tmp.height = 1; -+ } else { -+ tmp.width = 1024; -+ tmp.height = (bo->base.base.size + 4095) / 4096; - } +- } - goto again; -+ tmp.data = bo->base.base.virtual; -+ -+ tex.format = RADEON_TXFORMAT_ARGB8888; -+ tex.width = tmp.width; -+ tex.height = tmp.height; -+ tex.pitch = MAX2(tmp.width / 16, 1); -+ -+ do { -+ ret = drmCommandWriteRead(bufmgr->screen->driScreen->fd, -+ DRM_RADEON_TEXTURE, &tex, -+ sizeof(drm_radeon_texture_t)); -+ if (ret) { -+ if (RADEON_DEBUG & DEBUG_IOCTL) -+ fprintf(stderr, -+ "DRM_RADEON_TEXTURE: again!\n"); -+ usleep(1); -+ } -+ } while (ret == -EAGAIN); -+ -+ bo->backing_store_dirty = 0; - } - +- } +- - alloc.region = RADEON_MEM_REGION_GART; - alloc.alignment = alignment; - alloc.size = size; - alloc.region_offset = &offset; -+ bo->base.validated = 1; -+ return 0; -+} - +- - ret = - drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc, - sizeof(alloc)); @@ -3796,119 +3582,41 @@ index f8f9d4f..3c0b055 100644 - size); - return 0; -#endif -+/* No need for actual mmap actions since we have backing store, -+ * but mark buffer dirty when necessary */ -+static void vram_map(radeon_bo_classic *bo_base, GLboolean write) -+{ -+ radeon_bo_vram *bo = get_bo_vram(bo_base); -+ -+ if (write) { -+ bo->base.validated = 0; -+ bo->backing_store_dirty = 1; - } -+} -+ -+static void vram_bind(radeon_bo_classic *bo_base) -+{ -+ radeon_bo_vram *bo = get_bo_vram(bo_base); - +- } +- - i = free; -+ if (bo->vram) { -+ bo->vram->base.bound = 1; -+ driUpdateTextureLRU(&bo->vram->base); -+ } -+} - +- - if (i > rmesa->rmm->u_last) - rmesa->rmm->u_last = i; -+static void vram_unbind(radeon_bo_classic *bo_base) -+{ -+ radeon_bo_vram *bo = get_bo_vram(bo_base); - +- - rmesa->rmm->u_list[i].ptr = - ((GLubyte *) rmesa->radeon.radeonScreen->gartTextures.map) + offset; - rmesa->rmm->u_list[i].size = size; - rmesa->rmm->u_list[i].age = 0; - //fprintf(stderr, "alloc %p at id %d\n", rmesa->rmm->u_list[i].ptr, i); -+ if (bo->vram) -+ bo->vram->base.bound = 0; -+} - +- -#ifdef MM_DEBUG - fprintf(stderr, "allocated %d at age %x\n", i, - radeonGetAge((radeonContextPtr) rmesa)); -#endif -+/** Callback function called by the texture heap when a texture is evicted */ -+static void destroy_vram_wrapper(void *data, driTextureObject *t) -+{ -+ radeon_vram_wrapper *wrapper = (radeon_vram_wrapper*)t; - +- - return i; -+ if (wrapper->bo && wrapper->bo->vram == wrapper) { -+ wrapper->bo->base.validated = 0; -+ wrapper->bo->vram = 0; -+ } - } - +-} +- -void r300_mem_use(r300ContextPtr rmesa, int id) -+static const radeon_bo_functions vram_bo_functions = { -+ .free = vram_free, -+ .validate = vram_validate, -+ .map = vram_map, -+ .bind = vram_bind, -+ .unbind = vram_unbind -+}; -+ -+/** -+ * Free a VRAM-based buffer object. -+ */ -+static void static_free(radeon_bo_classic *bo_base) - { +-{ - uint64_t ull; -#ifdef MM_DEBUG - fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, - radeonGetAge((radeonContextPtr) rmesa)); -#endif - drm_r300_cmd_header_t *cmd; -+ radeon_bo_vram *bo = get_bo_vram(bo_base); - +- - assert(id <= rmesa->rmm->u_last); -+ free(bo); -+} - +- - if (id == 0) - return; -+static void static_map(radeon_bo_classic *bo_base, GLboolean write) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo_base->base.bufmgr); -+ -+ /* don't map static for kernel mm - we have hardcoded maps */ -+ if (!bufmgr->screen->kernel_mm) -+ bo_base->base.virtual = bufmgr->screen->driScreen->pFB + -+ (bo_base->base.offset - bufmgr->screen->fbLocation); -+ -+ /* Read the first pixel in the frame buffer. This should -+ * be a noop, right? In fact without this conform fails as reading -+ * from the framebuffer sometimes produces old results -- the -+ * on-card read cache gets mixed up and doesn't notice that the -+ * framebuffer has been updated. -+ * -+ * Note that we should probably be reading some otherwise unused -+ * region of VRAM, otherwise we might get incorrect results when -+ * reading pixels from the top left of the screen. -+ * -+ * I found this problem on an R420 with glean's texCube test. -+ * Note that the R200 span code also *writes* the first pixel in the -+ * framebuffer, but I've found this to be unnecessary. -+ * -- Nicolai Hähnle, June 2008 -+ */ -+ { -+ int p; -+ volatile int *buf = (int*)bufmgr->screen->driScreen->pFB; -+ p = *buf; -+ } -+} - +- - cmd = - (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, - 2 + sizeof(ull) / 4, @@ -3918,476 +3626,129 @@ index f8f9d4f..3c0b055 100644 - cmd[0].scratch.n_bufs = 1; - cmd[0].scratch.flags = 0; - cmd++; -+static void static_unmap(radeon_bo_classic *bo_base) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo_base->base.bufmgr); -+ /* don't unmap for kernel mm we have hardcoded maps */ -+ if (!bufmgr->screen->kernel_mm) -+ bo_base->base.virtual = 0; -+} - +- - ull = (uint64_t) (intptr_t) & rmesa->rmm->u_list[id].age; - _mesa_memcpy(cmd, &ull, sizeof(ull)); - cmd += sizeof(ull) / 4; -+static const radeon_bo_functions static_bo_functions = { -+ .free = static_free, -+ .map = static_map, -+ .unmap = static_unmap -+}; - +- - cmd[0].u = /*id */ 0; -+/** -+ * Allocate a backing store buffer object that is validated into VRAM. -+ */ -+static dri_bo *vram_alloc(radeon_bufmgr_classic *bufmgr, const char *name, -+ unsigned long size, unsigned int alignment) -+{ -+ radeon_bo_vram* bo = (radeon_bo_vram*)calloc(1, sizeof(radeon_bo_vram)); -+ uint32_t pgsize = getpagesize() - 1; -+ -+ size = (size + pgsize) & ~pgsize; -+ /* round size up to page size */ -+ bo->base.functions = &vram_bo_functions; -+ bo->base.base.virtual = malloc(size); -+ init_buffer(bufmgr, &bo->base, size); -+ return &bo->base.base; -+} - +- - LOCK_HARDWARE(&rmesa->radeon); /* Protect from DRM. */ - rmesa->rmm->u_list[id].h_pending++; - UNLOCK_HARDWARE(&rmesa->radeon); -+dri_bo *radeon_bufmgr_classic_bo_alloc(dri_bufmgr *bufmgr_ctx, const char *name, -+ unsigned long size, unsigned int alignment, -+ uint64_t location_mask) -+{ -+ radeon_bufmgr_classic* bufmgr = get_bufmgr_classic(bufmgr_ctx); -+ -+ if (location_mask & DRM_BO_MEM_CMDBUF) { -+ return cmdbuf_alloc(bufmgr, name, size); -+ } else if (location_mask & DRM_BO_MEM_DMA) { -+ return dma_alloc(bufmgr, name, size, alignment); -+ } else { -+ return vram_alloc(bufmgr, name, size, alignment); -+ } - } - +-} +- -unsigned long r300_mem_offset(r300ContextPtr rmesa, int id) -+static dri_bo *bufmgr_classic_bo_alloc_static(dri_bufmgr *bufmgr_ctx, const char *name, -+ unsigned long offset, unsigned long size, -+ void *virtual, uint64_t location_mask) - { +-{ - unsigned long offset; -+ radeon_bufmgr_classic* bufmgr = get_bufmgr_classic(bufmgr_ctx); -+ radeon_bo_vram* bo = (radeon_bo_vram*)calloc(1, sizeof(radeon_bo_vram)); - +- - assert(id <= rmesa->rmm->u_last); -+ bo->base.functions = &static_bo_functions; -+ bo->base.base.virtual = virtual; -+ bo->base.base.offset = offset + bufmgr->screen->fbLocation; -+ bo->base.validated = 1; /* Static buffer offsets are always valid */ - +- - offset = (char *)rmesa->rmm->u_list[id].ptr - - (char *)rmesa->radeon.radeonScreen->gartTextures.map; - offset += rmesa->radeon.radeonScreen->gart_texture_offset; -+ init_buffer(bufmgr, &bo->base, size); -+ return &bo->base.base; - +- - return offset; - } - +-} +- -void *r300_mem_map(r300ContextPtr rmesa, int id, int access) -+static void bufmgr_classic_bo_reference(dri_bo *bo_base) - { +-{ -#ifdef MM_DEBUG - fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, - radeonGetAge((radeonContextPtr) rmesa)); -#endif - void *ptr; - int tries = 0; -+ radeon_bo_classic *bo = get_bo_classic(bo_base); -+ bo->refcount++; -+ assert(bo->refcount > 0); -+} -+ -+static void bufmgr_classic_bo_unreference(dri_bo *bo_base) -+{ -+ radeon_bo_classic *bo = get_bo_classic(bo_base); -+ -+ if (!bo_base) -+ return; -+ -+ assert(bo->refcount > 0); -+ bo->refcount--; -+ if (!bo->refcount) { -+ // Ugly HACK - figure out whether this is really necessary -+ get_bufmgr_classic(bo_base->bufmgr)->rmesa->dma.nr_released_bufs++; -+ -+ assert(!bo->mapcount); -+ if (!bo->pending) -+ bo_free(bo); -+ } -+} -+ -+static int bufmgr_classic_bo_map(dri_bo *bo_base, int write_enable) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo_base->bufmgr); -+ radeon_bo_classic *bo = get_bo_classic(bo_base); -+ assert(bo->refcount > 0); -+ -+ if (bo->pending) { -+ track_pending_buffers(bufmgr); -+ if (bo->pending) { -+ // TODO: Better fence waiting -+ if (RADEON_DEBUG & DEBUG_MEMORY) -+ fprintf(stderr, "bo_map: buffer is pending. Flushing...\n"); -+ radeonFinish(bufmgr->rmesa->radeon.glCtx); -+ track_pending_buffers(bufmgr); -+ if (bo->pending) { -+ fprintf(stderr, "Internal error or hardware lockup: bo_map: buffer is still pending.\n"); -+ abort(); -+ } -+ } -+ } - +- - assert(id <= rmesa->rmm->u_last); -+ if (!bo->mapcount && bo->functions->map) -+ bo->functions->map(bo, write_enable); - +- - if (access == R300_MEM_R) { -+ bo->mapcount++; -+ assert(bo->mapcount > 0); -+ return 0; -+} - +- - if (rmesa->rmm->u_list[id].mapped == 1) - WARN_ONCE("buffer %d already mapped\n", id); -+static int bufmgr_classic_bo_unmap(dri_bo *buf) -+{ -+ radeon_bo_classic *bo = get_bo_classic(buf); -+ assert(bo->refcount > 0); -+ assert(bo->mapcount > 0); -+ bo->mapcount--; - +- - rmesa->rmm->u_list[id].mapped = 1; - ptr = r300_mem_ptr(rmesa, id); -+ if (!bo->mapcount && bo->functions->unmap) -+ bo->functions->unmap(bo); - +- - return ptr; -+ return 0; -+} -+ -+/** -+ * Mark the given buffer as pending and move it to the tail -+ * of the pending list. -+ * The caller is responsible for setting up pending_count and pending_age. -+ */ -+static void move_to_pending_tail(radeon_bo_classic *bo) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo->base.bufmgr); -+ -+ if (bo->pending) { -+ *bo->pending_pprev = bo->pending_next; -+ if (bo->pending_next) -+ bo->pending_next->pending_pprev = bo->pending_pprev; -+ else -+ bufmgr->pending_tail = bo->pending_pprev; - } - +- } +- - if (rmesa->rmm->u_list[id].h_pending) - r300FlushCmdBuf(rmesa, __FUNCTION__); -+ bo->pending = 1; -+ bo->pending_pprev = bufmgr->pending_tail; -+ bo->pending_next = 0; -+ *bufmgr->pending_tail = bo; -+ bufmgr->pending_tail = &bo->pending_next; -+} -+ -+/** -+ * Emit commands to the batch buffer that cause the guven buffer's -+ * pending_count and pending_age to be updated. -+ */ -+static void emit_age_for_buffer(radeon_bo_classic* bo) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo->base.bufmgr); -+ BATCH_LOCALS(bufmgr->rmesa); -+ drm_r300_cmd_header_t cmd; -+ uint64_t ull; -+ -+ cmd.scratch.cmd_type = R300_CMD_SCRATCH; -+ cmd.scratch.reg = 2; /* Scratch register 2 corresponds to what radeonGetAge polls */ -+ cmd.scratch.n_bufs = 1; -+ cmd.scratch.flags = 0; -+ ull = (uint64_t) (intptr_t) &bo->pending_age; -+ -+ BEGIN_BATCH(4); -+ OUT_BATCH(cmd.u); -+ OUT_BATCH(ull & 0xffffffff); -+ OUT_BATCH(ull >> 32); -+ OUT_BATCH(0); -+ END_BATCH(); -+ COMMIT_BATCH(); -+ -+ bo->pending_count++; -+} - +- - if (rmesa->rmm->u_list[id].h_pending) { - return NULL; -+static int bufmgr_classic_emit_reloc(dri_bo *batch_buf, uint64_t flags, GLuint delta, -+ GLuint offset, dri_bo *target) -+{ -+ radeon_bo_classic *bo = get_bo_classic(batch_buf); -+ radeon_reloc *reloc; -+ -+ if (bo->relocs_used >= bo->relocs_size) { -+ bo->relocs_size *= 2; -+ if (bo->relocs_size < 32) -+ bo->relocs_size = 32; -+ -+ bo->relocs = (radeon_reloc*)realloc(bo->relocs, bo->relocs_size*sizeof(radeon_reloc)); - } - +- } +- - while (rmesa->rmm->u_list[id].age > - radeonGetAge((radeonContextPtr) rmesa) && tries++ < 1000) - usleep(10); -+ reloc = &bo->relocs[bo->relocs_used++]; -+ reloc->flags = flags; -+ reloc->offset = offset; -+ reloc->delta = delta; -+ reloc->target = get_bo_classic(target); -+ dri_bo_reference(target); -+ return 0; -+} - +- - if (tries >= 1000) { - fprintf(stderr, "Idling failed (%x vs %x)\n", - rmesa->rmm->u_list[id].age, - radeonGetAge((radeonContextPtr) rmesa)); - return NULL; -+static void bufmgr_kick_all_buffers(radeon_bufmgr_classic *bufmgr) -+{ -+ radeon_bo_classic *bo; -+ -+ bo = bufmgr->buffers; -+ while(bo) { -+ if (bo->functions == &vram_bo_functions) { -+ radeon_bo_vram *bo_vram = get_bo_vram(bo); -+ if (bo->validated) { -+ driDestroyTextureObject(&bo_vram->vram->base); -+ bo_vram->vram = 0; -+ bo->validated = 0; -+ } -+ } -+ bo = bo->next; - } -+} - +- } +- - if (rmesa->rmm->u_list[id].mapped == 1) - WARN_ONCE("buffer %d already mapped\n", id); -+/* process_relocs is called just before the given command buffer -+ * is executed. It ensures that all referenced buffers are in -+ * the right GPU domain. -+ */ -+static void *bufmgr_classic_process_relocs(dri_bo *batch_buf) -+{ -+ radeon_bo_classic *batch_bo = get_bo_classic(batch_buf); -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(batch_bo->base.bufmgr); -+ int i; -+ int ret = 0; -+ int retries = 0; -+ -+ // Warning: At this point, we append something to the batch buffer -+ // during flush. -+ emit_age_for_buffer(batch_bo); -+ -+ dri_bo_map(batch_buf, GL_TRUE); -+ -+restart: -+ for(i = 0; i < batch_bo->relocs_used; ++i) { -+ radeon_reloc *reloc = &batch_bo->relocs[i]; -+ uint32_t *dest = (uint32_t*)((char*)batch_buf->virtual + reloc->offset); -+ uint32_t offset; -+ -+ ret = 0; -+ if (!reloc->target->validated) -+ ret = reloc->target->functions->validate(reloc->target); -+ -+ if (ret == -1) { -+ track_pending_buffers(bufmgr); -+ /* seriously not afraid of the police */ -+ bufmgr_kick_all_buffers(bufmgr); -+ retries++; -+ if (retries == 2) { -+ fprintf(stderr,"r300: Failed to get relocations into aperture\n"); -+ exit(-1); -+ } -+ goto restart; -+ } - +- - rmesa->rmm->u_list[id].mapped = 1; - ptr = r300_mem_ptr(rmesa, id); -+ reloc->target->used = 1; -+ offset = reloc->target->base.offset + reloc->delta; - +- - return ptr; -+ if (reloc->flags & DRM_RELOC_BLITTER) -+ *dest = (*dest & 0xffc00000) | (offset >> 10); -+ else if (reloc->flags & DRM_RELOC_TXOFFSET) -+ *dest = (*dest & 31) | (offset & ~31); -+ else -+ *dest = offset; -+ } -+ dri_bo_unmap(batch_buf); -+ return 0; - } - +-} +- -void r300_mem_unmap(r300ContextPtr rmesa, int id) -+/* post_submit is called just after the given command buffer -+ * is executed. It ensures that buffers are properly marked as -+ * pending. -+ */ -+static void bufmgr_classic_post_submit(dri_bo *batch_buf) - { +-{ -#ifdef MM_DEBUG - fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, - radeonGetAge((radeonContextPtr) rmesa)); -#endif -+ radeon_bo_classic *batch_bo = get_bo_classic(batch_buf); -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(batch_bo->base.bufmgr); -+ int i; - +- - assert(id <= rmesa->rmm->u_last); -+ assert(!batch_bo->pending_count); - +- - if (rmesa->rmm->u_list[id].mapped == 0) - WARN_ONCE("buffer %d not mapped\n", id); -+ for(i = 0; i < batch_bo->relocs_used; ++i) { -+ radeon_reloc *reloc = &batch_bo->relocs[i]; - +- - rmesa->rmm->u_list[id].mapped = 0; -+ if (reloc->target->used) { -+ reloc->target->used = 0; -+ assert(!reloc->target->pending_count); -+ reloc->target->pending_age = batch_bo->pending_age; -+ move_to_pending_tail(reloc->target); -+ if (reloc->target->functions->bind) -+ (*reloc->target->functions->bind)(reloc->target); -+ } -+ if (reloc->target->space_accounted) -+ reloc->target->space_accounted = 0; -+ } -+ bufmgr->total_vram_used = 0; - } - +-} +- -void r300_mem_free(r300ContextPtr rmesa, int id) -+static void bufmgr_classic_destroy(dri_bufmgr *bufmgr_ctx) - { +-{ -#ifdef MM_DEBUG - fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, - radeonGetAge((radeonContextPtr) rmesa)); -#endif -+ radeon_bufmgr_classic* bufmgr = get_bufmgr_classic(bufmgr_ctx); -+ -+ track_pending_buffers(bufmgr); -+ if (bufmgr->pending) -+ radeonFinish(bufmgr->rmesa->radeon.glCtx); -+ track_pending_buffers(bufmgr); -+ -+ if (bufmgr->buffers) { -+ //fprintf(stderr, "Warning: Buffer objects have leaked\n"); -+ while(bufmgr->buffers) { -+ // fprintf(stderr, " Leak of size %ld\n", bufmgr->buffers->base.size); -+ bufmgr->buffers->refcount = 0; -+ bufmgr->buffers->mapcount = 0; -+ bufmgr->buffers->pending = 0; -+ bo_free(bufmgr->buffers); -+ } -+ } - +- - assert(id <= rmesa->rmm->u_last); -+ driDestroyTextureHeap(bufmgr->texture_heap); -+ bufmgr->texture_heap = 0; -+ assert(is_empty_list(&bufmgr->texture_swapped)); - +- - if (id == 0) - return; -+ free(bufmgr); -+} - +- - if (rmesa->rmm->u_list[id].ptr == NULL) { - WARN_ONCE("Not allocated!\n"); - return; -+static int bufmgr_check_aperture_space(dri_bo *buf) -+{ -+ radeon_bo_classic *bo = get_bo_classic(buf); -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bo->base.bufmgr); -+ if (bo->space_accounted == 0) { -+ bo->space_accounted = 1; -+ if (bo->functions == &vram_bo_functions) { -+ bufmgr->total_vram_used += bo->base.size; -+ } - } - +- } +- - if (rmesa->rmm->u_list[id].pending) { - WARN_ONCE("%p already pended!\n", rmesa->rmm->u_list[id].ptr); - return; -+ if (bufmgr->total_vram_used >= bufmgr->texture_heap->size) { -+ bufmgr->total_vram_used -= bo->base.size; -+ bo->space_accounted = 0; -+ return -1; - } - +- } +- - rmesa->rmm->u_list[id].pending = 1; -+ return 0; -+} -+ -+dri_bufmgr* radeonBufmgrClassicInit(r300ContextPtr rmesa) -+{ -+ radeon_bufmgr_classic* bufmgr = (radeon_bufmgr_classic*)calloc(1, sizeof(radeon_bufmgr_classic)); -+ -+ bufmgr->screen = rmesa->radeon.radeonScreen; -+ bufmgr->rmesa = rmesa; -+ bufmgr->base.bo_alloc = &radeon_bufmgr_classic_bo_alloc; -+ bufmgr->base.bo_alloc_static = bufmgr_classic_bo_alloc_static; -+ bufmgr->base.bo_reference = &bufmgr_classic_bo_reference; -+ bufmgr->base.bo_unreference = &bufmgr_classic_bo_unreference; -+ bufmgr->base.bo_map = &bufmgr_classic_bo_map; -+ bufmgr->base.bo_unmap = &bufmgr_classic_bo_unmap; -+ bufmgr->base.emit_reloc = &bufmgr_classic_emit_reloc; -+ bufmgr->base.process_relocs = &bufmgr_classic_process_relocs; -+ bufmgr->base.post_submit = &bufmgr_classic_post_submit; -+ bufmgr->base.destroy = &bufmgr_classic_destroy; -+ bufmgr->base.check_aperture_space = &bufmgr_check_aperture_space; -+ bufmgr->pending_tail = &bufmgr->pending; -+ -+ /* Init texture heap */ -+ make_empty_list(&bufmgr->texture_swapped); -+ bufmgr->texture_heap = driCreateTextureHeap(0, bufmgr, -+ bufmgr->screen->texSize[0], 12, RADEON_NR_TEX_REGIONS, -+ (drmTextureRegionPtr)rmesa->radeon.sarea->tex_list[0], -+ &rmesa->radeon.sarea->tex_age[0], -+ &bufmgr->texture_swapped, sizeof(radeon_vram_wrapper), -+ &destroy_vram_wrapper); -+ bufmgr->texture_offset = bufmgr->screen->texOffset[0]; -+ -+ return &bufmgr->base; -+} -+ -+void radeonBufmgrContendedLockTake(dri_bufmgr* bufmgr_ctx) -+{ -+ radeon_bufmgr_classic *bufmgr = get_bufmgr_classic(bufmgr_ctx); -+ -+ DRI_AGE_TEXTURES(bufmgr->texture_heap); - } +-} -#endif diff --git a/src/mesa/drivers/dri/r300/r300_mem.h b/src/mesa/drivers/dri/r300/r300_mem.h -index 625a7f6..a6788a8 100644 +deleted file mode 100644 +index 625a7f6..0000000 --- a/src/mesa/drivers/dri/r300/r300_mem.h -+++ b/src/mesa/drivers/dri/r300/r300_mem.h -@@ -1,37 +1,22 @@ - #ifndef __R300_MEM_H__ - #define __R300_MEM_H__ - ++++ /dev/null +@@ -1,37 +0,0 @@ +-#ifndef __R300_MEM_H__ +-#define __R300_MEM_H__ +- -//#define R300_MEM_PDL 0 -#define R300_MEM_UL 1 - @@ -4420,31 +3781,14 @@ index 625a7f6..a6788a8 100644 -extern void *r300_mem_map(r300ContextPtr rmesa, int id, int access); -extern void r300_mem_unmap(r300ContextPtr rmesa, int id); -extern void r300_mem_free(r300ContextPtr rmesa, int id); -+#include "main/glheader.h" -+ -+#include "r300_context.h" -+ -+ -+/* Note: The following flags should probably be ultimately eliminated, -+ * or replaced by something else. -+ */ -+#define DRM_BO_MEM_DMA (1 << 27) /** Use for transient buffers (texture upload, vertex buffers...) */ -+#define DRM_BO_MEM_CMDBUF (1 << 28) /** Use for command buffers */ -+ -+#define DRM_RELOC_BLITTER (1 << 23) /** Offset overwrites lower 22 bits (used with blit packet3) */ -+#define DRM_RELOC_TXOFFSET (1 << 24) /** Offset overwrites everything but low bits (used for texture offsets) */ -+ -+dri_bufmgr* radeonBufmgrClassicInit(r300ContextPtr rmesa); -+void radeonBufmgrContendedLockTake(dri_bufmgr* bufmgr_ctx); -+ - - #endif +- +-#endif diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.c b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c new file mode 100644 -index 0000000..49fc161 +index 0000000..097f9cd --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c -@@ -0,0 +1,317 @@ +@@ -0,0 +1,319 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * @@ -4482,7 +3826,6 @@ index 0000000..49fc161 +#include "main/texformat.h" + +#include "radeon_buffer.h" -+#include "r300_mem.h" + +static GLuint r300_compressed_texture_size(GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, @@ -4611,7 +3954,10 @@ index 0000000..49fc161 + + calculate_miptree_layout(mt); + -+ mt->bo = dri_bo_alloc(rmesa->radeon.bufmgr, "texture", mt->totalsize, 1024, 0); ++ mt->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, ++ 0, mt->totalsize, 1024, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); + + return mt; +} @@ -4630,7 +3976,7 @@ index 0000000..49fc161 + assert(mt->refcount > 0); + mt->refcount--; + if (!mt->refcount) { -+ dri_bo_unreference(mt->bo); ++ radeon_bo_unref(mt->bo); + free(mt); + } +} @@ -4764,7 +4110,7 @@ index 0000000..49fc161 +} diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.h b/src/mesa/drivers/dri/r300/r300_mipmap_tree.h new file mode 100644 -index 0000000..7705a4d +index 0000000..aeb52dc --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_mipmap_tree.h @@ -0,0 +1,97 @@ @@ -4829,7 +4175,7 @@ index 0000000..7705a4d +struct _r300_mipmap_tree { + r300ContextPtr r300; + r300TexObj *t; -+ dri_bo *bo; ++ struct radeon_bo *bo; + GLuint refcount; + + GLuint totalsize; /** total size of the miptree, in bytes */ @@ -4865,11 +4211,29 @@ index 0000000..7705a4d + + +#endif /* __R300_MIPMAP_TREE_H_ */ +diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h +index 778db96..8b3fe43 100644 +--- a/src/mesa/drivers/dri/r300/r300_reg.h ++++ b/src/mesa/drivers/dri/r300/r300_reg.h +@@ -1525,6 +1525,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + # define R500_SEL_FILTER4_TC3 (3 << 18) + + #define R300_TX_OFFSET_0 0x4540 ++#define R300_TX_OFFSET_1 0x4544 ++#define R300_TX_OFFSET_2 0x4548 ++#define R300_TX_OFFSET_3 0x454C ++#define R300_TX_OFFSET_4 0x4550 ++#define R300_TX_OFFSET_5 0x4554 ++#define R300_TX_OFFSET_6 0x4558 ++#define R300_TX_OFFSET_7 0x455C + /* BEGIN: Guess from R200 */ + # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) + # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c -index 292f87a..4cf11cf 100644 +index 292f87a..dd9da80 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c -@@ -175,89 +175,79 @@ int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) +@@ -175,89 +175,171 @@ int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -4890,12 +4254,16 @@ index 292f87a..4cf11cf 100644 - - r300AllocDmaRegion(rmesa, rvb, n_elts * 4, 4); - rvb->aos_offset = GET_START(rvb); -+ r300AllocDmaRegion(rmesa, &rmesa->state.elt_dma_bo, &rmesa->state.elt_dma_offset, -+ n_elts * 4, 4); - +- - out = rvb->address + rvb->start; -+ out = rmesa->state.elt_dma_bo->virtual + rmesa->state.elt_dma_offset; ++ rmesa->state.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, ++ 0, n_elts * 4, 4, ++ RADEON_GEM_DOMAIN_GTT, 0); ++ rmesa->state.elt_dma_offset = 0; ++ radeon_bo_map(rmesa->state.elt_dma_bo, 1); ++ out = rmesa->state.elt_dma_bo->ptr + rmesa->state.elt_dma_offset; memcpy(out, elts, n_elts * 4); ++ radeon_bo_unmap(rmesa->state.elt_dma_bo); } -static void r300FireEB(r300ContextPtr rmesa, unsigned long addr, @@ -4905,28 +4273,51 @@ index 292f87a..4cf11cf 100644 - int cmd_reserved = 0; - int cmd_written = 0; - drm_radeon_cmd_header_t *cmd = NULL; -+ BATCH_LOCALS(rmesa); - +- - start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0), 0); - e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); -+ BEGIN_BATCH(8); -+ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0); -+ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); - +- - start_packet3(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2), 2); - e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); - e32(addr); - e32(vertex_count); -+ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); -+ OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); -+ OUT_BATCH_RELOC(0, rmesa->state.elt_dma_bo, rmesa->state.elt_dma_offset, 0); -+ OUT_BATCH(vertex_count); -+ END_BATCH(); ++ BATCH_LOCALS(rmesa); ++ ++ if (vertex_count > 0) { ++ BEGIN_BATCH(8); ++ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0); ++ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | ++ ((vertex_count + 0) << 16) | ++ type | ++ R300_VAP_VF_CNTL__INDEX_SIZE_32bit); ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { ++ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); ++ OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); ++ OUT_BATCH_RELOC(rmesa->state.elt_dma_offset, ++ rmesa->state.elt_dma_bo, ++ rmesa->state.elt_dma_offset, ++ RADEON_GEM_DOMAIN_GTT, 0, 0); ++ OUT_BATCH(vertex_count); ++ } else { ++ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); ++ OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); ++ OUT_BATCH(rmesa->state.elt_dma_offset); ++ OUT_BATCH(vertex_count); ++ radeon_cs_write_reloc(rmesa->cmdbuf.cs, ++ rmesa->state.elt_dma_bo, ++ 0, ++ rmesa->state.elt_dma_bo->size, ++ RADEON_GEM_DOMAIN_GTT, 0, 0); ++ } ++ END_BATCH(); ++ } } static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) { + BATCH_LOCALS(rmesa); ++ uint32_t voffset; int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; int i; - int cmd_reserved = 0; @@ -4943,23 +4334,60 @@ index 292f87a..4cf11cf 100644 + OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1); + OUT_BATCH(nr); ++ ++ if (!rmesa->radeon.radeonScreen->kernel_mm) { for (i = 0; i + 1 < nr; i += 2) { - e32((rmesa->state.aos[i].aos_size << 0) | - (rmesa->state.aos[i].aos_stride << 8) | - (rmesa->state.aos[i + 1].aos_size << 16) | - (rmesa->state.aos[i + 1].aos_stride << 24)); -- -- e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride); -- e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride); + OUT_BATCH((rmesa->state.aos[i].components << 0) | + (rmesa->state.aos[i].stride << 8) | + (rmesa->state.aos[i + 1].components << 16) | + (rmesa->state.aos[i + 1].stride << 24)); + -+ OUT_BATCH_RELOC(0, rmesa->state.aos[i].bo, -+ rmesa->state.aos[i].offset + offset * 4 * rmesa->state.aos[i].stride, 0); -+ OUT_BATCH_RELOC(0, rmesa->state.aos[i+1].bo, -+ rmesa->state.aos[i+1].offset + offset * 4 * rmesa->state.aos[i + 1].stride, 0); ++ voffset = rmesa->state.aos[i + 0].offset + ++ offset * 4 * rmesa->state.aos[i + 0].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->state.aos[i].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->state.aos[i + 1].offset + ++ offset * 4 * rmesa->state.aos[i + 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->state.aos[i+1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } + +- e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride); +- e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride); ++ if (nr & 1) { ++ OUT_BATCH((rmesa->state.aos[nr - 1].components << 0) | ++ (rmesa->state.aos[nr - 1].stride << 8)); ++ voffset = rmesa->state.aos[nr - 1].offset + ++ offset * 4 * rmesa->state.aos[nr - 1].stride; ++ OUT_BATCH_RELOC(voffset, ++ rmesa->state.aos[nr - 1].bo, ++ voffset, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ } else { ++ for (i = 0; i + 1 < nr; i += 2) { ++ OUT_BATCH((rmesa->state.aos[i].components << 0) | ++ (rmesa->state.aos[i].stride << 8) | ++ (rmesa->state.aos[i + 1].components << 16) | ++ (rmesa->state.aos[i + 1].stride << 24)); ++ ++ voffset = rmesa->state.aos[i + 0].offset + ++ offset * 4 * rmesa->state.aos[i + 0].stride; ++ OUT_BATCH(voffset); ++ voffset = rmesa->state.aos[i + 1].offset + ++ offset * 4 * rmesa->state.aos[i + 1].stride; ++ OUT_BATCH(voffset); } if (nr & 1) { @@ -4968,9 +4396,39 @@ index 292f87a..4cf11cf 100644 - e32(rmesa->state.aos[nr - 1].aos_offset + offset * 4 * rmesa->state.aos[nr - 1].aos_stride); + OUT_BATCH((rmesa->state.aos[nr - 1].components << 0) | + (rmesa->state.aos[nr - 1].stride << 8)); -+ OUT_BATCH_RELOC(0, rmesa->state.aos[nr - 1].bo, -+ rmesa->state.aos[nr - 1].offset + offset * 4 * rmesa->state.aos[nr - 1].stride, 0); ++ voffset = rmesa->state.aos[nr - 1].offset + ++ offset * 4 * rmesa->state.aos[nr - 1].stride; ++ OUT_BATCH(voffset); ++ } ++ for (i = 0; i + 1 < nr; i += 2) { ++ voffset = rmesa->state.aos[i + 0].offset + ++ offset * 4 * rmesa->state.aos[i + 0].stride; ++ radeon_cs_write_reloc(rmesa->cmdbuf.cs, ++ rmesa->state.aos[i+0].bo, ++ voffset, ++ rmesa->state.aos[i+0].bo->size, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ voffset = rmesa->state.aos[i + 1].offset + ++ offset * 4 * rmesa->state.aos[i + 1].stride; ++ radeon_cs_write_reloc(rmesa->cmdbuf.cs, ++ rmesa->state.aos[i+1].bo, ++ voffset, ++ rmesa->state.aos[i+1].bo->size, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); ++ } ++ if (nr & 1) { ++ voffset = rmesa->state.aos[nr - 1].offset + ++ offset * 4 * rmesa->state.aos[nr - 1].stride; ++ radeon_cs_write_reloc(rmesa->cmdbuf.cs, ++ rmesa->state.aos[nr-1].bo, ++ voffset, ++ rmesa->state.aos[nr-1].bo->size, ++ RADEON_GEM_DOMAIN_GTT, ++ 0, 0); } ++ } + END_BATCH(); } @@ -4996,7 +4454,7 @@ index 292f87a..4cf11cf 100644 int type, num_verts; TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; -@@ -268,6 +258,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, +@@ -268,6 +350,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, if (type < 0 || num_verts <= 0) return; @@ -5009,7 +4467,7 @@ index 292f87a..4cf11cf 100644 if (vb->Elts) { if (num_verts > 65535) { /* not implemented yet */ -@@ -287,11 +283,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, +@@ -287,11 +375,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, */ r300EmitElts(ctx, vb->Elts, num_verts); r300EmitAOS(rmesa, rmesa->state.aos_count, start); @@ -5023,18 +4481,15 @@ index 292f87a..4cf11cf 100644 } static GLboolean r300RunRender(GLcontext * ctx, -@@ -310,6 +307,10 @@ static GLboolean r300RunRender(GLcontext * ctx, - if (r300EmitArrays(ctx)) - return GL_TRUE; +@@ -302,7 +391,6 @@ static GLboolean r300RunRender(GLcontext * ctx, + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *vb = &tnl->vb; -+ -+ if (r300ValidateTextures(ctx)) -+ return GL_TRUE; -+ - r300UpdateShaderStates(rmesa); +- + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s\n", __FUNCTION__); - r300EmitCacheFlush(rmesa); -@@ -324,10 +325,6 @@ static GLboolean r300RunRender(GLcontext * ctx, +@@ -324,10 +412,6 @@ static GLboolean r300RunRender(GLcontext * ctx, r300EmitCacheFlush(rmesa); @@ -5046,7 +4501,7 @@ index 292f87a..4cf11cf 100644 return GL_FALSE; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c -index 6a5c363..ed399b2 100644 +index 6a5c363..c79e69a 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -5057,9 +4512,31 @@ index 6a5c363..ed399b2 100644 #include "r300_context.h" #include "r300_ioctl.h" #include "r300_state.h" -@@ -1146,39 +1147,25 @@ void r300UpdateDrawBuffer(GLcontext * ctx) +@@ -1100,10 +1101,19 @@ static void r300UpdateWindow(GLcontext * ctx) + static void r300Viewport(GLcontext * ctx, GLint x, GLint y, + GLsizei width, GLsizei height) + { ++ r300ContextPtr rmesa = R300_CONTEXT(ctx); ++ __DRIcontext *driContext = rmesa->radeon.dri.context; + /* Don't pipeline viewport changes, conflict with window offset + * setting below. Could apply deltas to rescue pipelined viewport + * values, or keep the originals hanging around. + */ ++ if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { ++ radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); ++ if (driContext->driDrawablePriv != driContext->driReadablePriv) { ++ radeon_update_renderbuffers(driContext, ++ driContext->driReadablePriv); ++ } ++ } + r300UpdateWindow(ctx); + } + +@@ -1144,55 +1154,25 @@ void r300UpdateViewportOffset(GLcontext * ctx) + void r300UpdateDrawBuffer(GLcontext * ctx) + { r300ContextPtr rmesa = R300_CONTEXT(ctx); - r300ContextPtr r300 = rmesa; +- r300ContextPtr r300 = rmesa; struct gl_framebuffer *fb = ctx->DrawBuffer; - driRenderbuffer *drb; + struct radeon_renderbuffer *rrb; @@ -5088,7 +4565,7 @@ index 6a5c363..ed399b2 100644 + assert(rrb->pitch); R300_STATECHANGE(rmesa, cb); - +- - r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset + - r300->radeon.radeonScreen->fbLocation; - r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch; //r300->radeon.state.color.drawPitch; @@ -5100,10 +4577,34 @@ index 6a5c363..ed399b2 100644 - - if (r300->radeon.sarea->tiling_enabled) - r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE; - #if 0 - R200_STATECHANGE(rmesa, ctx); +-#if 0 +- R200_STATECHANGE(rmesa, ctx); +- +- /* Note: we used the (possibly) page-flipped values */ +- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] +- = ((drb->flippedOffset + rmesa->r200Screen->fbLocation) +- & R200_COLOROFFSET_MASK); +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; +- +- if (rmesa->sarea->tiling_enabled) { +- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= +- R200_COLOR_TILE_ENABLE; +- } +-#endif + } -@@ -1497,14 +1484,9 @@ static void r300SetupTextures(GLcontext * ctx) + static void +@@ -1412,7 +1392,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) + } + + r300->hw.fpt.cmd[R300_FPT_CMD_0] = +- cmdpacket0(R300_US_TEX_INST_0, code->tex.length); ++ cmdpacket0(r300->radeon.radeonScreen, ++ R300_US_TEX_INST_0, code->tex.length); + } + + static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) +@@ -1497,14 +1478,9 @@ static void r300SetupTextures(GLcontext * ctx) /* We cannot let disabled tmu offsets pass DRM */ for (i = 0; i < mtu; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { @@ -5119,7 +4620,7 @@ index 6a5c363..ed399b2 100644 if (!t) continue; -@@ -1530,21 +1512,20 @@ static void r300SetupTextures(GLcontext * ctx) +@@ -1530,21 +1506,20 @@ static void r300SetupTextures(GLcontext * ctx) */ r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->filter_1 | @@ -5145,7 +4646,80 @@ index 6a5c363..ed399b2 100644 WARN_ONCE("micro tiling enabled!\n"); } -@@ -2223,8 +2204,6 @@ static void r300ResetHwState(r300ContextPtr r300) +@@ -1561,21 +1536,21 @@ static void r300SetupTextures(GLcontext * ctx) + } + + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER0_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, last_hw_tmu + 1); + r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER1_0, last_hw_tmu + 1); + r300->hw.tex.size.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_SIZE_0, last_hw_tmu + 1); + r300->hw.tex.format.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FORMAT_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT_0, last_hw_tmu + 1); + r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FORMAT2_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, last_hw_tmu + 1); + r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, last_hw_tmu + 1); + r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_CHROMA_KEY_0, last_hw_tmu + 1); + r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); + + if (!fp) /* should only happenen once, just after context is created */ + return; +@@ -1587,7 +1562,7 @@ static void r300SetupTextures(GLcontext * ctx) + r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0; + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = +- cmdpacket0(R300_TX_FILTER0_0, 1); ++ cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1); + } + r300SetupFragmentShaderTextures(ctx, tmu_mappings); + } else +@@ -1749,7 +1724,7 @@ static void r300SetupRSUnit(GLcontext * ctx) + | R300_HIRES_EN; + + assert(high_rr >= 0); +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, high_rr + 1); + r300->hw.rc.cmd[2] = high_rr; + + if (InputsRead) +@@ -1909,7 +1884,7 @@ static void r500SetupRSUnit(GLcontext * ctx) + | R300_HIRES_EN; + + assert(high_rr >= 0); +- r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, high_rr + 1); ++ r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, high_rr + 1); + r300->hw.rc.cmd[2] = 0xC0 | high_rr; + + if (InputsRead) +@@ -2107,6 +2082,7 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa) + (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); + } + ++ + static void r300SetupVertexProgram(r300ContextPtr rmesa) + { + GLcontext *ctx = rmesa->radeon.glCtx; +@@ -2193,6 +2169,7 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) + static void r300ResetHwState(r300ContextPtr r300) + { + GLcontext *ctx = r300->radeon.glCtx; ++ struct radeon_renderbuffer *rrb; + int has_tcl = 1; + + if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) +@@ -2223,8 +2200,6 @@ static void r300ResetHwState(r300ContextPtr r300) r300UpdateCulling(ctx); @@ -5154,7 +4728,7 @@ index 6a5c363..ed399b2 100644 r300SetBlendState(ctx); r300SetLogicOpState(ctx); -@@ -2371,20 +2350,6 @@ static void r300ResetHwState(r300ContextPtr r300) +@@ -2371,20 +2346,6 @@ static void r300ResetHwState(r300ContextPtr r300) r300BlendColor(ctx, ctx->Color.BlendColor); @@ -5175,7 +4749,7 @@ index 6a5c363..ed399b2 100644 r300->hw.rb3d_dither_ctl.cmd[1] = 0; r300->hw.rb3d_dither_ctl.cmd[2] = 0; r300->hw.rb3d_dither_ctl.cmd[3] = 0; -@@ -2400,10 +2365,6 @@ static void r300ResetHwState(r300ContextPtr r300) +@@ -2400,12 +2361,8 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; @@ -5183,49 +4757,103 @@ index 6a5c363..ed399b2 100644 - r300->radeon.radeonScreen->depthOffset + - r300->radeon.radeonScreen->fbLocation; - r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch; - - if (r300->radeon.sarea->tiling_enabled) { +- +- if (r300->radeon.sarea->tiling_enabled) { ++ rrb = r300->radeon.state.depth_buffer; ++ if (rrb && rrb->bo && (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)) { /* XXX: Turn off when clearing buffers ? */ -@@ -2675,7 +2636,6 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) + r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; + +@@ -2539,10 +2496,10 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) + R300_STATECHANGE(rmesa, fpi[1]); + R300_STATECHANGE(rmesa, fpi[2]); + R300_STATECHANGE(rmesa, fpi[3]); +- rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, code->alu.length); +- rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, code->alu.length); +- rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, code->alu.length); +- rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); ++ rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_RGB_INST_0, code->alu.length); ++ rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_RGB_ADDR_0, code->alu.length); ++ rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, code->alu.length); ++ rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, code->alu.length); + for (i = 0; i < code->alu.length; i++) { + rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst0; + rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst1; +@@ -2573,7 +2530,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) + } + + R300_STATECHANGE(rmesa, fpp); +- rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, code->const_nr * 4); ++ rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4); + for (i = 0; i < code->const_nr; i++) { + const GLfloat *constant = get_fragmentprogram_constant(ctx, + &fp->mesa_program.Base, code->constant[i]); +@@ -2675,7 +2632,7 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) GLcontext *ctx; ctx = rmesa->radeon.glCtx; - r300UpdateTextureState(ctx); ++ r300ValidateTextures(ctx); r300SetEarlyZState(ctx); GLuint fgdepthsrc = R300_FG_DEPTH_SRC_SCAN; diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h -index 0589ab7..96177ba 100644 +index 0589ab7..4d0a25f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.h +++ b/src/mesa/drivers/dri/r300/r300_state.h -@@ -59,7 +59,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -39,8 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define R300_NEWPRIM( rmesa ) \ + do { \ +- if ( rmesa->dma.flush ) \ +- rmesa->dma.flush( rmesa ); \ + } while (0) + + #define R300_STATECHANGE(r300, atom) \ +@@ -57,13 +55,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + TODO: This has not been implemented yet + */ #define R300_FIREVERTICES( r300 ) \ - do { \ - \ +-do { \ +- \ - if ( (r300)->cmdbuf.count_used || (r300)->dma.flush ) { \ -+ if ( (r300)->cmdbuf.committed || (r300)->dma.flush ) { \ - r300Flush( (r300)->radeon.glCtx ); \ - } \ - \ +- r300Flush( (r300)->radeon.glCtx ); \ +- } \ +- \ +-} while (0) ++ do { \ ++ r300Flush( (r300)->radeon.glCtx ); \ ++ } while (0) + + // r300_state.c + extern int future_hw_tcl_on; diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c -index b6e7ce1..c4e88e2 100644 +index b6e7ce1..fbfa8f4 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c -@@ -57,11 +57,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -56,12 +56,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "r300_state.h" #include "r300_ioctl.h" #include "r300_emit.h" - #include "r300_mem.h" -+#include "r300_tex.h" +-#include "r300_mem.h" static void flush_last_swtcl_prim( r300ContextPtr rmesa ); -void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset); -+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, dri_bo *bo, GLuint offset); ++void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset); void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr); #define EMIT_ATTR( ATTR, STYLE ) \ do { \ -@@ -175,7 +176,7 @@ static void r300SetVertexFormat( GLcontext *ctx ) +@@ -86,7 +85,6 @@ static void r300SetVertexFormat( GLcontext *ctx ) + DECLARE_RENDERINPUTS(index_bitset); + GLuint InputsRead = 0, OutputsWritten = 0; + int vap_fmt_0 = 0; +- int vap_vte_cntl = 0; + int offset = 0; + int vte = 0; + GLint inputs[VERT_ATTRIB_MAX]; +@@ -175,7 +173,7 @@ static void r300SetVertexFormat( GLcontext *ctx ) inputs[i] = -1; } } @@ -5234,7 +4862,7 @@ index b6e7ce1..c4e88e2 100644 /* Fixed, apply to vir0 only */ if (InputsRead & (1 << VERT_ATTRIB_POS)) inputs[VERT_ATTRIB_POS] = 0; -@@ -186,16 +187,16 @@ static void r300SetVertexFormat( GLcontext *ctx ) +@@ -186,16 +184,16 @@ static void r300SetVertexFormat( GLcontext *ctx ) for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) if (InputsRead & (1 << i)) inputs[i] = 6 + (i - VERT_ATTRIB_TEX0); @@ -5254,7 +4882,7 @@ index b6e7ce1..c4e88e2 100644 swizzle[i][0] = SWIZZLE_ZERO; swizzle[i][1] = SWIZZLE_ZERO; swizzle[i][2] = SWIZZLE_ZERO; -@@ -215,21 +216,21 @@ static void r300SetVertexFormat( GLcontext *ctx ) +@@ -215,21 +213,21 @@ static void r300SetVertexFormat( GLcontext *ctx ) ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, nr); @@ -5281,89 +4909,96 @@ index b6e7ce1..c4e88e2 100644 rmesa->swtcl.vertex_size /= 4; RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset ); -@@ -245,38 +246,40 @@ static void r300SetVertexFormat( GLcontext *ctx ) - */ - static void flush_last_swtcl_prim( r300ContextPtr rmesa ) +@@ -247,37 +245,22 @@ static void flush_last_swtcl_prim( r300ContextPtr rmesa ) { -+ BATCH_LOCALS(rmesa); -+ if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); - -+ - rmesa->dma.flush = NULL; - +- rmesa->dma.flush = NULL; +- - if (rmesa->dma.current.buf) { - struct r300_dma_region *current = &rmesa->dma.current; - GLuint current_offset = GET_START(current); -+ if (rmesa->dma.current) { -+ GLuint current_offset = rmesa->dma.current_used; - +- - assert (current->start + -+ assert (rmesa->dma.current_used + - rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == - current->ptr); -+ rmesa->dma.current_vertexptr); - +- - if (rmesa->dma.current.start != rmesa->dma.current.ptr) { -+ if (rmesa->dma.current_used != rmesa->dma.current_vertexptr) { -+ rmesa->dma.current_used = rmesa->dma.current_vertexptr; - - r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__); +- +- r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__); - -+ - r300EmitState(rmesa); +- r300EmitState(rmesa); - -+ - r300EmitVertexAOS( rmesa, - rmesa->swtcl.vertex_size, +- r300EmitVertexAOS( rmesa, +- rmesa->swtcl.vertex_size, - current_offset); - -+ rmesa->dma.current, current_offset); -+ - r300EmitVbufPrim( rmesa, - rmesa->swtcl.hw_primitive, - rmesa->swtcl.numverts); +- r300EmitVbufPrim( rmesa, +- rmesa->swtcl.hw_primitive, +- rmesa->swtcl.numverts); - -+ - r300EmitCacheFlush(rmesa); -+ COMMIT_BATCH(); - } +- r300EmitCacheFlush(rmesa); +- } - -+ - rmesa->swtcl.numverts = 0; +- rmesa->swtcl.numverts = 0; - current->start = current->ptr; - } +- } ++ rmesa->swtcl.flush = NULL; ++ radeon_bo_unmap(rmesa->swtcl.bo); ++ r300EnsureCmdBufSpace(rmesa, ++ rmesa->hw.max_state_size + (12*sizeof(int)), ++ __FUNCTION__); ++ r300EmitState(rmesa); ++ r300EmitVertexAOS(rmesa, ++ rmesa->swtcl.vertex_size, ++ rmesa->swtcl.bo, ++ 0); ++ r300EmitVbufPrim(rmesa, ++ rmesa->swtcl.hw_primitive, ++ rmesa->swtcl.numverts); ++ r300EmitCacheFlush(rmesa); ++ COMMIT_BATCH(); ++ rmesa->swtcl.numverts = 0; } -@@ -287,7 +290,7 @@ r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize ) + /* Alloc space in the current dma region. +@@ -287,26 +270,14 @@ r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize ) { GLuint bytes = vsize * nverts; - if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) -+ if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) - r300RefillCurrentDmaRegion( rmesa, bytes); - - if (!rmesa->dma.flush) { -@@ -297,13 +300,13 @@ r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize ) - - ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); - ASSERT( rmesa->dma.flush == flush_last_swtcl_prim ); +- r300RefillCurrentDmaRegion( rmesa, bytes); +- +- if (!rmesa->dma.flush) { +- rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; +- rmesa->dma.flush = flush_last_swtcl_prim; +- } +- +- ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); +- ASSERT( rmesa->dma.flush == flush_last_swtcl_prim ); - ASSERT( rmesa->dma.current.start + -+ ASSERT( rmesa->dma.current_used + - rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == +- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == - rmesa->dma.current.ptr ); -+ rmesa->dma.current_vertexptr ); - - { +- +- { - GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->dma.current.ptr += bytes; -+ GLubyte *head = (GLubyte *) (rmesa->dma.current->virtual + rmesa->dma.current_vertexptr); -+ rmesa->dma.current_vertexptr += bytes; - rmesa->swtcl.numverts += nverts; - return head; - } -@@ -352,7 +355,7 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim ); +- rmesa->swtcl.numverts += nverts; +- return head; +- } ++ rmesa->swtcl.bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, ++ 0, bytes, 4, RADEON_GEM_DOMAIN_GTT, 0); ++ radeon_bo_map(rmesa->swtcl.bo, 1); ++ if (rmesa->swtcl.flush == NULL) { ++ rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; ++ rmesa->swtcl.flush = flush_last_swtcl_prim; ++ } ++ return rmesa->swtcl.bo->ptr; + } + + static GLuint reduced_prim[] = { +@@ -352,7 +323,7 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim ); r300ContextPtr rmesa = R300_CONTEXT(ctx); \ const char *r300verts = (char *)rmesa->swtcl.verts; #define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int))) @@ -5372,7 +5007,7 @@ index b6e7ce1..c4e88e2 100644 #define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS)) #define PRINT_VERTEX(x) #undef TAG -@@ -572,15 +575,17 @@ static void r300RenderStart(GLcontext *ctx) +@@ -572,18 +543,16 @@ static void r300RenderStart(GLcontext *ctx) r300ContextPtr rmesa = R300_CONTEXT( ctx ); // fprintf(stderr, "%s\n", __FUNCTION__); @@ -5381,19 +5016,21 @@ index b6e7ce1..c4e88e2 100644 r300SetVertexFormat(ctx); r300UpdateShaders(rmesa); -+ -+ r300ValidateTextures(ctx); r300UpdateShaderStates(rmesa); r300EmitCacheFlush(rmesa); - - if (rmesa->dma.flush != 0 && -+ -+ if (rmesa->dma.flush != 0 && - rmesa->dma.flush != flush_last_swtcl_prim) - rmesa->dma.flush( rmesa ); +- rmesa->dma.flush != flush_last_swtcl_prim) +- rmesa->dma.flush( rmesa ); +- ++ if (rmesa->swtcl.flush != NULL) { ++ rmesa->swtcl.flush(rmesa); ++ } + } -@@ -593,7 +598,7 @@ static void r300RenderFinish(GLcontext *ctx) + static void r300RenderFinish(GLcontext *ctx) +@@ -593,7 +562,7 @@ static void r300RenderFinish(GLcontext *ctx) static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim ) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -5402,7 +5039,7 @@ index b6e7ce1..c4e88e2 100644 if (rmesa->swtcl.hw_primitive != hwprim) { R300_NEWPRIM( rmesa ); rmesa->swtcl.hw_primitive = hwprim; -@@ -611,7 +616,7 @@ static void r300RenderPrimitive(GLcontext *ctx, GLenum prim) +@@ -611,7 +580,7 @@ static void r300RenderPrimitive(GLcontext *ctx, GLenum prim) r300RasterPrimitive( ctx, reduced_prim[prim] ); // fprintf(stderr, "%s\n", __FUNCTION__); @@ -5411,7 +5048,7 @@ index b6e7ce1..c4e88e2 100644 } static void r300ResetLineStipple(GLcontext *ctx) -@@ -625,12 +630,12 @@ void r300InitSwtcl(GLcontext *ctx) +@@ -625,12 +594,12 @@ void r300InitSwtcl(GLcontext *ctx) TNLcontext *tnl = TNL_CONTEXT(ctx); r300ContextPtr rmesa = R300_CONTEXT(ctx); static int firsttime = 1; @@ -5426,7 +5063,7 @@ index b6e7ce1..c4e88e2 100644 tnl->Driver.Render.Start = r300RenderStart; tnl->Driver.Render.Finish = r300RenderFinish; tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive; -@@ -638,15 +643,15 @@ void r300InitSwtcl(GLcontext *ctx) +@@ -638,15 +607,15 @@ void r300InitSwtcl(GLcontext *ctx) tnl->Driver.Render.BuildVertices = _tnl_build_vertices; tnl->Driver.Render.CopyPV = _tnl_copy_pv; tnl->Driver.Render.Interp = _tnl_interp; @@ -5446,7 +5083,7 @@ index b6e7ce1..c4e88e2 100644 _tnl_invalidate_vertex_state( ctx, ~0 ); _tnl_invalidate_vertices( ctx, ~0 ); -@@ -655,9 +660,9 @@ void r300InitSwtcl(GLcontext *ctx) +@@ -655,9 +624,9 @@ void r300InitSwtcl(GLcontext *ctx) _tnl_need_projected_coords( ctx, GL_FALSE ); r300ChooseRenderState(ctx); @@ -5458,12 +5095,12 @@ index b6e7ce1..c4e88e2 100644 _mesa_validate_all_lighting_tables; } -@@ -665,33 +670,32 @@ void r300DestroySwtcl(GLcontext *ctx) +@@ -665,33 +634,32 @@ void r300DestroySwtcl(GLcontext *ctx) { } -void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset) -+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, dri_bo *bo, GLuint offset) ++void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset) { - int cmd_reserved = 0; - int cmd_written = 0; @@ -5485,7 +5122,7 @@ index b6e7ce1..c4e88e2 100644 + OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2); + OUT_BATCH(1); + OUT_BATCH(vertex_size | (vertex_size << 8)); -+ OUT_BATCH_RELOC(0, bo, offset, 0); ++ OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); } @@ -5510,7 +5147,7 @@ index b6e7ce1..c4e88e2 100644 + END_BATCH(); } diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c -index 8ab382c..bdb971a 100644 +index 8ab382c..9ceac70 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -5588,7 +5225,7 @@ index 8ab382c..bdb971a 100644 /* try to find a format which will only need a memcopy */ static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat, GLenum srcType) -@@ -434,277 +406,204 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, +@@ -434,277 +406,208 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, return NULL; /* never get here */ } @@ -5631,6 +5268,10 @@ index 8ab382c..bdb971a 100644 + } else { + _mesa_free_texture_image_data(ctx, timage); + } ++ if (image->bo) { ++ radeon_bo_unref(image->bo); ++ image->bo = NULL; ++ } +} - if (ctx->_ImageTransferState || @@ -5650,7 +5291,7 @@ index 8ab382c..bdb971a 100644 +static void teximage_set_map_data(r300_texture_image *image) +{ + r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; -+ image->base.Data = image->mt->bo->virtual + lvl->faces[image->mtface].offset; ++ image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; + image->base.RowStride = lvl->rowstride / image->mt->bpp; +} @@ -5682,7 +5323,7 @@ index 8ab382c..bdb971a 100644 - default: - return 0; -+ dri_bo_map(image->mt->bo, write_enable); ++ radeon_bo_map(image->mt->bo, write_enable); + teximage_set_map_data(image); } +} @@ -5705,7 +5346,7 @@ index 8ab382c..bdb971a 100644 - fprintf(stderr, "%s: srcRowStride %d/%x\n", - __FUNCTION__, srcRowStride, srcRowStride); + image->base.Data = 0; -+ dri_bo_unmap(image->mt->bo); ++ radeon_bo_unmap(image->mt->bo); + } +} @@ -5736,7 +5377,7 @@ index 8ab382c..bdb971a 100644 + assert(t->mt); - return 1; -+ dri_bo_map(t->mt->bo, GL_FALSE); ++ radeon_bo_map(t->mt->bo, GL_FALSE); + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + teximage_set_map_data(get_r300_texture_image(texObj->Image[face][level])); @@ -5778,7 +5419,7 @@ index 8ab382c..bdb971a 100644 + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + texObj->Image[face][level]->Data = 0; + } -+ dri_bo_unmap(t->mt->bo); ++ radeon_bo_unmap(t->mt->bo); } -static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level, @@ -6020,7 +5661,7 @@ index 8ab382c..bdb971a 100644 switch (target) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: -@@ -712,103 +611,50 @@ static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target, +@@ -712,103 +615,50 @@ static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: @@ -6158,7 +5799,7 @@ index 8ab382c..bdb971a 100644 } static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level, -@@ -820,51 +666,100 @@ static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level, +@@ -820,51 +670,100 @@ static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { @@ -6296,7 +5937,7 @@ index 8ab382c..bdb971a 100644 static void r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, -@@ -875,30 +770,29 @@ r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level, +@@ -875,30 +774,29 @@ r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { @@ -6345,7 +5986,7 @@ index 8ab382c..bdb971a 100644 /** * Changes variables and flags for a state update, which will happen at the * next UpdateTextureState -@@ -908,7 +802,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, +@@ -908,7 +806,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat * params) { @@ -6354,7 +5995,7 @@ index 8ab382c..bdb971a 100644 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { fprintf(stderr, "%s( %s )\n", __FUNCTION__, -@@ -941,7 +835,11 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, +@@ -941,7 +839,11 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ @@ -6367,7 +6008,7 @@ index 8ab382c..bdb971a 100644 break; case GL_DEPTH_TEXTURE_MODE: -@@ -964,27 +862,10 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, +@@ -964,27 +866,10 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, } } @@ -6396,7 +6037,7 @@ index 8ab382c..bdb971a 100644 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, -@@ -992,14 +873,19 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) +@@ -992,14 +877,19 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) _mesa_lookup_enum_by_nr(texObj->Target)); } @@ -6422,7 +6063,7 @@ index 8ab382c..bdb971a 100644 _mesa_delete_texture_object(ctx, texObj); } -@@ -1008,8 +894,6 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) +@@ -1008,8 +898,6 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) * Called via ctx->Driver.NewTextureObject. * Note: this function will be called during context creation to * allocate the default texture objects. @@ -6431,7 +6072,7 @@ index 8ab382c..bdb971a 100644 * Fixup MaxAnisotropy according to user preference. */ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, -@@ -1017,14 +901,23 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, +@@ -1017,14 +905,23 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, GLenum target) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -6462,7 +6103,7 @@ index 8ab382c..bdb971a 100644 } void r300InitTextureFuncs(struct dd_function_table *functions) -@@ -1032,6 +925,11 @@ void r300InitTextureFuncs(struct dd_function_table *functions) +@@ -1032,6 +929,11 @@ void r300InitTextureFuncs(struct dd_function_table *functions) /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. */ @@ -6474,7 +6115,7 @@ index 8ab382c..bdb971a 100644 functions->ChooseTextureFormat = r300ChooseTextureFormat; functions->TexImage1D = r300TexImage1D; functions->TexImage2D = r300TexImage2D; -@@ -1040,7 +938,6 @@ void r300InitTextureFuncs(struct dd_function_table *functions) +@@ -1040,7 +942,6 @@ void r300InitTextureFuncs(struct dd_function_table *functions) functions->TexSubImage2D = r300TexSubImage2D; functions->TexSubImage3D = r300TexSubImage3D; functions->NewTextureObject = r300NewTextureObject; @@ -6482,7 +6123,7 @@ index 8ab382c..bdb971a 100644 functions->DeleteTexture = r300DeleteTexture; functions->IsTextureResident = driIsTextureResident; -@@ -1049,5 +946,7 @@ void r300InitTextureFuncs(struct dd_function_table *functions) +@@ -1049,5 +950,7 @@ void r300InitTextureFuncs(struct dd_function_table *functions) functions->CompressedTexImage2D = r300CompressedTexImage2D; functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D; @@ -6491,7 +6132,7 @@ index 8ab382c..bdb971a 100644 driInitTextureFormats(); } diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h -index b86d45b..a293ccf 100644 +index b86d45b..358b927 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -41,12 +41,7 @@ extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, @@ -6504,15 +6145,15 @@ index b86d45b..a293ccf 100644 - GLuint face); - -extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t); -+extern GLboolean r300ValidateTextures(GLcontext * ctx); ++extern void r300ValidateTextures(GLcontext * ctx); extern void r300InitTextureFuncs(struct dd_function_table *functions); diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c -index b03eefa..bacf12f 100644 +index b03eefa..53eeca1 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c -@@ -48,520 +48,12 @@ SOFTWARE. +@@ -48,520 +48,11 @@ SOFTWARE. #include "r300_context.h" #include "r300_state.h" #include "r300_cmdbuf.h" @@ -6524,7 +6165,7 @@ index b03eefa..bacf12f 100644 #include /* for usleep() */ -#ifdef USER_BUFFERS - #include "r300_mem.h" +-#include "r300_mem.h" -#endif -/** @@ -7036,18 +6677,21 @@ index b03eefa..bacf12f 100644 - return 0; -} diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c -index e2329f0..f42f020 100644 +index e2329f0..4fea822 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c -@@ -48,6 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -48,8 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_ioctl.h" #include "radeon_ioctl.h" +#include "r300_mipmap_tree.h" #include "r300_tex.h" #include "r300_reg.h" ++#include "radeon_buffer.h" -@@ -148,8 +149,7 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) + #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \ + || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \ +@@ -148,8 +150,7 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) if (!tObj) return; @@ -7057,7 +6701,7 @@ index e2329f0..f42f020 100644 switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) { case MESA_FORMAT_Z16: -@@ -190,399 +190,241 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) +@@ -190,399 +191,228 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) /** @@ -7350,14 +6994,14 @@ index e2329f0..f42f020 100644 - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; -+ assert(rowsize <= dststride); -+ assert(rowsize <= srcstride); - +- - ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); - - if (t->base.dirty_images[0]) { - R300_FIREVERTICES(rmesa); -- ++ assert(rowsize <= dststride); ++ assert(rowsize <= srcstride); + - r300SetTexImages(rmesa, tObj); - r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); - if (!t->base.memBlock && !t->image_override) @@ -7400,8 +7044,8 @@ index e2329f0..f42f020 100644 - if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) { - return GL_FALSE; - } -+ dri_bo_map(mt->bo, GL_TRUE); -+ dest = mt->bo->virtual + dstlvl->faces[face].offset; ++ radeon_bo_map(mt->bo, GL_TRUE); ++ dest = mt->bo->ptr + dstlvl->faces[face].offset; - if (t->base.dirty_images[0]) { - R300_FIREVERTICES(rmesa); @@ -7440,11 +7084,11 @@ index e2329f0..f42f020 100644 - /* layout memory space, once for all faces */ - r300SetTexImages(rmesa, tObj); - } -+ dri_bo_map(image->mt->bo, GL_FALSE); ++ radeon_bo_map(image->mt->bo, GL_FALSE); + memcpy(dest, -+ image->mt->bo->virtual + srclvl->faces[face].offset, ++ image->mt->bo->ptr + srclvl->faces[face].offset, + dstlvl->size); -+ dri_bo_unmap(image->mt->bo); ++ radeon_bo_unmap(image->mt->bo); - /* upload (per face) */ - for (face = 0; face < 6; face++) { @@ -7472,7 +7116,7 @@ index e2329f0..f42f020 100644 } - return GL_TRUE; -+ dri_bo_unmap(mt->bo); ++ radeon_bo_unmap(mt->bo); + + image->mt = mt; + image->mtface = face; @@ -7497,22 +7141,18 @@ index e2329f0..f42f020 100644 + r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[0][texObj->BaseLevel]); + int face, level; + -+ if (t->validated) ++ if (t->validated || t->image_override) + return GL_TRUE; - -- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); ++ + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); -- if (t->base.dirty_images[0]) { -- R300_FIREVERTICES(rmesa); +- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); + if (baseimage->base.Border > 0) + return GL_FALSE; -- r300SetTexImages(rmesa, tObj); -- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); -- if (!t->base.memBlock && !t->image_override && -- !rmesa->prefer_gart_client_texturing) +- if (t->base.dirty_images[0]) { +- R300_FIREVERTICES(rmesa); + /* Ensure a matching miptree exists. + * + * Differing mipmap trees can result when the app uses TexImage to @@ -7533,7 +7173,11 @@ index e2329f0..f42f020 100644 + r300_miptree_unreference(t->mt); + t->mt = 0; + } -+ + +- r300SetTexImages(rmesa, tObj); +- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); +- if (!t->base.memBlock && !t->image_override && +- !rmesa->prefer_gart_client_texturing) + if (!t->mt) { + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, " Allocate new miptree\n"); @@ -7542,8 +7186,8 @@ index e2329f0..f42f020 100644 + _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); return GL_FALSE; + } -+ } -+ + } + + /* Ensure all images are stored in the single main miptree */ + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { @@ -7560,8 +7204,8 @@ index e2329f0..f42f020 100644 + fprintf(stderr, "migrating\n"); + migrate_image_to_miptree(t->mt, image, face, level); + } - } - ++ } ++ + /* Configure the hardware registers (more precisely, the cached version + * of the hardware registers). */ + setup_hardware_state(rmesa, t); @@ -7575,21 +7219,18 @@ index e2329f0..f42f020 100644 +/** + * Ensure all enabled and complete textures are uploaded. + */ -+GLboolean r300ValidateTextures(GLcontext * ctx) ++void r300ValidateTextures(GLcontext * ctx) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData; + int i; -+ int flushed = 0; - /* Fallback if there's a texture border */ - if (tObj->Image[0][tObj->BaseLevel]->Border > 0) - return GL_FALSE; -+ again: + for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { -+ r300TexObj *t; + if (!ctx->Texture.Unit[i]._ReallyEnabled) + continue; @@ -7604,31 +7245,22 @@ index e2329f0..f42f020 100644 - - rmesa->state.texture.unit[unit].texobj->base.bound &= - ~(1 << unit); -+ t = r300_tex_obj(ctx->Texture.Unit[i]._Current); -+ if (!r300_validate_texture(ctx, t)) { ++ if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) { + _mesa_warning(ctx, + "failed to validate texture for unit %d.\n", + i); } - +- - rmesa->state.texture.unit[unit].texobj = t; - t->base.bound |= (1 << unit); - driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */ -+ if (dri_bufmgr_check_aperture_space(t->mt->bo)) { -+ r300Flush(ctx); -+ if (flushed) -+ return GL_TRUE; -+ flushed = 1; -+ goto again; -+ } } - - return !t->border_fallback; -+ return GL_FALSE; } void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, -@@ -591,20 +433,18 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, +@@ -591,20 +421,18 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, r300ContextPtr rmesa = pDRICtx->driverPrivate; struct gl_texture_object *tObj = _mesa_lookup_texture(rmesa->radeon.glCtx, texname); @@ -7645,19 +7277,20 @@ index e2329f0..f42f020 100644 if (!offset) return; - +- - t->offset = offset; ++ t->bo = NULL; + t->override_offset = offset; t->pitch_reg &= (1 << 13) -1; pitch_val = pitch; -@@ -630,39 +470,3 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, - +@@ -631,38 +459,96 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, t->pitch_reg |= pitch_val; } -- + -static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit) --{ ++void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) + { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - - if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) { @@ -7682,17 +7315,105 @@ index e2329f0..f42f020 100644 -void r300UpdateTextureState(GLcontext * ctx) -{ - int i; -- ++ struct gl_texture_unit *texUnit; ++ struct gl_texture_object *texObj; ++ struct gl_texture_image *texImage; ++ struct radeon_renderbuffer *rb; ++ r300_texture_image *rImage; ++ radeonContextPtr radeon; ++ r300ContextPtr rmesa; ++ GLframebuffer *fb; ++ r300TexObjPtr t; ++ uint32_t pitch_val; + - for (i = 0; i < 8; i++) { - if (!r300UpdateTextureUnit(ctx, i)) { - _mesa_warning(ctx, - "failed to update texture state for unit %d.\n", - i); - } -- } --} ++ target = GL_TEXTURE_RECTANGLE_ARB; ++ radeon = pDRICtx->driverPrivate; ++ rmesa = pDRICtx->driverPrivate; ++ fb = dPriv->driverPrivate; ++ texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; ++ texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); ++ texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); ++ rImage = get_r300_texture_image(texImage); ++ t = r300_tex_obj(texObj); ++ if (t == NULL) { ++ return; ++ } ++ ++ radeon_update_renderbuffers(pDRICtx, dPriv); ++ /* back & depth buffer are useless free them right away */ ++ rb = (void*)fb->Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void*)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; ++ if (rb->bo == NULL) { ++ /* Failed to BO for the buffer */ ++ return; ++ } ++ ++ _mesa_lock_texture(radeon->glCtx, texObj); ++ if (t->bo) { ++ t->bo = NULL; ++ } ++ if (t->mt) { ++ t->mt = NULL; ++ } ++ if (rImage->mt) { ++ r300_miptree_unreference(rImage->mt); ++ rImage->mt = NULL; ++ } ++ _mesa_init_teximage_fields(radeon->glCtx, target, texImage, ++ rb->width, rb->height, rb->cpp, 0, rb->cpp); ++ texImage->TexFormat = &_mesa_texformat_rgba8888_rev; ++ rImage->bo = rb->bo; ++ ++ t->bo = rb->bo; ++ t->tile_bits = 0; ++ t->image_override = GL_TRUE; ++ t->override_offset = 0; ++ t->pitch_reg &= (1 << 13) -1; ++ pitch_val = rb->pitch; ++ switch (rb->cpp) { ++ case 4: ++ t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); ++ t->filter |= tx_table[2].filter; ++ pitch_val /= 4; ++ break; ++ case 3: ++ default: ++ t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); ++ t->filter |= tx_table[4].filter; ++ pitch_val /= 4; ++ break; ++ case 2: ++ t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); ++ t->filter |= tx_table[5].filter; ++ pitch_val /= 2; ++ break; + } ++ pitch_val--; ++ t->size = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) | ++ ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT); ++ t->size |= R300_TX_SIZE_TXPITCH_EN; ++ t->pitch_reg |= pitch_val; ++ t->validated = GL_TRUE; ++ _mesa_unlock_texture(radeon->glCtx, texObj); ++ return; + } diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c -index 5267fe9..c1c2168 100644 +index 5267fe9..2bb679b 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -7711,64 +7432,305 @@ index 5267fe9..c1c2168 100644 #define DRIVER_DATE "20060815" -@@ -258,6 +260,56 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +@@ -189,6 +191,43 @@ GLboolean radeonInitContext(radeonContextPtr radeon, + */ + void radeonCleanupContext(radeonContextPtr radeon) + { ++ FILE *track; ++ struct radeon_renderbuffer *rb; ++ GLframebuffer *fb; ++ ++ fb = (void*)radeon->dri.drawable->driverPrivate; ++ rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ fb = (void*)radeon->dri.readable->driverPrivate; ++ rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ + /* _mesa_destroy_context() might result in calls to functions that + * depend on the DriverCtx, so don't set it to NULL before. + * +@@ -202,6 +241,11 @@ void radeonCleanupContext(radeonContextPtr radeon) + FREE(radeon->state.scissor.pClipRects); + radeon->state.scissor.pClipRects = 0; + } ++ track = fopen("/tmp/tracklog", "w"); ++ if (track) { ++ radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); ++ fclose(track); ++ } + } + + +@@ -218,7 +262,7 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) + ctx = radeon->glCtx; + + if (ctx->Visual.doubleBufferMode) { +- _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ ++ _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ + if (radeon->doPageFlip) { + radeonPageFlip(dPriv); + } else { +@@ -258,6 +302,232 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, } } +static void -+radeon_make_renderbuffer_current(radeonContextPtr radeon, -+ GLframebuffer *draw) ++radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, ++ GLframebuffer *draw) +{ -+ int size = radeon->radeonScreen->driScreen->fbSize; -+ void *map = 0; + /* if radeon->fake */ + struct radeon_renderbuffer *rb; -+ uint32_t offset; -+ -+ if (!radeon->bufmgr) -+ return; + + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + -+ if (radeon->radeonScreen->kernel_mm) -+ map = radeon->radeonScreen->front.map; -+ -+ offset = radeon->radeonScreen->kernel_mm ? radeon->radeonScreen->front.offset : radeon->radeonScreen->frontOffset; -+ rb->bo = dri_bo_alloc_static(radeon->bufmgr, "front buffer", -+ offset, size, map, 0); ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->frontOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } + rb->cpp = radeon->radeonScreen->cpp; -+ rb->pitch = radeon->radeonScreen->frontPitch; ++ rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { -+ -+ if (radeon->radeonScreen->kernel_mm) -+ map = radeon->radeonScreen->back.map; -+ -+ offset = radeon->radeonScreen->kernel_mm ? radeon->radeonScreen->back.offset : radeon->radeonScreen->backOffset; -+ if (!rb->bo) -+ rb->bo = dri_bo_alloc_static(radeon->bufmgr, "back buffer", -+ offset, size, map, 0); ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->backOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } + rb->cpp = radeon->radeonScreen->cpp; -+ rb->pitch = radeon->radeonScreen->backPitch; ++ rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { -+ offset = radeon->radeonScreen->kernel_mm ? radeon->radeonScreen->depth.offset : radeon->radeonScreen->depthOffset; -+ -+ if (radeon->radeonScreen->kernel_mm) -+ map = radeon->radeonScreen->depth.map; -+ -+ if (!rb->bo) -+ rb->bo = dri_bo_alloc_static(radeon->bufmgr, "depth buffer", -+ offset, size, map, 0); ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->depthOffset, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } + rb->cpp = radeon->radeonScreen->cpp; -+ rb->pitch = radeon->radeonScreen->depthPitch; ++ rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } +} ++ ++static void ++radeon_make_renderbuffer_current(radeonContextPtr radeon, ++ GLframebuffer *draw) ++{ ++ int size = 4096*4096*4; ++ /* if radeon->fake */ ++ struct radeon_renderbuffer *rb; ++ ++ if (radeon->radeonScreen->kernel_mm) { ++ radeon_make_kernel_renderbuffer_current(radeon, draw); ++ return; ++ } ++ ++ ++ if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->frontOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->backOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; ++ } ++ if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { ++ if (!rb->bo) { ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ radeon->radeonScreen->depthOffset + ++ radeon->radeonScreen->fbLocation, ++ size, ++ 4096, ++ RADEON_GEM_DOMAIN_VRAM, ++ 0); ++ } ++ rb->cpp = radeon->radeonScreen->cpp; ++ rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; ++ } ++} ++ ++ ++void ++radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) ++{ ++ unsigned int attachments[10]; ++ __DRIbuffer *buffers; ++ __DRIscreen *screen; ++ struct radeon_renderbuffer *rb; ++ int i, count; ++ GLframebuffer *draw; ++ radeonContextPtr radeon; ++ ++ draw = drawable->driverPrivate; ++ screen = context->driScreenPriv; ++ radeon = (radeonContextPtr) context->driverPrivate; ++ i = 0; ++ if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { ++ attachments[i++] = __DRI_BUFFER_FRONT_LEFT; ++ } ++ if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { ++ attachments[i++] = __DRI_BUFFER_BACK_LEFT; ++ } ++ if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { ++ attachments[i++] = __DRI_BUFFER_DEPTH; ++ } ++ ++ buffers = (*screen->dri2.loader->getBuffers)(drawable, ++ &drawable->w, ++ &drawable->h, ++ attachments, i, ++ &count, ++ drawable->loaderPrivate); ++ if (buffers == NULL) ++ return; ++ ++ /* set one cliprect to cover the whole drawable */ ++ drawable->x = 0; ++ drawable->y = 0; ++ drawable->backX = 0; ++ drawable->backY = 0; ++ drawable->numClipRects = 1; ++ drawable->pClipRects[0].x1 = 0; ++ drawable->pClipRects[0].y1 = 0; ++ drawable->pClipRects[0].x2 = drawable->w; ++ drawable->pClipRects[0].y2 = drawable->h; ++ drawable->numBackClipRects = 1; ++ drawable->pBackClipRects[0].x1 = 0; ++ drawable->pBackClipRects[0].y1 = 0; ++ drawable->pBackClipRects[0].x2 = drawable->w; ++ drawable->pBackClipRects[0].y2 = drawable->h; ++ for (i = 0; i < count; i++) { ++ switch (buffers[i].attachment) { ++ case __DRI_BUFFER_FRONT_LEFT: ++ rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; ++ if (rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb->cpp = buffers[i].cpp; ++ rb->pitch = buffers[i].pitch; ++ rb->width = drawable->w; ++ rb->height = drawable->h; ++ rb->has_surface = 0; ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ buffers[i].name, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ buffers[i].flags); ++ if (rb->bo == NULL) { ++ fprintf(stderr, "failled to attach front %d\n", ++ buffers[i].name); ++ } ++ break; ++ case __DRI_BUFFER_BACK_LEFT: ++ rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb->cpp = buffers[i].cpp; ++ rb->pitch = buffers[i].pitch; ++ rb->width = drawable->w; ++ rb->height = drawable->h; ++ rb->has_surface = 0; ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ buffers[i].name, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ buffers[i].flags); ++ break; ++ case __DRI_BUFFER_DEPTH: ++ rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb->cpp = buffers[i].cpp; ++ rb->pitch = buffers[i].pitch; ++ rb->width = drawable->w; ++ rb->height = drawable->h; ++ rb->has_surface = 0; ++ rb->bo = radeon_bo_open(radeon->radeonScreen->bom, ++ buffers[i].name, ++ 0, ++ 0, ++ RADEON_GEM_DOMAIN_VRAM, ++ buffers[i].flags); ++ break; ++ case __DRI_BUFFER_STENCIL: ++ break; ++ case __DRI_BUFFER_ACCUM: ++ default: ++ fprintf(stderr, ++ "unhandled buffer attach event, attacment type %d\n", ++ buffers[i].attachment); ++ return; ++ } ++ } ++ radeon = (radeonContextPtr) context->driverPrivate; ++ driUpdateFramebufferSize(radeon->glCtx, drawable); ++} ++ + /* Force the context `c' to be the current context and associate with it * buffer `b'. */ -@@ -265,51 +317,57 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, +@@ -265,51 +535,71 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driDrawPriv, __DRIdrawablePrivate * driReadPriv) { @@ -7794,29 +7756,39 @@ index 5267fe9..c1c2168 100644 + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; + } ++ radeon = (radeonContextPtr) driContextPriv->driverPrivate; ++ dfb = driDrawPriv->driverPrivate; ++ rfb = driReadPriv->driverPrivate; ++ ++ if (driContextPriv->driScreenPriv->dri2.enabled) { ++ radeon_update_renderbuffers(driContextPriv, driDrawPriv); ++ if (driDrawPriv != driReadPriv) ++ radeon_update_renderbuffers(driContextPriv, driReadPriv); ++ radeon->state.color.rrb = ++ (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ radeon->state.depth_buffer = ++ (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; ++ } - driDrawableInitVBlank(driDrawPriv); - } - } -+ radeon = (radeonContextPtr) driContextPriv->driverPrivate; -+ dfb = driDrawPriv->driverPrivate; -+ rfb = driReadPriv->driverPrivate; - radeon->dri.readable = driReadPriv; + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, radeon->glCtx); -+ -+ driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); -+ if (driReadPriv != driDrawPriv) -+ driUpdateFramebufferSize(radeon->glCtx, driReadPriv); - if (radeon->dri.drawable != driDrawPriv || - radeon->lastStamp != driDrawPriv->lastStamp) { - radeon->dri.drawable = driDrawPriv; -+ radeon_make_renderbuffer_current(radeon, dfb); - -- radeonSetCliprects(radeon); -- r300UpdateViewportOffset(radeon->glCtx); ++ driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); ++ if (driReadPriv != driDrawPriv) ++ driUpdateFramebufferSize(radeon->glCtx, driReadPriv); ++ ++ if (!driContextPriv->driScreenPriv->dri2.enabled) { ++ radeon_make_renderbuffer_current(radeon, dfb); ++ } ++ + _mesa_make_current(radeon->glCtx, dfb, rfb); + + if (radeon->dri.drawable != driDrawPriv) { @@ -7826,7 +7798,9 @@ index 5267fe9..c1c2168 100644 + ? driGetDefaultVBlankFlags(&radeon-> + optionCache) + : VBLANK_FLAG_NO_IRQ; -+ + +- radeonSetCliprects(radeon); +- r300UpdateViewportOffset(radeon->glCtx); + driDrawableInitVBlank(driDrawPriv); } + } @@ -7854,24 +7828,18 @@ index 5267fe9..c1c2168 100644 + _mesa_update_state(radeon->glCtx); + -+ radeonUpdatePageFlipping(radeon); ++ if (!driContextPriv->driScreenPriv->dri2.enabled) { ++ radeonUpdatePageFlipping(radeon); ++ } + if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "End %s\n", __FUNCTION__); return GL_TRUE; diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h -index 47cbc22..a1f0225 100644 +index 47cbc22..d5bbf29 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h -@@ -45,6 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - #include "main/mtypes.h" - #include "main/colormac.h" -+#include "radeon_dri_bufmgr.h" - #include "radeon_screen.h" - #include "drm.h" - #include "dri_util.h" -@@ -132,12 +133,13 @@ struct radeon_scissor_state { +@@ -132,12 +132,13 @@ struct radeon_scissor_state { struct radeon_colorbuffer_state { GLuint clear; @@ -7886,17 +7854,16 @@ index 47cbc22..a1f0225 100644 }; /** -@@ -185,6 +187,8 @@ struct radeon_context { - /* Configuration cache - */ - driOptionCache optionCache; -+ -+ dri_bufmgr *bufmgr; - }; +@@ -202,6 +203,7 @@ extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + extern GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); ++void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); - #define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) + /* ================================================================ + * Debugging: diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c -index 36502eb..6186d1f 100644 +index 36502eb..c8d6bf9 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.c +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c @@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -7969,19 +7936,20 @@ index 36502eb..6186d1f 100644 } void radeonWaitForIdleLocked(radeonContextPtr radeon) +@@ -391,6 +374,7 @@ void radeonFinish(GLcontext * ctx) + radeonEmitIrqLocked(radeon); + UNLOCK_HARDWARE(radeon); + radeonWaitIrq(radeon); +- } else ++ } else { + radeonWaitForIdle(radeon); ++ } + } diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c -index 4f47afd..9e59c76 100644 +index 4f47afd..a1b2163 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.c +++ b/src/mesa/drivers/dri/r300/radeon_lock.c -@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - #include "radeon_state.h" - #include "r300_context.h" - #include "r300_state.h" -+#include "r300_mem.h" - - #include "main/framebuffer.h" - -@@ -59,11 +60,11 @@ int prevLockLine = 0; +@@ -59,11 +59,11 @@ int prevLockLine = 0; void radeonUpdatePageFlipping(radeonContextPtr rmesa) { int use_back; @@ -7995,7 +7963,7 @@ index 4f47afd..9e59c76 100644 r300UpdateDrawBuffer(rmesa->glCtx); } -@@ -72,16 +73,12 @@ void radeonUpdatePageFlipping(radeonContextPtr rmesa) +@@ -72,16 +72,12 @@ void radeonUpdatePageFlipping(radeonContextPtr rmesa) BUFFER_BACK_LEFT) : 1; use_back ^= (rmesa->sarea->pfCurrentPage == 1); @@ -8018,7 +7986,15 @@ index 4f47afd..9e59c76 100644 } /* Update the hardware state. This is called if another context has -@@ -125,12 +122,8 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) +@@ -98,7 +94,6 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + __DRIscreenPrivate *sPriv = rmesa->dri.screen; + drm_radeon_sarea_t *sarea = rmesa->sarea; +- r300ContextPtr r300 = (r300ContextPtr) rmesa; + + assert(drawable != NULL); + +@@ -125,12 +120,9 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) } if (sarea->ctx_owner != rmesa->dri.hwContext) { @@ -8028,12 +8004,41 @@ index 4f47afd..9e59c76 100644 - for (i = 0; i < r300->nr_heaps; i++) { - DRI_AGE_TEXTURES(r300->texture_heaps[i]); - } -+ radeonBufmgrContendedLockTake(r300->radeon.bufmgr); ++ if (!rmesa->radeonScreen->kernel_mm) ++ radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom); } rmesa->lost_context = GL_TRUE; +diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h +index a344837..eaef49c 100644 +--- a/src/mesa/drivers/dri/r300/radeon_lock.h ++++ b/src/mesa/drivers/dri/r300/radeon_lock.h +@@ -97,19 +97,23 @@ extern int prevLockLine; + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ ++ if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_CAS((rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ + (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret); \ + if (__ret) \ + radeonGetLock((rmesa), 0); \ ++ }\ + DEBUG_LOCK(); \ + } while (0) + + #define UNLOCK_HARDWARE( rmesa ) \ + do { \ ++ if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_UNLOCK((rmesa)->dri.fd, \ + (rmesa)->dri.hwLock, \ + (rmesa)->dri.hwContext); \ + DEBUG_RESET(); \ ++ }\ + } while (0) + + #endif /* __RADEON_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/r300/radeon_span.c b/src/mesa/drivers/dri/r300/radeon_span.c -index 16f9fb9..de94888 100644 +index 16f9fb9..30dde80 100644 --- a/src/mesa/drivers/dri/r300/radeon_span.c +++ b/src/mesa/drivers/dri/r300/radeon_span.c @@ -48,7 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -8045,7 +8050,7 @@ index 16f9fb9..de94888 100644 #define DBG 0 -@@ -58,21 +58,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -58,21 +58,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * information. */ #define LOCAL_VARS \ @@ -8056,10 +8061,10 @@ index 16f9fb9..de94888 100644 const GLuint bottom = dPriv->h - 1; \ - GLubyte *buf = (GLubyte *) drb->flippedData \ - + (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \ -+ GLubyte *buf = (GLubyte *) rrb->bo->virtual \ -+ + (dPriv->y * rrb->pitch + dPriv->x) * rrb->cpp; \ - GLuint p; \ - (void) p; +- GLuint p; \ +- (void) p; ++ GLuint p; \ ++ (void)p; #define LOCAL_DEPTH_VARS \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ @@ -8068,164 +8073,357 @@ index 16f9fb9..de94888 100644 + const __DRIdrawablePrivate *dPriv = rrb->dPriv; \ const GLuint bottom = dPriv->h - 1; \ GLuint xo = dPriv->x; \ - GLuint yo = dPriv->y; \ +- GLuint yo = dPriv->y; \ - GLubyte *buf = (GLubyte *) drb->Base.Data; -+ GLubyte *buf = (GLubyte *) rrb->base.Data; ++ GLuint yo = dPriv->y; #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS -@@ -93,7 +93,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -82,6 +79,133 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + #define HW_UNLOCK() + ++static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, ++ GLint x, GLint y) ++{ ++ GLubyte *ptr = rrb->bo->ptr; ++ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; ++ GLint offset; ++ GLint nmacroblkpl; ++ GLint nmicroblkpl; ++ ++ if (rrb->has_surface || !(rrb->bo->flags & mask)) { ++ offset = x * rrb->cpp + y * rrb->pitch; ++ } else { ++ offset = 0; ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { ++ nmacroblkpl = rrb->pitch >> 5; ++ offset += ((y >> 4) * nmacroblkpl) << 11; ++ offset += ((y & 15) >> 1) << 8; ++ offset += (y & 1) << 4; ++ offset += (x >> 5) << 11; ++ offset += ((x & 31) >> 2) << 5; ++ offset += (x & 3) << 2; ++ } else { ++ nmacroblkpl = rrb->pitch >> 6; ++ offset += ((y >> 3) * nmacroblkpl) << 11; ++ offset += (y & 7) << 8; ++ offset += (x >> 6) << 11; ++ offset += ((x & 63) >> 3) << 5; ++ offset += (x & 7) << 2; ++ } ++ } else { ++ nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; ++ offset += (y * nmicroblkpl) << 5; ++ offset += (x >> 3) << 5; ++ offset += (x & 7) << 2; ++ } ++ } ++ return &ptr[offset]; ++} ++ ++static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, ++ GLint x, GLint y) ++{ ++ GLubyte *ptr = rrb->bo->ptr; ++ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; ++ GLint offset; ++ GLint nmacroblkpl; ++ GLint nmicroblkpl; ++ ++ if (rrb->has_surface || !(rrb->bo->flags & mask)) { ++ offset = x * rrb->cpp + y * rrb->pitch; ++ } else { ++ offset = 0; ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { ++ nmacroblkpl = rrb->pitch >> 6; ++ offset += ((y >> 4) * nmacroblkpl) << 11; ++ offset += ((y & 15) >> 1) << 8; ++ offset += (y & 1) << 4; ++ offset += (x >> 6) << 11; ++ offset += ((x & 63) >> 3) << 5; ++ offset += (x & 7) << 1; ++ } else { ++ nmacroblkpl = rrb->pitch >> 7; ++ offset += ((y >> 3) * nmacroblkpl) << 11; ++ offset += (y & 7) << 8; ++ offset += (x >> 7) << 11; ++ offset += ((x & 127) >> 4) << 5; ++ offset += (x & 15) << 2; ++ } ++ } else { ++ nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; ++ offset += (y * nmicroblkpl) << 5; ++ offset += (x >> 4) << 5; ++ offset += (x & 15) << 2; ++ } ++ } ++ return &ptr[offset]; ++} ++ ++static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, ++ GLint x, GLint y) ++{ ++ GLubyte *ptr = rrb->bo->ptr; ++ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; ++ GLint offset; ++ GLint microblkxs; ++ GLint macroblkxs; ++ GLint nmacroblkpl; ++ GLint nmicroblkpl; ++ ++ if (rrb->has_surface || !(rrb->bo->flags & mask)) { ++ offset = x * rrb->cpp + y * rrb->pitch; ++ } else { ++ offset = 0; ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { ++ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { ++ microblkxs = 16 / rrb->cpp; ++ macroblkxs = 128 / rrb->cpp; ++ nmacroblkpl = rrb->pitch / macroblkxs; ++ offset += ((y >> 4) * nmacroblkpl) << 11; ++ offset += ((y & 15) >> 1) << 8; ++ offset += (y & 1) << 4; ++ offset += (x / macroblkxs) << 11; ++ offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; ++ offset += (x & (microblkxs - 1)) * rrb->cpp; ++ } else { ++ microblkxs = 32 / rrb->cpp; ++ macroblkxs = 256 / rrb->cpp; ++ nmacroblkpl = rrb->pitch / macroblkxs; ++ offset += ((y >> 3) * nmacroblkpl) << 11; ++ offset += (y & 7) << 8; ++ offset += (x / macroblkxs) << 11; ++ offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; ++ offset += (x & (microblkxs - 1)) * rrb->cpp; ++ } ++ } else { ++ microblkxs = 32 / rrb->cpp; ++ nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; ++ offset += (y * nmicroblkpl) << 5; ++ offset += (x / microblkxs) << 5; ++ offset += (x & (microblkxs - 1)) * rrb->cpp; ++ } ++ } ++ return &ptr[offset]; ++} ++ + /* ================================================================ + * Color buffer + */ +@@ -93,7 +217,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y -#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 2) -+#define GET_PTR(X,Y) (buf + ((Y) * rrb->pitch + (X)) * 2) ++#define GET_PTR(X,Y) radeon_ptr16(rrb, (X), (Y)) #include "spantmp2.h" /* 32 bit, ARGB8888 color spanline and pixel functions -@@ -103,7 +103,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -103,7 +227,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y -#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 4) -+#define GET_PTR(X,Y) (buf + ((Y) * rrb->pitch + (X)) * 4) ++#define GET_PTR(X,Y) radeon_ptr32(rrb, (X), (Y)) #include "spantmp2.h" /* ================================================================ -@@ -120,10 +120,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -120,65 +244,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * too... */ -static GLuint radeon_mba_z32(const driRenderbuffer * drb, GLint x, GLint y) -+static GLuint radeon_mba_z32(const struct radeon_renderbuffer * rrb, -+ GLint x, GLint y) - { +-{ - GLuint pitch = drb->pitch; - if (drb->depthHasSurface) { -+ GLuint pitch = rrb->pitch; -+ if (rrb->depthHasSurface) { - return 4 * (x + y * pitch); - } else { - GLuint ba, address = 0; /* a[0..1] = 0 */ -@@ -148,10 +149,10 @@ static GLuint radeon_mba_z32(const driRenderbuffer * drb, GLint x, GLint y) - } - - static INLINE GLuint +- return 4 * (x + y * pitch); +- } else { +- GLuint ba, address = 0; /* a[0..1] = 0 */ +- +-#ifdef COMPILE_R300 +- ba = (y / 8) * (pitch / 8) + (x / 8); +-#else +- ba = (y / 16) * (pitch / 16) + (x / 16); +-#endif +- +- address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ +- address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ +- address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ +- address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ +- +- address |= (y & 0x8) << 7; /* a[10] = y[3] */ +- address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ +- address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ +- +- return address; +- } +-} +- +-static INLINE GLuint -radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) -+radeon_mba_z16(const struct radeon_renderbuffer *rrb, GLint x, GLint y) - { +-{ - GLuint pitch = drb->pitch; - if (drb->depthHasSurface) { -+ GLuint pitch = rrb->pitch; -+ if (rrb->depthHasSurface) { - return 2 * (x + y * pitch); - } else { - GLuint ba, address = 0; /* a[0] = 0 */ -@@ -175,10 +176,10 @@ radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) +- return 2 * (x + y * pitch); +- } else { +- GLuint ba, address = 0; /* a[0] = 0 */ +- +- ba = (y / 16) * (pitch / 32) + (x / 32); +- +- address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ +- address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ +- address |= (x & 0x8) << 4; /* a[7] = x[3] */ +- address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ +- address |= (y & 0x8) << 7; /* a[10] = y[3] */ +- address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ +- address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ +- +- return address; +- } +-} +- + /* 16-bit depth buffer functions + */ #define VALUE_TYPE GLushort #define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )) = d; -+ *(GLushort *)(buf + radeon_mba_z16( rrb, _x + xo, _y + yo )) = d; ++ *(GLushort *)radeon_ptr(rrb, _x + xo, _y + yo) = d #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )); -+ d = *(GLushort *)(buf + radeon_mba_z16( rrb, _x + xo, _y + yo )); ++ d = *(GLushort *)radeon_ptr(rrb, _x + xo, _y + yo) #define TAG(x) radeon##x##_z16 #include "depthtmp.h" -@@ -193,7 +194,7 @@ radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) +@@ -193,35 +267,36 @@ radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y) #ifdef COMPILE_R300 #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ -+ GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ ++ GLuint tmp = *_ptr; \ tmp &= 0x000000ff; \ tmp |= ((d << 8) & 0xffffff00); \ -@@ -202,7 +203,7 @@ do { \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ -+ GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ ++ GLuint tmp = *_ptr; \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ -@@ -213,12 +214,12 @@ do { \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) + #endif + #ifdef COMPILE_R300 #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ -+ d = (*(GLuint *)(buf + radeon_mba_z32( rrb, _x + xo, \ - _y + yo )) & 0xffffff00) >> 8; \ +- _y + yo )) & 0xffffff00) >> 8; \ ++ d = (*(GLuint*)(radeon_ptr32(rrb, _x + xo, _y + yo)) & 0xffffff00) >> 8; \ }while(0) #else #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ -+ d = *(GLuint *)(buf + radeon_mba_z32( rrb, _x + xo, \ - _y + yo )) & 0x00ffffff; +- _y + yo )) & 0x00ffffff; ++ d = *(GLuint*)(radeon_ptr32(rrb, _x + xo, _y + yo )) & 0x00ffffff; #endif +- ++/* ++ fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\ ++ d = *(GLuint*)(radeon_ptr(rrb, _x + xo, _y + yo )) & 0x00ffffff; ++*/ + #define TAG(x) radeon##x##_z24_s8 + #include "depthtmp.h" -@@ -234,7 +235,7 @@ do { \ +@@ -234,35 +309,35 @@ do { \ #ifdef COMPILE_R300 #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ -+ GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + xo, _y + yo); \ ++ GLuint tmp = *_ptr; \ tmp &= 0xffffff00; \ tmp |= (d) & 0xff; \ -@@ -243,7 +244,7 @@ do { \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) #else #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ -+ GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + xo, _y + yo); \ ++ GLuint tmp = *_ptr; \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ -@@ -254,14 +255,14 @@ do { \ +- *(GLuint *)(buf + offset) = tmp; \ ++ *_ptr = tmp; \ + } while (0) + #endif + #ifdef COMPILE_R300 #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ -+ GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ ++ GLuint tmp = *_ptr; \ d = tmp & 0x000000ff; \ } while (0) #else #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ -+ GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ +- GLuint tmp = *(GLuint *)(buf + offset); \ ++ GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ ++ GLuint tmp = *_ptr; \ d = (tmp & 0xff000000) >> 24; \ } while (0) -@@ -270,6 +271,22 @@ do { \ + #endif +@@ -270,6 +345,29 @@ do { \ #define TAG(x) radeon##x##_z24_s8 #include "stenciltmp.h" +static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) +{ + struct radeon_renderbuffer *rrb = (void*)rb; ++ int r; + -+ if (rrb->bo) -+ dri_bo_map(rrb->bo, write); ++ if (rrb->bo) { ++ r = radeon_bo_map(rrb->bo, write); ++ if (r) { ++ fprintf(stderr, "(%s) error(%d) mapping buffer.\n", ++ __FUNCTION__, r); ++ } ++ } +} + +static void unmap_buffer(struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = (void*)rb; + -+ if (rrb->bo) -+ dri_bo_unmap(rrb->bo); ++ if (rrb->bo) { ++ radeon_bo_unmap(rrb->bo); ++ } +} + /* Move locking out to get reasonable span performance (10x better * than doing this in HW_LOCK above). WaitForIdle() is the main * culprit. -@@ -278,45 +295,61 @@ do { \ +@@ -278,45 +376,63 @@ do { \ static void radeonSpanRenderStart(GLcontext * ctx) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -8267,13 +8465,15 @@ index 16f9fb9..de94888 100644 } + + /* color draw buffers */ -+ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) ++ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); ++ } + + map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); + -+ if (ctx->DrawBuffer->_DepthBuffer) ++ if (ctx->DrawBuffer->_DepthBuffer) { + map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); ++ } + if (ctx->DrawBuffer->_StencilBuffer) + map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); + @@ -8311,7 +8511,7 @@ index 16f9fb9..de94888 100644 } void radeonInitSpanFuncs(GLcontext * ctx) -@@ -330,20 +363,17 @@ void radeonInitSpanFuncs(GLcontext * ctx) +@@ -330,20 +446,17 @@ void radeonInitSpanFuncs(GLcontext * ctx) /** * Plug in the Get/Put routines for the given driRenderbuffer. */ @@ -8344,10 +8544,26 @@ index 16f9fb9..de94888 100644 } } diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c -index c401da6..0241903 100644 +index c401da6..14d489b 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c -@@ -223,14 +223,6 @@ void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state) +@@ -153,6 +153,7 @@ void radeonSetCliprects(radeonContextPtr radeon) + GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + ++ if (!radeon->radeonScreen->driScreen->dri2.enabled) { + if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. */ + if (drawable->numBackClipRects == 0 || radeon->doPageFlip || +@@ -168,6 +169,7 @@ void radeonSetCliprects(radeonContextPtr radeon) + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } ++ } + + if ((draw_fb->Width != drawable->w) || + (draw_fb->Height != drawable->h)) { +@@ -223,14 +225,6 @@ void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state) void radeonInitState(radeonContextPtr radeon) { radeon->Fallback = 0; @@ -8362,12 +8578,795 @@ index c401da6..0241903 100644 } +diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +new file mode 100644 +index 0000000..3aa1d86 +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +@@ -0,0 +1,724 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Dave Airlie ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE 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 ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Dave Airlie ++ * Jérôme Glisse ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "xf86drm.h" ++#include "drm.h" ++#include "radeon_drm.h" ++#include "radeon_bo.h" ++#include "radeon_bo_legacy.h" ++#include "radeon_ioctl.h" ++#include "texmem.h" ++ ++struct bo_legacy { ++ struct radeon_bo base; ++ driTextureObject tobj_base; ++ int map_count; ++ uint32_t pending; ++ int is_pending; ++ int validated; ++ int static_bo; ++ int got_dri_texture_obj; ++ int dirty; ++ uint32_t offset; ++ driTextureObject dri_texture_obj; ++ void *ptr; ++ struct bo_legacy *next, *prev; ++ struct bo_legacy *pnext, *pprev; ++}; ++ ++struct bo_manager_legacy { ++ struct radeon_bo_manager base; ++ unsigned nhandle; ++ unsigned nfree_handles; ++ unsigned cfree_handles; ++ uint32_t current_age; ++ struct bo_legacy bos; ++ struct bo_legacy pending_bos; ++ uint32_t fb_location; ++ uint32_t texture_offset; ++ unsigned dma_alloc_size; ++ unsigned cpendings; ++ driTextureObject texture_swapped; ++ driTexHeap *texture_heap; ++ struct radeon_screen *screen; ++ unsigned *free_handles; ++}; ++ ++static void bo_legacy_tobj_destroy(void *data, driTextureObject *t) ++{ ++ struct bo_legacy *bo_legacy; ++ ++ bo_legacy = (struct bo_legacy*)((char*)t)-sizeof(struct radeon_bo); ++ bo_legacy->got_dri_texture_obj = 0; ++ bo_legacy->validated = 0; ++} ++ ++static int legacy_new_handle(struct bo_manager_legacy *bom, uint32_t *handle) ++{ ++ uint32_t tmp; ++ ++ *handle = 0; ++ if (bom->nhandle == 0xFFFFFFFF) { ++ return -EINVAL; ++ } ++ if (bom->cfree_handles > 0) { ++ tmp = bom->free_handles[--bom->cfree_handles]; ++ while (!bom->free_handles[bom->cfree_handles - 1]) { ++ bom->cfree_handles--; ++ if (bom->cfree_handles <= 0) { ++ bom->cfree_handles = 0; ++ } ++ } ++ } else { ++ bom->cfree_handles = 0; ++ tmp = bom->nhandle++; ++ } ++ assert(tmp); ++ *handle = tmp; ++ return 0; ++} ++ ++static int legacy_free_handle(struct bo_manager_legacy *bom, uint32_t handle) ++{ ++ uint32_t *handles; ++ ++ if (!handle) { ++ return 0; ++ } ++ if (handle == (bom->nhandle - 1)) { ++ int i; ++ ++ bom->nhandle--; ++ for (i = bom->cfree_handles - 1; i >= 0; i--) { ++ if (bom->free_handles[i] == (bom->nhandle - 1)) { ++ bom->nhandle--; ++ bom->free_handles[i] = 0; ++ } ++ } ++ while (!bom->free_handles[bom->cfree_handles - 1]) { ++ bom->cfree_handles--; ++ if (bom->cfree_handles <= 0) { ++ bom->cfree_handles = 0; ++ } ++ } ++ return 0; ++ } ++ if (bom->cfree_handles < bom->nfree_handles) { ++ bom->free_handles[bom->cfree_handles++] = handle; ++ return 0; ++ } ++ bom->nfree_handles += 0x100; ++ handles = (uint32_t*)realloc(bom->free_handles, bom->nfree_handles * 4); ++ if (handles == NULL) { ++ bom->nfree_handles -= 0x100; ++ return -ENOMEM; ++ } ++ bom->free_handles = handles; ++ bom->free_handles[bom->cfree_handles++] = handle; ++ return 0; ++} ++ ++static void legacy_get_current_age(struct bo_manager_legacy *boml) ++{ ++ drm_radeon_getparam_t gp; ++ int r; ++ ++ gp.param = RADEON_PARAM_LAST_CLEAR; ++ gp.value = (int *)&boml->current_age; ++ r = drmCommandWriteRead(boml->base.fd, DRM_RADEON_GETPARAM, ++ &gp, sizeof(gp)); ++ if (r) { ++ fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, r); ++ exit(1); ++ } ++} ++ ++static int legacy_is_pending(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (bo_legacy->is_pending <= 0) { ++ bo_legacy->is_pending = 0; ++ return 0; ++ } ++ if (boml->current_age >= bo_legacy->pending) { ++ if (boml->pending_bos.pprev == bo_legacy) { ++ boml->pending_bos.pprev = bo_legacy->pprev; ++ } ++ bo_legacy->pprev->pnext = bo_legacy->pnext; ++ if (bo_legacy->pnext) { ++ bo_legacy->pnext->pprev = bo_legacy->pprev; ++ } ++ while (bo_legacy->is_pending--) { ++ radeon_bo_unref(bo); ++ } ++ bo_legacy->is_pending = 0; ++ boml->cpendings--; ++ return 0; ++ } ++ return 1; ++} ++ ++static int legacy_wait_pending(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (!bo_legacy->is_pending) { ++ return 0; ++ } ++ /* FIXME: lockup and userspace busy looping that's all the folks */ ++ legacy_get_current_age(boml); ++ while (legacy_is_pending(bo)) { ++ usleep(10); ++ legacy_get_current_age(boml); ++ } ++ return 0; ++} ++ ++static void legacy_track_pending(struct bo_manager_legacy *boml) ++{ ++ struct bo_legacy *bo_legacy; ++ struct bo_legacy *next; ++ ++ legacy_get_current_age(boml); ++ bo_legacy = boml->pending_bos.pnext; ++ while (bo_legacy) { ++ next = bo_legacy->pnext; ++ if (legacy_is_pending(&(bo_legacy->base))) { ++ } ++ bo_legacy = next; ++ } ++} ++ ++static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml, ++ uint32_t size, ++ uint32_t alignment, ++ uint32_t domains, ++ uint32_t flags) ++{ ++ struct bo_legacy *bo_legacy; ++ ++ bo_legacy = (struct bo_legacy*)calloc(1, sizeof(struct bo_legacy)); ++ if (bo_legacy == NULL) { ++ return NULL; ++ } ++ bo_legacy->base.bom = (struct radeon_bo_manager*)boml; ++ bo_legacy->base.handle = 0; ++ bo_legacy->base.size = size; ++ bo_legacy->base.alignment = alignment; ++ bo_legacy->base.domains = domains; ++ bo_legacy->base.flags = flags; ++ bo_legacy->base.ptr = NULL; ++ bo_legacy->map_count = 0; ++ bo_legacy->next = NULL; ++ bo_legacy->prev = NULL; ++ bo_legacy->got_dri_texture_obj = 0; ++ bo_legacy->pnext = NULL; ++ bo_legacy->pprev = NULL; ++ bo_legacy->next = boml->bos.next; ++ bo_legacy->prev = &boml->bos; ++ boml->bos.next = bo_legacy; ++ if (bo_legacy->next) { ++ bo_legacy->next->prev = bo_legacy; ++ } ++ return bo_legacy; ++} ++ ++static int bo_dma_alloc(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ drm_radeon_mem_alloc_t alloc; ++ unsigned size; ++ int base_offset; ++ int r; ++ ++ /* align size on 4Kb */ ++ size = (((4 * 1024) - 1) + bo->size) & ~((4 * 1024) - 1); ++ alloc.region = RADEON_MEM_REGION_GART; ++ alloc.alignment = bo_legacy->base.alignment; ++ alloc.size = size; ++ alloc.region_offset = &base_offset; ++ r = drmCommandWriteRead(bo->bom->fd, ++ DRM_RADEON_ALLOC, ++ &alloc, ++ sizeof(alloc)); ++ if (r) { ++ /* ptr is set to NULL if dma allocation failed */ ++ bo_legacy->ptr = NULL; ++ exit(0); ++ return r; ++ } ++ bo_legacy->ptr = boml->screen->gartTextures.map + base_offset; ++ bo_legacy->offset = boml->screen->gart_texture_offset + base_offset; ++ bo->size = size; ++ boml->dma_alloc_size += size; ++ return 0; ++} ++ ++static int bo_dma_free(struct radeon_bo *bo) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ drm_radeon_mem_free_t memfree; ++ int r; ++ ++ if (bo_legacy->ptr == NULL) { ++ /* ptr is set to NULL if dma allocation failed */ ++ return 0; ++ } ++ legacy_get_current_age(boml); ++ memfree.region = RADEON_MEM_REGION_GART; ++ memfree.region_offset = bo_legacy->offset; ++ memfree.region_offset -= boml->screen->gart_texture_offset; ++ r = drmCommandWrite(boml->base.fd, ++ DRM_RADEON_FREE, ++ &memfree, ++ sizeof(memfree)); ++ if (r) { ++ fprintf(stderr, "Failed to free bo[%p] at %08x\n", ++ &bo_legacy->base, memfree.region_offset); ++ fprintf(stderr, "ret = %s\n", strerror(-r)); ++ return r; ++ } ++ boml->dma_alloc_size -= bo_legacy->base.size; ++ return 0; ++} ++ ++static void bo_free(struct bo_legacy *bo_legacy) ++{ ++ struct bo_manager_legacy *boml; ++ ++ if (bo_legacy == NULL) { ++ return; ++ } ++ boml = (struct bo_manager_legacy *)bo_legacy->base.bom; ++ bo_legacy->prev->next = bo_legacy->next; ++ if (bo_legacy->next) { ++ bo_legacy->next->prev = bo_legacy->prev; ++ } ++ if (!bo_legacy->static_bo) { ++ legacy_free_handle(boml, bo_legacy->base.handle); ++ if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { ++ /* dma buffers */ ++ bo_dma_free(&bo_legacy->base); ++ } else { ++ /* free backing store */ ++ free(bo_legacy->ptr); ++ } ++ } ++ memset(bo_legacy, 0 , sizeof(struct bo_legacy)); ++ free(bo_legacy); ++} ++ ++static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, ++ uint32_t handle, ++ uint32_t size, ++ uint32_t alignment, ++ uint32_t domains, ++ uint32_t flags) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; ++ struct bo_legacy *bo_legacy; ++ int r; ++ ++ if (handle) { ++ bo_legacy = boml->bos.next; ++ while (bo_legacy) { ++ if (bo_legacy->base.handle == handle) { ++ radeon_bo_ref(&(bo_legacy->base)); ++ return (struct radeon_bo*)bo_legacy; ++ } ++ bo_legacy = bo_legacy->next; ++ } ++ return NULL; ++ } ++ ++ bo_legacy = bo_allocate(boml, size, alignment, domains, flags); ++ bo_legacy->static_bo = 0; ++ r = legacy_new_handle(boml, &bo_legacy->base.handle); ++ if (r) { ++ bo_free(bo_legacy); ++ return NULL; ++ } ++ if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { ++ legacy_track_pending(boml); ++ /* dma buffers */ ++ r = bo_dma_alloc(&(bo_legacy->base)); ++ if (r) { ++ fprintf(stderr, "Ran out of GART memory (for %d)!\n", size); ++ fprintf(stderr, "Please consider adjusting GARTSize option.\n"); ++ bo_free(bo_legacy); ++ exit(-1); ++ return NULL; ++ } ++ } else { ++ bo_legacy->ptr = malloc(bo_legacy->base.size); ++ if (bo_legacy->ptr == NULL) { ++ bo_free(bo_legacy); ++ return NULL; ++ } ++ } ++ radeon_bo_ref(&(bo_legacy->base)); ++ return (struct radeon_bo*)bo_legacy; ++} ++ ++static void bo_ref(struct radeon_bo *bo) ++{ ++} ++ ++static struct radeon_bo *bo_unref(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (bo->cref <= 0) { ++ bo_legacy->prev->next = bo_legacy->next; ++ if (bo_legacy->next) { ++ bo_legacy->next->prev = bo_legacy->prev; ++ } ++ if (!bo_legacy->is_pending) { ++ bo_free(bo_legacy); ++ } ++ return NULL; ++ } ++ return bo; ++} ++ ++static int bo_map(struct radeon_bo *bo, int write) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ legacy_wait_pending(bo); ++ bo_legacy->validated = 0; ++ bo_legacy->dirty = 1; ++ bo_legacy->map_count++; ++ bo->ptr = bo_legacy->ptr; ++ /* Read the first pixel in the frame buffer. This should ++ * be a noop, right? In fact without this conform fails as reading ++ * from the framebuffer sometimes produces old results -- the ++ * on-card read cache gets mixed up and doesn't notice that the ++ * framebuffer has been updated. ++ * ++ * Note that we should probably be reading some otherwise unused ++ * region of VRAM, otherwise we might get incorrect results when ++ * reading pixels from the top left of the screen. ++ * ++ * I found this problem on an R420 with glean's texCube test. ++ * Note that the R200 span code also *writes* the first pixel in the ++ * framebuffer, but I've found this to be unnecessary. ++ * -- Nicolai Hähnle, June 2008 ++ */ ++ { ++ int p; ++ volatile int *buf = (int*)boml->screen->driScreen->pFB; ++ p = *buf; ++ } ++ ++ return 0; ++} ++ ++static int bo_unmap(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (--bo_legacy->map_count > 0) { ++ return 0; ++ } ++ bo->ptr = NULL; ++ return 0; ++} ++ ++static struct radeon_bo_funcs bo_legacy_funcs = { ++ bo_open, ++ bo_ref, ++ bo_unref, ++ bo_map, ++ bo_unmap ++}; ++ ++static int bo_vram_validate(struct radeon_bo *bo, ++ uint32_t *soffset, ++ uint32_t *eoffset) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ int r; ++ ++ if (!bo_legacy->got_dri_texture_obj) { ++ make_empty_list(&bo_legacy->dri_texture_obj); ++ bo_legacy->dri_texture_obj.totalSize = bo->size; ++ r = driAllocateTexture(&boml->texture_heap, 1, ++ &bo_legacy->dri_texture_obj); ++ if (r) { ++ uint8_t *segfault=NULL; ++ fprintf(stderr, "Ouch! vram_validate failed %d\n", r); ++ *segfault=1; ++ return -1; ++ } ++ bo_legacy->offset = boml->texture_offset + ++ bo_legacy->dri_texture_obj.memBlock->ofs; ++ bo_legacy->got_dri_texture_obj = 1; ++ bo_legacy->dirty = 1; ++ } ++ if (bo_legacy->dirty) { ++ /* Copy to VRAM using a blit. ++ * All memory is 4K aligned. We're using 1024 pixels wide blits. ++ */ ++ drm_radeon_texture_t tex; ++ drm_radeon_tex_image_t tmp; ++ int ret; ++ ++ tex.offset = bo_legacy->offset; ++ tex.image = &tmp; ++ assert(!(tex.offset & 1023)); ++ ++ tmp.x = 0; ++ tmp.y = 0; ++ if (bo->size < 4096) { ++ tmp.width = (bo->size + 3) / 4; ++ tmp.height = 1; ++ } else { ++ tmp.width = 1024; ++ tmp.height = (bo->size + 4095) / 4096; ++ } ++ tmp.data = bo_legacy->ptr; ++ tex.format = RADEON_TXFORMAT_ARGB8888; ++ tex.width = tmp.width; ++ tex.height = tmp.height; ++ tex.pitch = MAX2(tmp.width / 16, 1); ++ do { ++ ret = drmCommandWriteRead(bo->bom->fd, ++ DRM_RADEON_TEXTURE, ++ &tex, ++ sizeof(drm_radeon_texture_t)); ++ if (ret) { ++ if (RADEON_DEBUG & DEBUG_IOCTL) ++ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n"); ++ usleep(1); ++ } ++ } while (ret == -EAGAIN); ++ bo_legacy->dirty = 0; ++ } ++ return 0; ++} ++ ++int radeon_bo_legacy_validate(struct radeon_bo *bo, ++ uint32_t *soffset, ++ uint32_t *eoffset) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ int r; ++ ++ if (bo_legacy->map_count) { ++ fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n", ++ bo, bo->size, bo_legacy->map_count); ++ return -EINVAL; ++ } ++ if (bo_legacy->static_bo || bo_legacy->validated) { ++ *soffset = bo_legacy->offset; ++ *eoffset = bo_legacy->offset + bo->size; ++ return 0; ++ } ++ if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) { ++ r = bo_vram_validate(bo, soffset, eoffset); ++ if (r) { ++ return r; ++ } ++ } ++ *soffset = bo_legacy->offset; ++ *eoffset = bo_legacy->offset + bo->size; ++ bo_legacy->validated = 1; ++ return 0; ++} ++ ++void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ bo_legacy->pending = pending; ++ bo_legacy->is_pending += 1; ++ /* add to pending list */ ++ radeon_bo_ref(bo); ++ if (bo_legacy->is_pending > 1) { ++ return; ++ } ++ bo_legacy->pprev = boml->pending_bos.pprev; ++ bo_legacy->pnext = NULL; ++ bo_legacy->pprev->pnext = bo_legacy; ++ boml->pending_bos.pprev = bo_legacy; ++ boml->cpendings++; ++} ++ ++void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; ++ struct bo_legacy *bo_legacy; ++ ++ if (bom == NULL) { ++ return; ++ } ++ bo_legacy = boml->bos.next; ++ while (bo_legacy) { ++ struct bo_legacy *next; ++ ++ next = bo_legacy->next; ++ bo_free(bo_legacy); ++ bo_legacy = next; ++ } ++ free(boml->free_handles); ++ free(boml); ++} ++ ++struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn) ++{ ++ struct bo_manager_legacy *bom; ++ struct bo_legacy *bo; ++ unsigned size; ++ ++ bom = (struct bo_manager_legacy*) ++ calloc(1, sizeof(struct bo_manager_legacy)); ++ if (bom == NULL) { ++ return NULL; ++ } ++ ++ bom->texture_heap = driCreateTextureHeap(0, ++ bom, ++ scrn->texSize[0], ++ 12, ++ RADEON_NR_TEX_REGIONS, ++ (drmTextureRegionPtr)scrn->sarea->tex_list[0], ++ &scrn->sarea->tex_age[0], ++ &bom->texture_swapped, ++ sizeof(struct bo_legacy), ++ &bo_legacy_tobj_destroy); ++ bom->texture_offset = scrn->texOffset[0]; ++ ++ bom->base.funcs = &bo_legacy_funcs; ++ bom->base.fd = scrn->driScreen->fd; ++ bom->bos.next = NULL; ++ bom->bos.prev = NULL; ++ bom->pending_bos.pprev = &bom->pending_bos; ++ bom->pending_bos.pnext = NULL; ++ bom->screen = scrn; ++ bom->fb_location = scrn->fbLocation; ++ bom->nhandle = 1; ++ bom->cfree_handles = 0; ++ bom->nfree_handles = 0x400; ++ bom->free_handles = (uint32_t*)malloc(bom->nfree_handles * 4); ++ if (bom->free_handles == NULL) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ ++ /* biggest framebuffer size */ ++ size = 4096*4096*4; ++ /* allocate front */ ++ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ if (bo == NULL) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ if (scrn->sarea->tiling_enabled) { ++ bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE; ++ } ++ bo->static_bo = 1; ++ bo->offset = bom->screen->frontOffset + bom->fb_location; ++ bo->base.handle = bo->offset; ++ bo->ptr = scrn->driScreen->pFB + bom->screen->frontOffset; ++ if (bo->base.handle > bom->nhandle) { ++ bom->nhandle = bo->base.handle + 1; ++ } ++ /* allocate back */ ++ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ if (bo == NULL) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ if (scrn->sarea->tiling_enabled) { ++ bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE; ++ } ++ bo->static_bo = 1; ++ bo->offset = bom->screen->backOffset + bom->fb_location; ++ bo->base.handle = bo->offset; ++ bo->ptr = scrn->driScreen->pFB + bom->screen->backOffset; ++ if (bo->base.handle > bom->nhandle) { ++ bom->nhandle = bo->base.handle + 1; ++ } ++ /* allocate depth */ ++ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); ++ if (bo == NULL) { ++ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); ++ return NULL; ++ } ++ bo->base.flags = 0; ++ if (scrn->sarea->tiling_enabled) { ++ bo->base.flags |= RADEON_BO_FLAGS_MACRO_TILE; ++ bo->base.flags |= RADEON_BO_FLAGS_MICRO_TILE; ++ } ++ bo->static_bo = 1; ++ bo->offset = bom->screen->depthOffset + bom->fb_location; ++ bo->base.handle = bo->offset; ++ bo->ptr = scrn->driScreen->pFB + bom->screen->depthOffset; ++ if (bo->base.handle > bom->nhandle) { ++ bom->nhandle = bo->base.handle + 1; ++ } ++ return (struct radeon_bo_manager*)bom; ++} ++ ++void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom) ++{ ++ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; ++ DRI_AGE_TEXTURES(boml->texture_heap); ++} ++ ++unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo) ++{ ++ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; ++ ++ if (bo_legacy->static_bo || (bo->domains & RADEON_GEM_DOMAIN_GTT)) { ++ return 0; ++ } ++ return bo->size; ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h +new file mode 100644 +index 0000000..208171e +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE 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 ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_BO_LEGACY_H ++#define RADEON_BO_LEGACY_H ++ ++#include "radeon_bo.h" ++#include "radeon_screen.h" ++ ++void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending); ++int radeon_bo_legacy_validate(struct radeon_bo *bo, ++ uint32_t *soffset, ++ uint32_t *eoffset); ++struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn); ++void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom); ++void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom); ++unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo); ++ ++#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer.h b/src/mesa/drivers/dri/radeon/radeon_buffer.h new file mode 100644 -index 0000000..1f9fdff +index 0000000..62cdfad --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_buffer.h -@@ -0,0 +1,47 @@ +@@ -0,0 +1,49 @@ +/* + * Copyright 2008 Red Hat, Inc. + * @@ -8396,201 +9395,36 @@ index 0000000..1f9fdff +#ifndef RADEON_BUFFER_H +#define RADEON_BUFFER_H + -+#include "radeon_dri_bufmgr.h" ++#include "radeon_bo.h" +#include "dri_util.h" + +struct radeon_renderbuffer +{ + struct gl_renderbuffer base; -+ dri_bo *bo; ++ struct radeon_bo *bo; + unsigned int cpp; + /* unsigned int offset; */ + unsigned int pitch; ++ unsigned int width; + unsigned int height; + + /* boo Xorg 6.8.2 compat */ -+ int depthHasSurface; ++ int has_surface; ++ + + __DRIdrawablePrivate *dPriv; +}; + +#endif -diff --git a/src/mesa/drivers/dri/radeon/radeon_dri_bufmgr.c b/src/mesa/drivers/dri/radeon/radeon_dri_bufmgr.c +diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c new file mode 100644 -index 0000000..0bae2b5 +index 0000000..20956ff --- /dev/null -+++ b/src/mesa/drivers/dri/radeon/radeon_dri_bufmgr.c -@@ -0,0 +1,160 @@ -+/* -+ * Copyright © 2007 Intel Corporation -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ * -+ * Authors: -+ * Eric Anholt -+ * -+ */ -+ -+#include -+#include -+#include -+#include "main/mtypes.h" -+#include "radeon_dri_bufmgr.h" -+ -+/** @file dri_bufmgr.c -+ * -+ * Convenience functions for buffer management methods. -+ */ -+ -+dri_bo * -+dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, -+ unsigned int alignment, uint64_t location_mask) -+{ -+ return bufmgr->bo_alloc(bufmgr, name, size, alignment, location_mask); -+} -+ -+dri_bo * -+dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, -+ unsigned long size, void *virtual, -+ uint64_t location_mask) -+{ -+ return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, -+ location_mask); -+} -+ -+void -+dri_bo_reference(dri_bo *bo) -+{ -+ bo->bufmgr->bo_reference(bo); -+} -+ -+void -+dri_bo_unreference(dri_bo *bo) -+{ -+ if (bo == NULL) -+ return; -+ -+ bo->bufmgr->bo_unreference(bo); -+} -+ -+int -+dri_bo_map(dri_bo *buf, GLboolean write_enable) -+{ -+ return buf->bufmgr->bo_map(buf, write_enable); -+} -+ -+int -+dri_bo_unmap(dri_bo *buf) -+{ -+ return buf->bufmgr->bo_unmap(buf); -+} -+ -+void -+dri_fence_wait(dri_fence *fence) -+{ -+ fence->bufmgr->fence_wait(fence); -+} -+ -+void -+dri_fence_reference(dri_fence *fence) -+{ -+ fence->bufmgr->fence_reference(fence); -+} -+ -+void -+dri_fence_unreference(dri_fence *fence) -+{ -+ if (fence == NULL) -+ return; -+ -+ fence->bufmgr->fence_unreference(fence); -+} -+ -+void -+dri_bo_subdata(dri_bo *bo, unsigned long offset, -+ unsigned long size, const void *data) -+{ -+ if (size == 0 || data == NULL) -+ return; -+ -+ dri_bo_map(bo, GL_TRUE); -+ memcpy((unsigned char *)bo->virtual + offset, data, size); -+ dri_bo_unmap(bo); -+} -+ -+void -+dri_bo_get_subdata(dri_bo *bo, unsigned long offset, -+ unsigned long size, void *data) -+{ -+ if (size == 0 || data == NULL) -+ return; -+ -+ dri_bo_map(bo, GL_FALSE); -+ memcpy(data, (unsigned char *)bo->virtual + offset, size); -+ dri_bo_unmap(bo); -+} -+ -+void -+dri_bufmgr_destroy(dri_bufmgr *bufmgr) -+{ -+ bufmgr->destroy(bufmgr); -+} -+ -+ -+int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta, -+ GLuint offset, dri_bo *target_buf) -+{ -+ return reloc_buf->bufmgr->emit_reloc(reloc_buf, flags, delta, offset, target_buf); -+} -+ -+void *dri_process_relocs(dri_bo *batch_buf, GLuint *count) -+{ -+ return batch_buf->bufmgr->process_relocs(batch_buf, count); -+} -+ -+void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence) -+{ -+ batch_buf->bufmgr->post_submit(batch_buf, last_fence); -+} -+ -+void -+dri_bufmgr_set_debug(dri_bufmgr *bufmgr, GLboolean enable_debug) -+{ -+ bufmgr->debug = enable_debug; -+} -+ -+int -+dri_bufmgr_check_aperture_space(dri_bo *bo) -+{ -+ return bo->bufmgr->check_aperture_space(bo); -+} -diff --git a/src/mesa/drivers/dri/radeon/radeon_dri_bufmgr.h b/src/mesa/drivers/dri/radeon/radeon_dri_bufmgr.h -new file mode 100644 -index 0000000..0a726dc ---- /dev/null -+++ b/src/mesa/drivers/dri/radeon/radeon_dri_bufmgr.h -@@ -0,0 +1,260 @@ -+/************************************************************************** -+ * -+ * Copyright © 2007 Intel Corporation -+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA ++++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +@@ -0,0 +1,424 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a @@ -8612,246 +9446,466 @@ index 0000000..0a726dc + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. -+ * -+ * -+ **************************************************************************/ ++ */ +/* -+ * Authors: Thomas Hellström -+ * Keith Whitwell -+ * Eric Anholt ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse + */ ++#include ++#include "r300_reg.h" ++#include "r300_emit.h" ++#include "r300_cmdbuf.h" ++#include "radeon_cs.h" ++#include "radeon_cs_legacy.h" ++#include "radeon_bo_legacy.h" ++#include "radeon_context.h" + -+#ifndef _DRI_BUFMGR_H_ -+#define _DRI_BUFMGR_H_ -+#include -+ -+typedef struct _dri_bufmgr dri_bufmgr; -+typedef struct _dri_bo dri_bo; -+typedef struct _dri_fence dri_fence; -+ -+struct _dri_bo { -+ /** Size in bytes of the buffer object. */ -+ unsigned long size; -+ /** -+ * Card virtual address (offset from the beginning of the aperture) for the -+ * object. Only valid while validated. -+ */ -+ unsigned long offset; -+ /** -+ * Virtual address for accessing the buffer data. Only valid while mapped. -+ */ -+ void *virtual; -+ /** Buffer manager context associated with this buffer object */ -+ dri_bufmgr *bufmgr; ++struct cs_manager_legacy { ++ struct radeon_cs_manager base; ++ struct radeon_context *ctx; ++ /* hack for scratch stuff */ ++ uint32_t pending_age; ++ uint32_t pending_count; +}; + -+struct _dri_fence { -+ /** -+ * This is an ORed mask of DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE, and -+ * DRM_FLAG_EXE indicating the operations associated with this fence. -+ * -+ * It is constant for the life of the fence object. -+ */ -+ unsigned int type; -+ /** Buffer manager context associated with this fence */ -+ dri_bufmgr *bufmgr; ++struct cs_reloc_legacy { ++ struct radeon_cs_reloc base; ++ uint32_t cindices; ++ uint32_t *indices; +}; + -+/** -+ * Context for a buffer manager instance. ++ ++static struct radeon_cs *cs_create(struct radeon_cs_manager *csm, ++ uint32_t ndw) ++{ ++ struct radeon_cs *cs; ++ ++ cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs)); ++ if (cs == NULL) { ++ return NULL; ++ } ++ cs->csm = csm; ++ cs->ndw = (ndw + 0x3FF) & (~0x3FF); ++ cs->packets = (uint32_t*)malloc(4*cs->ndw); ++ if (cs->packets == NULL) { ++ free(cs); ++ return NULL; ++ } ++ cs->relocs_total_size = 0; ++ return cs; ++} ++ ++static int cs_write_dword(struct radeon_cs *cs, uint32_t dword) ++{ ++ if (cs->cdw >= cs->ndw) { ++ uint32_t tmp, *ptr; ++ tmp = (cs->cdw + 1 + 0x3FF) & (~0x3FF); ++ ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); ++ if (ptr == NULL) { ++ return -ENOMEM; ++ } ++ cs->packets = ptr; ++ cs->ndw = tmp; ++ } ++ cs->packets[cs->cdw++] = dword; ++ if (cs->section) { ++ cs->section_cdw++; ++ } ++ return 0; ++} ++ ++static int cs_write_reloc(struct radeon_cs *cs, ++ struct radeon_bo *bo, ++ uint32_t start_offset, ++ uint32_t end_offset, ++ uint32_t read_domain, ++ uint32_t write_domain, ++ uint32_t flags) ++{ ++ struct cs_reloc_legacy *relocs; ++ int i; ++ ++ relocs = (struct cs_reloc_legacy *)cs->relocs; ++ /* check domains */ ++ if ((read_domain && write_domain) || (!read_domain && !write_domain)) { ++ /* in one CS a bo can only be in read or write domain but not ++ * in read & write domain at the same sime ++ */ ++ return -EINVAL; ++ } ++ if (read_domain == RADEON_GEM_DOMAIN_CPU) { ++ return -EINVAL; ++ } ++ if (write_domain == RADEON_GEM_DOMAIN_CPU) { ++ return -EINVAL; ++ } ++ /* check reloc window */ ++ if (end_offset > bo->size) { ++ return -EINVAL; ++ } ++ if (start_offset > end_offset) { ++ return -EINVAL; ++ } ++ /* check if bo is already referenced */ ++ for(i = 0; i < cs->crelocs; i++) { ++ uint32_t *indices; ++ ++ if (relocs[i].base.bo->handle == bo->handle) { ++ /* update start and end offset */ ++ if (start_offset < relocs[i].base.start_offset) { ++ relocs[i].base.start_offset = start_offset; ++ } ++ if (end_offset > relocs[i].base.end_offset) { ++ relocs[i].base.end_offset = end_offset; ++ } ++ /* Check domains must be in read or write. As we check already ++ * checked that in argument one of the read or write domain was ++ * set we only need to check that if previous reloc as the read ++ * domain set then the read_domain should also be set for this ++ * new relocation. ++ */ ++ if (relocs[i].base.read_domain && !read_domain) { ++ return -EINVAL; ++ } ++ if (relocs[i].base.write_domain && !write_domain) { ++ return -EINVAL; ++ } ++ relocs[i].base.read_domain |= read_domain; ++ relocs[i].base.write_domain |= write_domain; ++ /* save indice */ ++ relocs[i].cindices += 1; ++ indices = (uint32_t*)realloc(relocs[i].indices, ++ relocs[i].cindices * 4); ++ if (indices == NULL) { ++ relocs[i].cindices -= 1; ++ return -ENOMEM; ++ } ++ relocs[i].indices = indices; ++ relocs[i].indices[relocs[i].cindices - 1] = cs->cdw - 1; ++ return 0; ++ } ++ } ++ /* add bo to reloc */ ++ relocs = (struct cs_reloc_legacy*) ++ realloc(cs->relocs, ++ sizeof(struct cs_reloc_legacy) * (cs->crelocs + 1)); ++ if (relocs == NULL) { ++ return -ENOMEM; ++ } ++ cs->relocs = relocs; ++ relocs[cs->crelocs].base.bo = bo; ++ relocs[cs->crelocs].base.start_offset = start_offset; ++ relocs[cs->crelocs].base.end_offset = end_offset; ++ relocs[cs->crelocs].base.read_domain = read_domain; ++ relocs[cs->crelocs].base.write_domain = write_domain; ++ relocs[cs->crelocs].base.flags = flags; ++ relocs[cs->crelocs].indices = (uint32_t*)malloc(4); ++ if (relocs[cs->crelocs].indices == NULL) { ++ return -ENOMEM; ++ } ++ relocs[cs->crelocs].indices[0] = cs->cdw - 1; ++ relocs[cs->crelocs].cindices = 1; ++ cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo); ++ cs->crelocs++; ++ radeon_bo_ref(bo); ++ return 0; ++} ++ ++static int cs_begin(struct radeon_cs *cs, ++ uint32_t ndw, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ if (cs->section) { ++ fprintf(stderr, "CS already in a section(%s,%s,%d)\n", ++ cs->section_file, cs->section_func, cs->section_line); ++ fprintf(stderr, "CS can't start section(%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ cs->section = 1; ++ cs->section_ndw = ndw; ++ cs->section_cdw = 0; ++ cs->section_file = file; ++ cs->section_func = func; ++ cs->section_line = line; ++ return 0; ++} ++ ++static int cs_end(struct radeon_cs *cs, ++ const char *file, ++ const char *func, ++ int line) ++ ++{ ++ if (!cs->section) { ++ fprintf(stderr, "CS no section to end at (%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ cs->section = 0; ++ if (cs->section_ndw != cs->section_cdw) { ++ fprintf(stderr, "CS section size missmatch start at (%s,%s,%d)\n", ++ cs->section_file, cs->section_func, cs->section_line); ++ fprintf(stderr, "CS section end at (%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ return 0; ++} ++ ++static int cs_process_relocs(struct radeon_cs *cs) ++{ ++ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; ++ struct cs_reloc_legacy *relocs; ++ int i, j, r; ++ ++ if (!IS_R300_CLASS(csm->ctx->radeonScreen)) { ++ /* FIXME: r300 only right now */ ++ return -EINVAL; ++ } ++ csm = (struct cs_manager_legacy*)cs->csm; ++ relocs = (struct cs_reloc_legacy *)cs->relocs; ++ for (i = 0; i < cs->crelocs; i++) { ++ for (j = 0; j < relocs[i].cindices; j++) { ++ uint32_t soffset, eoffset; ++ ++ soffset = relocs[i].base.start_offset; ++ eoffset = relocs[i].base.end_offset; ++ r = radeon_bo_legacy_validate(relocs[i].base.bo, ++ &soffset, &eoffset); ++ if (r) { ++ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n", ++ relocs[i].base.bo, soffset, eoffset); ++ return r; ++ } ++ cs->packets[relocs[i].indices[j]] += soffset; ++ if (cs->packets[relocs[i].indices[j]] >= eoffset) { ++ radeon_bo_debug(relocs[i].base.bo, 12); ++ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n", ++ relocs[i].base.bo, soffset, eoffset); ++ fprintf(stderr, "above end: %p 0x%08X 0x%08X\n", ++ relocs[i].base.bo, ++ cs->packets[relocs[i].indices[j]], ++ eoffset); ++ exit(0); ++ return -EINVAL; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int cs_set_age(struct radeon_cs *cs) ++{ ++ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; ++ struct cs_reloc_legacy *relocs; ++ int i; ++ ++ relocs = (struct cs_reloc_legacy *)cs->relocs; ++ for (i = 0; i < cs->crelocs; i++) { ++ radeon_bo_legacy_pending(relocs[i].base.bo, csm->pending_age); ++ radeon_bo_unref(relocs[i].base.bo); ++ } ++ return 0; ++} ++ ++static int cs_emit(struct radeon_cs *cs) ++{ ++ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; ++ drm_radeon_cmd_buffer_t cmd; ++ drm_r300_cmd_header_t age; ++ uint64_t ull; ++ int r; ++ ++ /* please flush pipe do all pending work */ ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_SC_SCREENDOOR, 1)); ++ cs_write_dword(cs, 0x0); ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_SC_SCREENDOOR, 1)); ++ cs_write_dword(cs, 0x00FFFFFF); ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_SC_HYPERZ, 1)); ++ cs_write_dword(cs, 0x0); ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_US_CONFIG, 1)); ++ cs_write_dword(cs, 0x0); ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_ZB_CNTL, 1)); ++ cs_write_dword(cs, 0x0); ++ cs_write_dword(cs, cmdwait(csm->ctx->radeonScreen, R300_WAIT_3D)); ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_RB3D_DSTCACHE_CTLSTAT, 1)); ++ cs_write_dword(cs, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); ++ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, ++ R300_ZB_ZCACHE_CTLSTAT, 1)); ++ cs_write_dword(cs, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); ++ cs_write_dword(cs, cmdwait(csm->ctx->radeonScreen, ++ R300_WAIT_3D | R300_WAIT_3D_CLEAN)); ++ ++ /* append buffer age */ ++ age.scratch.cmd_type = R300_CMD_SCRATCH; ++ /* Scratch register 2 corresponds to what radeonGetAge polls */ ++ csm->pending_age = 0; ++ csm->pending_count = 1; ++ ull = (uint64_t) (intptr_t) &csm->pending_age; ++ age.scratch.reg = 2; ++ age.scratch.n_bufs = 1; ++ age.scratch.flags = 0; ++ radeon_cs_write_dword(cs, age.u); ++ radeon_cs_write_dword(cs, ull & 0xffffffff); ++ radeon_cs_write_dword(cs, ull >> 32); ++ radeon_cs_write_dword(cs, 0); ++ ++ r = cs_process_relocs(cs); ++ if (r) { ++ return 0; ++ } ++ ++ cmd.buf = (char *)cs->packets; ++ cmd.bufsz = cs->cdw * 4; ++ if (csm->ctx->state.scissor.enabled) { ++ cmd.nbox = csm->ctx->state.scissor.numClipRects; ++ cmd.boxes = (drm_clip_rect_t *) csm->ctx->state.scissor.pClipRects; ++ } else { ++ cmd.nbox = csm->ctx->numClipRects; ++ cmd.boxes = (drm_clip_rect_t *) csm->ctx->pClipRects; ++ } ++ ++ r = drmCommandWrite(cs->csm->fd, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd)); ++ if (r) { ++ return r; ++ } ++ cs_set_age(cs); ++ return 0; ++} ++ ++static int cs_destroy(struct radeon_cs *cs) ++{ ++ free(cs->relocs); ++ free(cs->packets); ++ free(cs); ++ return 0; ++} ++ ++static int cs_erase(struct radeon_cs *cs) ++{ ++ free(cs->relocs); ++ cs->relocs_total_size = 0; ++ cs->relocs = NULL; ++ cs->crelocs = 0; ++ cs->cdw = 0; ++ cs->section = 0; ++ return 0; ++} ++ ++static int cs_need_flush(struct radeon_cs *cs) ++{ ++ /* FIXME: we should get the texture heap size */ ++ return (cs->relocs_total_size > (7*1024*1024)); ++} ++ ++static void cs_print(struct radeon_cs *cs, FILE *file) ++{ ++} ++ ++static struct radeon_cs_funcs radeon_cs_legacy_funcs = { ++ cs_create, ++ cs_write_dword, ++ cs_write_reloc, ++ cs_begin, ++ cs_end, ++ cs_emit, ++ cs_destroy, ++ cs_erase, ++ cs_need_flush, ++ cs_print ++}; ++ ++struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx) ++{ ++ struct cs_manager_legacy *csm; ++ ++ csm = (struct cs_manager_legacy*) ++ calloc(1, sizeof(struct cs_manager_legacy)); ++ if (csm == NULL) { ++ return NULL; ++ } ++ csm->base.funcs = &radeon_cs_legacy_funcs; ++ csm->base.fd = ctx->dri.fd; ++ csm->ctx = ctx; ++ csm->pending_age = 1; ++ return (struct radeon_cs_manager*)csm; ++} ++ ++void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm) ++{ ++ free(csm); ++} +diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +new file mode 100644 +index 0000000..71a4dad +--- /dev/null ++++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE 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 ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. + * -+ * Contains public methods followed by private storage for the buffer manager. ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. + */ -+struct _dri_bufmgr { -+ /** -+ * Allocate a buffer object. -+ * -+ * Buffer objects are not necessarily initially mapped into CPU virtual -+ * address space or graphics device aperture. They must be mapped using -+ * bo_map() to be used by the CPU, and validated for use using bo_validate() -+ * to be used from the graphics device. -+ */ -+ dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, -+ unsigned long size, unsigned int alignment, -+ uint64_t location_mask); ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_CS_LEGACY_H ++#define RADEON_CS_LEGACY_H + -+ /** -+ * Allocates a buffer object for a static allocation. -+ * -+ * Static allocations are ones such as the front buffer that are offered by -+ * the X Server, which are never evicted and never moved. -+ */ -+ dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name, -+ unsigned long offset, unsigned long size, -+ void *virtual, uint64_t location_mask); ++#include "radeon_cs.h" ++#include "radeon_context.h" + -+ /** Takes a reference on a buffer object */ -+ void (*bo_reference)(dri_bo *bo); -+ -+ /** -+ * Releases a reference on a buffer object, freeing the data if -+ * rerefences remain. -+ */ -+ void (*bo_unreference)(dri_bo *bo); -+ -+ /** -+ * Maps the buffer into userspace. -+ * -+ * This function will block waiting for any existing fence on the buffer to -+ * clear, first. The resulting mapping is available at buf->virtual. -+\ */ -+ int (*bo_map)(dri_bo *buf, GLboolean write_enable); -+ -+ /** Reduces the refcount on the userspace mapping of the buffer object. */ -+ int (*bo_unmap)(dri_bo *buf); -+ -+ /** Takes a reference on a fence object */ -+ void (*fence_reference)(dri_fence *fence); -+ -+ /** -+ * Releases a reference on a fence object, freeing the data if -+ * rerefences remain. -+ */ -+ void (*fence_unreference)(dri_fence *fence); -+ -+ /** -+ * Blocks until the given fence is signaled. -+ */ -+ void (*fence_wait)(dri_fence *fence); -+ -+ /** -+ * Tears down the buffer manager instance. -+ */ -+ void (*destroy)(dri_bufmgr *bufmgr); -+ -+ /** -+ * Add relocation entry in reloc_buf, which will be updated with the -+ * target buffer's real offset on on command submission. -+ * -+ * Relocations remain in place for the lifetime of the buffer object. -+ * -+ * \param reloc_buf Buffer to write the relocation into. -+ * \param flags BO flags to be used in validating the target buffer. -+ * Applicable flags include: -+ * - DRM_BO_FLAG_READ: The buffer will be read in the process of -+ * command execution. -+ * - DRM_BO_FLAG_WRITE: The buffer will be written in the process of -+ * command execution. -+ * - DRM_BO_FLAG_MEM_TT: The buffer should be validated in TT memory. -+ * - DRM_BO_FLAG_MEM_VRAM: The buffer should be validated in video -+ * memory. -+ * \param delta Constant value to be added to the relocation target's offset. -+ * \param offset Byte offset within batch_buf of the relocated pointer. -+ * \param target Buffer whose offset should be written into the relocation -+ * entry. -+ */ -+ int (*emit_reloc)(dri_bo *reloc_buf, uint64_t flags, GLuint delta, -+ GLuint offset, dri_bo *target); -+ -+ /** -+ * Processes the relocations, either in userland or by converting the list -+ * for use in batchbuffer submission. -+ * -+ * Kernel-based implementations will return a pointer to the arguments -+ * to be handed with batchbuffer submission to the kernel. The userland -+ * implementation performs the buffer validation and emits relocations -+ * into them the appopriate order. -+ * -+ * \param batch_buf buffer at the root of the tree of relocations -+ * \param count returns the number of buffers validated. -+ * \return relocation record for use in command submission. -+ * */ -+ void *(*process_relocs)(dri_bo *batch_buf, GLuint *count); -+ -+ void (*post_submit)(dri_bo *batch_buf, dri_fence **fence); -+ -+ int (*check_aperture_space)(dri_bo *bo); -+ GLboolean debug; /**< Enables verbose debugging printouts */ -+}; -+ -+dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, -+ unsigned int alignment, uint64_t location_mask); -+dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, -+ unsigned long offset, unsigned long size, -+ void *virtual, uint64_t location_mask); -+void dri_bo_reference(dri_bo *bo); -+void dri_bo_unreference(dri_bo *bo); -+int dri_bo_map(dri_bo *buf, GLboolean write_enable); -+int dri_bo_unmap(dri_bo *buf); -+void dri_fence_wait(dri_fence *fence); -+void dri_fence_reference(dri_fence *fence); -+void dri_fence_unreference(dri_fence *fence); -+ -+void dri_bo_subdata(dri_bo *bo, unsigned long offset, -+ unsigned long size, const void *data); -+void dri_bo_get_subdata(dri_bo *bo, unsigned long offset, -+ unsigned long size, void *data); -+ -+void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); -+dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, -+ unsigned long size, -+ unsigned int (*fence_emit)(void *private), -+ int (*fence_wait)(void *private, -+ unsigned int cookie), -+ void *driver_priv); -+void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, GLboolean enable_debug); -+void dri_bo_fake_disable_backing_store(dri_bo *bo, -+ void (*invalidate_cb)(dri_bo *bo, -+ void *ptr), -+ void *ptr); -+void dri_bufmgr_destroy(dri_bufmgr *bufmgr); -+ -+int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta, -+ GLuint offset, dri_bo *target_buf); -+void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count); -+void dri_post_process_relocs(dri_bo *batch_buf); -+void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence); -+int dri_bufmgr_check_aperture_space(dri_bo *bo); -+ -+#ifndef TTM_API -+/* reuse some TTM API */ -+ -+#define DRM_BO_MEM_LOCAL 0 -+#define DRM_BO_MEM_TT 1 -+#define DRM_BO_MEM_VRAM 2 -+#define DRM_BO_MEM_PRIV0 3 -+#define DRM_BO_MEM_PRIV1 4 -+#define DRM_BO_MEM_PRIV2 5 -+#define DRM_BO_MEM_PRIV3 6 -+#define DRM_BO_MEM_PRIV4 7 -+ -+#define DRM_BO_FLAG_READ (1ULL << 0) -+#define DRM_BO_FLAG_WRITE (1ULL << 1) -+#define DRM_BO_FLAG_EXE (1ULL << 2) -+#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) -+#define DRM_BO_FLAG_NO_EVICT (1ULL << 4) -+ -+#define DRM_BO_FLAG_MAPPABLE (1ULL << 5) -+#define DRM_BO_FLAG_SHAREABLE (1ULL << 6) -+ -+#define DRM_BO_FLAG_CACHED (1ULL << 7) -+ -+#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) -+#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19) -+#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13) -+#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) -+#define DRM_BO_FLAG_TILE (1ULL << 15) -+ -+#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) -+#define DRM_BO_FLAG_MEM_TT (1ULL << 25) -+#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) -+ -+#define DRM_BO_MASK_MEM 0x00000000FF000000ULL -+ -+#define DRM_FENCE_TYPE_EXE 0x00000001 -+#endif ++struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); ++void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm); + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c -index 05107dd..1810ded 100644 +index 5f32dd5..0dda28e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c -@@ -45,6 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@@ -35,6 +35,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * \author Gareth Hughes + */ + ++#include + #include "main/glheader.h" + #include "main/imports.h" + #include "main/mtypes.h" +@@ -45,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_chipset.h" #include "radeon_macros.h" #include "radeon_screen.h" @@ -8859,135 +9913,40 @@ index 05107dd..1810ded 100644 #if !RADEON_COMMON #include "radeon_context.h" #include "radeon_span.h" -@@ -67,6 +68,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - #include "GL/internal/dri_interface.h" - -+#include -+#include -+ +@@ -70,6 +72,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Radeon configuration */ #include "xmlpool.h" -@@ -348,11 +352,115 @@ static const __DRItexOffsetExtension r300texOffsetExtension = { ++#include "radeon_bo_legacy.h" ++#include "radeon_bo_gem.h" + + #if !RADEON_COMMON /* R100 */ + PUBLIC const char __driConfigOptions[] = +@@ -346,6 +350,14 @@ static const __DRItexOffsetExtension r300texOffsetExtension = { + { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, + r300SetTexOffset, }; ++ ++void r300SetTexBuffer(__DRIcontext *pDRICtx, ++ GLint target, ++ __DRIdrawable *dPriv); ++static const __DRItexBufferExtension r300TexBufferExtension = { ++ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, ++ r300SetTexBuffer, ++}; #endif -+ -+static int -+radeon_gem_update_handle(radeonScreenPtr screen, __DRIscreenPrivate *sPriv, -+ struct radeon_gem_object *gem_obj) -+{ -+ struct drm_gem_close close_args; -+ struct drm_gem_open args; -+ struct drm_radeon_gem_mmap mmap_args; -+ struct drm_radeon_gem_pin pin_args; -+ int ret; -+ -+ if (gem_obj->gem_handle) { -+ close_args.handle = gem_obj->gem_handle; -+ -+ ioctl(sPriv->fd, DRM_IOCTL_GEM_CLOSE, &close_args); -+ gem_obj->gem_handle = 0; -+ } -+ -+ /* do open */ -+ args.name = gem_obj->gem_name; -+ ret = ioctl(sPriv->fd, DRM_IOCTL_GEM_OPEN, &args); -+ if (ret) { -+ fprintf(stderr,"failed to open\n"); -+ return ret; -+ } -+ -+ gem_obj->gem_handle = args.handle; -+ gem_obj->size = args.size; -+ -+ mmap_args.handle = gem_obj->gem_handle; -+ mmap_args.size = gem_obj->size; -+ mmap_args.offset = 0; -+ -+ ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GEM_MMAP, &mmap_args, -+ sizeof(mmap_args)); -+ -+ if (ret) { -+ fprintf(stderr,"failed to mmap\n"); -+ return ret; -+ } -+ -+ gem_obj->map = (void *)(unsigned long)(mmap_args.addr_ptr); -+ -+ pin_args.handle = gem_obj->gem_handle; -+ pin_args.pin_domain = 0; -+ pin_args.alignment = 0; -+ -+ ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GEM_PIN, &pin_args, -+ sizeof(pin_args)); -+ -+ if (ret) { -+ fprintf(stderr,"failed to get offset\n"); -+ return ret; -+ } -+ -+ gem_obj->offset = pin_args.offset; -+ return 0; -+} -+ -+static int -+radeon_init_mm_buffers(radeonScreenPtr screen, __DRIscreenPrivate *sPriv, -+ RADEONDRIPtr dri_priv) -+{ -+ int ret; -+ /* STOP GAP HERE */ -+ -+ screen->front.gem_name = dri_priv->frontOffset; -+ ret = radeon_gem_update_handle(screen, sPriv, &screen->front); -+ if (ret) -+ return ret; -+ -+ screen->frontOffset = screen->front.offset; -+ -+ screen->back.gem_name = dri_priv->backOffset; -+ ret = radeon_gem_update_handle(screen, sPriv, &screen->back); -+ if (ret) -+ return ret; -+ -+ screen->backOffset = screen->back.offset; -+ -+ screen->depth.gem_name = dri_priv->depthOffset; -+ ret = radeon_gem_update_handle(screen, sPriv, &screen->depth); -+ if (ret) -+ return ret; -+ -+ screen->depthOffset = screen->depth.offset; -+ -+ screen->vram_texture.gem_name = dri_priv->textureOffset; -+ ret = radeon_gem_update_handle(screen, sPriv, &screen->vram_texture); -+ if (ret) -+ return ret; -+ -+ screen->texOffset[RADEON_LOCAL_TEX_HEAP] = screen->vram_texture.offset + screen->fbLocation; -+ screen->texSize[RADEON_LOCAL_TEX_HEAP] = screen->vram_texture.size; -+ -+ screen->gart_texture.gem_name = dri_priv->gartTexHandle; -+ ret = radeon_gem_update_handle(screen, sPriv, &screen->gart_texture); -+ if (ret) -+ return ret; -+ -+ screen->gartTextures.map = screen->gart_texture.map; -+ screen->gart_texture_offset = screen->gart_texture.offset + screen->gart_base; -+ return 0; -+} -+ /* Create the device specific screen private data struct. - */ - static radeonScreenPtr --radeonCreateScreen( __DRIscreenPrivate *sPriv ) --{ -+radeonCreateScreen( __DRIscreenPrivate *sPriv ){ +@@ -355,7 +367,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + { radeonScreenPtr screen; RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; - unsigned char *RADEONMMIO; -@@ -387,6 +495,21 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) +- unsigned char *RADEONMMIO; ++ unsigned char *RADEONMMIO = NULL; + int i; + int ret; + uint32_t temp; +@@ -387,6 +399,21 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP); { int ret; @@ -9009,7 +9968,7 @@ index 05107dd..1810ded 100644 ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET, &screen->gart_buffer_offset); -@@ -420,32 +543,34 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) +@@ -420,58 +447,60 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25); } @@ -9023,21 +9982,9 @@ index 05107dd..1810ded 100644 - __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); - return NULL; - } -+ if (!screen->kernel_mm) { -+ screen->mmio.handle = dri_priv->registerHandle; -+ screen->mmio.size = dri_priv->registerSize; -+ if ( drmMap( sPriv->fd, -+ screen->mmio.handle, -+ screen->mmio.size, -+ &screen->mmio.map ) ) { -+ FREE( screen ); -+ __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); -+ return NULL; -+ } - +- - RADEONMMIO = screen->mmio.map; -+ RADEONMMIO = screen->mmio.map; - +- - screen->status.handle = dri_priv->statusHandle; - screen->status.size = dri_priv->statusSize; - if ( drmMap( sPriv->fd, @@ -9048,29 +9995,19 @@ index 05107dd..1810ded 100644 - FREE( screen ); - __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); - return NULL; -+ screen->status.handle = dri_priv->statusHandle; -+ screen->status.size = dri_priv->statusSize; -+ if ( drmMap( sPriv->fd, -+ screen->status.handle, -+ screen->status.size, -+ &screen->status.map ) ) { -+ drmUnmap( screen->mmio.map, screen->mmio.size ); -+ FREE( screen ); -+ __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); -+ return NULL; -+ } -+ screen->scratch = (__volatile__ u_int32_t *) -+ ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); - } +- } - screen->scratch = (__volatile__ uint32_t *) - ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); - - screen->buffers = drmMapBufs( sPriv->fd ); - if ( !screen->buffers ) { -@@ -456,22 +581,24 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) - return NULL; - } - +- +- screen->buffers = drmMapBufs( sPriv->fd ); +- if ( !screen->buffers ) { +- drmUnmap( screen->status.map, screen->status.size ); +- drmUnmap( screen->mmio.map, screen->mmio.size ); +- FREE( screen ); +- __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); +- return NULL; +- } +- - if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) { - screen->gartTextures.handle = dri_priv->gartTexHandle; - screen->gartTextures.size = dri_priv->gartTexMapSize; @@ -9078,36 +10015,67 @@ index 05107dd..1810ded 100644 - screen->gartTextures.handle, - screen->gartTextures.size, - (drmAddressPtr)&screen->gartTextures.map ) ) { -- drmUnmapBufs( screen->buffers ); -- drmUnmap( screen->status.map, screen->status.size ); -- drmUnmap( screen->mmio.map, screen->mmio.size ); -- FREE( screen ); -- __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__); -- return NULL; + if (!screen->kernel_mm) { -+ if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) { -+ screen->gartTextures.handle = dri_priv->gartTexHandle; -+ screen->gartTextures.size = dri_priv->gartTexMapSize; -+ if ( drmMap( sPriv->fd, -+ screen->gartTextures.handle, -+ screen->gartTextures.size, -+ (drmAddressPtr)&screen->gartTextures.map ) ) { -+ drmUnmapBufs( screen->buffers ); -+ drmUnmap( screen->status.map, screen->status.size ); -+ drmUnmap( screen->mmio.map, screen->mmio.size ); -+ FREE( screen ); -+ __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__); -+ return NULL; -+ } -+ -+ screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base; - } ++ screen->mmio.handle = dri_priv->registerHandle; ++ screen->mmio.size = dri_priv->registerSize; ++ if ( drmMap( sPriv->fd, ++ screen->mmio.handle, ++ screen->mmio.size, ++ &screen->mmio.map ) ) { ++ FREE( screen ); ++ __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); ++ return NULL; ++ } ++ ++ RADEONMMIO = screen->mmio.map; ++ ++ screen->status.handle = dri_priv->statusHandle; ++ screen->status.size = dri_priv->statusSize; ++ if ( drmMap( sPriv->fd, ++ screen->status.handle, ++ screen->status.size, ++ &screen->status.map ) ) { ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ FREE( screen ); ++ __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); ++ return NULL; ++ } ++ screen->scratch = (__volatile__ uint32_t *) ++ ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); ++ ++ screen->buffers = drmMapBufs( sPriv->fd ); ++ if ( !screen->buffers ) { ++ drmUnmap( screen->status.map, screen->status.size ); ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ FREE( screen ); ++ __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); ++ return NULL; ++ } ++ ++ if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) { ++ screen->gartTextures.handle = dri_priv->gartTexHandle; ++ screen->gartTextures.size = dri_priv->gartTexMapSize; ++ if ( drmMap( sPriv->fd, ++ screen->gartTextures.handle, ++ screen->gartTextures.size, ++ (drmAddressPtr)&screen->gartTextures.map ) ) { + drmUnmapBufs( screen->buffers ); + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__); + return NULL; +- } - - screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base; ++ } ++ ++ screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base; ++ } } screen->chip_flags = 0; -@@ -838,7 +965,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) +@@ -838,7 +867,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) ret = radeonGetParam( sPriv->fd, RADEON_PARAM_FB_LOCATION, &temp); if (ret) { @@ -9116,149 +10084,160 @@ index 05107dd..1810ded 100644 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16; else { FREE( screen ); -@@ -879,55 +1006,65 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) - } - } +@@ -960,6 +989,85 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) -- if ( sPriv->drm_version.minor >= 10 ) { -- drm_radeon_setparam_t sp; -- -- sp.param = RADEON_SETPARAM_FB_LOCATION; -- sp.value = screen->fbLocation; -- -- drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM, -- &sp, sizeof( sp ) ); -- } -- -- screen->frontOffset = dri_priv->frontOffset; - screen->frontPitch = dri_priv->frontPitch; -- screen->backOffset = dri_priv->backOffset; - screen->backPitch = dri_priv->backPitch; -- screen->depthOffset = dri_priv->depthOffset; - screen->depthPitch = dri_priv->depthPitch; - -- /* Check if ddx has set up a surface reg to cover depth buffer */ -- screen->depthHasSurface = (sPriv->ddx_version.major > 4) || -- /* these chips don't use tiled z without hyperz. So always pretend -- we have set up a surface which will cause linear reads/writes */ -- ((screen->chip_family & RADEON_CLASS_R100) && -- !(screen->chip_flags & RADEON_CHIPSET_TCL)); -- -- if ( dri_priv->textureSize == 0 ) { -- screen->texOffset[RADEON_LOCAL_TEX_HEAP] = screen->gart_texture_offset; -- screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->gartTexMapSize; -- screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] = -- dri_priv->log2GARTTexGran; -- } else { -- screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset -- + screen->fbLocation; -- screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize; -- screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] = -- dri_priv->log2TexGran; -- } -+ if (!screen->kernel_mm) { -+ if ( sPriv->drm_version.minor >= 10 ) { -+ drm_radeon_setparam_t sp; + screen->driScreen = sPriv; + screen->sarea_priv_offset = dri_priv->sarea_priv_offset; ++ screen->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + ++ screen->sarea_priv_offset); + -+ sp.param = RADEON_SETPARAM_FB_LOCATION; -+ sp.value = screen->fbLocation; ++ if (screen->kernel_mm) ++ screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd); ++ else ++ screen->bom = radeon_bo_manager_legacy_ctor(screen); ++ if (screen->bom == NULL) { ++ free(screen); ++ return NULL; ++ } ++ return screen; ++} + -+ drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM, -+ &sp, sizeof( sp ) ); -+ } - -- if ( !screen->gartTextures.map || dri_priv->textureSize == 0 -- || getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) { -- screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; -- screen->texOffset[RADEON_GART_TEX_HEAP] = 0; -- screen->texSize[RADEON_GART_TEX_HEAP] = 0; -- screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0; -+ screen->frontOffset = dri_priv->frontOffset; -+ screen->backOffset = dri_priv->backOffset; -+ screen->depthOffset = dri_priv->depthOffset; ++static radeonScreenPtr ++radeonCreateScreen2(__DRIscreenPrivate *sPriv) ++{ ++ radeonScreenPtr screen; ++ int i; + -+ -+ /* Check if ddx has set up a surface reg to cover depth buffer */ -+ screen->depthHasSurface = (sPriv->ddx_version.major > 4) || -+ /* these chips don't use tiled z without hyperz. So always pretend -+ we have set up a surface which will cause linear reads/writes */ -+ ((screen->chip_family & RADEON_CLASS_R100) && -+ !(screen->chip_flags & RADEON_CHIPSET_TCL)); -+ -+ if ( dri_priv->textureSize == 0 ) { -+ screen->texOffset[RADEON_LOCAL_TEX_HEAP] = screen->gart_texture_offset; -+ screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->gartTexMapSize; -+ screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] = -+ dri_priv->log2GARTTexGran; -+ } else { -+ screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset -+ + screen->fbLocation; -+ screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize; -+ screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] = -+ dri_priv->log2TexGran; -+ } -+ -+ if ( !screen->gartTextures.map || dri_priv->textureSize == 0 -+ || getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) { -+ screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; -+ screen->texOffset[RADEON_GART_TEX_HEAP] = 0; -+ screen->texSize[RADEON_GART_TEX_HEAP] = 0; -+ screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0; -+ } else { -+ screen->numTexHeaps = RADEON_NR_TEX_HEAPS; -+ screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset; -+ screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize; -+ screen->logTexGranularity[RADEON_GART_TEX_HEAP] = dri_priv->log2GARTTexGran; -+ } - } else { -- screen->numTexHeaps = RADEON_NR_TEX_HEAPS; -- screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset; -- screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize; -- screen->logTexGranularity[RADEON_GART_TEX_HEAP] = -- dri_priv->log2GARTTexGran; -+ ret = radeon_init_mm_buffers(screen, sPriv, dri_priv); -+ if (ret) { -+ FREE( screen ); -+ fprintf(stderr, "Unable to get mm buffers inited\n"); -+ return NULL; -+ } - } - - i = 0; -@@ -952,7 +1089,8 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) - #endif - - #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) -- screen->extensions[i++] = &r300texOffsetExtension.base; -+ if (!screen->kernel_mm) -+ screen->extensions[i++] = &r300texOffsetExtension.base; - #endif - - screen->extensions[i++] = NULL; -@@ -973,12 +1111,14 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv ) - if (!screen) - return; ++ /* Allocate the private area */ ++ screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); ++ if ( !screen ) { ++ __driUtilMessage("%s: Could not allocate memory for screen structure", ++ __FUNCTION__); ++ fprintf(stderr, "leaving here\n"); ++ return NULL; ++ } ++ ++#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) ++ RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control); ++#endif ++ ++ /* parse information in __driConfigOptions */ ++ driParseOptionInfo (&screen->optionCache, ++ __driConfigOptions, __driNConfigOptions); ++ ++ screen->kernel_mm = 1; ++ screen->chip_flags = 0; ++ /* FIXME: do either an ioctl (bad) or a sysfs file for driver to ++ * information about which chipset is their */ ++ screen->chip_family = CHIP_FAMILY_RV350; ++ screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CLASS_R300; ++ ++ i = 0; ++ screen->extensions[i++] = &driCopySubBufferExtension.base; ++ screen->extensions[i++] = &driFrameTrackingExtension.base; ++ screen->extensions[i++] = &driReadDrawableExtension; ++ ++ if ( screen->irq != 0 ) { ++ screen->extensions[i++] = &driSwapControlExtension.base; ++ screen->extensions[i++] = &driMediaStreamCounterExtension.base; ++ } ++ ++#if !RADEON_COMMON ++ screen->extensions[i++] = &radeonTexOffsetExtension.base; ++#endif ++ ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) ++ if (IS_R200_CLASS(screen)) ++ screen->extensions[i++] = &r200AllocateExtension.base; ++ ++ screen->extensions[i++] = &r200texOffsetExtension.base; ++#endif ++ ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) ++ screen->extensions[i++] = &r300texOffsetExtension.base; ++ screen->extensions[i++] = &r300TexBufferExtension.base; ++#endif ++ ++ screen->extensions[i++] = NULL; ++ sPriv->extensions = screen->extensions; ++ ++ screen->driScreen = sPriv; ++ screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd); ++ if (screen->bom == NULL) { ++ free(screen); ++ return NULL; ++ } + return screen; + } +@@ -968,23 +1076,30 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) + static void + radeonDestroyScreen( __DRIscreenPrivate *sPriv ) + { +- radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; +- +- if (!screen) +- return; +- - if ( screen->gartTextures.map ) { - drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); - } - drmUnmapBufs( screen->buffers ); +- drmUnmapBufs( screen->buffers ); - drmUnmap( screen->status.map, screen->status.size ); - drmUnmap( screen->mmio.map, screen->mmio.size ); -+ if (!screen->kernel_mm) { -+ if ( screen->gartTextures.map ) { -+ drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); -+ } -+ drmUnmap( screen->status.map, screen->status.size ); -+ drmUnmap( screen->mmio.map, screen->mmio.size ); -+ } ++ radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; ++ ++ if (!screen) ++ return; ++ ++ if (screen->kernel_mm) { ++ radeon_tracker_print(&screen->bom->tracker, stderr); ++ radeon_bo_manager_gem_dtor(screen->bom); ++ } else { ++ radeon_bo_manager_legacy_dtor(screen->bom); ++ ++ if ( screen->gartTextures.map ) { ++ drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); ++ } ++ drmUnmapBufs( screen->buffers ); ++ drmUnmap( screen->status.map, screen->status.size ); ++ drmUnmap( screen->mmio.map, screen->mmio.size ); ++ } - /* free all option information */ - driDestroyOptionInfo (&screen->optionCache); -@@ -1002,6 +1142,160 @@ radeonInitDriver( __DRIscreenPrivate *sPriv ) - return GL_TRUE; +- /* free all option information */ +- driDestroyOptionInfo (&screen->optionCache); ++ /* free all option information */ ++ driDestroyOptionInfo (&screen->optionCache); + +- FREE( screen ); +- sPriv->private = NULL; ++ FREE( screen ); ++ sPriv->private = NULL; } + +@@ -993,15 +1108,176 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv ) + static GLboolean + radeonInitDriver( __DRIscreenPrivate *sPriv ) + { +- sPriv->private = (void *) radeonCreateScreen( sPriv ); +- if ( !sPriv->private ) { +- radeonDestroyScreen( sPriv ); +- return GL_FALSE; +- } ++ if (sPriv->dri2.enabled) { ++ sPriv->private = (void *) radeonCreateScreen2( sPriv ); ++ } else { ++ sPriv->private = (void *) radeonCreateScreen( sPriv ); ++ } ++ if ( !sPriv->private ) { ++ radeonDestroyScreen( sPriv ); ++ return GL_FALSE; ++ } ++ ++ return GL_TRUE; ++} ++ +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +static GLboolean +radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb, @@ -9332,7 +10311,8 @@ index 05107dd..1810ded 100644 + _mesa_delete_renderbuffer(&ret->base); + return NULL; + } -+ + +- return GL_TRUE; + ret->dPriv = driDrawPriv; + ret->base.InternalFormat = format; + @@ -9340,9 +10320,10 @@ index 05107dd..1810ded 100644 + + radeonSetSpanFunctions(ret); + ++ ret->bo = NULL; + return ret; -+} -+ + } + +/** + * Create the Mesa framebuffer and renderbuffers for a given window/drawable. + * @@ -9376,6 +10357,7 @@ index 05107dd..1810ded 100644 + struct radeon_renderbuffer *front = + radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base); ++ front->has_surface = 1; + } + + /* back color renderbuffer */ @@ -9383,6 +10365,7 @@ index 05107dd..1810ded 100644 + struct radeon_renderbuffer *back = + radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base); ++ back->has_surface = 1; + } + + /* depth renderbuffer */ @@ -9390,7 +10373,7 @@ index 05107dd..1810ded 100644 + struct radeon_renderbuffer *depth = + radeon_create_renderbuffer(depthFormat, driDrawPriv); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base); -+ depth->depthHasSurface = screen->depthHasSurface; ++ depth->has_surface = screen->depthHasSurface; + } + + /* stencil renderbuffer */ @@ -9398,7 +10381,7 @@ index 05107dd..1810ded 100644 + struct radeon_renderbuffer *stencil = + radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base); -+ stencil->depthHasSurface = screen->depthHasSurface; ++ stencil->has_surface = screen->depthHasSurface; + } + + _mesa_add_soft_renderbuffers(fb, @@ -9416,7 +10399,34 @@ index 05107dd..1810ded 100644 /** * Create the Mesa framebuffer and renderbuffers for a given window/drawable. -@@ -1101,7 +1395,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, +@@ -1062,7 +1338,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, + driDrawPriv); + radeonSetSpanFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); +- depthRb->depthHasSurface = screen->depthHasSurface; ++ depthRb->has_surface = screen->depthHasSurface; + } + else if (mesaVis->depthBits == 24) { + driRenderbuffer *depthRb +@@ -1073,7 +1349,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, + driDrawPriv); + radeonSetSpanFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); +- depthRb->depthHasSurface = screen->depthHasSurface; ++ depthRb->has_surface = screen->depthHasSurface; + } + + /* stencil renderbuffer */ +@@ -1086,7 +1362,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, + driDrawPriv); + radeonSetSpanFunctions(stencilRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); +- stencilRb->depthHasSurface = screen->depthHasSurface; ++ stencilRb->has_surface = screen->depthHasSurface; + } + + _mesa_add_soft_renderbuffers(fb, +@@ -1101,11 +1377,30 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, return (driDrawPriv->driverPrivate != NULL); } } @@ -9425,7 +10435,30 @@ index 05107dd..1810ded 100644 static void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) -@@ -1197,11 +1491,11 @@ radeonInitScreen(__DRIscreenPrivate *psp) + { ++ struct radeon_renderbuffer *rb; ++ GLframebuffer *fb; ++ ++ fb = (void*)driDrawPriv->driverPrivate; ++ rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } ++ rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; ++ if (rb && rb->bo) { ++ radeon_bo_unref(rb->bo); ++ rb->bo = NULL; ++ } + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); + } + +@@ -1197,13 +1492,48 @@ radeonInitScreen(__DRIscreenPrivate *psp) if (!radeonInitDriver(psp)) return NULL; @@ -9438,37 +10471,90 @@ index 05107dd..1810ded 100644 + (dri_priv->bpp == 16) ? 0 : 8, 1); } ++/** ++ * This is the driver specific part of the createNewScreen entry point. ++ * Called when using DRI2. ++ * ++ * \return the __GLcontextModes supported by this driver ++ */ ++static const ++__DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) ++{ ++ /* Calling driInitExtensions here, with a NULL context pointer, ++ * does not actually enable the extensions. It just makes sure ++ * that all the dispatch offsets for all the extensions that ++ * *might* be enables are known. This is needed because the ++ * dispatch offsets need to be known when _mesa_context_create ++ * is called, but we can't enable the extensions until we have a ++ * context pointer. ++ * ++ * Hello chicken. Hello egg. How are you two today? ++ */ ++ driInitExtensions( NULL, card_extensions, GL_FALSE ); ++#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) ++ driInitExtensions( NULL, blend_extensions, GL_FALSE ); ++ driInitSingleExtension( NULL, ARB_vp_extension ); ++ driInitSingleExtension( NULL, NV_vp_extension ); ++ driInitSingleExtension( NULL, ATI_fs_extension ); ++ driInitExtensions( NULL, point_extensions, GL_FALSE ); ++#endif ++ ++ if (!radeonInitDriver(psp)) { ++ return NULL; ++ } ++ ++ /* for now fill in all modes */ ++ return radeonFillInModes( psp, 24, 24, 8, 1); ++} + /** + * Get information about previous buffer swaps. +@@ -1252,6 +1582,8 @@ const struct __DriverAPIRec driDriverAPI = { + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = radeonCopySubBuffer, ++ /* DRI2 */ ++ .InitScreen2 = radeonInitScreen2, + }; + #else + const struct __DriverAPIRec driDriverAPI = { +@@ -1272,3 +1604,4 @@ const struct __DriverAPIRec driDriverAPI = { + .CopySubBuffer = r200CopySubBuffer, + }; + #endif ++ diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h -index b84c70b..59f1e86 100644 +index b84c70b..3287e12 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h -@@ -54,6 +54,14 @@ typedef struct { +@@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include "radeon_reg.h" + #include "drm_sarea.h" + #include "xmlconfig.h" ++#include "radeon_bo.h" + + + typedef struct { +@@ -54,7 +55,7 @@ typedef struct { drmAddress map; /* Mapping of the DRM region */ } radeonRegionRec, *radeonRegionPtr; -+struct radeon_gem_object { -+ uint32_t gem_name; -+ uint32_t gem_handle; -+ uint64_t size; -+ void *map; -+ uint64_t offset; -+}; -+ - typedef struct { +-typedef struct { ++typedef struct radeon_screen { int chip_family; int chip_flags; -@@ -106,6 +114,13 @@ typedef struct { - const __DRIextension *extensions[8]; + int cpp; +@@ -103,9 +104,12 @@ typedef struct { + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; + +- const __DRIextension *extensions[8]; ++ const __DRIextension *extensions[16]; int num_gb_pipes; -+ + int kernel_mm; -+ struct radeon_gem_object front; -+ struct radeon_gem_object back; -+ struct radeon_gem_object depth; -+ struct radeon_gem_object vram_texture; -+ struct radeon_gem_object gart_texture; ++ drm_radeon_sarea_t *sarea; /* Private SAREA data */ ++ struct radeon_bo_manager *bom; } radeonScreenRec, *radeonScreenPtr; #define IS_R100_CLASS(screen) \ @@ -9491,17 +10577,3 @@ index 9abe086..1650a9b 100644 +extern void radeonSetSpanFunctions(driRenderbuffer * rb, const GLvisual * vis); +#endif #endif -diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c -index 13d90e7..fe49faf 100644 ---- a/src/mesa/main/mipmap.c -+++ b/src/mesa/main/mipmap.c -@@ -1073,8 +1073,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, - _mesa_free(dstImage->ImageOffsets); - - /* Free old image data */ -- if (dstImage->Data) -- ctx->Driver.FreeTexImageData(ctx, dstImage); -+ ctx->Driver.FreeTexImageData(ctx, dstImage); - - /* initialize new image */ - _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, diff --git a/sources b/sources index 51d06c5..0e2fd31 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ a5ec51ed9f0a55dc3462d90d52ff899c xdriinfo-1.0.2.tar.bz2 6ae05158e678f4594343f32c2ca50515 gl-manpages-1.0.1.tar.bz2 -2a67b54e44727e83045c8778db63d28d mesa-20081001.tar.bz2 +b19670958386915cec8826aec505d01a mesa-20081220.tar.bz2