Path: blob/21.2-virgl/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
4574 views
/*1* Copyright (C) 2018 Rob Clark <[email protected]>2* Copyright © 2018 Google, Inc.3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23* Authors:24* Rob Clark <[email protected]>25*/2627#include "drm-uapi/drm_fourcc.h"2829#include "fd6_format.h"30#include "fd6_resource.h"3132#include "a6xx.xml.h"3334/* A subset of the valid tiled formats can be compressed. We do35* already require tiled in order to be compressed, but just because36* it can be tiled doesn't mean it can be compressed.37*/38static bool39ok_ubwc_format(struct pipe_screen *pscreen, enum pipe_format pfmt)40{41const struct fd_dev_info *info = fd_screen(pscreen)->info;4243switch (pfmt) {44case PIPE_FORMAT_X24S8_UINT:45case PIPE_FORMAT_Z24_UNORM_S8_UINT:46/* We can't sample stencil with UBWC on a630, and we may need to be able47* to sample stencil at some point. We can't just use48* fd_resource_uncompress() at the point of stencil sampling because49* that itself uses stencil sampling in the fd_blitter_blit path.50*/51return info->a6xx.has_z24uint_s8uint;5253case PIPE_FORMAT_R8_G8B8_420_UNORM:54return true;5556default:57break;58}5960switch (fd6_pipe2color(pfmt)) {61case FMT6_10_10_10_2_UINT:62case FMT6_10_10_10_2_UNORM_DEST:63case FMT6_11_11_10_FLOAT:64case FMT6_16_FLOAT:65case FMT6_16_16_16_16_FLOAT:66case FMT6_16_16_16_16_SINT:67case FMT6_16_16_16_16_UINT:68case FMT6_16_16_FLOAT:69case FMT6_16_16_SINT:70case FMT6_16_16_UINT:71case FMT6_16_SINT:72case FMT6_16_UINT:73case FMT6_32_32_32_32_SINT:74case FMT6_32_32_32_32_UINT:75case FMT6_32_32_SINT:76case FMT6_32_32_UINT:77case FMT6_5_6_5_UNORM:78case FMT6_8_8_8_8_SINT:79case FMT6_8_8_8_8_UINT:80case FMT6_8_8_8_8_UNORM:81case FMT6_8_8_8_X8_UNORM:82case FMT6_8_8_SINT:83case FMT6_8_8_UINT:84case FMT6_8_8_UNORM:85case FMT6_Z24_UNORM_S8_UINT:86case FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8:87return true;88case FMT6_8_UNORM:89return info->a6xx.has_8bpp_ubwc;90default:91return false;92}93}9495static bool96can_do_ubwc(struct pipe_resource *prsc)97{98/* limit things to simple single level 2d for now: */99if ((prsc->depth0 != 1) || (prsc->array_size != 1) ||100(prsc->last_level != 0))101return false;102if (prsc->target != PIPE_TEXTURE_2D)103return false;104if (!ok_ubwc_format(prsc->screen, prsc->format))105return false;106return true;107}108109static bool110is_norm(enum pipe_format format)111{112const struct util_format_description *desc = util_format_description(format);113114return desc->is_snorm || desc->is_unorm;115}116117static bool118valid_format_cast(struct fd_resource *rsc, enum pipe_format format)119{120/* Special case "casting" format in hw: */121if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8)122return true;123124/* For some color values (just "solid white") compression metadata maps to125* different pixel values for uint/sint vs unorm/snorm, so we can't reliably126* "cast" u/snorm to u/sint and visa versa:127*/128if (is_norm(format) != is_norm(rsc->b.b.format))129return false;130131/* The UBWC formats can be re-interpreted so long as the components132* have the same # of bits133*/134for (unsigned i = 0; i < 4; i++) {135unsigned sb, db;136137sb = util_format_get_component_bits(rsc->b.b.format, UTIL_FORMAT_COLORSPACE_RGB, i);138db = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, i);139140if (sb != db)141return false;142}143144return true;145}146147/**148* R8G8 have a different block width/height and height alignment from other149* formats that would normally be compatible (like R16), and so if we are150* trying to, for example, sample R16 as R8G8 we need to demote to linear.151*/152static bool153is_r8g8(enum pipe_format format)154{155return (util_format_get_blocksize(format) == 2) &&156(util_format_get_nr_components(format) == 2);157}158159/**160* Ensure the rsc is in an ok state to be used with the specified format.161* This handles the case of UBWC buffers used with non-UBWC compatible162* formats, by triggering an uncompress.163*/164void165fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc,166enum pipe_format format)167{168enum pipe_format orig_format = rsc->b.b.format;169170tc_assert_driver_thread(ctx->tc);171172if (orig_format == format)173return;174175if (rsc->layout.tile_mode && (is_r8g8(orig_format) != is_r8g8(format))) {176perf_debug_ctx(ctx,177"%" PRSC_FMT ": demoted to linear+uncompressed due to use as %s",178PRSC_ARGS(&rsc->b.b), util_format_short_name(format));179180fd_resource_uncompress(ctx, rsc, true);181return;182}183184if (!rsc->layout.ubwc)185return;186187if (ok_ubwc_format(rsc->b.b.screen, format) && valid_format_cast(rsc, format))188return;189190perf_debug_ctx(ctx,191"%" PRSC_FMT ": demoted to uncompressed due to use as %s",192PRSC_ARGS(&rsc->b.b), util_format_short_name(format));193194fd_resource_uncompress(ctx, rsc, false);195}196197static void198setup_lrz(struct fd_resource *rsc)199{200struct fd_screen *screen = fd_screen(rsc->b.b.screen);201unsigned width0 = rsc->b.b.width0;202unsigned height0 = rsc->b.b.height0;203204/* LRZ buffer is super-sampled: */205switch (rsc->b.b.nr_samples) {206case 4:207width0 *= 2;208FALLTHROUGH;209case 2:210height0 *= 2;211}212213unsigned lrz_pitch = align(DIV_ROUND_UP(width0, 8), 32);214unsigned lrz_height = align(DIV_ROUND_UP(height0, 8), 16);215216unsigned size = lrz_pitch * lrz_height * 2;217218rsc->lrz_height = lrz_height;219rsc->lrz_width = lrz_pitch;220rsc->lrz_pitch = lrz_pitch;221rsc->lrz = fd_bo_new(screen->dev, size, 0, "lrz");222}223224static uint32_t225fd6_setup_slices(struct fd_resource *rsc)226{227struct pipe_resource *prsc = &rsc->b.b;228229if (!FD_DBG(NOLRZ) && has_depth(rsc->b.b.format))230setup_lrz(rsc);231232if (rsc->layout.ubwc && !ok_ubwc_format(rsc->b.b.screen, rsc->b.b.format))233rsc->layout.ubwc = false;234235fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc),236prsc->width0, prsc->height0, prsc->depth0, prsc->last_level + 1,237prsc->array_size, prsc->target == PIPE_TEXTURE_3D, NULL);238239return rsc->layout.size;240}241242static int243fill_ubwc_buffer_sizes(struct fd_resource *rsc)244{245struct pipe_resource *prsc = &rsc->b.b;246struct fdl_explicit_layout explicit = {247.offset = rsc->layout.slices[0].offset,248.pitch = rsc->layout.pitch0,249};250251if (!can_do_ubwc(prsc))252return -1;253254rsc->layout.ubwc = true;255rsc->layout.tile_mode = TILE6_3;256257if (!fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc),258prsc->width0, prsc->height0, prsc->depth0,259prsc->last_level + 1, prsc->array_size, false, &explicit))260return -1;261262if (rsc->layout.size > fd_bo_size(rsc->bo))263return -1;264265return 0;266}267268static int269fd6_layout_resource_for_modifier(struct fd_resource *rsc, uint64_t modifier)270{271switch (modifier) {272case DRM_FORMAT_MOD_QCOM_COMPRESSED:273return fill_ubwc_buffer_sizes(rsc);274case DRM_FORMAT_MOD_LINEAR:275if (can_do_ubwc(&rsc->b.b)) {276perf_debug("%" PRSC_FMT277": not UBWC: imported with DRM_FORMAT_MOD_LINEAR!",278PRSC_ARGS(&rsc->b.b));279}280return 0;281case DRM_FORMAT_MOD_INVALID:282if (can_do_ubwc(&rsc->b.b)) {283perf_debug("%" PRSC_FMT284": not UBWC: imported with DRM_FORMAT_MOD_INVALID!",285PRSC_ARGS(&rsc->b.b));286}287return 0;288default:289return -1;290}291}292293static const uint64_t supported_modifiers[] = {294DRM_FORMAT_MOD_LINEAR,295DRM_FORMAT_MOD_QCOM_COMPRESSED,296};297298void299fd6_resource_screen_init(struct pipe_screen *pscreen)300{301struct fd_screen *screen = fd_screen(pscreen);302303screen->setup_slices = fd6_setup_slices;304screen->layout_resource_for_modifier = fd6_layout_resource_for_modifier;305screen->supported_modifiers = supported_modifiers;306screen->num_supported_modifiers = ARRAY_SIZE(supported_modifiers);307}308309310