1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2013 Advanced Micro Devices, Inc. 3bf215546Sopenharmony_ci * All Rights Reserved. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci/** 26bf215546Sopenharmony_ci * This file contains helpers for writing commands to commands streams. 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#ifndef SI_BUILD_PM4_H 30bf215546Sopenharmony_ci#define SI_BUILD_PM4_H 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "si_pipe.h" 33bf215546Sopenharmony_ci#include "sid.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#if 0 36bf215546Sopenharmony_ci#include "ac_shadowed_regs.h" 37bf215546Sopenharmony_ci#define SI_CHECK_SHADOWED_REGS(reg_offset, count) ac_check_shadowed_regs(GFX10, CHIP_NAVI14, reg_offset, count) 38bf215546Sopenharmony_ci#else 39bf215546Sopenharmony_ci#define SI_CHECK_SHADOWED_REGS(reg_offset, count) 40bf215546Sopenharmony_ci#endif 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#define radeon_begin(cs) struct radeon_cmdbuf *__cs = (cs); \ 43bf215546Sopenharmony_ci unsigned __cs_num = __cs->current.cdw; \ 44bf215546Sopenharmony_ci UNUSED unsigned __cs_num_initial = __cs_num; \ 45bf215546Sopenharmony_ci uint32_t *__cs_buf = __cs->current.buf 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci#define radeon_begin_again(cs) do { \ 48bf215546Sopenharmony_ci assert(__cs == NULL); \ 49bf215546Sopenharmony_ci __cs = (cs); \ 50bf215546Sopenharmony_ci __cs_num = __cs->current.cdw; \ 51bf215546Sopenharmony_ci __cs_num_initial = __cs_num; \ 52bf215546Sopenharmony_ci __cs_buf = __cs->current.buf; \ 53bf215546Sopenharmony_ci} while (0) 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci#define radeon_end() do { \ 56bf215546Sopenharmony_ci __cs->current.cdw = __cs_num; \ 57bf215546Sopenharmony_ci assert(__cs->current.cdw <= __cs->current.max_dw); \ 58bf215546Sopenharmony_ci __cs = NULL; \ 59bf215546Sopenharmony_ci} while (0) 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci#define radeon_emit(value) __cs_buf[__cs_num++] = (value) 62bf215546Sopenharmony_ci#define radeon_packets_added() (__cs_num != __cs_num_initial) 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci#define radeon_end_update_context_roll(sctx) do { \ 65bf215546Sopenharmony_ci radeon_end(); \ 66bf215546Sopenharmony_ci if (radeon_packets_added()) \ 67bf215546Sopenharmony_ci (sctx)->context_roll = true; \ 68bf215546Sopenharmony_ci} while (0) 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci#define radeon_emit_array(values, num) do { \ 71bf215546Sopenharmony_ci unsigned __n = (num); \ 72bf215546Sopenharmony_ci memcpy(__cs_buf + __cs_num, (values), __n * 4); \ 73bf215546Sopenharmony_ci __cs_num += __n; \ 74bf215546Sopenharmony_ci} while (0) 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci#define radeon_set_config_reg_seq(reg, num) do { \ 77bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, num); \ 78bf215546Sopenharmony_ci assert((reg) < SI_CONTEXT_REG_OFFSET); \ 79bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_SET_CONFIG_REG, num, 0)); \ 80bf215546Sopenharmony_ci radeon_emit(((reg) - SI_CONFIG_REG_OFFSET) >> 2); \ 81bf215546Sopenharmony_ci} while (0) 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci#define radeon_set_config_reg(reg, value) do { \ 84bf215546Sopenharmony_ci radeon_set_config_reg_seq(reg, 1); \ 85bf215546Sopenharmony_ci radeon_emit(value); \ 86bf215546Sopenharmony_ci} while (0) 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci#define radeon_set_context_reg_seq(reg, num) do { \ 89bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, num); \ 90bf215546Sopenharmony_ci assert((reg) >= SI_CONTEXT_REG_OFFSET); \ 91bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_SET_CONTEXT_REG, num, 0)); \ 92bf215546Sopenharmony_ci radeon_emit(((reg) - SI_CONTEXT_REG_OFFSET) >> 2); \ 93bf215546Sopenharmony_ci} while (0) 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci#define radeon_set_context_reg(reg, value) do { \ 96bf215546Sopenharmony_ci radeon_set_context_reg_seq(reg, 1); \ 97bf215546Sopenharmony_ci radeon_emit(value); \ 98bf215546Sopenharmony_ci} while (0) 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci#define radeon_set_context_reg_seq_array(reg, num, values) do { \ 101bf215546Sopenharmony_ci radeon_set_context_reg_seq(reg, num); \ 102bf215546Sopenharmony_ci radeon_emit_array(values, num); \ 103bf215546Sopenharmony_ci} while (0) 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci#define radeon_set_context_reg_idx(reg, idx, value) do { \ 106bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, 1); \ 107bf215546Sopenharmony_ci assert((reg) >= SI_CONTEXT_REG_OFFSET); \ 108bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_SET_CONTEXT_REG, 1, 0)); \ 109bf215546Sopenharmony_ci radeon_emit(((reg) - SI_CONTEXT_REG_OFFSET) >> 2 | ((idx) << 28)); \ 110bf215546Sopenharmony_ci radeon_emit(value); \ 111bf215546Sopenharmony_ci} while (0) 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci#define radeon_set_sh_reg_seq(reg, num) do { \ 114bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, num); \ 115bf215546Sopenharmony_ci assert((reg) >= SI_SH_REG_OFFSET && (reg) < SI_SH_REG_END); \ 116bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_SET_SH_REG, num, 0)); \ 117bf215546Sopenharmony_ci radeon_emit(((reg) - SI_SH_REG_OFFSET) >> 2); \ 118bf215546Sopenharmony_ci} while (0) 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci#define radeon_set_sh_reg_idx3_seq(reg, num) do { \ 121bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, num); \ 122bf215546Sopenharmony_ci assert((reg) >= SI_SH_REG_OFFSET && (reg) < SI_SH_REG_END); \ 123bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_SET_SH_REG_INDEX, num, 0)); \ 124bf215546Sopenharmony_ci radeon_emit((((reg) - SI_SH_REG_OFFSET) >> 2) | (3 << 28)); \ 125bf215546Sopenharmony_ci} while (0) 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci#define radeon_set_sh_reg(reg, value) do { \ 128bf215546Sopenharmony_ci radeon_set_sh_reg_seq(reg, 1); \ 129bf215546Sopenharmony_ci radeon_emit(value); \ 130bf215546Sopenharmony_ci} while (0) 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci#define radeon_set_sh_reg_idx3(reg, value) do { \ 133bf215546Sopenharmony_ci radeon_set_sh_reg_idx3_seq(reg, 1); \ 134bf215546Sopenharmony_ci radeon_emit(value); \ 135bf215546Sopenharmony_ci} while (0) 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci#define radeon_set_uconfig_reg_seq(reg, num, perfctr) do { \ 138bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, num); \ 139bf215546Sopenharmony_ci assert((reg) >= CIK_UCONFIG_REG_OFFSET && (reg) < CIK_UCONFIG_REG_END); \ 140bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_SET_UCONFIG_REG, num, perfctr)); \ 141bf215546Sopenharmony_ci radeon_emit(((reg) - CIK_UCONFIG_REG_OFFSET) >> 2); \ 142bf215546Sopenharmony_ci} while (0) 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci#define radeon_set_uconfig_reg(reg, value) do { \ 145bf215546Sopenharmony_ci radeon_set_uconfig_reg_seq(reg, 1, false); \ 146bf215546Sopenharmony_ci radeon_emit(value); \ 147bf215546Sopenharmony_ci} while (0) 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci#define radeon_set_uconfig_reg_perfctr(reg, value) do { \ 150bf215546Sopenharmony_ci radeon_set_uconfig_reg_seq(reg, 1, true); \ 151bf215546Sopenharmony_ci radeon_emit(value); \ 152bf215546Sopenharmony_ci} while (0) 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci#define radeon_set_uconfig_reg_idx(screen, gfx_level, reg, idx, value) do { \ 155bf215546Sopenharmony_ci SI_CHECK_SHADOWED_REGS(reg, 1); \ 156bf215546Sopenharmony_ci assert((reg) >= CIK_UCONFIG_REG_OFFSET && (reg) < CIK_UCONFIG_REG_END); \ 157bf215546Sopenharmony_ci assert((idx) != 0); \ 158bf215546Sopenharmony_ci unsigned __opcode = PKT3_SET_UCONFIG_REG_INDEX; \ 159bf215546Sopenharmony_ci if ((gfx_level) < GFX9 || \ 160bf215546Sopenharmony_ci ((gfx_level) == GFX9 && (screen)->info.me_fw_version < 26)) \ 161bf215546Sopenharmony_ci __opcode = PKT3_SET_UCONFIG_REG; \ 162bf215546Sopenharmony_ci radeon_emit(PKT3(__opcode, 1, 0)); \ 163bf215546Sopenharmony_ci radeon_emit(((reg) - CIK_UCONFIG_REG_OFFSET) >> 2 | ((idx) << 28)); \ 164bf215546Sopenharmony_ci radeon_emit(value); \ 165bf215546Sopenharmony_ci} while (0) 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci/* Emit PKT3_SET_CONTEXT_REG if the register value is different. */ 168bf215546Sopenharmony_ci#define radeon_opt_set_context_reg(sctx, offset, reg, val) do { \ 169bf215546Sopenharmony_ci unsigned __value = val; \ 170bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x1) != 0x1 || \ 171bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value) { \ 172bf215546Sopenharmony_ci radeon_set_context_reg(offset, __value); \ 173bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= 0x1ull << (reg); \ 174bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value; \ 175bf215546Sopenharmony_ci } \ 176bf215546Sopenharmony_ci} while (0) 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci/** 179bf215546Sopenharmony_ci * Set 2 consecutive registers if any registers value is different. 180bf215546Sopenharmony_ci * @param offset starting register offset 181bf215546Sopenharmony_ci * @param val1 is written to first register 182bf215546Sopenharmony_ci * @param val2 is written to second register 183bf215546Sopenharmony_ci */ 184bf215546Sopenharmony_ci#define radeon_opt_set_context_reg2(sctx, offset, reg, val1, val2) do { \ 185bf215546Sopenharmony_ci unsigned __value1 = (val1), __value2 = (val2); \ 186bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x3) != 0x3 || \ 187bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value1 || \ 188bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 1] != __value2) { \ 189bf215546Sopenharmony_ci radeon_set_context_reg_seq(offset, 2); \ 190bf215546Sopenharmony_ci radeon_emit(__value1); \ 191bf215546Sopenharmony_ci radeon_emit(__value2); \ 192bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value1; \ 193bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 1] = __value2; \ 194bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= 0x3ull << (reg); \ 195bf215546Sopenharmony_ci } \ 196bf215546Sopenharmony_ci} while (0) 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci/** 199bf215546Sopenharmony_ci * Set 3 consecutive registers if any registers value is different. 200bf215546Sopenharmony_ci */ 201bf215546Sopenharmony_ci#define radeon_opt_set_context_reg3(sctx, offset, reg, val1, val2, val3) do { \ 202bf215546Sopenharmony_ci unsigned __value1 = (val1), __value2 = (val2), __value3 = (val3); \ 203bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x7) != 0x7 || \ 204bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value1 || \ 205bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 1] != __value2 || \ 206bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 2] != __value3) { \ 207bf215546Sopenharmony_ci radeon_set_context_reg_seq(offset, 3); \ 208bf215546Sopenharmony_ci radeon_emit(__value1); \ 209bf215546Sopenharmony_ci radeon_emit(__value2); \ 210bf215546Sopenharmony_ci radeon_emit(__value3); \ 211bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value1; \ 212bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 1] = __value2; \ 213bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 2] = __value3; \ 214bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= 0x7ull << (reg); \ 215bf215546Sopenharmony_ci } \ 216bf215546Sopenharmony_ci} while (0) 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci/** 219bf215546Sopenharmony_ci * Set 4 consecutive registers if any registers value is different. 220bf215546Sopenharmony_ci */ 221bf215546Sopenharmony_ci#define radeon_opt_set_context_reg4(sctx, offset, reg, val1, val2, val3, val4) do { \ 222bf215546Sopenharmony_ci unsigned __value1 = (val1), __value2 = (val2), __value3 = (val3), __value4 = (val4); \ 223bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0xf) != 0xf || \ 224bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value1 || \ 225bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 1] != __value2 || \ 226bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 2] != __value3 || \ 227bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 3] != __value4) { \ 228bf215546Sopenharmony_ci radeon_set_context_reg_seq(offset, 4); \ 229bf215546Sopenharmony_ci radeon_emit(__value1); \ 230bf215546Sopenharmony_ci radeon_emit(__value2); \ 231bf215546Sopenharmony_ci radeon_emit(__value3); \ 232bf215546Sopenharmony_ci radeon_emit(__value4); \ 233bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value1; \ 234bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 1] = __value2; \ 235bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 2] = __value3; \ 236bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[(reg) + 3] = __value4; \ 237bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= 0xfull << (reg); \ 238bf215546Sopenharmony_ci } \ 239bf215546Sopenharmony_ci} while (0) 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci/** 242bf215546Sopenharmony_ci * Set consecutive registers if any registers value is different. 243bf215546Sopenharmony_ci */ 244bf215546Sopenharmony_ci#define radeon_opt_set_context_regn(sctx, offset, value, saved_val, num) do { \ 245bf215546Sopenharmony_ci if (memcmp(value, saved_val, sizeof(uint32_t) * (num))) { \ 246bf215546Sopenharmony_ci radeon_set_context_reg_seq(offset, num); \ 247bf215546Sopenharmony_ci radeon_emit_array(value, num); \ 248bf215546Sopenharmony_ci memcpy(saved_val, value, sizeof(uint32_t) * (num)); \ 249bf215546Sopenharmony_ci } \ 250bf215546Sopenharmony_ci} while (0) 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci#define radeon_opt_set_sh_reg(sctx, offset, reg, val) do { \ 253bf215546Sopenharmony_ci unsigned __value = val; \ 254bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x1) != 0x1 || \ 255bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value) { \ 256bf215546Sopenharmony_ci radeon_set_sh_reg(offset, __value); \ 257bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= BITFIELD64_BIT(reg); \ 258bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value; \ 259bf215546Sopenharmony_ci } \ 260bf215546Sopenharmony_ci} while (0) 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci#define radeon_opt_set_sh_reg_idx3(sctx, offset, reg, val) do { \ 263bf215546Sopenharmony_ci unsigned __value = val; \ 264bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x1) != 0x1 || \ 265bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value) { \ 266bf215546Sopenharmony_ci if (sctx->gfx_level >= GFX10) \ 267bf215546Sopenharmony_ci radeon_set_sh_reg_idx3(offset, __value); \ 268bf215546Sopenharmony_ci else \ 269bf215546Sopenharmony_ci radeon_set_sh_reg(offset, __value); \ 270bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= BITFIELD64_BIT(reg); \ 271bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value; \ 272bf215546Sopenharmony_ci } \ 273bf215546Sopenharmony_ci} while (0) 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci#define radeon_opt_set_uconfig_reg(sctx, offset, reg, val) do { \ 276bf215546Sopenharmony_ci unsigned __value = val; \ 277bf215546Sopenharmony_ci if (((sctx->tracked_regs.reg_saved >> (reg)) & 0x1) != 0x1 || \ 278bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] != __value) { \ 279bf215546Sopenharmony_ci radeon_set_uconfig_reg(offset, __value); \ 280bf215546Sopenharmony_ci sctx->tracked_regs.reg_saved |= 0x1ull << (reg); \ 281bf215546Sopenharmony_ci sctx->tracked_regs.reg_value[reg] = __value; \ 282bf215546Sopenharmony_ci } \ 283bf215546Sopenharmony_ci} while (0) 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci#define radeon_set_privileged_config_reg(reg, value) do { \ 286bf215546Sopenharmony_ci assert((reg) < CIK_UCONFIG_REG_OFFSET); \ 287bf215546Sopenharmony_ci radeon_emit(PKT3(PKT3_COPY_DATA, 4, 0)); \ 288bf215546Sopenharmony_ci radeon_emit(COPY_DATA_SRC_SEL(COPY_DATA_IMM) | \ 289bf215546Sopenharmony_ci COPY_DATA_DST_SEL(COPY_DATA_PERF)); \ 290bf215546Sopenharmony_ci radeon_emit(value); \ 291bf215546Sopenharmony_ci radeon_emit(0); /* unused */ \ 292bf215546Sopenharmony_ci radeon_emit((reg) >> 2); \ 293bf215546Sopenharmony_ci radeon_emit(0); /* unused */ \ 294bf215546Sopenharmony_ci} while (0) 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci#define radeon_emit_32bit_pointer(sscreen, va) do { \ 297bf215546Sopenharmony_ci radeon_emit(va); \ 298bf215546Sopenharmony_ci assert((va) == 0 || ((va) >> 32) == sscreen->info.address32_hi); \ 299bf215546Sopenharmony_ci} while (0) 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci#define radeon_emit_one_32bit_pointer(sctx, desc, sh_base) do { \ 302bf215546Sopenharmony_ci unsigned sh_offset = (sh_base) + (desc)->shader_userdata_offset; \ 303bf215546Sopenharmony_ci radeon_set_sh_reg_seq(sh_offset, 1); \ 304bf215546Sopenharmony_ci radeon_emit_32bit_pointer(sctx->screen, (desc)->gpu_address); \ 305bf215546Sopenharmony_ci} while (0) 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci/* Wrappers that are only used when they are passed as function pointers. */ 308bf215546Sopenharmony_cistatic inline void radeon_set_sh_reg_func(struct radeon_cmdbuf *cs, unsigned reg_offset, 309bf215546Sopenharmony_ci uint32_t value) 310bf215546Sopenharmony_ci{ 311bf215546Sopenharmony_ci radeon_begin(cs); 312bf215546Sopenharmony_ci radeon_set_sh_reg(reg_offset, value); 313bf215546Sopenharmony_ci radeon_end(); 314bf215546Sopenharmony_ci} 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_cistatic inline void radeon_set_sh_reg_idx3_func(struct radeon_cmdbuf *cs, unsigned reg_offset, 317bf215546Sopenharmony_ci uint32_t value) 318bf215546Sopenharmony_ci{ 319bf215546Sopenharmony_ci radeon_begin(cs); 320bf215546Sopenharmony_ci radeon_set_sh_reg_idx3(reg_offset, value); 321bf215546Sopenharmony_ci radeon_end(); 322bf215546Sopenharmony_ci} 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci/* This should be evaluated at compile time if all parameters are constants. */ 325bf215546Sopenharmony_cistatic ALWAYS_INLINE unsigned 326bf215546Sopenharmony_cisi_get_user_data_base(enum amd_gfx_level gfx_level, enum si_has_tess has_tess, 327bf215546Sopenharmony_ci enum si_has_gs has_gs, enum si_has_ngg ngg, 328bf215546Sopenharmony_ci enum pipe_shader_type shader) 329bf215546Sopenharmony_ci{ 330bf215546Sopenharmony_ci switch (shader) { 331bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 332bf215546Sopenharmony_ci /* VS can be bound as VS, ES, or LS. */ 333bf215546Sopenharmony_ci if (has_tess) { 334bf215546Sopenharmony_ci if (gfx_level >= GFX10) { 335bf215546Sopenharmony_ci return R_00B430_SPI_SHADER_USER_DATA_HS_0; 336bf215546Sopenharmony_ci } else if (gfx_level == GFX9) { 337bf215546Sopenharmony_ci return R_00B430_SPI_SHADER_USER_DATA_LS_0; 338bf215546Sopenharmony_ci } else { 339bf215546Sopenharmony_ci return R_00B530_SPI_SHADER_USER_DATA_LS_0; 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci } else if (gfx_level >= GFX10) { 342bf215546Sopenharmony_ci if (ngg || has_gs) { 343bf215546Sopenharmony_ci return R_00B230_SPI_SHADER_USER_DATA_GS_0; 344bf215546Sopenharmony_ci } else { 345bf215546Sopenharmony_ci return R_00B130_SPI_SHADER_USER_DATA_VS_0; 346bf215546Sopenharmony_ci } 347bf215546Sopenharmony_ci } else if (has_gs) { 348bf215546Sopenharmony_ci return R_00B330_SPI_SHADER_USER_DATA_ES_0; 349bf215546Sopenharmony_ci } else { 350bf215546Sopenharmony_ci return R_00B130_SPI_SHADER_USER_DATA_VS_0; 351bf215546Sopenharmony_ci } 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 354bf215546Sopenharmony_ci if (gfx_level == GFX9) { 355bf215546Sopenharmony_ci return R_00B430_SPI_SHADER_USER_DATA_LS_0; 356bf215546Sopenharmony_ci } else { 357bf215546Sopenharmony_ci return R_00B430_SPI_SHADER_USER_DATA_HS_0; 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 361bf215546Sopenharmony_ci /* TES can be bound as ES, VS, or not bound. */ 362bf215546Sopenharmony_ci if (has_tess) { 363bf215546Sopenharmony_ci if (gfx_level >= GFX10) { 364bf215546Sopenharmony_ci if (ngg || has_gs) { 365bf215546Sopenharmony_ci return R_00B230_SPI_SHADER_USER_DATA_GS_0; 366bf215546Sopenharmony_ci } else { 367bf215546Sopenharmony_ci return R_00B130_SPI_SHADER_USER_DATA_VS_0; 368bf215546Sopenharmony_ci } 369bf215546Sopenharmony_ci } else if (has_gs) { 370bf215546Sopenharmony_ci return R_00B330_SPI_SHADER_USER_DATA_ES_0; 371bf215546Sopenharmony_ci } else { 372bf215546Sopenharmony_ci return R_00B130_SPI_SHADER_USER_DATA_VS_0; 373bf215546Sopenharmony_ci } 374bf215546Sopenharmony_ci } else { 375bf215546Sopenharmony_ci return 0; 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 379bf215546Sopenharmony_ci if (gfx_level == GFX9) { 380bf215546Sopenharmony_ci return R_00B330_SPI_SHADER_USER_DATA_ES_0; 381bf215546Sopenharmony_ci } else { 382bf215546Sopenharmony_ci return R_00B230_SPI_SHADER_USER_DATA_GS_0; 383bf215546Sopenharmony_ci } 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci default: 386bf215546Sopenharmony_ci assert(0); 387bf215546Sopenharmony_ci return 0; 388bf215546Sopenharmony_ci } 389bf215546Sopenharmony_ci} 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci#endif 392