[Mesa-dev] [PATCH 5/9] ac/surface: add EQAA support

Marek Olšák maraeo at gmail.com
Wed May 2 04:13:21 UTC 2018


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

---
 src/amd/common/ac_surface.c                   | 29 +++++++++++++++++--
 src/amd/common/ac_surface.h                   |  3 +-
 src/amd/vulkan/radv_image.c                   |  1 +
 src/gallium/drivers/radeon/radeon_winsys.h    |  1 +
 src/gallium/drivers/radeonsi/si_texture.c     |  4 +--
 .../winsys/amdgpu/drm/amdgpu_surface.c        |  2 ++
 .../winsys/radeon/drm/radeon_drm_surface.c    |  6 ++--
 7 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index 5030d10242e..16c4da706ca 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -242,24 +242,41 @@ static int surf_config_sanity(const struct ac_surf_config *config,
 	    !config->info.array_size || !config->info.levels)
 		return -EINVAL;
 
 	switch (config->info.samples) {
 	case 0:
 	case 1:
 	case 2:
 	case 4:
 	case 8:
 		break;
+	case 16:
+		if (flags & RADEON_SURF_Z_OR_SBUFFER)
+			return -EINVAL;
+		break;
 	default:
 		return -EINVAL;
 	}
 
+	if (!(flags & RADEON_SURF_Z_OR_SBUFFER)) {
+		switch (config->info.color_samples) {
+		case 0:
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
 	if (config->is_3d && config->info.array_size > 1)
 		return -EINVAL;
 	if (config->is_cube && config->info.depth > 1)
 		return -EINVAL;
 
 	return 0;
 }
 
 static int gfx6_compute_level(ADDR_HANDLE addrlib,
 			      const struct ac_surf_config *config,
@@ -600,23 +617,28 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 			break;
 		default:
 			assert(0);
 		}
 	}
 	else {
 		AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8;
 	}
 
 	AddrDccIn.numSamples = AddrSurfInfoIn.numSamples =
-		config->info.samples ? config->info.samples : 1;
+		MAX2(1, config->info.samples);
 	AddrSurfInfoIn.tileIndex = -1;
 
+	if (!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)) {
+		AddrDccIn.numSamples = AddrSurfInfoIn.numFrags =
+			MAX2(1, config->info.color_samples);
+	}
+
 	/* Set the micro tile type. */
 	if (surf->flags & RADEON_SURF_SCANOUT)
 		AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
 	else if (surf->flags & RADEON_SURF_Z_OR_SBUFFER)
 		AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
 	else
 		AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;
 
 	AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
 	AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
@@ -1315,23 +1337,26 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 
 	AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
 	AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
 	AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
 	/* flags.texture currently refers to TC-compatible HTILE */
 	AddrSurfInfoIn.flags.texture = AddrSurfInfoIn.flags.color ||
 				       surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
 	AddrSurfInfoIn.flags.opt4space = 1;
 
 	AddrSurfInfoIn.numMipLevels = config->info.levels;
-	AddrSurfInfoIn.numSamples = config->info.samples ? config->info.samples : 1;
+	AddrSurfInfoIn.numSamples = MAX2(1, config->info.samples);
 	AddrSurfInfoIn.numFrags = AddrSurfInfoIn.numSamples;
 
+	if (!(surf->flags & RADEON_SURF_Z_OR_SBUFFER))
+		AddrSurfInfoIn.numFrags = MAX2(1, config->info.color_samples);
+
 	/* GFX9 doesn't support 1D depth textures, so allocate all 1D textures
 	 * as 2D to avoid having shader variants for 1D vs 2D, so all shaders
 	 * must sample 1D textures as 2D. */
 	if (config->is_3d)
 		AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_3D;
 	else
 		AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_2D;
 
 	AddrSurfInfoIn.width = config->info.width;
 	AddrSurfInfoIn.height = config->info.height;
diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
index 45fb8045e53..864b5bad529 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -217,21 +217,22 @@ struct radeon_surf {
 
         /* GFX9+ return values. */
         struct gfx9_surf_layout gfx9;
     } u;
 };
 
 struct ac_surf_info {
 	uint32_t width;
 	uint32_t height;
 	uint32_t depth;
-	uint8_t samples;
+	uint8_t samples; /* For Z/S: samples; For color: FMASK coverage samples */
+	uint8_t color_samples; /* For color: color samples */
 	uint8_t levels;
 	uint8_t num_channels; /* heuristic for displayability */
 	uint16_t array_size;
 	uint32_t *surf_index; /* Set a monotonic counter for tile swizzling. */
 	uint32_t *fmask_surf_index;
 };
 
 struct ac_surf_config {
 	struct ac_surf_info info;
 	unsigned is_3d : 1;
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 031250b1cb2..4d42148805d 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -923,20 +923,21 @@ radv_image_create(VkDevice _device,
 	image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8,
 			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
 	if (!image)
 		return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
 	image->type = pCreateInfo->imageType;
 	image->info.width = pCreateInfo->extent.width;
 	image->info.height = pCreateInfo->extent.height;
 	image->info.depth = pCreateInfo->extent.depth;
 	image->info.samples = pCreateInfo->samples;
+	image->info.color_samples = pCreateInfo->samples;
 	image->info.array_size = pCreateInfo->arrayLayers;
 	image->info.levels = pCreateInfo->mipLevels;
 	image->info.num_channels = vk_format_get_nr_components(pCreateInfo->format);
 
 	image->vk_format = pCreateInfo->format;
 	image->tiling = pCreateInfo->tiling;
 	image->usage = pCreateInfo->usage;
 	image->flags = pCreateInfo->flags;
 
 	image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index fae4fb7a95d..abf70ce762b 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -642,20 +642,21 @@ struct radeon_winsys {
      *
      * \param ws        The winsys this function is called from.
      * \param tex       Input texture description
      * \param flags     Bitmask of RADEON_SURF_* flags
      * \param bpe       Bytes per pixel, it can be different for Z buffers.
      * \param mode      Preferred tile mode. (linear, 1D, or 2D)
      * \param surf      Output structure
      */
     int (*surface_init)(struct radeon_winsys *ws,
                         const struct pipe_resource *tex,
+                        unsigned num_color_samples,
                         unsigned flags, unsigned bpe,
                         enum radeon_surf_mode mode,
                         struct radeon_surf *surf);
 
     uint64_t (*query_value)(struct radeon_winsys *ws,
                             enum radeon_value_id value);
 
     bool (*read_registers)(struct radeon_winsys *ws, unsigned reg_offset,
                            unsigned num_registers, uint32_t *out);
 
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 81a70153f32..1e328b90b62 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -294,22 +294,22 @@ static int si_init_surface(struct si_screen *sscreen,
 		flags |= RADEON_SURF_SCANOUT;
 	}
 
 	if (ptex->bind & PIPE_BIND_SHARED)
 		flags |= RADEON_SURF_SHAREABLE;
 	if (is_imported)
 		flags |= RADEON_SURF_IMPORTED | RADEON_SURF_SHAREABLE;
 	if (!(ptex->flags & SI_RESOURCE_FLAG_FORCE_TILING))
 		flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
 
-	r = sscreen->ws->surface_init(sscreen->ws, ptex, flags, bpe,
-				      array_mode, surface);
+	r = sscreen->ws->surface_init(sscreen->ws, ptex, ptex->nr_samples,
+				      flags, bpe, array_mode, surface);
 	if (r) {
 		return r;
 	}
 
 	unsigned pitch = pitch_in_bytes_override / bpe;
 
 	if (sscreen->info.chip_class >= GFX9) {
 		if (pitch) {
 			surface->u.gfx9.surf_pitch = pitch;
 			surface->u.gfx9.surf_slice_size =
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index b5a1ebb1628..d5fa37bb6d9 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -55,20 +55,21 @@ static int amdgpu_surface_sanity(const struct pipe_resource *tex)
          return -EINVAL;
       break;
    default:
       return -EINVAL;
    }
    return 0;
 }
 
 static int amdgpu_surface_init(struct radeon_winsys *rws,
                                const struct pipe_resource *tex,
+                               unsigned num_color_samples,
                                unsigned flags, unsigned bpe,
                                enum radeon_surf_mode mode,
                                struct radeon_surf *surf)
 {
    struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws;
    int r;
 
    r = amdgpu_surface_sanity(tex);
    if (r)
       return r;
@@ -78,20 +79,21 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
    surf->bpe = bpe;
    surf->flags = flags;
 
    struct ac_surf_config config;
 
    config.info.width = tex->width0;
    config.info.height = tex->height0;
    config.info.depth = tex->depth0;
    config.info.array_size = tex->array_size;
    config.info.samples = tex->nr_samples;
+   config.info.color_samples = num_color_samples;
    config.info.levels = tex->last_level + 1;
    config.info.num_channels = util_format_get_nr_components(tex->format);
    config.is_3d = !!(tex->target == PIPE_TEXTURE_3D);
    config.is_cube = !!(tex->target == PIPE_TEXTURE_CUBE);
 
    /* Use different surface counters for color and FMASK, so that MSAA MRTs
     * always use consecutive surface indices when FMASK is allocated between
     * them.
     */
    if (flags & RADEON_SURF_FMASK)
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
index 61220ed7fe3..4677a3bea7c 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
@@ -215,20 +215,21 @@ static void surf_drm_to_winsys(struct radeon_drm_winsys *ws,
     }
 
     set_micro_tile_mode(surf_ws, &ws->info);
     surf_ws->is_displayable = surf_ws->is_linear ||
 			      surf_ws->micro_tile_mode == RADEON_MICRO_MODE_DISPLAY ||
 			      surf_ws->micro_tile_mode == RADEON_MICRO_MODE_ROTATED;
 }
 
 static int radeon_winsys_surface_init(struct radeon_winsys *rws,
                                       const struct pipe_resource *tex,
+                                      unsigned num_color_samples,
                                       unsigned flags, unsigned bpe,
                                       enum radeon_surf_mode mode,
                                       struct radeon_surf *surf_ws)
 {
     struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
     struct radeon_surface surf_drm;
     int r;
 
     surf_winsys_to_drm(&surf_drm, tex, flags, bpe, mode, surf_ws);
 
@@ -262,22 +263,23 @@ static int radeon_winsys_surface_init(struct radeon_winsys *rws,
             bpe = 1;
             break;
         case 8:
             bpe = 4;
             break;
         default:
             fprintf(stderr, "radeon: Invalid sample count for FMASK allocation.\n");
             return -1;
         }
 
-        if (radeon_winsys_surface_init(rws, &templ, fmask_flags, bpe,
-                                       RADEON_SURF_MODE_2D, &fmask)) {
+        if (radeon_winsys_surface_init(rws, &templ, num_color_samples,
+				       fmask_flags, bpe, RADEON_SURF_MODE_2D,
+				       &fmask)) {
             fprintf(stderr, "Got error in surface_init while allocating FMASK.\n");
             return -1;
         }
 
         assert(fmask.u.legacy.level[0].mode == RADEON_SURF_MODE_2D);
 
         surf_ws->fmask_size = fmask.surf_size;
         surf_ws->fmask_alignment = MAX2(256, fmask.surf_alignment);
         surf_ws->fmask_tile_swizzle = fmask.tile_swizzle;
 
-- 
2.17.0



More information about the mesa-dev mailing list