From: Marek Olšák <[email protected]>

---
 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

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to