1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 4bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * based in part on anv driver which is: 7bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 8bf215546Sopenharmony_ci */ 9bf215546Sopenharmony_ci 10bf215546Sopenharmony_ci#ifndef TU_CMD_BUFFER_H 11bf215546Sopenharmony_ci#define TU_CMD_BUFFER_H 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include "tu_common.h" 14bf215546Sopenharmony_ci 15bf215546Sopenharmony_ci#include "tu_cs.h" 16bf215546Sopenharmony_ci#include "tu_descriptor_set.h" 17bf215546Sopenharmony_ci#include "tu_device.h" 18bf215546Sopenharmony_ci#include "tu_lrz.h" 19bf215546Sopenharmony_ci#include "tu_pass.h" 20bf215546Sopenharmony_ci#include "tu_pipeline.h" 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_cienum tu_draw_state_group_id 23bf215546Sopenharmony_ci{ 24bf215546Sopenharmony_ci TU_DRAW_STATE_PROGRAM_CONFIG, 25bf215546Sopenharmony_ci TU_DRAW_STATE_PROGRAM, 26bf215546Sopenharmony_ci TU_DRAW_STATE_PROGRAM_BINNING, 27bf215546Sopenharmony_ci TU_DRAW_STATE_VB, 28bf215546Sopenharmony_ci TU_DRAW_STATE_VI, 29bf215546Sopenharmony_ci TU_DRAW_STATE_VI_BINNING, 30bf215546Sopenharmony_ci TU_DRAW_STATE_RAST, 31bf215546Sopenharmony_ci TU_DRAW_STATE_CONST, 32bf215546Sopenharmony_ci TU_DRAW_STATE_DESC_SETS, 33bf215546Sopenharmony_ci TU_DRAW_STATE_DESC_SETS_LOAD, 34bf215546Sopenharmony_ci TU_DRAW_STATE_VS_PARAMS, 35bf215546Sopenharmony_ci TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM, 36bf215546Sopenharmony_ci TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM, 37bf215546Sopenharmony_ci TU_DRAW_STATE_LRZ_AND_DEPTH_PLANE, 38bf215546Sopenharmony_ci TU_DRAW_STATE_PRIM_MODE_GMEM, 39bf215546Sopenharmony_ci TU_DRAW_STATE_PRIM_MODE_SYSMEM, 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci /* dynamic state related draw states */ 42bf215546Sopenharmony_ci TU_DRAW_STATE_DYNAMIC, 43bf215546Sopenharmony_ci TU_DRAW_STATE_COUNT = TU_DRAW_STATE_DYNAMIC + TU_DYNAMIC_STATE_COUNT, 44bf215546Sopenharmony_ci}; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cistruct tu_descriptor_state 47bf215546Sopenharmony_ci{ 48bf215546Sopenharmony_ci struct tu_descriptor_set *sets[MAX_SETS]; 49bf215546Sopenharmony_ci struct tu_descriptor_set push_set; 50bf215546Sopenharmony_ci uint32_t dynamic_descriptors[MAX_DYNAMIC_BUFFERS_SIZE]; 51bf215546Sopenharmony_ci}; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cienum tu_cmd_dirty_bits 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci TU_CMD_DIRTY_VERTEX_BUFFERS = BIT(0), 56bf215546Sopenharmony_ci TU_CMD_DIRTY_VB_STRIDE = BIT(1), 57bf215546Sopenharmony_ci TU_CMD_DIRTY_GRAS_SU_CNTL = BIT(2), 58bf215546Sopenharmony_ci TU_CMD_DIRTY_RB_DEPTH_CNTL = BIT(3), 59bf215546Sopenharmony_ci TU_CMD_DIRTY_RB_STENCIL_CNTL = BIT(4), 60bf215546Sopenharmony_ci TU_CMD_DIRTY_DESC_SETS_LOAD = BIT(5), 61bf215546Sopenharmony_ci TU_CMD_DIRTY_COMPUTE_DESC_SETS_LOAD = BIT(6), 62bf215546Sopenharmony_ci TU_CMD_DIRTY_SHADER_CONSTS = BIT(7), 63bf215546Sopenharmony_ci TU_CMD_DIRTY_LRZ = BIT(8), 64bf215546Sopenharmony_ci TU_CMD_DIRTY_VS_PARAMS = BIT(9), 65bf215546Sopenharmony_ci TU_CMD_DIRTY_RASTERIZER_DISCARD = BIT(10), 66bf215546Sopenharmony_ci TU_CMD_DIRTY_VIEWPORTS = BIT(11), 67bf215546Sopenharmony_ci TU_CMD_DIRTY_BLEND = BIT(12), 68bf215546Sopenharmony_ci /* all draw states were disabled and need to be re-enabled: */ 69bf215546Sopenharmony_ci TU_CMD_DIRTY_DRAW_STATE = BIT(13) 70bf215546Sopenharmony_ci}; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci/* There are only three cache domains we have to care about: the CCU, or 73bf215546Sopenharmony_ci * color cache unit, which is used for color and depth/stencil attachments 74bf215546Sopenharmony_ci * and copy/blit destinations, and is split conceptually into color and depth, 75bf215546Sopenharmony_ci * and the universal cache or UCHE which is used for pretty much everything 76bf215546Sopenharmony_ci * else, except for the CP (uncached) and host. We need to flush whenever data 77bf215546Sopenharmony_ci * crosses these boundaries. 78bf215546Sopenharmony_ci */ 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_cienum tu_cmd_access_mask { 81bf215546Sopenharmony_ci TU_ACCESS_UCHE_READ = 1 << 0, 82bf215546Sopenharmony_ci TU_ACCESS_UCHE_WRITE = 1 << 1, 83bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_READ = 1 << 2, 84bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_WRITE = 1 << 3, 85bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_READ = 1 << 4, 86bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_WRITE = 1 << 5, 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci /* Experiments have shown that while it's safe to avoid flushing the CCU 89bf215546Sopenharmony_ci * after each blit/renderpass, it's not safe to assume that subsequent 90bf215546Sopenharmony_ci * lookups with a different attachment state will hit unflushed cache 91bf215546Sopenharmony_ci * entries. That is, the CCU needs to be flushed and possibly invalidated 92bf215546Sopenharmony_ci * when accessing memory with a different attachment state. Writing to an 93bf215546Sopenharmony_ci * attachment under the following conditions after clearing using the 94bf215546Sopenharmony_ci * normal 2d engine path is known to have issues: 95bf215546Sopenharmony_ci * 96bf215546Sopenharmony_ci * - It isn't the 0'th layer. 97bf215546Sopenharmony_ci * - There are more than one attachment, and this isn't the 0'th attachment 98bf215546Sopenharmony_ci * (this seems to also depend on the cpp of the attachments). 99bf215546Sopenharmony_ci * 100bf215546Sopenharmony_ci * Our best guess is that the layer/MRT state is used when computing 101bf215546Sopenharmony_ci * the location of a cache entry in CCU, to avoid conflicts. We assume that 102bf215546Sopenharmony_ci * any access in a renderpass after or before an access by a transfer needs 103bf215546Sopenharmony_ci * a flush/invalidate, and use the _INCOHERENT variants to represent access 104bf215546Sopenharmony_ci * by a renderpass. 105bf215546Sopenharmony_ci */ 106bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_INCOHERENT_READ = 1 << 6, 107bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_INCOHERENT_WRITE = 1 << 7, 108bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_INCOHERENT_READ = 1 << 8, 109bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_INCOHERENT_WRITE = 1 << 9, 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci /* Accesses which bypasses any cache. e.g. writes via the host, 112bf215546Sopenharmony_ci * CP_EVENT_WRITE::BLIT, and the CP are SYSMEM_WRITE. 113bf215546Sopenharmony_ci */ 114bf215546Sopenharmony_ci TU_ACCESS_SYSMEM_READ = 1 << 10, 115bf215546Sopenharmony_ci TU_ACCESS_SYSMEM_WRITE = 1 << 11, 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci /* Memory writes from the CP start in-order with draws and event writes, 118bf215546Sopenharmony_ci * but execute asynchronously and hence need a CP_WAIT_MEM_WRITES if read. 119bf215546Sopenharmony_ci */ 120bf215546Sopenharmony_ci TU_ACCESS_CP_WRITE = 1 << 12, 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci TU_ACCESS_READ = 123bf215546Sopenharmony_ci TU_ACCESS_UCHE_READ | 124bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_READ | 125bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_READ | 126bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_INCOHERENT_READ | 127bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_INCOHERENT_READ | 128bf215546Sopenharmony_ci TU_ACCESS_SYSMEM_READ, 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci TU_ACCESS_WRITE = 131bf215546Sopenharmony_ci TU_ACCESS_UCHE_WRITE | 132bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_WRITE | 133bf215546Sopenharmony_ci TU_ACCESS_CCU_COLOR_INCOHERENT_WRITE | 134bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_WRITE | 135bf215546Sopenharmony_ci TU_ACCESS_CCU_DEPTH_INCOHERENT_WRITE | 136bf215546Sopenharmony_ci TU_ACCESS_SYSMEM_WRITE | 137bf215546Sopenharmony_ci TU_ACCESS_CP_WRITE, 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci TU_ACCESS_ALL = 140bf215546Sopenharmony_ci TU_ACCESS_READ | 141bf215546Sopenharmony_ci TU_ACCESS_WRITE, 142bf215546Sopenharmony_ci}; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci/* Starting with a6xx, the pipeline is split into several "clusters" (really 145bf215546Sopenharmony_ci * pipeline stages). Each stage has its own pair of register banks and can 146bf215546Sopenharmony_ci * switch them independently, so that earlier stages can run ahead of later 147bf215546Sopenharmony_ci * ones. e.g. the FS of draw N and the VS of draw N + 1 can be executing at 148bf215546Sopenharmony_ci * the same time. 149bf215546Sopenharmony_ci * 150bf215546Sopenharmony_ci * As a result of this, we need to insert a WFI when an earlier stage depends 151bf215546Sopenharmony_ci * on the result of a later stage. CP_DRAW_* and CP_BLIT will wait for any 152bf215546Sopenharmony_ci * pending WFI's to complete before starting, and usually before reading 153bf215546Sopenharmony_ci * indirect params even, so a WFI also acts as a full "pipeline stall". 154bf215546Sopenharmony_ci * 155bf215546Sopenharmony_ci * Note, the names of the stages come from CLUSTER_* in devcoredump. We 156bf215546Sopenharmony_ci * include all the stages for completeness, even ones which do not read/write 157bf215546Sopenharmony_ci * anything. 158bf215546Sopenharmony_ci */ 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_cienum tu_stage { 161bf215546Sopenharmony_ci /* This doesn't correspond to a cluster, but we need it for tracking 162bf215546Sopenharmony_ci * indirect draw parameter reads etc. 163bf215546Sopenharmony_ci */ 164bf215546Sopenharmony_ci TU_STAGE_CP, 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci /* - Fetch index buffer 167bf215546Sopenharmony_ci * - Fetch vertex attributes, dispatch VS 168bf215546Sopenharmony_ci */ 169bf215546Sopenharmony_ci TU_STAGE_FE, 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci /* Execute all geometry stages (VS thru GS) */ 172bf215546Sopenharmony_ci TU_STAGE_SP_VS, 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci /* Write to VPC, do primitive assembly. */ 175bf215546Sopenharmony_ci TU_STAGE_PC_VS, 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci /* Rasterization. RB_DEPTH_BUFFER_BASE only exists in CLUSTER_PS according 178bf215546Sopenharmony_ci * to devcoredump so presumably this stage stalls for TU_STAGE_PS when 179bf215546Sopenharmony_ci * early depth testing is enabled before dispatching fragments? However 180bf215546Sopenharmony_ci * GRAS reads and writes LRZ directly. 181bf215546Sopenharmony_ci */ 182bf215546Sopenharmony_ci TU_STAGE_GRAS, 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci /* Execute FS */ 185bf215546Sopenharmony_ci TU_STAGE_SP_PS, 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci /* - Fragment tests 188bf215546Sopenharmony_ci * - Write color/depth 189bf215546Sopenharmony_ci * - Streamout writes (???) 190bf215546Sopenharmony_ci * - Varying interpolation (???) 191bf215546Sopenharmony_ci */ 192bf215546Sopenharmony_ci TU_STAGE_PS, 193bf215546Sopenharmony_ci}; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cienum tu_cmd_flush_bits { 196bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_FLUSH_DEPTH = 1 << 0, 197bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_FLUSH_COLOR = 1 << 1, 198bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_INVALIDATE_DEPTH = 1 << 2, 199bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_INVALIDATE_COLOR = 1 << 3, 200bf215546Sopenharmony_ci TU_CMD_FLAG_CACHE_FLUSH = 1 << 4, 201bf215546Sopenharmony_ci TU_CMD_FLAG_CACHE_INVALIDATE = 1 << 5, 202bf215546Sopenharmony_ci TU_CMD_FLAG_WAIT_MEM_WRITES = 1 << 6, 203bf215546Sopenharmony_ci TU_CMD_FLAG_WAIT_FOR_IDLE = 1 << 7, 204bf215546Sopenharmony_ci TU_CMD_FLAG_WAIT_FOR_ME = 1 << 8, 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci TU_CMD_FLAG_ALL_FLUSH = 207bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_FLUSH_DEPTH | 208bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_FLUSH_COLOR | 209bf215546Sopenharmony_ci TU_CMD_FLAG_CACHE_FLUSH | 210bf215546Sopenharmony_ci /* Treat the CP as a sort of "cache" which may need to be "flushed" via 211bf215546Sopenharmony_ci * waiting for writes to land with WAIT_FOR_MEM_WRITES. 212bf215546Sopenharmony_ci */ 213bf215546Sopenharmony_ci TU_CMD_FLAG_WAIT_MEM_WRITES, 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci TU_CMD_FLAG_ALL_INVALIDATE = 216bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_INVALIDATE_DEPTH | 217bf215546Sopenharmony_ci TU_CMD_FLAG_CCU_INVALIDATE_COLOR | 218bf215546Sopenharmony_ci TU_CMD_FLAG_CACHE_INVALIDATE | 219bf215546Sopenharmony_ci /* Treat CP_WAIT_FOR_ME as a "cache" that needs to be invalidated when a 220bf215546Sopenharmony_ci * a command that needs CP_WAIT_FOR_ME is executed. This means we may 221bf215546Sopenharmony_ci * insert an extra WAIT_FOR_ME before an indirect command requiring it 222bf215546Sopenharmony_ci * in case there was another command before the current command buffer 223bf215546Sopenharmony_ci * that it needs to wait for. 224bf215546Sopenharmony_ci */ 225bf215546Sopenharmony_ci TU_CMD_FLAG_WAIT_FOR_ME, 226bf215546Sopenharmony_ci}; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci/* Changing the CCU from sysmem mode to gmem mode or vice-versa is pretty 229bf215546Sopenharmony_ci * heavy, involving a CCU cache flush/invalidate and a WFI in order to change 230bf215546Sopenharmony_ci * which part of the gmem is used by the CCU. Here we keep track of what the 231bf215546Sopenharmony_ci * state of the CCU. 232bf215546Sopenharmony_ci */ 233bf215546Sopenharmony_cienum tu_cmd_ccu_state { 234bf215546Sopenharmony_ci TU_CMD_CCU_SYSMEM, 235bf215546Sopenharmony_ci TU_CMD_CCU_GMEM, 236bf215546Sopenharmony_ci TU_CMD_CCU_UNKNOWN, 237bf215546Sopenharmony_ci}; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_cistruct tu_cache_state { 240bf215546Sopenharmony_ci /* Caches which must be made available (flushed) eventually if there are 241bf215546Sopenharmony_ci * any users outside that cache domain, and caches which must be 242bf215546Sopenharmony_ci * invalidated eventually if there are any reads. 243bf215546Sopenharmony_ci */ 244bf215546Sopenharmony_ci enum tu_cmd_flush_bits pending_flush_bits; 245bf215546Sopenharmony_ci /* Pending flushes */ 246bf215546Sopenharmony_ci enum tu_cmd_flush_bits flush_bits; 247bf215546Sopenharmony_ci}; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_cistruct tu_vs_params { 250bf215546Sopenharmony_ci uint32_t vertex_offset; 251bf215546Sopenharmony_ci uint32_t first_instance; 252bf215546Sopenharmony_ci}; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci/* This should be for state that is set inside a renderpass and used at 255bf215546Sopenharmony_ci * renderpass end time, e.g. to decide whether to use sysmem. This needs 256bf215546Sopenharmony_ci * special handling for secondary cmdbufs and suspending/resuming render 257bf215546Sopenharmony_ci * passes where the state may need to be combined afterwards. 258bf215546Sopenharmony_ci */ 259bf215546Sopenharmony_cistruct tu_render_pass_state 260bf215546Sopenharmony_ci{ 261bf215546Sopenharmony_ci bool xfb_used; 262bf215546Sopenharmony_ci bool has_tess; 263bf215546Sopenharmony_ci bool has_prim_generated_query_in_rp; 264bf215546Sopenharmony_ci bool disable_gmem; 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci /* Track whether conditional predicate for COND_REG_EXEC is changed in draw_cs */ 267bf215546Sopenharmony_ci bool draw_cs_writes_to_cond_pred; 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci uint32_t drawcall_count; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* A calculated "draw cost" value for renderpass, which tries to 272bf215546Sopenharmony_ci * estimate the bandwidth-per-sample of all the draws according 273bf215546Sopenharmony_ci * to: 274bf215546Sopenharmony_ci * 275bf215546Sopenharmony_ci * foreach_draw (...) { 276bf215546Sopenharmony_ci * sum += pipeline->color_bandwidth_per_sample; 277bf215546Sopenharmony_ci * if (depth_test_enabled) 278bf215546Sopenharmony_ci * sum += pipeline->depth_cpp_per_sample; 279bf215546Sopenharmony_ci * if (depth_write_enabled) 280bf215546Sopenharmony_ci * sum += pipeline->depth_cpp_per_sample; 281bf215546Sopenharmony_ci * if (stencil_write_enabled) 282bf215546Sopenharmony_ci * sum += pipeline->stencil_cpp_per_sample * 2; 283bf215546Sopenharmony_ci * } 284bf215546Sopenharmony_ci * drawcall_bandwidth_per_sample = sum / drawcall_count; 285bf215546Sopenharmony_ci * 286bf215546Sopenharmony_ci * It allows us to estimate the total bandwidth of drawcalls later, by 287bf215546Sopenharmony_ci * calculating (drawcall_bandwidth_per_sample * zpass_sample_count). 288bf215546Sopenharmony_ci * 289bf215546Sopenharmony_ci * This does ignore depth buffer traffic for samples which do not 290bf215546Sopenharmony_ci * pass due to depth-test fail, and some other details. But it is 291bf215546Sopenharmony_ci * just intended to be a rough estimate that is easy to calculate. 292bf215546Sopenharmony_ci */ 293bf215546Sopenharmony_ci uint32_t drawcall_bandwidth_per_sample_sum; 294bf215546Sopenharmony_ci}; 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_cistruct tu_cmd_state 297bf215546Sopenharmony_ci{ 298bf215546Sopenharmony_ci uint32_t dirty; 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci struct tu_pipeline *pipeline; 301bf215546Sopenharmony_ci struct tu_pipeline *compute_pipeline; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci struct tu_render_pass_state rp; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci /* Vertex buffers, viewports, and scissors 306bf215546Sopenharmony_ci * the states for these can be updated partially, so we need to save these 307bf215546Sopenharmony_ci * to be able to emit a complete draw state 308bf215546Sopenharmony_ci */ 309bf215546Sopenharmony_ci struct { 310bf215546Sopenharmony_ci uint64_t base; 311bf215546Sopenharmony_ci uint32_t size; 312bf215546Sopenharmony_ci uint32_t stride; 313bf215546Sopenharmony_ci } vb[MAX_VBS]; 314bf215546Sopenharmony_ci VkViewport viewport[MAX_VIEWPORTS]; 315bf215546Sopenharmony_ci VkRect2D scissor[MAX_SCISSORS]; 316bf215546Sopenharmony_ci uint32_t max_viewport, max_scissor; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci /* for dynamic states that can't be emitted directly */ 319bf215546Sopenharmony_ci uint32_t dynamic_stencil_mask; 320bf215546Sopenharmony_ci uint32_t dynamic_stencil_wrmask; 321bf215546Sopenharmony_ci uint32_t dynamic_stencil_ref; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci uint32_t gras_su_cntl, rb_depth_cntl, rb_stencil_cntl; 324bf215546Sopenharmony_ci uint32_t pc_raster_cntl, vpc_unknown_9107; 325bf215546Sopenharmony_ci uint32_t rb_mrt_control[MAX_RTS], rb_mrt_blend_control[MAX_RTS]; 326bf215546Sopenharmony_ci uint32_t rb_mrt_control_rop; 327bf215546Sopenharmony_ci uint32_t rb_blend_cntl, sp_blend_cntl; 328bf215546Sopenharmony_ci uint32_t pipeline_color_write_enable, pipeline_blend_enable; 329bf215546Sopenharmony_ci uint32_t color_write_enable; 330bf215546Sopenharmony_ci bool logic_op_enabled; 331bf215546Sopenharmony_ci bool rop_reads_dst; 332bf215546Sopenharmony_ci enum pc_di_primtype primtype; 333bf215546Sopenharmony_ci bool primitive_restart_enable; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci /* saved states to re-emit in TU_CMD_DIRTY_DRAW_STATE case */ 336bf215546Sopenharmony_ci struct tu_draw_state dynamic_state[TU_DYNAMIC_STATE_COUNT]; 337bf215546Sopenharmony_ci struct tu_draw_state vertex_buffers; 338bf215546Sopenharmony_ci struct tu_draw_state shader_const; 339bf215546Sopenharmony_ci struct tu_draw_state desc_sets; 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci struct tu_draw_state vs_params; 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci /* Index buffer */ 344bf215546Sopenharmony_ci uint64_t index_va; 345bf215546Sopenharmony_ci uint32_t max_index_count; 346bf215546Sopenharmony_ci uint8_t index_size; 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci /* because streamout base has to be 32-byte aligned 349bf215546Sopenharmony_ci * there is an extra offset to deal with when it is 350bf215546Sopenharmony_ci * unaligned 351bf215546Sopenharmony_ci */ 352bf215546Sopenharmony_ci uint8_t streamout_offset[IR3_MAX_SO_BUFFERS]; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci /* Renderpasses are tricky, because we may need to flush differently if 355bf215546Sopenharmony_ci * using sysmem vs. gmem and therefore we have to delay any flushing that 356bf215546Sopenharmony_ci * happens before a renderpass. So we have to have two copies of the flush 357bf215546Sopenharmony_ci * state, one for intra-renderpass flushes (i.e. renderpass dependencies) 358bf215546Sopenharmony_ci * and one for outside a renderpass. 359bf215546Sopenharmony_ci */ 360bf215546Sopenharmony_ci struct tu_cache_state cache; 361bf215546Sopenharmony_ci struct tu_cache_state renderpass_cache; 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci enum tu_cmd_ccu_state ccu_state; 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci /* Decides which GMEM layout to use from the tu_pass, based on whether the CCU 366bf215546Sopenharmony_ci * might get used by tu_store_gmem_attachment(). 367bf215546Sopenharmony_ci */ 368bf215546Sopenharmony_ci enum tu_gmem_layout gmem_layout; 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci const struct tu_render_pass *pass; 371bf215546Sopenharmony_ci const struct tu_subpass *subpass; 372bf215546Sopenharmony_ci const struct tu_framebuffer *framebuffer; 373bf215546Sopenharmony_ci const struct tu_tiling_config *tiling; 374bf215546Sopenharmony_ci VkRect2D render_area; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci const struct tu_image_view **attachments; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci /* State that in the dynamic case comes from VkRenderingInfo and needs to 379bf215546Sopenharmony_ci * be saved/restored when suspending. This holds the state for the last 380bf215546Sopenharmony_ci * suspended renderpass, which may point to this command buffer's dynamic_* 381bf215546Sopenharmony_ci * or another command buffer if executed on a secondary. 382bf215546Sopenharmony_ci */ 383bf215546Sopenharmony_ci struct { 384bf215546Sopenharmony_ci const struct tu_render_pass *pass; 385bf215546Sopenharmony_ci const struct tu_subpass *subpass; 386bf215546Sopenharmony_ci const struct tu_framebuffer *framebuffer; 387bf215546Sopenharmony_ci VkRect2D render_area; 388bf215546Sopenharmony_ci enum tu_gmem_layout gmem_layout; 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci const struct tu_image_view **attachments; 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci struct tu_lrz_state lrz; 393bf215546Sopenharmony_ci } suspended_pass; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci bool tessfactor_addr_set; 396bf215546Sopenharmony_ci bool predication_active; 397bf215546Sopenharmony_ci enum a5xx_line_mode line_mode; 398bf215546Sopenharmony_ci bool z_negative_one_to_one; 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci /* VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT and 401bf215546Sopenharmony_ci * VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT are allowed to run simultaniously, 402bf215546Sopenharmony_ci * but they use the same {START,STOP}_PRIMITIVE_CTRS control. 403bf215546Sopenharmony_ci */ 404bf215546Sopenharmony_ci uint32_t prim_counters_running; 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci bool prim_generated_query_running_before_rp; 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci /* These are the states of the suspend/resume state machine. In addition to 409bf215546Sopenharmony_ci * tracking whether we're in the middle of a chain of suspending and 410bf215546Sopenharmony_ci * resuming passes that will be merged, we need to track whether the 411bf215546Sopenharmony_ci * command buffer begins in the middle of such a chain, for when it gets 412bf215546Sopenharmony_ci * merged with other command buffers. We call such a chain that begins 413bf215546Sopenharmony_ci * before the command buffer starts a "pre-chain". 414bf215546Sopenharmony_ci * 415bf215546Sopenharmony_ci * Note that when this command buffer is finished, this state is untouched 416bf215546Sopenharmony_ci * but it gains a different meaning. For example, if we finish in state 417bf215546Sopenharmony_ci * SR_IN_CHAIN, we finished in the middle of a suspend/resume chain, so 418bf215546Sopenharmony_ci * there's a suspend/resume chain that extends past the end of the command 419bf215546Sopenharmony_ci * buffer. In this sense it's the "opposite" of SR_AFTER_PRE_CHAIN, which 420bf215546Sopenharmony_ci * means that there's a suspend/resume chain that extends before the 421bf215546Sopenharmony_ci * beginning. 422bf215546Sopenharmony_ci */ 423bf215546Sopenharmony_ci enum { 424bf215546Sopenharmony_ci /* Either there are no suspend/resume chains, or they are entirely 425bf215546Sopenharmony_ci * contained in the current command buffer. 426bf215546Sopenharmony_ci * 427bf215546Sopenharmony_ci * BeginCommandBuffer() <- start of current command buffer 428bf215546Sopenharmony_ci * ... 429bf215546Sopenharmony_ci * // we are here 430bf215546Sopenharmony_ci */ 431bf215546Sopenharmony_ci SR_NONE = 0, 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci /* We are in the middle of a suspend/resume chain that starts before the 434bf215546Sopenharmony_ci * current command buffer. This happens when the command buffer begins 435bf215546Sopenharmony_ci * with a resuming render pass and all of the passes up to the current 436bf215546Sopenharmony_ci * one are suspending. In this state, our part of the chain is not saved 437bf215546Sopenharmony_ci * and is in the current draw_cs/state. 438bf215546Sopenharmony_ci * 439bf215546Sopenharmony_ci * BeginRendering() ... EndRendering(suspending) 440bf215546Sopenharmony_ci * BeginCommandBuffer() <- start of current command buffer 441bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 442bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 443bf215546Sopenharmony_ci * ... 444bf215546Sopenharmony_ci * // we are here 445bf215546Sopenharmony_ci */ 446bf215546Sopenharmony_ci SR_IN_PRE_CHAIN, 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci /* We are currently outside of any suspend/resume chains, but there is a 449bf215546Sopenharmony_ci * chain starting before the current command buffer. It is saved in 450bf215546Sopenharmony_ci * pre_chain. 451bf215546Sopenharmony_ci * 452bf215546Sopenharmony_ci * BeginRendering() ... EndRendering(suspending) 453bf215546Sopenharmony_ci * BeginCommandBuffer() <- start of current command buffer 454bf215546Sopenharmony_ci * // This part is stashed in pre_chain 455bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 456bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 457bf215546Sopenharmony_ci * ... 458bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering() // end of chain 459bf215546Sopenharmony_ci * ... 460bf215546Sopenharmony_ci * // we are here 461bf215546Sopenharmony_ci */ 462bf215546Sopenharmony_ci SR_AFTER_PRE_CHAIN, 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci /* We are in the middle of a suspend/resume chain and there is no chain 465bf215546Sopenharmony_ci * starting before the current command buffer. 466bf215546Sopenharmony_ci * 467bf215546Sopenharmony_ci * BeginCommandBuffer() <- start of current command buffer 468bf215546Sopenharmony_ci * ... 469bf215546Sopenharmony_ci * BeginRendering() ... EndRendering(suspending) 470bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 471bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 472bf215546Sopenharmony_ci * ... 473bf215546Sopenharmony_ci * // we are here 474bf215546Sopenharmony_ci */ 475bf215546Sopenharmony_ci SR_IN_CHAIN, 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci /* We are in the middle of a suspend/resume chain and there is another, 478bf215546Sopenharmony_ci * separate, chain starting before the current command buffer. 479bf215546Sopenharmony_ci * 480bf215546Sopenharmony_ci * BeginRendering() ... EndRendering(suspending) 481bf215546Sopenharmony_ci * CommandBufferBegin() <- start of current command buffer 482bf215546Sopenharmony_ci * // This part is stashed in pre_chain 483bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 484bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 485bf215546Sopenharmony_ci * ... 486bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering() // end of chain 487bf215546Sopenharmony_ci * ... 488bf215546Sopenharmony_ci * BeginRendering() ... EndRendering(suspending) 489bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 490bf215546Sopenharmony_ci * BeginRendering(resuming) ... EndRendering(suspending) 491bf215546Sopenharmony_ci * ... 492bf215546Sopenharmony_ci * // we are here 493bf215546Sopenharmony_ci */ 494bf215546Sopenharmony_ci SR_IN_CHAIN_AFTER_PRE_CHAIN, 495bf215546Sopenharmony_ci } suspend_resume; 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci bool suspending, resuming; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci struct tu_lrz_state lrz; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci struct tu_draw_state lrz_and_depth_plane_state; 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci struct tu_vs_params last_vs_params; 504bf215546Sopenharmony_ci}; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_cistruct tu_cmd_pool 507bf215546Sopenharmony_ci{ 508bf215546Sopenharmony_ci struct vk_command_pool vk; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci struct list_head cmd_buffers; 511bf215546Sopenharmony_ci struct list_head free_cmd_buffers; 512bf215546Sopenharmony_ci}; 513bf215546Sopenharmony_ciVK_DEFINE_NONDISP_HANDLE_CASTS(tu_cmd_pool, vk.base, VkCommandPool, 514bf215546Sopenharmony_ci VK_OBJECT_TYPE_COMMAND_POOL) 515bf215546Sopenharmony_ci 516bf215546Sopenharmony_cienum tu_cmd_buffer_status 517bf215546Sopenharmony_ci{ 518bf215546Sopenharmony_ci TU_CMD_BUFFER_STATUS_INVALID, 519bf215546Sopenharmony_ci TU_CMD_BUFFER_STATUS_INITIAL, 520bf215546Sopenharmony_ci TU_CMD_BUFFER_STATUS_RECORDING, 521bf215546Sopenharmony_ci TU_CMD_BUFFER_STATUS_EXECUTABLE, 522bf215546Sopenharmony_ci TU_CMD_BUFFER_STATUS_PENDING, 523bf215546Sopenharmony_ci}; 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_cistruct tu_cmd_buffer 526bf215546Sopenharmony_ci{ 527bf215546Sopenharmony_ci struct vk_command_buffer vk; 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci struct tu_device *device; 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci struct tu_cmd_pool *pool; 532bf215546Sopenharmony_ci struct list_head pool_link; 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci struct u_trace trace; 535bf215546Sopenharmony_ci struct u_trace_iterator trace_renderpass_start; 536bf215546Sopenharmony_ci struct u_trace_iterator trace_renderpass_end; 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci struct list_head renderpass_autotune_results; 539bf215546Sopenharmony_ci struct tu_autotune_results_buffer* autotune_buffer; 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci VkCommandBufferUsageFlags usage_flags; 542bf215546Sopenharmony_ci enum tu_cmd_buffer_status status; 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci VkQueryPipelineStatisticFlags inherited_pipeline_statistics; 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci struct tu_cmd_state state; 547bf215546Sopenharmony_ci uint32_t queue_family_index; 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci uint32_t push_constants[MAX_PUSH_CONSTANTS_SIZE / 4]; 550bf215546Sopenharmony_ci VkShaderStageFlags push_constant_stages; 551bf215546Sopenharmony_ci struct tu_descriptor_set meta_push_descriptors; 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci struct tu_descriptor_state descriptors[MAX_BIND_POINTS]; 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci struct tu_render_pass_attachment dynamic_rp_attachments[2 * (MAX_RTS + 1)]; 556bf215546Sopenharmony_ci struct tu_subpass_attachment dynamic_color_attachments[MAX_RTS]; 557bf215546Sopenharmony_ci struct tu_subpass_attachment dynamic_resolve_attachments[MAX_RTS + 1]; 558bf215546Sopenharmony_ci const struct tu_image_view *dynamic_attachments[2 * (MAX_RTS + 1)]; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci struct tu_render_pass dynamic_pass; 561bf215546Sopenharmony_ci struct tu_subpass dynamic_subpass; 562bf215546Sopenharmony_ci struct tu_framebuffer dynamic_framebuffer; 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci VkResult record_result; 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci struct tu_cs cs; 567bf215546Sopenharmony_ci struct tu_cs draw_cs; 568bf215546Sopenharmony_ci struct tu_cs tile_store_cs; 569bf215546Sopenharmony_ci struct tu_cs draw_epilogue_cs; 570bf215546Sopenharmony_ci struct tu_cs sub_cs; 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci /* If the first render pass in the command buffer is resuming, then it is 573bf215546Sopenharmony_ci * part of a suspend/resume chain that starts before the current command 574bf215546Sopenharmony_ci * buffer and needs to be merged later. In this case, its incomplete state 575bf215546Sopenharmony_ci * is stored in pre_chain. In the symmetric case where the last render pass 576bf215546Sopenharmony_ci * is suspending, we just skip ending the render pass and its state is 577bf215546Sopenharmony_ci * stored in draw_cs/the current state. The first and last render pass 578bf215546Sopenharmony_ci * might be part of different chains, which is why all the state may need 579bf215546Sopenharmony_ci * to be saved separately here. 580bf215546Sopenharmony_ci */ 581bf215546Sopenharmony_ci struct { 582bf215546Sopenharmony_ci struct tu_cs draw_cs; 583bf215546Sopenharmony_ci struct tu_cs draw_epilogue_cs; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci struct u_trace_iterator trace_renderpass_start, trace_renderpass_end; 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci struct tu_render_pass_state state; 588bf215546Sopenharmony_ci } pre_chain; 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci uint32_t vsc_draw_strm_pitch; 591bf215546Sopenharmony_ci uint32_t vsc_prim_strm_pitch; 592bf215546Sopenharmony_ci}; 593bf215546Sopenharmony_ciVK_DEFINE_HANDLE_CASTS(tu_cmd_buffer, vk.base, VkCommandBuffer, 594bf215546Sopenharmony_ci VK_OBJECT_TYPE_COMMAND_BUFFER) 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_cistatic inline uint32_t 597bf215546Sopenharmony_citu_attachment_gmem_offset(struct tu_cmd_buffer *cmd, 598bf215546Sopenharmony_ci const struct tu_render_pass_attachment *att) 599bf215546Sopenharmony_ci{ 600bf215546Sopenharmony_ci assert(cmd->state.gmem_layout < TU_GMEM_LAYOUT_COUNT); 601bf215546Sopenharmony_ci return att->gmem_offset[cmd->state.gmem_layout]; 602bf215546Sopenharmony_ci} 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_cistatic inline uint32_t 605bf215546Sopenharmony_citu_attachment_gmem_offset_stencil(struct tu_cmd_buffer *cmd, 606bf215546Sopenharmony_ci const struct tu_render_pass_attachment *att) 607bf215546Sopenharmony_ci{ 608bf215546Sopenharmony_ci assert(cmd->state.gmem_layout < TU_GMEM_LAYOUT_COUNT); 609bf215546Sopenharmony_ci return att->gmem_offset_stencil[cmd->state.gmem_layout]; 610bf215546Sopenharmony_ci} 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_civoid tu_render_pass_state_merge(struct tu_render_pass_state *dst, 613bf215546Sopenharmony_ci const struct tu_render_pass_state *src); 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ciVkResult tu_cmd_buffer_begin(struct tu_cmd_buffer *cmd_buffer, 616bf215546Sopenharmony_ci VkCommandBufferUsageFlags usage_flags); 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_civoid tu_emit_cache_flush_renderpass(struct tu_cmd_buffer *cmd_buffer, 619bf215546Sopenharmony_ci struct tu_cs *cs); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_civoid tu_emit_cache_flush_ccu(struct tu_cmd_buffer *cmd_buffer, 622bf215546Sopenharmony_ci struct tu_cs *cs, 623bf215546Sopenharmony_ci enum tu_cmd_ccu_state ccu_state); 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_civoid 626bf215546Sopenharmony_citu_append_pre_chain(struct tu_cmd_buffer *cmd, 627bf215546Sopenharmony_ci struct tu_cmd_buffer *secondary); 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_civoid 630bf215546Sopenharmony_citu_append_pre_post_chain(struct tu_cmd_buffer *cmd, 631bf215546Sopenharmony_ci struct tu_cmd_buffer *secondary); 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_civoid 634bf215546Sopenharmony_citu_append_post_chain(struct tu_cmd_buffer *cmd, 635bf215546Sopenharmony_ci struct tu_cmd_buffer *secondary); 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_civoid 638bf215546Sopenharmony_citu_restore_suspended_pass(struct tu_cmd_buffer *cmd, 639bf215546Sopenharmony_ci struct tu_cmd_buffer *suspended); 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_civoid tu_cmd_render(struct tu_cmd_buffer *cmd); 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_civoid 644bf215546Sopenharmony_citu6_emit_event_write(struct tu_cmd_buffer *cmd, 645bf215546Sopenharmony_ci struct tu_cs *cs, 646bf215546Sopenharmony_ci enum vgt_event_type event); 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_cistatic inline struct tu_descriptor_state * 649bf215546Sopenharmony_citu_get_descriptors_state(struct tu_cmd_buffer *cmd_buffer, 650bf215546Sopenharmony_ci VkPipelineBindPoint bind_point) 651bf215546Sopenharmony_ci{ 652bf215546Sopenharmony_ci return &cmd_buffer->descriptors[bind_point]; 653bf215546Sopenharmony_ci} 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_civoid tu6_emit_msaa(struct tu_cs *cs, VkSampleCountFlagBits samples, 656bf215546Sopenharmony_ci enum a5xx_line_mode line_mode); 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_civoid tu6_emit_window_scissor(struct tu_cs *cs, uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2); 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_civoid tu6_emit_window_offset(struct tu_cs *cs, uint32_t x1, uint32_t y1); 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_civoid tu_disable_draw_states(struct tu_cmd_buffer *cmd, struct tu_cs *cs); 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_civoid tu6_apply_depth_bounds_workaround(struct tu_device *device, 665bf215546Sopenharmony_ci uint32_t *rb_depth_cntl); 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_civoid 668bf215546Sopenharmony_ciupdate_stencil_mask(uint32_t *value, VkStencilFaceFlags face, uint32_t mask); 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci#endif /* TU_CMD_BUFFER_H */ 671