#include "si_pipe.h"
#include "si_query.h"
#include "sid.h"
-#include "state_tracker/drm_driver.h"
+#include "frontend/drm_driver.h"
#include "util/format/u_format.h"
#include "util/os_time.h"
#include "util/u_log.h"
if (vi_dcc_enabled(src, src_level) || vi_dcc_enabled(dst, dst_level))
return false;
+ /* TMZ: mixing encrypted and non-encrypted buffer in a single command
+ * doesn't seem supported.
+ */
+ if ((src->buffer.flags & RADEON_FLAG_ENCRYPTED) !=
+ (dst->buffer.flags & RADEON_FLAG_ENCRYPTED))
+ return false;
+
/* CMASK as:
* src: Both texture and SDMA paths need decompression. Use SDMA.
* dst: If overwriting the whole texture, discard CMASK and use
}
if (sscreen->info.chip_class >= GFX8 &&
- (ptex->flags & SI_RESOURCE_FLAG_DISABLE_DCC || ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT ||
+ (ptex->flags & SI_RESOURCE_FLAG_DISABLE_DCC ||
+ (sscreen->info.chip_class < GFX10_3 &&
+ ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT) ||
(ptex->nr_samples >= 2 && !sscreen->dcc_msaa_allowed)))
flags |= RADEON_SURF_DISABLE_DCC;
static void si_texture_destroy(struct pipe_screen *screen, struct pipe_resource *ptex)
{
- struct si_screen *sscreen = (struct si_screen *)screen;
struct si_texture *tex = (struct si_texture *)ptex;
struct si_resource *resource = &tex->buffer;
- if (sscreen->info.chip_class >= GFX9)
- free(tex->surface.u.gfx9.dcc_retile_map);
-
si_texture_reference(&tex->flushed_depth_texture, NULL);
if (tex->cmask_buffer != &tex->buffer) {
/* don't include stencil-only formats which we don't support for rendering */
tex->is_depth = util_format_has_depth(util_format_description(tex->buffer.b.b.format));
tex->surface = *surface;
- tex->tc_compatible_htile = false; /* This will be enabled on demand. */
+
+ /* On GFX8, HTILE uses different tiling depending on the TC_COMPATIBLE_HTILE
+ * setting, so we have to enable it if we enabled it at allocation.
+ *
+ * GFX9 and later use the same tiling for both, so TC-compatible HTILE can be
+ * enabled on demand.
+ */
+ tex->tc_compatible_htile = sscreen->info.chip_class == GFX8 &&
+ tex->surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
/* TC-compatible HTILE:
* - GFX8 only supports Z32_FLOAT.
*/
bool use_uint16 = tex->surface.u.gfx9.dcc_retile_use_uint16;
unsigned num_elements = tex->surface.u.gfx9.dcc_retile_num_elements;
+ unsigned dcc_retile_map_size = num_elements * (use_uint16 ? 2 : 4);
struct si_resource *buf = si_aligned_buffer_create(screen, 0, PIPE_USAGE_STREAM,
- num_elements * (use_uint16 ? 2 : 4),
+ dcc_retile_map_size,
sscreen->info.tcc_cache_line_size);
- uint32_t *ui = (uint32_t *)sscreen->ws->buffer_map(buf->buf, NULL, PIPE_TRANSFER_WRITE);
- uint16_t *us = (uint16_t *)ui;
+ void *map = sscreen->ws->buffer_map(buf->buf, NULL, PIPE_TRANSFER_WRITE);
- /* Upload the retile map into a staging buffer. */
- if (use_uint16) {
- for (unsigned i = 0; i < num_elements; i++)
- us[i] = tex->surface.u.gfx9.dcc_retile_map[i];
- } else {
- for (unsigned i = 0; i < num_elements; i++)
- ui[i] = tex->surface.u.gfx9.dcc_retile_map[i];
- }
+ /* Upload the retile map into the staging buffer. */
+ memcpy(map, tex->surface.u.gfx9.dcc_retile_map, dcc_retile_map_size);
/* Copy the staging buffer to the buffer backing the texture. */
struct si_context *sctx = (struct si_context *)sscreen->aux_context;
error:
FREE(tex);
- if (sscreen->info.chip_class >= GFX9)
- free(surface->u.gfx9.dcc_retile_map);
return NULL;
}
return RADEON_SURF_MODE_2D;
/* Transfer resources should be linear. */
- if (templ->flags & SI_RESOURCE_FLAG_TRANSFER)
+ if (templ->flags & SI_RESOURCE_FLAG_FORCE_LINEAR)
return RADEON_SURF_MODE_LINEAR_ALIGNED;
/* Avoid Z/S decompress blits by forcing TC-compatible HTILE on GFX8,
if (templ->nr_samples >= 2) {
/* This is hackish (overwriting the const pipe_resource template),
- * but should be harmless and state trackers can also see
+ * but should be harmless and gallium frontends can also see
* the overriden number of samples in the created pipe_resource.
*/
if (is_zs && sscreen->eqaa_force_z_samples) {
}
}
- bool is_flushed_depth =
- templ->flags & SI_RESOURCE_FLAG_FLUSHED_DEPTH || templ->flags & SI_RESOURCE_FLAG_TRANSFER;
+ bool is_flushed_depth = templ->flags & SI_RESOURCE_FLAG_FLUSHED_DEPTH ||
+ templ->flags & SI_RESOURCE_FLAG_FORCE_LINEAR;
bool tc_compatible_htile =
sscreen->info.chip_class >= GFX8 &&
/* There are issues with TC-compatible HTILE on Tonga (and
*/
static void si_init_temp_resource_from_box(struct pipe_resource *res, struct pipe_resource *orig,
const struct pipe_box *box, unsigned level,
- unsigned flags)
+ unsigned usage, unsigned flags)
{
memset(res, 0, sizeof(*res));
res->format = orig->format;
res->height0 = box->height;
res->depth0 = 1;
res->array_size = 1;
- res->usage = flags & SI_RESOURCE_FLAG_TRANSFER ? PIPE_USAGE_STAGING : PIPE_USAGE_DEFAULT;
+ res->usage = usage;
res->flags = flags;
- if (flags & SI_RESOURCE_FLAG_TRANSFER && util_format_is_compressed(orig->format)) {
+ if (flags & SI_RESOURCE_FLAG_FORCE_LINEAR && util_format_is_compressed(orig->format)) {
/* Transfer resources are allocated with linear tiling, which is
* not supported for compressed formats.
*/
char *map;
bool use_staging_texture = false;
- assert(!(texture->flags & SI_RESOURCE_FLAG_TRANSFER));
+ assert(!(texture->flags & SI_RESOURCE_FLAG_FORCE_LINEAR));
assert(box->width && box->height && box->depth);
- /* If we are uploading into FP16 or R11G11B10_FLOAT via a blit, CB clobbers NaNs,
- * so in order to preserve them exactly, we have to use the compute blit.
- * The compute blit is used only when the destination doesn't have DCC, so
- * disable it here, which is kinda a hack.
- *
- * This makes KHR-GL45.texture_view.view_classes pass on gfx9.
- * gfx10 has the same issue, but the test doesn't use a large enough texture
- * to enable DCC and fail, so it always passes.
- */
- const struct util_format_description *desc = util_format_description(texture->format);
- if (vi_dcc_enabled(tex, level) &&
- desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT &&
- desc->channel[0].size < 32)
- si_texture_disable_dcc(sctx, tex);
-
if (tex->is_depth) {
/* Depth textures use staging unconditionally. */
use_staging_texture = true;
if (use_staging_texture) {
struct pipe_resource resource;
struct si_texture *staging;
+ unsigned bo_usage = usage & PIPE_TRANSFER_READ ? PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
+ unsigned bo_flags = SI_RESOURCE_FLAG_FORCE_LINEAR;
- si_init_temp_resource_from_box(&resource, texture, box, level, SI_RESOURCE_FLAG_TRANSFER);
- resource.usage = (usage & PIPE_TRANSFER_READ) ? PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
+ /* The pixel shader has a bad access pattern for linear textures.
+ * If a pixel shader is used to blit to/from staging, don't disable caches.
+ *
+ * MSAA, depth/stencil textures, and compressed textures use the pixel shader
+ * to blit.
+ */
+ if (texture->nr_samples <= 1 &&
+ !tex->is_depth &&
+ !util_format_is_compressed(texture->format) &&
+ /* Texture uploads with DCC use the pixel shader to blit */
+ (!(usage & PIPE_TRANSFER_WRITE) || !vi_dcc_enabled(tex, level)))
+ bo_flags |= SI_RESOURCE_FLAG_UNCACHED;
+
+ si_init_temp_resource_from_box(&resource, texture, box, level, bo_usage,
+ bo_flags);
/* Since depth-stencil textures don't support linear tiling,
* blit from ZS to color and vice versa. u_blitter will do