[Mesa-dev] [PATCH 6/9] radeonsi: support creating EQAA color textures
Marek Olšák
maraeo at gmail.com
Wed May 2 04:13:22 UTC 2018
From: Marek Olšák <marek.olsak at amd.com>
---
src/gallium/drivers/radeonsi/si_clear.c | 4 +-
src/gallium/drivers/radeonsi/si_pipe.h | 1 +
src/gallium/drivers/radeonsi/si_texture.c | 45 +++++++++++++++--------
3 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index 0f3546b02da..23977186611 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -240,32 +240,32 @@ void vi_dcc_clear_level(struct si_context *sctx,
} else {
dcc_buffer = &rtex->buffer.b.b;
dcc_offset = rtex->dcc_offset;
}
if (sctx->chip_class >= GFX9) {
/* Mipmap level clears aren't implemented. */
assert(rtex->buffer.b.b.last_level == 0);
/* 4x and 8x MSAA needs a sophisticated compute shader for
* the clear. See AMDVLK. */
- assert(rtex->buffer.b.b.nr_samples <= 2);
+ assert(rtex->num_color_samples <= 2);
clear_size = rtex->surface.dcc_size;
} else {
unsigned num_layers = util_num_layers(&rtex->buffer.b.b, level);
/* If this is 0, fast clear isn't possible. (can occur with MSAA) */
assert(rtex->surface.u.legacy.level[level].dcc_fast_clear_size);
/* Layered 4x and 8x MSAA DCC fast clears need to clear
* dcc_fast_clear_size bytes for each layer. A compute shader
* would be more efficient than separate per-layer clear operations.
*/
- assert(rtex->buffer.b.b.nr_samples <= 2 || num_layers == 1);
+ assert(rtex->num_color_samples <= 2 || num_layers == 1);
dcc_offset += rtex->surface.u.legacy.level[level].dcc_offset;
clear_size = rtex->surface.u.legacy.level[level].dcc_fast_clear_size *
num_layers;
}
si_clear_buffer(sctx, dcc_buffer, dcc_offset, clear_size,
clear_value, SI_COHERENCY_CB_META);
}
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index b5caf944759..241385baed7 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -247,20 +247,21 @@ struct r600_texture {
/* Colorbuffer compression and fast clear. */
uint64_t fmask_offset;
struct r600_cmask_info cmask;
struct r600_resource *cmask_buffer;
uint64_t dcc_offset; /* 0 = disabled */
unsigned cb_color_info; /* fast clear enable bit */
unsigned color_clear_value[2];
unsigned last_msaa_resolve_target_micro_mode;
unsigned num_level0_transfers;
+ unsigned num_color_samples;
/* Depth buffer compression and fast clear. */
uint64_t htile_offset;
float depth_clear_value;
uint16_t dirty_level_mask; /* each bit says if that mipmap is compressed */
uint16_t stencil_dirty_level_mask; /* each bit says if that mipmap is compressed */
enum pipe_format db_render_format:16;
uint8_t stencil_clear_value;
bool tc_compatible_htile:1;
bool depth_cleared:1; /* if it was cleared at least once */
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 1e328b90b62..52b8b87732f 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -213,20 +213,21 @@ static unsigned si_texture_get_offset(struct si_screen *sscreen,
box->z * (uint64_t)rtex->surface.u.legacy.level[level].slice_size_dw * 4 +
(box->y / rtex->surface.blk_h *
rtex->surface.u.legacy.level[level].nblk_x +
box->x / rtex->surface.blk_w) * rtex->surface.bpe;
}
}
static int si_init_surface(struct si_screen *sscreen,
struct radeon_surf *surface,
const struct pipe_resource *ptex,
+ unsigned num_color_samples,
enum radeon_surf_mode array_mode,
unsigned pitch_in_bytes_override,
unsigned offset,
bool is_imported,
bool is_scanout,
bool is_flushed_depth,
bool tc_compatible_htile)
{
const struct util_format_description *desc =
util_format_description(ptex->format);
@@ -267,48 +268,48 @@ static int si_init_surface(struct si_screen *sscreen,
}
if (sscreen->info.chip_class >= VI &&
(ptex->flags & SI_RESOURCE_FLAG_DISABLE_DCC ||
ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT ||
(ptex->nr_samples >= 2 && !sscreen->dcc_msaa_allowed)))
flags |= RADEON_SURF_DISABLE_DCC;
/* VI: DCC clear for 4x and 8x MSAA array textures unimplemented. */
if (sscreen->info.chip_class == VI &&
- ptex->nr_samples >= 4 &&
+ num_color_samples >= 4 &&
ptex->array_size > 1)
flags |= RADEON_SURF_DISABLE_DCC;
/* GFX9: DCC clear for 4x and 8x MSAA textures unimplemented. */
if (sscreen->info.chip_class >= GFX9 &&
- ptex->nr_samples >= 4)
+ num_color_samples >= 4)
flags |= RADEON_SURF_DISABLE_DCC;
if (ptex->bind & PIPE_BIND_SCANOUT || is_scanout) {
/* This should catch bugs in gallium users setting incorrect flags. */
assert(ptex->nr_samples <= 1 &&
ptex->array_size == 1 &&
ptex->depth0 == 1 &&
ptex->last_level == 0 &&
!(flags & RADEON_SURF_Z_OR_SBUFFER));
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, ptex->nr_samples,
+ r = sscreen->ws->surface_init(sscreen->ws, ptex, num_color_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;
@@ -1138,20 +1139,21 @@ void si_print_texture_info(struct si_screen *sscreen,
rtex->surface.u.legacy.stencil_level[i].mode,
rtex->surface.u.legacy.stencil_tiling_index[i]);
}
}
}
/* Common processing for r600_texture_create and r600_texture_from_handle */
static struct r600_texture *
si_texture_create_object(struct pipe_screen *screen,
const struct pipe_resource *base,
+ unsigned num_color_samples,
struct pb_buffer *buf,
struct radeon_surf *surface)
{
struct r600_texture *rtex;
struct r600_resource *resource;
struct si_screen *sscreen = (struct si_screen*)screen;
rtex = CALLOC_STRUCT(r600_texture);
if (!rtex)
return NULL;
@@ -1161,20 +1163,21 @@ si_texture_create_object(struct pipe_screen *screen,
resource->b.b.next = NULL;
resource->b.vtbl = &si_texture_vtbl;
pipe_reference_init(&resource->b.b.reference, 1);
resource->b.b.screen = screen;
/* don't include stencil-only formats which we don't support for rendering */
rtex->is_depth = util_format_has_depth(util_format_description(rtex->buffer.b.b.format));
rtex->surface = *surface;
rtex->size = rtex->surface.surf_size;
+ rtex->num_color_samples = num_color_samples;
rtex->tc_compatible_htile = rtex->surface.htile_size != 0 &&
(rtex->surface.flags &
RADEON_SURF_TC_COMPATIBLE_HTILE);
/* TC-compatible HTILE:
* - VI only supports Z32_FLOAT.
* - GFX9 only supports Z32_FLOAT and Z16_UNORM. */
if (rtex->tc_compatible_htile) {
if (sscreen->info.chip_class >= GFX9 &&
@@ -1377,53 +1380,60 @@ si_choose_tiling(struct si_screen *sscreen,
/* Make small textures 1D tiled. */
if (templ->width0 <= 16 || templ->height0 <= 16 ||
(sscreen->debug_flags & DBG(NO_2D_TILING)))
return RADEON_SURF_MODE_1D;
/* The allocator will switch to 1D if needed. */
return RADEON_SURF_MODE_2D;
}
+static unsigned si_get_num_color_samples(const struct pipe_resource *templ,
+ bool imported)
+{
+ return CLAMP(templ->nr_samples, 1, 8);
+}
+
struct pipe_resource *si_texture_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
{
struct si_screen *sscreen = (struct si_screen*)screen;
struct radeon_surf surface = {0};
bool is_flushed_depth = templ->flags & SI_RESOURCE_FLAG_FLUSHED_DEPTH;
bool tc_compatible_htile =
sscreen->info.chip_class >= VI &&
/* There are issues with TC-compatible HTILE on Tonga (and
* Iceland is the same design), and documented bug workarounds
* don't help. For example, this fails:
* piglit/bin/tex-miplevel-selection 'texture()' 2DShadow -auto
*/
sscreen->info.family != CHIP_TONGA &&
sscreen->info.family != CHIP_ICELAND &&
(templ->flags & PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY) &&
!(sscreen->debug_flags & DBG(NO_HYPERZ)) &&
!is_flushed_depth &&
templ->nr_samples <= 1 && /* TC-compat HTILE is less efficient with MSAA */
util_format_is_depth_or_stencil(templ->format);
-
+ unsigned num_color_samples = si_get_num_color_samples(templ, false);
int r;
- r = si_init_surface(sscreen, &surface, templ,
+ r = si_init_surface(sscreen, &surface, templ, num_color_samples,
si_choose_tiling(sscreen, templ, tc_compatible_htile),
0, 0, false, false, is_flushed_depth,
tc_compatible_htile);
if (r) {
return NULL;
}
return (struct pipe_resource *)
- si_texture_create_object(screen, templ, NULL, &surface);
+ si_texture_create_object(screen, templ, num_color_samples,
+ NULL, &surface);
}
static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
const struct pipe_resource *templ,
struct winsys_handle *whandle,
unsigned usage)
{
struct si_screen *sscreen = (struct si_screen*)screen;
struct pb_buffer *buf = NULL;
unsigned stride = 0, offset = 0;
@@ -1440,27 +1450,31 @@ static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
return NULL;
buf = sscreen->ws->buffer_from_handle(sscreen->ws, whandle, &stride, &offset);
if (!buf)
return NULL;
sscreen->ws->buffer_get_metadata(buf, &metadata);
si_surface_import_metadata(sscreen, &surface, &metadata,
&array_mode, &is_scanout);
- r = si_init_surface(sscreen, &surface, templ, array_mode, stride,
- offset, true, is_scanout, false, false);
+ unsigned num_color_samples = si_get_num_color_samples(templ, true);
+
+ r = si_init_surface(sscreen, &surface, templ, num_color_samples,
+ array_mode, stride, offset, true, is_scanout,
+ false, false);
if (r) {
return NULL;
}
- rtex = si_texture_create_object(screen, templ, buf, &surface);
+ rtex = si_texture_create_object(screen, templ, num_color_samples,
+ buf, &surface);
if (!rtex)
return NULL;
rtex->buffer.b.is_shared = true;
rtex->buffer.external_usage = usage;
si_apply_opaque_metadata(sscreen, rtex, &metadata);
assert(rtex->surface.tile_swizzle == 0);
return &rtex->buffer.b.b;
@@ -2368,31 +2382,32 @@ si_texture_from_memobj(struct pipe_screen *screen,
* All the use cases we are aware of at the moment for memory
* objects use dedicated allocations. So lets keep the initial
* implementation simple.
*
* A possible alternative is to attempt to reconstruct the
* tiling information when the TexParameter TEXTURE_TILING_EXT
* is set.
*/
array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
is_scanout = false;
-
}
- r = si_init_surface(sscreen, &surface, templ,
- array_mode, memobj->stride,
- offset, true, is_scanout,
- false, false);
+ unsigned num_color_samples = si_get_num_color_samples(templ, true);
+
+ r = si_init_surface(sscreen, &surface, templ, num_color_samples,
+ array_mode, memobj->stride, offset, true,
+ is_scanout, false, false);
if (r)
return NULL;
- rtex = si_texture_create_object(screen, templ, memobj->buf, &surface);
+ rtex = si_texture_create_object(screen, templ, num_color_samples,
+ memobj->buf, &surface);
if (!rtex)
return NULL;
/* r600_texture_create_object doesn't increment refcount of
* memobj->buf, so increment it here.
*/
pb_reference(&buf, memobj->buf);
rtex->buffer.b.is_shared = true;
rtex->buffer.external_usage = PIPE_HANDLE_USAGE_READ_WRITE;
--
2.17.0
More information about the mesa-dev
mailing list