Ati Radeon 7200 3D feature is buggy (kernel 2.6.34-rc6, ATI driver 6.13) (Answer TWO: more precise)

Uwe Bugla uwe.bugla at gmx.de
Mon May 3 12:50:53 PDT 2010


Am Montag, den 03.05.2010, 12:49 -0400 schrieb Alex Deucher:
> 2010/5/3 Uwe Bugla <uwe.bugla at gmx.de>:
> > Am Montag, den 03.05.2010, 15:27 +0200 schrieb Michel Dänzer:
> >> On Sam, 2010-05-01 at 09:33 +0200, Uwe Bugla wrote:
> >> > Hi,
> >> >
> >> > I am working with an ATI Radeon 7200 QD (R100) on a Pentium 4 machine
> >> > with Intel AGP chipset.
> >> > The card driver is 6.13 (latest snapshot from April 30).
> >> >
> >> > To savely exclude other side effects I did the following:
> >> > Recompile mesa library 7.9 devel and libdrm 2.4.20 from snapshot of
> >> > April 30.
> >> >
> >> > What is the symptom?
> >> > Via config manager of Gnome 2.30 I make metacity a composite manager for
> >> > a reduced
> >> > amount of 3D effects.
> >> > What happens with the ATI driver (NOT with the self-built nouveau driver
> >> > running
> >> > with my Nvidia cards - this one works fantastic!) is the following:
> >> >
> >> > If I go to the Linux Kernel archives via iceweasel 3.59 and push the
> >> > right mouse
> >> > button over some "View Patch" entry I get a window throwing shadows, as
> >> > intended.
> >> >
> >> > BUT: The window does not contain any text!
> >> > I wonder if the 6.13 driver can deal with the fact that the card only
> >> > has 32 MB RAM.
> >> > But this is wild guessing, as I do not have any idea.
> >> > Maybe this hint / symptom is helpful for the developers.
> >> >
> >> > When publishing driver 6.13 you were promising a driver being able of 3D
> >> > and 2D
> >> > effects plus KMS.
> >> > Except the 3D effects everything is working fine.
> >> > When will you finally fulfil that promise?
> >>
> >> Did you test the kernel patch I asked you to?
> >
> >
> > Hello everybody,
> >
> > SIGH! I got Compiz running together with my ATI Radeon QD 7200 (=R100).
> >
> > Just to make it clear for every one:
> >
> > Needed are:
> >
> > 1. Kernel 2.6.34-rc6
> > 2. a self built Debian package containing the latest snapshot from
> > driver xf86-video-ati, version 6.13.
> > 3. one AGP patch
> > 4. one Radeon patch
> > 5. most important (and this one cost me hours to find out!):
> >
> > NOT the latest master from here:
> > http://cgit.freedesktop.org/mesa/mesa/
> > This master contains hunks which make the whole thing incompatible!
> >
> 
> What hunks are causing problems?  What sort of problems are you seeing?
> 
> >
> >
> > Instead you can use this one:
> > http://cgit.freedesktop.org/mesa/mesa/snapshot/mesa-nvfx-next-6b.tar.gz
> >
> > This is Luca Barbieri's experimental tree, which not only works
> > excellent with my Nvidia nv34 cards, but furthermore seems to be the
> > only one to work with my ATI driver......
> >
> >
> >
> > Michel Dänzer does not like the Radeon patch, and Dave Airlie promised
> > to write a better one.
> > Unfortunately I haven't seen any patch from Dave yet, so the empty
> > promise stays to at least try to find a better solution......
> 
> There were several new variations of the patch from both Dave and
> Michel and you were cc'ed on most of them:
> http://marc.info/?l=dri-devel&m=127233579110506&w=2
> http://lists.freedesktop.org/archives/dri-devel/2010-April/000266.html
> http://lists.freedesktop.org/archives/dri-devel/2010-April/000309.html
> 
> Alex

Hi all,

1. I was not consequently cc'ed.
2. I am not familiar with acronyms like bo or VRM
3. I owe no subscription at the dri devel list.
4. None of the 3 patches applies against 2.6.34-rc6 without further
overworking, and this work does not only cover line adjustment....
5. If I must adjust the line numbers of the patches to avoid fuzz
factors and line overhead that is OK so far.
6. But if the patch does not compile after these adjustments that is
anything but healthy for the mood....
7. The Email header was changed, so I did not find Michel's approaches
in order to test them.

Now let's have a closer look to the patches:

Michel's contributions unfortunately neither apply as patch, nor do they
compile against kernel 2.6.34-rc6.....
Result: Unusable.

Dave's contribution contains a hunk 6 against radeon_object.c which is
pure crap, as radeon_object.c is simply not long enough: 509 lines!

