[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