summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/amd/common/ac_surface.c34
-rw-r--r--src/amd/common/ac_surface.h1
-rw-r--r--src/amd/vulkan/radv_image.c1
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_surface.c1
4 files changed, 33 insertions, 4 deletions
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index b294cd85259..1b4d72e31bd 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -415,6 +415,31 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
return index;
}
+static bool get_display_flag(const struct ac_surf_config *config,
+ const struct radeon_surf *surf)
+{
+ unsigned num_channels = config->info.num_channels;
+ unsigned bpe = surf->bpe;
+
+ if (surf->flags & RADEON_SURF_SCANOUT &&
+ !(surf->flags & RADEON_SURF_FMASK) &&
+ config->info.samples <= 1 &&
+ surf->blk_w <= 2 && surf->blk_h == 1) {
+ /* subsampled */
+ if (surf->blk_w == 2 && surf->blk_h == 1)
+ return true;
+
+ if (/* RGBA8 or RGBA16F */
+ (bpe >= 4 && bpe <= 8 && num_channels == 4) ||
+ /* R5G6B5 or R5G5B5A1 */
+ (bpe == 2 && num_channels >= 3) ||
+ /* C8 palette */
+ (bpe == 1 && num_channels == 1))
+ return true;
+ }
+ return false;
+}
+
/**
* This must be called after the first level is computed.
*
@@ -449,7 +474,7 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib,
config->info.surf_index &&
surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
!(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
- (config->info.samples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+ !get_display_flag(config, surf)) {
ADDR_COMPUTE_BASE_SWIZZLE_INPUT AddrBaseSwizzleIn = {0};
ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT AddrBaseSwizzleOut = {0};
@@ -568,7 +593,7 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
AddrSurfInfoIn.flags.cube = config->is_cube;
AddrSurfInfoIn.flags.fmask = (surf->flags & RADEON_SURF_FMASK) != 0;
- AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+ AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
AddrSurfInfoIn.flags.pow2Pad = config->info.levels > 1;
AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
@@ -848,6 +873,7 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
sin.preferredSwSet.sw_S = 1;
if (is_fmask) {
+ sin.flags.display = 0;
sin.flags.color = 0;
sin.flags.fmask = 1;
}
@@ -943,7 +969,7 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
in->swizzleMode >= ADDR_SW_64KB_Z_T &&
!out.mipChainInTail &&
!(surf->flags & RADEON_SURF_SHAREABLE) &&
- (in->numSamples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+ !in->flags.display) {
ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
@@ -1196,7 +1222,7 @@ 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 = (surf->flags & RADEON_SURF_SCANOUT) != 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;
diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
index 71f320af8ee..37df859e6de 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -219,6 +219,7 @@ struct ac_surf_info {
uint32_t depth;
uint8_t 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; /* GFX9+ */
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index b35df1d172a..acb569203d4 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -964,6 +964,7 @@ radv_image_create(VkDevice _device,
image->info.samples = pCreateInfo->samples;
image->info.array_size = pCreateInfo->arrayLayers;
image->info.levels = pCreateInfo->mipLevels;
+ image->info.num_channels = 4; /* TODO: set this correctly */
image->vk_format = pCreateInfo->format;
image->tiling = pCreateInfo->tiling;
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index fc5c9d5a127..b5a1ebb1628 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -86,6 +86,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
config.info.array_size = tex->array_size;
config.info.samples = tex->nr_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);