This is the piece of crap (i. e. hunk 6) which should not be there:

@@ -516,7 +520,7 @@ int radeon_bo_fault_reserve_notify(struct
ttm_buffer_object *bo)
 		offset = bo->mem.mm_node->start << PAGE_SHIFT;
 		if ((offset + size) > rdev->mc.visible_vram_size) {
 			/* hurrah the memory is not visible ! */
-			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM);
+			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM, false);
 			rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
 			r = ttm_bo_validate(bo, &rbo->placement, false, true, false);
 			if (unlikely(r != 0))

So what did I do?

Adjust the rest of Dave's patch, combine it with the AGP patch, apply it
against 2.6.34-rc6 and recompile the whole thing.

Result: Everything is fine!

This is the adjusted patch in a whole which is needed to be applied
against kernel 2.6.34-rc6 to make Compiz run with a R100 ATI Radeon
card:

--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -204,6 +204,7 @@ static const struct agp_bridge_driver
ali_generic_bridge = {
 	.aperture_sizes		= ali_generic_sizes,
 	.size_type		= U32_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= ali_configure,
 	.fetch_size		= ali_fetch_size,
 	.cleanup		= ali_cleanup,
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -142,6 +142,7 @@ static int amd_create_gatt_table(struct
agp_bridge_data *bridge)
 {
 	struct aper_size_info_lvl2 *value;
 	struct amd_page_map page_dir;
+	unsigned long __iomem *cur_gatt;
 	unsigned long addr;
 	int retval;
 	u32 temp;
@@ -178,6 +179,13 @@ static int amd_create_gatt_table(struct
agp_bridge_data *bridge)
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
 
+	for (i = 0; i < value->num_entries; i++) {
+		addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
+		cur_gatt = GET_GATT(addr);
+		writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
+		readl(cur_gatt+GET_GATT_OFF(addr));	/* PCI Posting. */
+	}
+
 	return 0;
 }
 
@@ -375,6 +383,7 @@ static const struct agp_bridge_driver
amd_irongate_driver = {
 	.aperture_sizes		= amd_irongate_sizes,
 	.size_type		= LVL2_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= amd_irongate_configure,
 	.fetch_size		= amd_irongate_fetch_size,
 	.cleanup		= amd_irongate_cleanup,
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -210,6 +210,7 @@ static const struct agp_bridge_driver
amd_8151_driver = {
 	.aperture_sizes		= amd_8151_sizes,
 	.size_type		= U32_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= amd_8151_configure,
 	.fetch_size		= amd64_fetch_size,
 	.cleanup		= amd64_cleanup,
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -341,6 +341,7 @@ static int ati_create_gatt_table(struct
agp_bridge_data *bridge)
 {
 	struct aper_size_info_lvl2 *value;
 	struct ati_page_map page_dir;
+	unsigned long __iomem *cur_gatt;
 	unsigned long addr;
 	int retval;
 	u32 temp;
@@ -395,6 +396,12 @@ static int ati_create_gatt_table(struct
agp_bridge_data *bridge)
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
 
+	for (i = 0; i < value->num_entries; i++) {
+		addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
+		cur_gatt = GET_GATT(addr);
+		writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
+	}
+
 	return 0;
 }
 
@@ -415,6 +422,7 @@ static const struct agp_bridge_driver
ati_generic_bridge = {
 	.aperture_sizes		= ati_generic_sizes,
 	.size_type		= LVL2_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= ati_configure,
 	.fetch_size		= ati_fetch_size,
 	.cleanup		= ati_cleanup,
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -1982,6 +1982,7 @@ static const struct agp_bridge_driver
intel_generic_driver = {
 	.aperture_sizes		= intel_generic_sizes,
 	.size_type		= U16_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_configure,
 	.fetch_size		= intel_fetch_size,
 	.cleanup		= intel_cleanup,
@@ -2035,6 +2036,7 @@ static const struct agp_bridge_driver
intel_815_driver = {
 	.aperture_sizes		= intel_815_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 2,
+	.needs_scratch_page	= true,
 	.configure		= intel_815_configure,
 	.fetch_size		= intel_815_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
@@ -2089,6 +2091,7 @@ static const struct agp_bridge_driver
intel_820_driver = {
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_820_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_820_cleanup,
@@ -2115,6 +2118,7 @@ static const struct agp_bridge_driver
intel_830mp_driver = {
 	.aperture_sizes		= intel_830mp_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 4,
+	.needs_scratch_page	= true,
 	.configure		= intel_830mp_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
@@ -2141,6 +2145,7 @@ static const struct agp_bridge_driver
intel_840_driver = {
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_840_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
@@ -2167,6 +2172,7 @@ static const struct agp_bridge_driver
intel_845_driver = {
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_845_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
@@ -2193,6 +2199,7 @@ static const struct agp_bridge_driver
intel_850_driver = {
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_850_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
@@ -2219,6 +2226,7 @@ static const struct agp_bridge_driver
intel_860_driver = {
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_860_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
@@ -2313,6 +2321,7 @@ static const struct agp_bridge_driver
intel_7505_driver = {
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= intel_7505_configure,
 	.fetch_size		= intel_8xx_fetch_size,
 	.cleanup		= intel_8xx_cleanup,
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -310,6 +310,7 @@ static const struct agp_bridge_driver nvidia_driver
= {
 	.aperture_sizes		= nvidia_generic_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 5,
+	.needs_scratch_page	= true,
 	.configure		= nvidia_configure,
 	.fetch_size		= nvidia_fetch_size,
 	.cleanup		= nvidia_cleanup,
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -125,6 +125,7 @@ static struct agp_bridge_driver sis_driver = {
 	.aperture_sizes		= sis_generic_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 7,
+	.needs_scratch_page	= true,
 	.configure		= sis_configure,
 	.fetch_size		= sis_fetch_size,
 	.cleanup		= sis_cleanup,
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -28,6 +28,7 @@
  */
 static int uninorth_rev;
 static int is_u3;
+static u32 scratch_value;
 
 #define DEFAULT_APERTURE_SIZE 256
 #define DEFAULT_APERTURE_STRING "256"
@@ -172,7 +173,7 @@ static int uninorth_insert_memory(struct agp_memory
*mem, off_t pg_start, int ty
 
 	gp = (u32 *) &agp_bridge->gatt_table[pg_start];
 	for (i = 0; i < mem->page_count; ++i) {
-		if (gp[i]) {
+		if (gp[i] != scratch_value) {
 			dev_info(&agp_bridge->dev->dev,
 				 "uninorth_insert_memory: entry 0x%x occupied (%x)\n",
 				 i, gp[i]);
@@ -214,8 +215,9 @@ int uninorth_remove_memory(struct agp_memory *mem,
off_t pg_start, int type)
 		return 0;
 
 	gp = (u32 *) &agp_bridge->gatt_table[pg_start];
-	for (i = 0; i < mem->page_count; ++i)
-		gp[i] = 0;
+	for (i = 0; i < mem->page_count; ++i) {
+		gp[i] = scratch_value;
+	}
 	mb();
 	uninorth_tlbflush(mem);
 
@@ -421,8 +423,13 @@ static int uninorth_create_gatt_table(struct
agp_bridge_data *bridge)
 
 	bridge->gatt_bus_addr = virt_to_phys(table);
 
+	if (is_u3)
+		scratch_value = (page_to_phys(agp_bridge->scratch_page_page) >>
PAGE_SHIFT) | 0x80000000UL;
+	else
+		scratch_value =
cpu_to_le32((page_to_phys(agp_bridge->scratch_page_page) & 0xFFFFF000UL)
|
+				0x1UL);
 	for (i = 0; i < num_entries; i++)
-		bridge->gatt_table[i] = 0;
+		bridge->gatt_table[i] = scratch_value;
 
 	return 0;
 
@@ -519,6 +526,7 @@ const struct agp_bridge_driver uninorth_agp_driver =
{
 	.agp_destroy_pages	= agp_generic_destroy_pages,
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 	.cant_use_aperture	= true,
+	.needs_scratch_page	= true,
 };
 
 const struct agp_bridge_driver u3_agp_driver = {
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -175,6 +175,7 @@ static const struct agp_bridge_driver
via_agp3_driver = {
 	.aperture_sizes		= agp3_generic_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 10,
+	.needs_scratch_page	= true,
 	.configure		= via_configure_agp3,
 	.fetch_size		= via_fetch_size_agp3,
 	.cleanup		= via_cleanup_agp3,
@@ -201,6 +202,7 @@ static const struct agp_bridge_driver via_driver = {
 	.aperture_sizes		= via_generic_sizes,
 	.size_type		= U8_APER_SIZE,
 	.num_aperture_sizes	= 9,
+	.needs_scratch_page	= true,
 	.configure		= via_configure,
 	.fetch_size		= via_fetch_size,
 	.cleanup		= via_cleanup,
diff --git a/drivers/gpu/drm/radeon/radeon.h
b/drivers/gpu/drm/radeon/radeon.h
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -239,7 +239,9 @@ struct radeon_bo {
 	struct list_head		list;
 	/* Protected by tbo.reserved */
 	u32				placements[3];
+	u32				busy_placements[3];
 	struct ttm_placement		placement;
+	struct ttm_placement		busy_placement;
 	struct ttm_buffer_object	tbo;
 	struct ttm_bo_kmap_obj		kmap;
 	unsigned			pin_count;
@@ -1192,7 +1194,7 @@ extern void radeon_surface_init(struct
radeon_device *rdev);
 extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void
*data);
 extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev,
int enable);
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev,
int enable);
-extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32
domain);
+extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32
domain, bool pinned);
 extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
 extern void radeon_vram_location(struct radeon_device *rdev, struct
radeon_mc *mc, u64 base);
 extern void radeon_gtt_location(struct radeon_device *rdev, struct
radeon_mc *mc);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c
b/drivers/gpu/drm/radeon/radeon_object.c
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -64,17 +64,21 @@ bool radeon_ttm_bo_is_radeon_bo(struct
ttm_buffer_object *bo)
 	return false;
 }
 
-void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32
domain)
+void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32
domain, bool pinned)
 {
-	u32 c = 0;
+	u32 c = 0, b = 0;
 
 	rbo->placement.fpfn = 0;
 	rbo->placement.lpfn = 0;
 	rbo->placement.placement = rbo->placements;
-	rbo->placement.busy_placement = rbo->placements;
+	rbo->placement.busy_placement = rbo->busy_placements;
 	if (domain & RADEON_GEM_DOMAIN_VRAM)
 		rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
 					TTM_PL_FLAG_VRAM;
+	/* add busy placement to TTM if VRAM is only option */
+	if (domain == RADEON_GEM_DOMAIN_VRAM && pinned == false) {
+		rbo->busy_placements[b++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	}
 	if (domain & RADEON_GEM_DOMAIN_GTT)
 		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
 	if (domain & RADEON_GEM_DOMAIN_CPU)
@@ -82,7 +86,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo
*rbo, u32 domain)
 	if (!c)
 		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
 	rbo->placement.num_placement = c;
-	rbo->placement.num_busy_placement = c;
+	rbo->placement.num_busy_placement = b;
 }
 
 int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object
*gobj,
@@ -110,7 +114,7 @@ int radeon_bo_create(struct radeon_device *rdev,
struct drm_gem_object *gobj,
 	bo->surface_reg = -1;
 	INIT_LIST_HEAD(&bo->list);
 
-	radeon_ttm_placement_from_domain(bo, domain);
+	radeon_ttm_placement_from_domain(bo, domain, false);
 	/* Kernel allocation are uninterruptible */
 	r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
 			&bo->placement, 0, 0, !kernel, NULL, size,
@@ -185,7 +189,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain,
u64 *gpu_addr)
 			*gpu_addr = radeon_bo_gpu_offset(bo);
 		return 0;
 	}
-	radeon_ttm_placement_from_domain(bo, domain);
+	radeon_ttm_placement_from_domain(bo, domain, true);
 	if (domain == RADEON_GEM_DOMAIN_VRAM) {
 		/* force to pin into visible video ram */
 		bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
@@ -325,10 +329,10 @@ int radeon_bo_list_validate(struct list_head
*head)
 		if (!bo->pin_count) {
 			if (lobj->wdomain) {
 				radeon_ttm_placement_from_domain(bo,
-								lobj->wdomain);
+								 lobj->wdomain, false);
 			} else {
 				radeon_ttm_placement_from_domain(bo,
-								lobj->rdomain);
+								 lobj->rdomain, false);
 			}
 			r = ttm_bo_validate(&bo->tbo, &bo->placement,
 						true, false);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c
b/drivers/gpu/drm/radeon/radeon_ttm.c
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -217,13 +217,13 @@ static void radeon_evict_flags(struct
ttm_buffer_object *bo,
 	switch (bo->mem.mem_type) {
 	case TTM_PL_VRAM:
 		if (rbo->rdev->cp.ready == false)
-			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
+			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU, false);
 		else
-			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
+			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT, false);
 		break;
 	case TTM_PL_TT:
 	default:
-		radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
+		radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU, false);
 	}
 	*placement = rbo->placement;
 }

And if you need formalism to push it, here is the stuff to satisfy
Mr. Torvalds:

Signed-off-by: Uwe Bugla <uwe.bugla at gmx.de>

or

Acked-by: Uwe Bugla <uwe.bugla at gmx.de>

Answer 2 dealing with mesa master versus Luca Barbieri's experimental
tree will take a while.

Cheers

Uwe

-------------- next part --------------
A non-text attachment was scrubbed...
Name: radeoncompiz.patch
Type: text/x-patch
Size: 13647 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg/attachments/20100503/a8e3c543/attachment.bin>


More information about the xorg mailing list