Path: blob/21.2-virgl/src/intel/isl/isl_aux_info.c
4547 views
/*1* Copyright 2019 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER20* DEALINGS IN THE SOFTWARE.21*/2223#include "isl/isl.h"2425#ifdef IN_UNIT_TEST26/* STATIC_ASSERT is a do { ... } while(0) statement */27UNUSED static void static_assert_func(void) {28STATIC_ASSERT(ISL_AUX_OP_ASSERT == ((enum isl_aux_op) 0));29STATIC_ASSERT(ISL_AUX_STATE_ASSERT == ((enum isl_aux_state) 0));30}3132#undef unreachable33#define unreachable(str) return 03435#undef assert36#define assert(cond) do { \37if (!(cond)) { \38return 0; \39} \40} while (0)41#endif4243/* How writes with an isl_aux_usage behave. */44enum write_behavior {45/* Writes only touch the main surface. */46WRITES_ONLY_TOUCH_MAIN = 0,4748/* Writes using the 3D engine are compressed. */49WRITES_COMPRESS,5051/* Writes using the 3D engine are either compressed or substituted with52* fast-cleared blocks.53*/54WRITES_COMPRESS_CLEAR,5556/* Writes implicitly fully resolve the compression block and write the data57* uncompressed into the main surface. The resolved aux blocks are58* ambiguated and left in the pass-through state.59*/60WRITES_RESOLVE_AMBIGUATE,61};6263/* A set of features supported by an isl_aux_usage. */64struct aux_usage_info {6566/* How writes affect the surface(s) in use. */67enum write_behavior write_behavior;6869/* Aux supports "real" compression beyond just fast-clears. */70bool compressed;7172/* SW can perform ISL_AUX_OP_FAST_CLEAR. */73bool fast_clear;7475/* SW can perform ISL_AUX_OP_PARTIAL_RESOLVE. */76bool partial_resolve;7778/* Performing ISL_AUX_OP_FULL_RESOLVE includes ISL_AUX_OP_AMBIGUATE. */79bool full_resolves_ambiguate;80};8182#define AUX(wb, c, fc, pr, fra, type) \83[ISL_AUX_USAGE_ ## type] = { WRITES_ ## wb, c, fc, pr, fra},84#define Y true85#define x false86static const struct aux_usage_info info[] = {87/* write_behavior c fc pr fra */88AUX( COMPRESS, Y, Y, x, x, HIZ)89AUX( COMPRESS, Y, Y, x, x, HIZ_CCS)90AUX( COMPRESS, Y, Y, x, x, HIZ_CCS_WT)91AUX( COMPRESS, Y, Y, Y, x, MCS)92AUX( COMPRESS, Y, Y, Y, x, MCS_CCS)93AUX( COMPRESS, Y, Y, Y, Y, CCS_E)94AUX( COMPRESS_CLEAR, Y, Y, Y, Y, GFX12_CCS_E)95AUX(RESOLVE_AMBIGUATE, x, Y, x, Y, CCS_D)96AUX(RESOLVE_AMBIGUATE, Y, x, x, Y, MC)97AUX( COMPRESS, Y, x, x, Y, STC_CCS)98};99#undef x100#undef Y101#undef AUX102103ASSERTED static bool104aux_state_possible(enum isl_aux_state state,105enum isl_aux_usage usage)106{107switch (state) {108case ISL_AUX_STATE_CLEAR:109case ISL_AUX_STATE_PARTIAL_CLEAR:110return info[usage].fast_clear;111case ISL_AUX_STATE_COMPRESSED_CLEAR:112return info[usage].fast_clear && info[usage].compressed;113case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:114return info[usage].compressed;115case ISL_AUX_STATE_RESOLVED:116case ISL_AUX_STATE_PASS_THROUGH:117case ISL_AUX_STATE_AUX_INVALID:118return true;119#ifdef IN_UNIT_TEST120case ISL_AUX_STATE_ASSERT:121break;122#endif123}124125unreachable("Invalid aux state.");126}127128enum isl_aux_op129isl_aux_prepare_access(enum isl_aux_state initial_state,130enum isl_aux_usage usage,131bool fast_clear_supported)132{133if (usage != ISL_AUX_USAGE_NONE) {134UNUSED const enum isl_aux_usage state_superset_usage =135usage == ISL_AUX_USAGE_CCS_D ? ISL_AUX_USAGE_CCS_E : usage;136assert(aux_state_possible(initial_state, state_superset_usage));137}138assert(!fast_clear_supported || info[usage].fast_clear);139140switch (initial_state) {141case ISL_AUX_STATE_COMPRESSED_CLEAR:142if (!info[usage].compressed)143return ISL_AUX_OP_FULL_RESOLVE;144FALLTHROUGH;145case ISL_AUX_STATE_CLEAR:146case ISL_AUX_STATE_PARTIAL_CLEAR:147return fast_clear_supported ?148ISL_AUX_OP_NONE :149info[usage].partial_resolve ?150ISL_AUX_OP_PARTIAL_RESOLVE : ISL_AUX_OP_FULL_RESOLVE;151case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:152return info[usage].compressed ?153ISL_AUX_OP_NONE : ISL_AUX_OP_FULL_RESOLVE;154case ISL_AUX_STATE_RESOLVED:155case ISL_AUX_STATE_PASS_THROUGH:156return ISL_AUX_OP_NONE;157case ISL_AUX_STATE_AUX_INVALID:158return info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN ?159ISL_AUX_OP_NONE : ISL_AUX_OP_AMBIGUATE;160#ifdef IN_UNIT_TEST161case ISL_AUX_STATE_ASSERT:162break;163#endif164}165166unreachable("Invalid aux state.");167}168169enum isl_aux_state170isl_aux_state_transition_aux_op(enum isl_aux_state initial_state,171enum isl_aux_usage usage,172enum isl_aux_op op)173{174assert(aux_state_possible(initial_state, usage));175assert(usage != ISL_AUX_USAGE_NONE || op == ISL_AUX_OP_NONE);176177switch (op) {178case ISL_AUX_OP_NONE:179return initial_state;180case ISL_AUX_OP_FAST_CLEAR:181assert(info[usage].fast_clear);182return ISL_AUX_STATE_CLEAR;183case ISL_AUX_OP_PARTIAL_RESOLVE:184assert(isl_aux_state_has_valid_aux(initial_state));185assert(info[usage].partial_resolve);186return initial_state == ISL_AUX_STATE_CLEAR ||187initial_state == ISL_AUX_STATE_PARTIAL_CLEAR ||188initial_state == ISL_AUX_STATE_COMPRESSED_CLEAR ?189ISL_AUX_STATE_COMPRESSED_NO_CLEAR : initial_state;190case ISL_AUX_OP_FULL_RESOLVE:191assert(isl_aux_state_has_valid_aux(initial_state));192return info[usage].full_resolves_ambiguate ||193initial_state == ISL_AUX_STATE_PASS_THROUGH ?194ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_RESOLVED;195case ISL_AUX_OP_AMBIGUATE:196return ISL_AUX_STATE_PASS_THROUGH;197#if IN_UNIT_TEST198case ISL_AUX_OP_ASSERT:199break;200#endif201}202203unreachable("Invalid aux op.");204}205206enum isl_aux_state207isl_aux_state_transition_write(enum isl_aux_state initial_state,208enum isl_aux_usage usage,209bool full_surface)210{211if (info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN) {212assert(full_surface || isl_aux_state_has_valid_primary(initial_state));213214return initial_state == ISL_AUX_STATE_PASS_THROUGH ?215ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_AUX_INVALID;216}217218assert(isl_aux_state_has_valid_aux(initial_state));219assert(aux_state_possible(initial_state, usage));220assert(info[usage].write_behavior == WRITES_COMPRESS ||221info[usage].write_behavior == WRITES_COMPRESS_CLEAR ||222info[usage].write_behavior == WRITES_RESOLVE_AMBIGUATE);223224if (full_surface) {225return info[usage].write_behavior == WRITES_COMPRESS ?226ISL_AUX_STATE_COMPRESSED_NO_CLEAR :227info[usage].write_behavior == WRITES_COMPRESS_CLEAR ?228ISL_AUX_STATE_COMPRESSED_CLEAR : ISL_AUX_STATE_PASS_THROUGH;229}230231switch (initial_state) {232case ISL_AUX_STATE_CLEAR:233case ISL_AUX_STATE_PARTIAL_CLEAR:234return info[usage].write_behavior == WRITES_RESOLVE_AMBIGUATE ?235ISL_AUX_STATE_PARTIAL_CLEAR : ISL_AUX_STATE_COMPRESSED_CLEAR;236case ISL_AUX_STATE_RESOLVED:237case ISL_AUX_STATE_PASS_THROUGH:238case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:239return info[usage].write_behavior == WRITES_COMPRESS ?240ISL_AUX_STATE_COMPRESSED_NO_CLEAR :241info[usage].write_behavior == WRITES_COMPRESS_CLEAR ?242ISL_AUX_STATE_COMPRESSED_CLEAR : initial_state;243case ISL_AUX_STATE_COMPRESSED_CLEAR:244case ISL_AUX_STATE_AUX_INVALID:245return initial_state;246#ifdef IN_UNIT_TEST247case ISL_AUX_STATE_ASSERT:248break;249#endif250}251252unreachable("Invalid aux state.");253}254255bool256isl_aux_usage_has_fast_clears(enum isl_aux_usage usage)257{258return info[usage].fast_clear;259}260261bool262isl_aux_usage_has_compression(enum isl_aux_usage usage)263{264return info[usage].compressed;265}266267268