[Mesa-dev] [PATCH] winsys/radeon: set/get the scanout flag with the tiling ioctls

Marek Olšák maraeo at gmail.com
Fri Nov 29 10:08:27 PST 2013


From: Marek Olšák <marek.olsak at amd.com>

If we assume that all buffers allocated by the DDX are scanout, a new flag
that says "this is not scanout" has to be added to support the non-scanout
buffers and maintain backward compatibility.

This fixes bad rendering on Wayland.

The flag is defined as:
  #define RADEON_TILING_R600_NO_SCANOUT   RADEON_TILING_SWAP_16BIT

AFAIK, RADEON_TILING_SWAP_16BIT is not used on SI.
---
 src/gallium/drivers/r300/r300_state.c         |  2 +-
 src/gallium/drivers/r300/r300_texture.c       |  5 +++--
 src/gallium/drivers/radeon/r600_texture.c     |  9 +++++----
 src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 12 ++++++++++--
 src/gallium/winsys/radeon/drm/radeon_winsys.h |  6 ++++--
 5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 6840e8b..048672c 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -844,7 +844,7 @@ static void r300_tex_set_tiling_flags(struct r300_context *r300,
         r300->rws->buffer_set_tiling(tex->buf, r300->cs,
                 tex->tex.microtile, tex->tex.macrotile[level],
                 0, 0, 0, 0, 0,
-                tex->tex.stride_in_bytes[0]);
+                tex->tex.stride_in_bytes[0], false);
 
         tex->surface_level = level;
     }
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index b7fb081..4ea69dc 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -1060,7 +1060,7 @@ r300_texture_create_object(struct r300_screen *rscreen,
     rws->buffer_set_tiling(tex->buf, NULL,
             tex->tex.microtile, tex->tex.macrotile[0],
             0, 0, 0, 0, 0,
-            tex->tex.stride_in_bytes[0]);
+            tex->tex.stride_in_bytes[0], false);
 
     return tex;
 
@@ -1115,7 +1115,8 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
     if (!buffer)
         return NULL;
 
-    rws->buffer_get_tiling(buffer, &microtile, &macrotile, NULL, NULL, NULL, NULL, NULL);
+    rws->buffer_get_tiling(buffer, &microtile, &macrotile, NULL, NULL, NULL,
+                           NULL, NULL, NULL);
 
     /* Enforce a microtiled zbuffer. */
     if (util_format_is_depth_or_stencil(base->format) &&
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 12f412d..bd1d4c8 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -253,7 +253,8 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
 				       surface->tile_split,
 				       surface->stencil_tile_split,
 				       surface->mtilea,
-				       surface->level[0].pitch_bytes);
+				       surface->level[0].pitch_bytes,
+				       (surface->flags & RADEON_SURF_SCANOUT) != 0);
 
 	return rscreen->ws->buffer_get_handle(resource->buf,
 						surface->level[0].pitch_bytes, whandle);
@@ -760,6 +761,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
 	unsigned array_mode;
 	enum radeon_bo_layout micro, macro;
 	struct radeon_surface surface;
+	bool scanout;
 	int r;
 
 	/* Support only 2D textures without mipmaps */
@@ -775,7 +777,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
 				       &surface.bankw, &surface.bankh,
 				       &surface.tile_split,
 				       &surface.stencil_tile_split,
-				       &surface.mtilea);
+				       &surface.mtilea, &scanout);
 
 	if (macro == RADEON_LAYOUT_TILED)
 		array_mode = RADEON_SURF_MODE_2D;
@@ -789,8 +791,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
 		return NULL;
 	}
 
-	/* always set the scanout flags on SI */
-	if (rscreen->chip_class >= SI)
+	if (scanout)
 		surface.flags |= RADEON_SURF_SCANOUT;
 
 	return (struct pipe_resource *)r600_texture_create_object(screen, templ,
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 3019a52..a99d754 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -49,6 +49,7 @@
 #define RADEON_BO_FLAGS_MACRO_TILE  1
 #define RADEON_BO_FLAGS_MICRO_TILE  2
 #define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20
+#define RADEON_TILING_R600_NO_SCANOUT RADEON_TILING_SWAP_16BIT
 
 #ifndef DRM_RADEON_GEM_WAIT
 #define DRM_RADEON_GEM_WAIT     0x2b
@@ -738,7 +739,8 @@ static void radeon_bo_get_tiling(struct pb_buffer *_buf,
                                  unsigned *bankw, unsigned *bankh,
                                  unsigned *tile_split,
                                  unsigned *stencil_tile_split,
-                                 unsigned *mtilea)
+                                 unsigned *mtilea,
+                                 bool *scanout)
 {
     struct radeon_bo *bo = get_radeon_bo(_buf);
     struct drm_radeon_gem_set_tiling args;
@@ -767,6 +769,8 @@ static void radeon_bo_get_tiling(struct pb_buffer *_buf,
         *mtilea = (args.tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
         *tile_split = eg_tile_split(*tile_split);
     }
+    if (scanout)
+        *scanout = bo->rws->gen >= DRV_SI && !(args.tiling_flags & RADEON_TILING_R600_NO_SCANOUT);
 }
 
 static void radeon_bo_set_tiling(struct pb_buffer *_buf,
@@ -777,7 +781,8 @@ static void radeon_bo_set_tiling(struct pb_buffer *_buf,
                                  unsigned tile_split,
                                  unsigned stencil_tile_split,
                                  unsigned mtilea,
-                                 uint32_t pitch)
+                                 uint32_t pitch,
+                                 bool scanout)
 {
     struct radeon_bo *bo = get_radeon_bo(_buf);
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
@@ -818,6 +823,9 @@ static void radeon_bo_set_tiling(struct pb_buffer *_buf,
     args.tiling_flags |= (mtilea & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK) <<
         RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
 
+    if (bo->rws->gen >= DRV_SI && !scanout)
+        args.tiling_flags |= RADEON_TILING_R600_NO_SCANOUT;
+
     args.handle = bo->handle;
     args.pitch = pitch;
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index d59f48f..85458c2 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -311,7 +311,8 @@ struct radeon_winsys {
                               unsigned *bankw, unsigned *bankh,
                               unsigned *tile_split,
                               unsigned *stencil_tile_split,
-                              unsigned *mtilea);
+                              unsigned *mtilea,
+                              bool *scanout);
 
     /**
      * Set tiling flags describing a memory layout of a buffer object.
@@ -332,7 +333,8 @@ struct radeon_winsys {
                               unsigned tile_split,
                               unsigned stencil_tile_split,
                               unsigned mtilea,
-                              unsigned stride);
+                              unsigned stride,
+                              bool scanout);
 
     /**
      * Get a winsys buffer from a winsys handle. The internal structure
-- 
1.8.3.2



More information about the mesa-dev mailing list