/*
 * Copyright 2012 Advanced Micro Devices, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 * license, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "ac_exp_param.h"
#include "ac_shader_util.h"
#include "compiler/nir/nir_serialize.h"
#include "nir/tgsi_to_nir.h"
#include "si_build_pm4.h"
#include "sid.h"
#include "util/crc32.h"
#include "util/disk_cache.h"
#include "util/hash_table.h"
#include "util/mesa-sha1.h"
#include "util/u_async_debug.h"
#include "util/u_memory.h"
#include "util/u_prim.h"
#include "tgsi/tgsi_from_mesa.h"

/* SHADER_CACHE */

/**
 * Return the IR key for the shader cache.
 */
void si_get_ir_cache_key(struct si_shader_selector *sel, bool ngg, bool es,
                         unsigned char ir_sha1_cache_key[20])
{
   struct blob blob = {};
   unsigned ir_size;
   void *ir_binary;

   if (sel->nir_binary) {
      ir_binary = sel->nir_binary;
      ir_size = sel->nir_size;
   } else {
      assert(sel->nir);

      blob_init(&blob);
      nir_serialize(&blob, sel->nir, true);
      ir_binary = blob.data;
      ir_size = blob.size;
   }

   /* These settings affect the compilation, but they are not derived
    * from the input shader IR.
    */
   unsigned shader_variant_flags = 0;

   if (ngg)
      shader_variant_flags |= 1 << 0;
   if (sel->nir)
      shader_variant_flags |= 1 << 1;
   if (si_get_wave_size(sel->screen, sel->info.stage, ngg, es, false, false) == 32)
      shader_variant_flags |= 1 << 2;
   if (sel->info.stage == MESA_SHADER_FRAGMENT && sel->info.uses_derivatives && sel->info.uses_kill &&
       sel->screen->debug_flags & DBG(FS_CORRECT_DERIVS_AFTER_KILL))
      shader_variant_flags |= 1 << 3;

   /* This varies depending on whether compute-based culling is enabled. */
   shader_variant_flags |= sel->screen->num_vbos_in_user_sgprs << 4;

   struct mesa_sha1 ctx;
   _mesa_sha1_init(&ctx);
   _mesa_sha1_update(&ctx, &shader_variant_flags, 4);
   _mesa_sha1_update(&ctx, ir_binary, ir_size);
   if (sel->info.stage == MESA_SHADER_VERTEX || sel->info.stage == MESA_SHADER_TESS_EVAL ||
       sel->info.stage == MESA_SHADER_GEOMETRY)
      _mesa_sha1_update(&ctx, &sel->so, sizeof(sel->so));
   _mesa_sha1_final(&ctx, ir_sha1_cache_key);

   if (ir_binary == blob.data)
      blob_finish(&blob);
}

/** Copy "data" to "ptr" and return the next dword following copied data. */
static uint32_t *write_data(uint32_t *ptr, const void *data, unsigned size)
{
   /* data may be NULL if size == 0 */
   if (size)
      memcpy(ptr, data, size);
   ptr += DIV_ROUND_UP(size, 4);
   return ptr;
}

/** Read data from "ptr". Return the next dword following the data. */
static uint32_t *read_data(uint32_t *ptr, void *data, unsigned size)
{
   memcpy(data, ptr, size);
   ptr += DIV_ROUND_UP(size, 4);
   return ptr;
}

/**
 * Write the size as uint followed by the data. Return the next dword
 * following the copied data.
 */
static uint32_t *write_chunk(uint32_t *ptr, const void *data, unsigned size)
{
   *ptr++ = size;
   return write_data(ptr, data, size);
}

/**
 * Read the size as uint followed by the data. Return both via parameters.
 * Return the next dword following the data.
 */
static uint32_t *read_chunk(uint32_t *ptr, void **data, unsigned *size)
{
   *size = *ptr++;
   assert(*data == NULL);
   if (!*size)
      return ptr;
   *data = malloc(*size);
   return read_data(ptr, *data, *size);
}

/**
 * Return the shader binary in a buffer. The first 4 bytes contain its size
 * as integer.
 */
static void *si_get_shader_binary(struct si_shader *shader)
{
   /* There is always a size of data followed by the data itself. */
   unsigned llvm_ir_size =
      shader->binary.llvm_ir_string ? strlen(shader->binary.llvm_ir_string) + 1 : 0;

   /* Refuse to allocate overly large buffers and guard against integer
    * overflow. */
   if (shader->binary.elf_size > UINT_MAX / 4 || llvm_ir_size > UINT_MAX / 4)
      return NULL;

   unsigned size = 4 + /* total size */
                   4 + /* CRC32 of the data below */
                   align(sizeof(shader->config), 4) + align(sizeof(shader->info), 4) + 4 +
                   align(shader->binary.elf_size, 4) + 4 + align(llvm_ir_size, 4);
   void *buffer = CALLOC(1, size);
   uint32_t *ptr = (uint32_t *)buffer;

   if (!buffer)
      return NULL;

   *ptr++ = size;
   ptr++; /* CRC32 is calculated at the end. */

   ptr = write_data(ptr, &shader->config, sizeof(shader->config));
   ptr = write_data(ptr, &shader->info, sizeof(shader->info));
   ptr = write_chunk(ptr, shader->binary.elf_buffer, shader->binary.elf_size);
   ptr = write_chunk(ptr, shader->binary.llvm_ir_string, llvm_ir_size);
   assert((char *)ptr - (char *)buffer == size);

   /* Compute CRC32. */
   ptr = (uint32_t *)buffer;
   ptr++;
   *ptr = util_hash_crc32(ptr + 1, size - 8);

   return buffer;
}

static bool si_load_shader_binary(struct si_shader *shader, void *binary)
{
   uint32_t *ptr = (uint32_t *)binary;
   uint32_t size = *ptr++;
   uint32_t crc32 = *ptr++;
   unsigned chunk_size;
   unsigned elf_size;

   if (util_hash_crc32(ptr, size - 8) != crc32) {
      fprintf(stderr, "radeonsi: binary shader has invalid CRC32\n");
      return false;
   }

   ptr = read_data(ptr, &shader->config, sizeof(shader->config));
   ptr = read_data(ptr, &shader->info, sizeof(shader->info));
   ptr = read_chunk(ptr, (void **)&shader->binary.elf_buffer, &elf_size);
   shader->binary.elf_size = elf_size;
   ptr = read_chunk(ptr, (void **)&shader->binary.llvm_ir_string, &chunk_size);

   return true;
}

/**
 * Insert a shader into the cache. It's assumed the shader is not in the cache.
 * Use si_shader_cache_load_shader before calling this.
 */
void si_shader_cache_insert_shader(struct si_screen *sscreen, unsigned char ir_sha1_cache_key[20],
                                   struct si_shader *shader, bool insert_into_disk_cache)
{
   void *hw_binary;
   struct hash_entry *entry;
   uint8_t key[CACHE_KEY_SIZE];

   entry = _mesa_hash_table_search(sscreen->shader_cache, ir_sha1_cache_key);
   if (entry)
      return; /* already added */

   hw_binary = si_get_shader_binary(shader);
   if (!hw_binary)
      return;

   if (_mesa_hash_table_insert(sscreen->shader_cache, mem_dup(ir_sha1_cache_key, 20), hw_binary) ==
       NULL) {
      FREE(hw_binary);
      return;
   }

   if (sscreen->disk_shader_cache && insert_into_disk_cache) {
      disk_cache_compute_key(sscreen->disk_shader_cache, ir_sha1_cache_key, 20, key);
      disk_cache_put(sscreen->disk_shader_cache, key, hw_binary, *((uint32_t *)hw_binary), NULL);
   }
}

bool si_shader_cache_load_shader(struct si_screen *sscreen, unsigned char ir_sha1_cache_key[20],
                                 struct si_shader *shader)
{
   struct hash_entry *entry = _mesa_hash_table_search(sscreen->shader_cache, ir_sha1_cache_key);

   if (entry) {
      if (si_load_shader_binary(shader, entry->data)) {
         p_atomic_inc(&sscreen->num_memory_shader_cache_hits);
         return true;
      }
   }
   p_atomic_inc(&sscreen->num_memory_shader_cache_misses);

   if (!sscreen->disk_shader_cache)
      return false;

   unsigned char sha1[CACHE_KEY_SIZE];
   disk_cache_compute_key(sscreen->disk_shader_cache, ir_sha1_cache_key, 20, sha1);

   size_t binary_size;
   uint8_t *buffer = disk_cache_get(sscreen->disk_shader_cache, sha1, &binary_size);
   if (buffer) {
      if (binary_size >= sizeof(uint32_t) && *((uint32_t *)buffer) == binary_size) {
         if (si_load_shader_binary(shader, buffer)) {
            free(buffer);
            si_shader_cache_insert_shader(sscreen, ir_sha1_cache_key, shader, false);
            p_atomic_inc(&sscreen->num_disk_shader_cache_hits);
            return true;
         }
      } else {
         /* Something has gone wrong discard the item from the cache and
          * rebuild/link from source.
          */
         assert(!"Invalid radeonsi shader disk cache item!");
         disk_cache_remove(sscreen->disk_shader_cache, sha1);
      }
   }

   free(buffer);
   p_atomic_inc(&sscreen->num_disk_shader_cache_misses);
   return false;
}

static uint32_t si_shader_cache_key_hash(const void *key)
{
   /* Take the first dword of SHA1. */
   return *(uint32_t *)key;
}

static bool si_shader_cache_key_equals(const void *a, const void *b)
{
   /* Compare SHA1s. */
   return memcmp(a, b, 20) == 0;
}

static void si_destroy_shader_cache_entry(struct hash_entry *entry)
{
   FREE((void *)entry->key);
   FREE(entry->data);
}

bool si_init_shader_cache(struct si_screen *sscreen)
{
   (void)simple_mtx_init(&sscreen->shader_cache_mutex, mtx_plain);
   sscreen->shader_cache =
      _mesa_hash_table_create(NULL, si_shader_cache_key_hash, si_shader_cache_key_equals);

   return sscreen->shader_cache != NULL;
}

void si_destroy_shader_cache(struct si_screen *sscreen)
{
   if (sscreen->shader_cache)
      _mesa_hash_table_destroy(sscreen->shader_cache, si_destroy_shader_cache_entry);
   simple_mtx_destroy(&sscreen->shader_cache_mutex);
}

/* SHADER STATES */

static void si_set_tesseval_regs(struct si_screen *sscreen, const struct si_shader_selector *tes,
                                 struct si_pm4_state *pm4)
{
   const struct si_shader_info *info = &tes->info;
   unsigned tes_prim_mode = info->base.tess.primitive_mode;
   unsigned tes_spacing = info->base.tess.spacing;
   bool tes_vertex_order_cw = !info->base.tess.ccw;
   bool tes_point_mode = info->base.tess.point_mode;
   unsigned type, partitioning, topology, distribution_mode;

   switch (tes_prim_mode) {
   case GL_LINES:
      type = V_028B6C_TESS_ISOLINE;
      break;
   case GL_TRIANGLES:
      type = V_028B6C_TESS_TRIANGLE;
      break;
   case GL_QUADS:
      type = V_028B6C_TESS_QUAD;
      break;
   default:
      assert(0);
      return;
   }

   switch (tes_spacing) {
   case TESS_SPACING_FRACTIONAL_ODD:
      partitioning = V_028B6C_PART_FRAC_ODD;
      break;
   case TESS_SPACING_FRACTIONAL_EVEN:
      partitioning = V_028B6C_PART_FRAC_EVEN;
      break;
   case TESS_SPACING_EQUAL:
      partitioning = V_028B6C_PART_INTEGER;
      break;
   default:
      assert(0);
      return;
   }

   if (tes_point_mode)
      topology = V_028B6C_OUTPUT_POINT;
   else if (tes_prim_mode == GL_LINES)
      topology = V_028B6C_OUTPUT_LINE;
   else if (tes_vertex_order_cw)
      /* for some reason, this must be the other way around */
      topology = V_028B6C_OUTPUT_TRIANGLE_CCW;
   else
      topology = V_028B6C_OUTPUT_TRIANGLE_CW;

   if (sscreen->info.has_distributed_tess) {
      if (sscreen->info.family == CHIP_FIJI || sscreen->info.family >= CHIP_POLARIS10)
         distribution_mode = V_028B6C_TRAPEZOIDS;
      else
         distribution_mode = V_028B6C_DONUTS;
   } else
      distribution_mode = V_028B6C_NO_DIST;

   assert(pm4->shader);
   pm4->shader->vgt_tf_param = S_028B6C_TYPE(type) | S_028B6C_PARTITIONING(partitioning) |
                               S_028B6C_TOPOLOGY(topology) |
                               S_028B6C_DISTRIBUTION_MODE(distribution_mode);
}

/* Polaris needs different VTX_REUSE_DEPTH settings depending on
 * whether the "fractional odd" tessellation spacing is used.
 *
 * Possible VGT configurations and which state should set the register:
 *
 *   Reg set in | VGT shader configuration   | Value
 * ------------------------------------------------------
 *     VS as VS | VS                         | 30
 *     VS as ES | ES -> GS -> VS             | 30
 *    TES as VS | LS -> HS -> VS             | 14 or 30
 *    TES as ES | LS -> HS -> ES -> GS -> VS | 14 or 30
 *
 * If "shader" is NULL, it's assumed it's not LS or GS copy shader.
 */
static void polaris_set_vgt_vertex_reuse(struct si_screen *sscreen, struct si_shader_selector *sel,
                                         struct si_shader *shader, struct si_pm4_state *pm4)
{
   if (sscreen->info.family < CHIP_POLARIS10 || sscreen->info.chip_class >= GFX10)
      return;

   /* VS as VS, or VS as ES: */
   if ((sel->info.stage == MESA_SHADER_VERTEX &&
        (!shader || (!shader->key.as_ls && !shader->is_gs_copy_shader))) ||
       /* TES as VS, or TES as ES: */
       sel->info.stage == MESA_SHADER_TESS_EVAL) {
      unsigned vtx_reuse_depth = 30;

      if (sel->info.stage == MESA_SHADER_TESS_EVAL &&
          sel->info.base.tess.spacing == TESS_SPACING_FRACTIONAL_ODD)
         vtx_reuse_depth = 14;

      assert(pm4->shader);
      pm4->shader->vgt_vertex_reuse_block_cntl = vtx_reuse_depth;
   }
}

static struct si_pm4_state *si_get_shader_pm4_state(struct si_shader *shader)
{
   if (shader->pm4)
      si_pm4_clear_state(shader->pm4);
   else
      shader->pm4 = CALLOC_STRUCT(si_pm4_state);

   if (shader->pm4) {
      shader->pm4->shader = shader;
      return shader->pm4;
   } else {
      fprintf(stderr, "radeonsi: Failed to create pm4 state.\n");
      return NULL;
   }
}

static unsigned si_get_num_vs_user_sgprs(struct si_shader *shader,
                                         unsigned num_always_on_user_sgprs)
{
   struct si_shader_selector *vs =
      shader->previous_stage_sel ? shader->previous_stage_sel : shader->selector;
   unsigned num_vbos_in_user_sgprs = vs->num_vbos_in_user_sgprs;

   /* 1 SGPR is reserved for the vertex buffer pointer. */
   assert(num_always_on_user_sgprs <= SI_SGPR_VS_VB_DESCRIPTOR_FIRST - 1);

   if (num_vbos_in_user_sgprs)
      return SI_SGPR_VS_VB_DESCRIPTOR_FIRST + num_vbos_in_user_sgprs * 4;

   /* Add the pointer to VBO descriptors. */
   return num_always_on_user_sgprs + 1;
}

/* Return VGPR_COMP_CNT for the API vertex shader. This can be hw LS, LSHS, ES, ESGS, VS. */
static unsigned si_get_vs_vgpr_comp_cnt(struct si_screen *sscreen, struct si_shader *shader,
                                        bool legacy_vs_prim_id)
{
   assert(shader->selector->info.stage == MESA_SHADER_VERTEX ||
          (shader->previous_stage_sel && shader->previous_stage_sel->info.stage == MESA_SHADER_VERTEX));

   /* GFX6-9 LS    (VertexID, RelAutoindex,                InstanceID / StepRate0(==1), ...).
    * GFX6-9 ES,VS (VertexID, InstanceID / StepRate0(==1), VSPrimID,                    ...)
    * GFX10  LS    (VertexID, RelAutoindex,                UserVGPR1,                   InstanceID).
    * GFX10  ES,VS (VertexID, UserVGPR0,                   UserVGPR1 or VSPrimID,       UserVGPR2 or
    * InstanceID)
    */
   bool is_ls = shader->selector->info.stage == MESA_SHADER_TESS_CTRL || shader->key.as_ls;

   if (sscreen->info.chip_class >= GFX10 && shader->info.uses_instanceid)
      return 3;
   else if ((is_ls && shader->info.uses_instanceid) || legacy_vs_prim_id)
      return 2;
   else if (is_ls || shader->info.uses_instanceid)
      return 1;
   else
      return 0;
}

static void si_shader_ls(struct si_screen *sscreen, struct si_shader *shader)
{
   struct si_pm4_state *pm4;
   uint64_t va;

   assert(sscreen->info.chip_class <= GFX8);

   pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   va = shader->bo->gpu_address;
   si_pm4_set_reg(pm4, R_00B520_SPI_SHADER_PGM_LO_LS, va >> 8);
   si_pm4_set_reg(pm4, R_00B524_SPI_SHADER_PGM_HI_LS, S_00B524_MEM_BASE(va >> 40));

   shader->config.rsrc1 = S_00B528_VGPRS((shader->config.num_vgprs - 1) / 4) |
                          S_00B528_SGPRS((shader->config.num_sgprs - 1) / 8) |
                          S_00B528_VGPR_COMP_CNT(si_get_vs_vgpr_comp_cnt(sscreen, shader, false)) |
                          S_00B528_DX10_CLAMP(1) | S_00B528_FLOAT_MODE(shader->config.float_mode);
   shader->config.rsrc2 =
      S_00B52C_USER_SGPR(si_get_num_vs_user_sgprs(shader, SI_VS_NUM_USER_SGPR)) |
      S_00B52C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0);
}

static void si_shader_hs(struct si_screen *sscreen, struct si_shader *shader)
{
   struct si_pm4_state *pm4;
   uint64_t va;

   pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   va = shader->bo->gpu_address;

   if (sscreen->info.chip_class >= GFX9) {
      if (sscreen->info.chip_class >= GFX10) {
         si_pm4_set_reg(pm4, R_00B520_SPI_SHADER_PGM_LO_LS, va >> 8);
         si_pm4_set_reg(pm4, R_00B524_SPI_SHADER_PGM_HI_LS, S_00B524_MEM_BASE(va >> 40));
      } else {
         si_pm4_set_reg(pm4, R_00B410_SPI_SHADER_PGM_LO_LS, va >> 8);
         si_pm4_set_reg(pm4, R_00B414_SPI_SHADER_PGM_HI_LS, S_00B414_MEM_BASE(va >> 40));
      }

      unsigned num_user_sgprs = si_get_num_vs_user_sgprs(shader, GFX9_TCS_NUM_USER_SGPR);

      shader->config.rsrc2 = S_00B42C_USER_SGPR(num_user_sgprs) |
                             S_00B42C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0);

      if (sscreen->info.chip_class >= GFX10)
         shader->config.rsrc2 |= S_00B42C_USER_SGPR_MSB_GFX10(num_user_sgprs >> 5);
      else
         shader->config.rsrc2 |= S_00B42C_USER_SGPR_MSB_GFX9(num_user_sgprs >> 5);
   } else {
      si_pm4_set_reg(pm4, R_00B420_SPI_SHADER_PGM_LO_HS, va >> 8);
      si_pm4_set_reg(pm4, R_00B424_SPI_SHADER_PGM_HI_HS, S_00B424_MEM_BASE(va >> 40));

      shader->config.rsrc2 = S_00B42C_USER_SGPR(GFX6_TCS_NUM_USER_SGPR) | S_00B42C_OC_LDS_EN(1) |
                             S_00B42C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0);
   }

   si_pm4_set_reg(
      pm4, R_00B428_SPI_SHADER_PGM_RSRC1_HS,
      S_00B428_VGPRS((shader->config.num_vgprs - 1) / (sscreen->ge_wave_size == 32 ? 8 : 4)) |
         (sscreen->info.chip_class <= GFX9 ? S_00B428_SGPRS((shader->config.num_sgprs - 1) / 8)
                                           : 0) |
         S_00B428_DX10_CLAMP(1) | S_00B428_MEM_ORDERED(sscreen->info.chip_class >= GFX10) |
         S_00B428_WGP_MODE(sscreen->info.chip_class >= GFX10) |
         S_00B428_FLOAT_MODE(shader->config.float_mode) |
         S_00B428_LS_VGPR_COMP_CNT(sscreen->info.chip_class >= GFX9
                                      ? si_get_vs_vgpr_comp_cnt(sscreen, shader, false)
                                      : 0));

   if (sscreen->info.chip_class <= GFX8) {
      si_pm4_set_reg(pm4, R_00B42C_SPI_SHADER_PGM_RSRC2_HS, shader->config.rsrc2);
   }
}

static void si_emit_shader_es(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.es->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   radeon_opt_set_context_reg(sctx, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
                              SI_TRACKED_VGT_ESGS_RING_ITEMSIZE,
                              shader->selector->esgs_itemsize / 4);

   if (shader->selector->info.stage == MESA_SHADER_TESS_EVAL)
      radeon_opt_set_context_reg(sctx, R_028B6C_VGT_TF_PARAM, SI_TRACKED_VGT_TF_PARAM,
                                 shader->vgt_tf_param);

   if (shader->vgt_vertex_reuse_block_cntl)
      radeon_opt_set_context_reg(sctx, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL,
                                 SI_TRACKED_VGT_VERTEX_REUSE_BLOCK_CNTL,
                                 shader->vgt_vertex_reuse_block_cntl);

   if (initial_cdw != sctx->gfx_cs->current.cdw)
      sctx->context_roll = true;
}

static void si_shader_es(struct si_screen *sscreen, struct si_shader *shader)
{
   struct si_pm4_state *pm4;
   unsigned num_user_sgprs;
   unsigned vgpr_comp_cnt;
   uint64_t va;
   unsigned oc_lds_en;

   assert(sscreen->info.chip_class <= GFX8);

   pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   pm4->atom.emit = si_emit_shader_es;
   va = shader->bo->gpu_address;

   if (shader->selector->info.stage == MESA_SHADER_VERTEX) {
      vgpr_comp_cnt = si_get_vs_vgpr_comp_cnt(sscreen, shader, false);
      num_user_sgprs = si_get_num_vs_user_sgprs(shader, SI_VS_NUM_USER_SGPR);
   } else if (shader->selector->info.stage == MESA_SHADER_TESS_EVAL) {
      vgpr_comp_cnt = shader->selector->info.uses_primid ? 3 : 2;
      num_user_sgprs = SI_TES_NUM_USER_SGPR;
   } else
      unreachable("invalid shader selector type");

   oc_lds_en = shader->selector->info.stage == MESA_SHADER_TESS_EVAL ? 1 : 0;

   si_pm4_set_reg(pm4, R_00B320_SPI_SHADER_PGM_LO_ES, va >> 8);
   si_pm4_set_reg(pm4, R_00B324_SPI_SHADER_PGM_HI_ES, S_00B324_MEM_BASE(va >> 40));
   si_pm4_set_reg(pm4, R_00B328_SPI_SHADER_PGM_RSRC1_ES,
                  S_00B328_VGPRS((shader->config.num_vgprs - 1) / 4) |
                     S_00B328_SGPRS((shader->config.num_sgprs - 1) / 8) |
                     S_00B328_VGPR_COMP_CNT(vgpr_comp_cnt) | S_00B328_DX10_CLAMP(1) |
                     S_00B328_FLOAT_MODE(shader->config.float_mode));
   si_pm4_set_reg(pm4, R_00B32C_SPI_SHADER_PGM_RSRC2_ES,
                  S_00B32C_USER_SGPR(num_user_sgprs) | S_00B32C_OC_LDS_EN(oc_lds_en) |
                     S_00B32C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0));

   if (shader->selector->info.stage == MESA_SHADER_TESS_EVAL)
      si_set_tesseval_regs(sscreen, shader->selector, pm4);

   polaris_set_vgt_vertex_reuse(sscreen, shader->selector, shader, pm4);
}

void gfx9_get_gs_info(struct si_shader_selector *es, struct si_shader_selector *gs,
                      struct gfx9_gs_info *out)
{
   unsigned gs_num_invocations = MAX2(gs->gs_num_invocations, 1);
   unsigned input_prim = gs->info.base.gs.input_primitive;
   bool uses_adjacency =
      input_prim >= PIPE_PRIM_LINES_ADJACENCY && input_prim <= PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY;

   /* All these are in dwords: */
   /* We can't allow using the whole LDS, because GS waves compete with
    * other shader stages for LDS space. */
   const unsigned max_lds_size = 8 * 1024;
   const unsigned esgs_itemsize = es->esgs_itemsize / 4;
   unsigned esgs_lds_size;

   /* All these are per subgroup: */
   const unsigned max_out_prims = 32 * 1024;
   const unsigned max_es_verts = 255;
   const unsigned ideal_gs_prims = 64;
   unsigned max_gs_prims, gs_prims;
   unsigned min_es_verts, es_verts, worst_case_es_verts;

   if (uses_adjacency || gs_num_invocations > 1)
      max_gs_prims = 127 / gs_num_invocations;
   else
      max_gs_prims = 255;

   /* MAX_PRIMS_PER_SUBGROUP = gs_prims * max_vert_out * gs_invocations.
    * Make sure we don't go over the maximum value.
    */
   if (gs->gs_max_out_vertices > 0) {
      max_gs_prims =
         MIN2(max_gs_prims, max_out_prims / (gs->gs_max_out_vertices * gs_num_invocations));
   }
   assert(max_gs_prims > 0);

   /* If the primitive has adjacency, halve the number of vertices
    * that will be reused in multiple primitives.
    */
   min_es_verts = gs->gs_input_verts_per_prim / (uses_adjacency ? 2 : 1);

   gs_prims = MIN2(ideal_gs_prims, max_gs_prims);
   worst_case_es_verts = MIN2(min_es_verts * gs_prims, max_es_verts);

   /* Compute ESGS LDS size based on the worst case number of ES vertices
    * needed to create the target number of GS prims per subgroup.
    */
   esgs_lds_size = esgs_itemsize * worst_case_es_verts;

   /* If total LDS usage is too big, refactor partitions based on ratio
    * of ESGS item sizes.
    */
   if (esgs_lds_size > max_lds_size) {
      /* Our target GS Prims Per Subgroup was too large. Calculate
       * the maximum number of GS Prims Per Subgroup that will fit
       * into LDS, capped by the maximum that the hardware can support.
       */
      gs_prims = MIN2((max_lds_size / (esgs_itemsize * min_es_verts)), max_gs_prims);
      assert(gs_prims > 0);
      worst_case_es_verts = MIN2(min_es_verts * gs_prims, max_es_verts);

      esgs_lds_size = esgs_itemsize * worst_case_es_verts;
      assert(esgs_lds_size <= max_lds_size);
   }

   /* Now calculate remaining ESGS information. */
   if (esgs_lds_size)
      es_verts = MIN2(esgs_lds_size / esgs_itemsize, max_es_verts);
   else
      es_verts = max_es_verts;

   /* Vertices for adjacency primitives are not always reused, so restore
    * it for ES_VERTS_PER_SUBGRP.
    */
   min_es_verts = gs->gs_input_verts_per_prim;

   /* For normal primitives, the VGT only checks if they are past the ES
    * verts per subgroup after allocating a full GS primitive and if they
    * are, kick off a new subgroup.  But if those additional ES verts are
    * unique (e.g. not reused) we need to make sure there is enough LDS
    * space to account for those ES verts beyond ES_VERTS_PER_SUBGRP.
    */
   es_verts -= min_es_verts - 1;

   out->es_verts_per_subgroup = es_verts;
   out->gs_prims_per_subgroup = gs_prims;
   out->gs_inst_prims_in_subgroup = gs_prims * gs_num_invocations;
   out->max_prims_per_subgroup = out->gs_inst_prims_in_subgroup * gs->gs_max_out_vertices;
   out->esgs_ring_size = esgs_lds_size;

   assert(out->max_prims_per_subgroup <= max_out_prims);
}

static void si_emit_shader_gs(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.gs->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   /* R_028A60_VGT_GSVS_RING_OFFSET_1, R_028A64_VGT_GSVS_RING_OFFSET_2
    * R_028A68_VGT_GSVS_RING_OFFSET_3 */
   radeon_opt_set_context_reg3(
      sctx, R_028A60_VGT_GSVS_RING_OFFSET_1, SI_TRACKED_VGT_GSVS_RING_OFFSET_1,
      shader->ctx_reg.gs.vgt_gsvs_ring_offset_1, shader->ctx_reg.gs.vgt_gsvs_ring_offset_2,
      shader->ctx_reg.gs.vgt_gsvs_ring_offset_3);

   /* R_028AB0_VGT_GSVS_RING_ITEMSIZE */
   radeon_opt_set_context_reg(sctx, R_028AB0_VGT_GSVS_RING_ITEMSIZE,
                              SI_TRACKED_VGT_GSVS_RING_ITEMSIZE,
                              shader->ctx_reg.gs.vgt_gsvs_ring_itemsize);

   /* R_028B38_VGT_GS_MAX_VERT_OUT */
   radeon_opt_set_context_reg(sctx, R_028B38_VGT_GS_MAX_VERT_OUT, SI_TRACKED_VGT_GS_MAX_VERT_OUT,
                              shader->ctx_reg.gs.vgt_gs_max_vert_out);

   /* R_028B5C_VGT_GS_VERT_ITEMSIZE, R_028B60_VGT_GS_VERT_ITEMSIZE_1
    * R_028B64_VGT_GS_VERT_ITEMSIZE_2, R_028B68_VGT_GS_VERT_ITEMSIZE_3 */
   radeon_opt_set_context_reg4(
      sctx, R_028B5C_VGT_GS_VERT_ITEMSIZE, SI_TRACKED_VGT_GS_VERT_ITEMSIZE,
      shader->ctx_reg.gs.vgt_gs_vert_itemsize, shader->ctx_reg.gs.vgt_gs_vert_itemsize_1,
      shader->ctx_reg.gs.vgt_gs_vert_itemsize_2, shader->ctx_reg.gs.vgt_gs_vert_itemsize_3);

   /* R_028B90_VGT_GS_INSTANCE_CNT */
   radeon_opt_set_context_reg(sctx, R_028B90_VGT_GS_INSTANCE_CNT, SI_TRACKED_VGT_GS_INSTANCE_CNT,
                              shader->ctx_reg.gs.vgt_gs_instance_cnt);

   if (sctx->chip_class >= GFX9) {
      /* R_028A44_VGT_GS_ONCHIP_CNTL */
      radeon_opt_set_context_reg(sctx, R_028A44_VGT_GS_ONCHIP_CNTL, SI_TRACKED_VGT_GS_ONCHIP_CNTL,
                                 shader->ctx_reg.gs.vgt_gs_onchip_cntl);
      /* R_028A94_VGT_GS_MAX_PRIMS_PER_SUBGROUP */
      radeon_opt_set_context_reg(sctx, R_028A94_VGT_GS_MAX_PRIMS_PER_SUBGROUP,
                                 SI_TRACKED_VGT_GS_MAX_PRIMS_PER_SUBGROUP,
                                 shader->ctx_reg.gs.vgt_gs_max_prims_per_subgroup);
      /* R_028AAC_VGT_ESGS_RING_ITEMSIZE */
      radeon_opt_set_context_reg(sctx, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
                                 SI_TRACKED_VGT_ESGS_RING_ITEMSIZE,
                                 shader->ctx_reg.gs.vgt_esgs_ring_itemsize);

      if (shader->key.part.gs.es->info.stage == MESA_SHADER_TESS_EVAL)
         radeon_opt_set_context_reg(sctx, R_028B6C_VGT_TF_PARAM, SI_TRACKED_VGT_TF_PARAM,
                                    shader->vgt_tf_param);
      if (shader->vgt_vertex_reuse_block_cntl)
         radeon_opt_set_context_reg(sctx, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL,
                                    SI_TRACKED_VGT_VERTEX_REUSE_BLOCK_CNTL,
                                    shader->vgt_vertex_reuse_block_cntl);
   }

   if (initial_cdw != sctx->gfx_cs->current.cdw)
      sctx->context_roll = true;
}

static void si_shader_gs(struct si_screen *sscreen, struct si_shader *shader)
{
   struct si_shader_selector *sel = shader->selector;
   const ubyte *num_components = sel->info.num_stream_output_components;
   unsigned gs_num_invocations = sel->gs_num_invocations;
   struct si_pm4_state *pm4;
   uint64_t va;
   unsigned max_stream = sel->max_gs_stream;
   unsigned offset;

   pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   pm4->atom.emit = si_emit_shader_gs;

   offset = num_components[0] * sel->gs_max_out_vertices;
   shader->ctx_reg.gs.vgt_gsvs_ring_offset_1 = offset;

   if (max_stream >= 1)
      offset += num_components[1] * sel->gs_max_out_vertices;
   shader->ctx_reg.gs.vgt_gsvs_ring_offset_2 = offset;

   if (max_stream >= 2)
      offset += num_components[2] * sel->gs_max_out_vertices;
   shader->ctx_reg.gs.vgt_gsvs_ring_offset_3 = offset;

   if (max_stream >= 3)
      offset += num_components[3] * sel->gs_max_out_vertices;
   shader->ctx_reg.gs.vgt_gsvs_ring_itemsize = offset;

   /* The GSVS_RING_ITEMSIZE register takes 15 bits */
   assert(offset < (1 << 15));

   shader->ctx_reg.gs.vgt_gs_max_vert_out = sel->gs_max_out_vertices;

   shader->ctx_reg.gs.vgt_gs_vert_itemsize = num_components[0];
   shader->ctx_reg.gs.vgt_gs_vert_itemsize_1 = (max_stream >= 1) ? num_components[1] : 0;
   shader->ctx_reg.gs.vgt_gs_vert_itemsize_2 = (max_stream >= 2) ? num_components[2] : 0;
   shader->ctx_reg.gs.vgt_gs_vert_itemsize_3 = (max_stream >= 3) ? num_components[3] : 0;

   shader->ctx_reg.gs.vgt_gs_instance_cnt =
      S_028B90_CNT(MIN2(gs_num_invocations, 127)) | S_028B90_ENABLE(gs_num_invocations > 0);

   va = shader->bo->gpu_address;

   if (sscreen->info.chip_class >= GFX9) {
      unsigned input_prim = sel->info.base.gs.input_primitive;
      gl_shader_stage es_stage = shader->key.part.gs.es->info.stage;
      unsigned es_vgpr_comp_cnt, gs_vgpr_comp_cnt;

      if (es_stage == MESA_SHADER_VERTEX) {
         es_vgpr_comp_cnt = si_get_vs_vgpr_comp_cnt(sscreen, shader, false);
      } else if (es_stage == MESA_SHADER_TESS_EVAL)
         es_vgpr_comp_cnt = shader->key.part.gs.es->info.uses_primid ? 3 : 2;
      else
         unreachable("invalid shader selector type");

      /* If offsets 4, 5 are used, GS_VGPR_COMP_CNT is ignored and
       * VGPR[0:4] are always loaded.
       */
      if (sel->info.uses_invocationid)
         gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID. */
      else if (sel->info.uses_primid)
         gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */
      else if (input_prim >= PIPE_PRIM_TRIANGLES)
         gs_vgpr_comp_cnt = 1; /* VGPR1 contains offsets 2, 3 */
      else
         gs_vgpr_comp_cnt = 0; /* VGPR0 contains offsets 0, 1 */

      unsigned num_user_sgprs;
      if (es_stage == MESA_SHADER_VERTEX)
         num_user_sgprs = si_get_num_vs_user_sgprs(shader, GFX9_VSGS_NUM_USER_SGPR);
      else
         num_user_sgprs = GFX9_TESGS_NUM_USER_SGPR;

      if (sscreen->info.chip_class >= GFX10) {
         si_pm4_set_reg(pm4, R_00B320_SPI_SHADER_PGM_LO_ES, va >> 8);
         si_pm4_set_reg(pm4, R_00B324_SPI_SHADER_PGM_HI_ES, S_00B324_MEM_BASE(va >> 40));
      } else {
         si_pm4_set_reg(pm4, R_00B210_SPI_SHADER_PGM_LO_ES, va >> 8);
         si_pm4_set_reg(pm4, R_00B214_SPI_SHADER_PGM_HI_ES, S_00B214_MEM_BASE(va >> 40));
      }

      uint32_t rsrc1 = S_00B228_VGPRS((shader->config.num_vgprs - 1) / 4) | S_00B228_DX10_CLAMP(1) |
                       S_00B228_MEM_ORDERED(sscreen->info.chip_class >= GFX10) |
                       S_00B228_WGP_MODE(sscreen->info.chip_class >= GFX10) |
                       S_00B228_FLOAT_MODE(shader->config.float_mode) |
                       S_00B228_GS_VGPR_COMP_CNT(gs_vgpr_comp_cnt);
      uint32_t rsrc2 = S_00B22C_USER_SGPR(num_user_sgprs) |
                       S_00B22C_ES_VGPR_COMP_CNT(es_vgpr_comp_cnt) |
                       S_00B22C_OC_LDS_EN(es_stage == MESA_SHADER_TESS_EVAL) |
                       S_00B22C_LDS_SIZE(shader->config.lds_size) |
                       S_00B22C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0);

      if (sscreen->info.chip_class >= GFX10) {
         rsrc2 |= S_00B22C_USER_SGPR_MSB_GFX10(num_user_sgprs >> 5);
      } else {
         rsrc1 |= S_00B228_SGPRS((shader->config.num_sgprs - 1) / 8);
         rsrc2 |= S_00B22C_USER_SGPR_MSB_GFX9(num_user_sgprs >> 5);
      }

      si_pm4_set_reg(pm4, R_00B228_SPI_SHADER_PGM_RSRC1_GS, rsrc1);
      si_pm4_set_reg(pm4, R_00B22C_SPI_SHADER_PGM_RSRC2_GS, rsrc2);

      if (sscreen->info.chip_class >= GFX10) {
         si_pm4_set_reg(pm4, R_00B204_SPI_SHADER_PGM_RSRC4_GS,
                        S_00B204_CU_EN(0xffff) | S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(0));
      }

      shader->ctx_reg.gs.vgt_gs_onchip_cntl =
         S_028A44_ES_VERTS_PER_SUBGRP(shader->gs_info.es_verts_per_subgroup) |
         S_028A44_GS_PRIMS_PER_SUBGRP(shader->gs_info.gs_prims_per_subgroup) |
         S_028A44_GS_INST_PRIMS_IN_SUBGRP(shader->gs_info.gs_inst_prims_in_subgroup);
      shader->ctx_reg.gs.vgt_gs_max_prims_per_subgroup =
         S_028A94_MAX_PRIMS_PER_SUBGROUP(shader->gs_info.max_prims_per_subgroup);
      shader->ctx_reg.gs.vgt_esgs_ring_itemsize = shader->key.part.gs.es->esgs_itemsize / 4;

      if (es_stage == MESA_SHADER_TESS_EVAL)
         si_set_tesseval_regs(sscreen, shader->key.part.gs.es, pm4);

      polaris_set_vgt_vertex_reuse(sscreen, shader->key.part.gs.es, NULL, pm4);
   } else {
      si_pm4_set_reg(pm4, R_00B220_SPI_SHADER_PGM_LO_GS, va >> 8);
      si_pm4_set_reg(pm4, R_00B224_SPI_SHADER_PGM_HI_GS, S_00B224_MEM_BASE(va >> 40));

      si_pm4_set_reg(pm4, R_00B228_SPI_SHADER_PGM_RSRC1_GS,
                     S_00B228_VGPRS((shader->config.num_vgprs - 1) / 4) |
                        S_00B228_SGPRS((shader->config.num_sgprs - 1) / 8) |
                        S_00B228_DX10_CLAMP(1) | S_00B228_FLOAT_MODE(shader->config.float_mode));
      si_pm4_set_reg(pm4, R_00B22C_SPI_SHADER_PGM_RSRC2_GS,
                     S_00B22C_USER_SGPR(GFX6_GS_NUM_USER_SGPR) |
                        S_00B22C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0));
   }
}

static void gfx10_emit_ge_pc_alloc(struct si_context *sctx, unsigned value)
{
   enum si_tracked_reg reg = SI_TRACKED_GE_PC_ALLOC;

   if (((sctx->tracked_regs.reg_saved >> reg) & 0x1) != 0x1 ||
       sctx->tracked_regs.reg_value[reg] != value) {
      struct radeon_cmdbuf *cs = sctx->gfx_cs;

      if (sctx->chip_class == GFX10) {
         /* SQ_NON_EVENT must be emitted before GE_PC_ALLOC is written. */
         radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
         radeon_emit(cs, EVENT_TYPE(V_028A90_SQ_NON_EVENT) | EVENT_INDEX(0));
      }

      radeon_set_uconfig_reg(cs, R_030980_GE_PC_ALLOC, value);

      sctx->tracked_regs.reg_saved |= 0x1ull << reg;
      sctx->tracked_regs.reg_value[reg] = value;
   }
}

/* Common tail code for NGG primitive shaders. */
static void gfx10_emit_shader_ngg_tail(struct si_context *sctx, struct si_shader *shader,
                                       unsigned initial_cdw)
{
   radeon_opt_set_context_reg(sctx, R_0287FC_GE_MAX_OUTPUT_PER_SUBGROUP,
                              SI_TRACKED_GE_MAX_OUTPUT_PER_SUBGROUP,
                              shader->ctx_reg.ngg.ge_max_output_per_subgroup);
   radeon_opt_set_context_reg(sctx, R_028B4C_GE_NGG_SUBGRP_CNTL, SI_TRACKED_GE_NGG_SUBGRP_CNTL,
                              shader->ctx_reg.ngg.ge_ngg_subgrp_cntl);
   radeon_opt_set_context_reg(sctx, R_028A84_VGT_PRIMITIVEID_EN, SI_TRACKED_VGT_PRIMITIVEID_EN,
                              shader->ctx_reg.ngg.vgt_primitiveid_en);
   radeon_opt_set_context_reg(sctx, R_028A44_VGT_GS_ONCHIP_CNTL, SI_TRACKED_VGT_GS_ONCHIP_CNTL,
                              shader->ctx_reg.ngg.vgt_gs_onchip_cntl);
   radeon_opt_set_context_reg(sctx, R_028B90_VGT_GS_INSTANCE_CNT, SI_TRACKED_VGT_GS_INSTANCE_CNT,
                              shader->ctx_reg.ngg.vgt_gs_instance_cnt);
   radeon_opt_set_context_reg(sctx, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
                              SI_TRACKED_VGT_ESGS_RING_ITEMSIZE,
                              shader->ctx_reg.ngg.vgt_esgs_ring_itemsize);
   radeon_opt_set_context_reg(sctx, R_0286C4_SPI_VS_OUT_CONFIG, SI_TRACKED_SPI_VS_OUT_CONFIG,
                              shader->ctx_reg.ngg.spi_vs_out_config);
   radeon_opt_set_context_reg2(
      sctx, R_028708_SPI_SHADER_IDX_FORMAT, SI_TRACKED_SPI_SHADER_IDX_FORMAT,
      shader->ctx_reg.ngg.spi_shader_idx_format, shader->ctx_reg.ngg.spi_shader_pos_format);
   radeon_opt_set_context_reg(sctx, R_028818_PA_CL_VTE_CNTL, SI_TRACKED_PA_CL_VTE_CNTL,
                              shader->ctx_reg.ngg.pa_cl_vte_cntl);
   radeon_opt_set_context_reg(sctx, R_028838_PA_CL_NGG_CNTL, SI_TRACKED_PA_CL_NGG_CNTL,
                              shader->ctx_reg.ngg.pa_cl_ngg_cntl);

   radeon_opt_set_context_reg_rmw(sctx, R_02881C_PA_CL_VS_OUT_CNTL,
                                  SI_TRACKED_PA_CL_VS_OUT_CNTL__VS, shader->pa_cl_vs_out_cntl,
                                  SI_TRACKED_PA_CL_VS_OUT_CNTL__VS_MASK);

   if (initial_cdw != sctx->gfx_cs->current.cdw)
      sctx->context_roll = true;

   /* GE_PC_ALLOC is not a context register, so it doesn't cause a context roll. */
   gfx10_emit_ge_pc_alloc(sctx, shader->ctx_reg.ngg.ge_pc_alloc);
}

static void gfx10_emit_shader_ngg_notess_nogs(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.gs->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   gfx10_emit_shader_ngg_tail(sctx, shader, initial_cdw);
}

static void gfx10_emit_shader_ngg_tess_nogs(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.gs->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   radeon_opt_set_context_reg(sctx, R_028B6C_VGT_TF_PARAM, SI_TRACKED_VGT_TF_PARAM,
                              shader->vgt_tf_param);

   gfx10_emit_shader_ngg_tail(sctx, shader, initial_cdw);
}

static void gfx10_emit_shader_ngg_notess_gs(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.gs->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   radeon_opt_set_context_reg(sctx, R_028B38_VGT_GS_MAX_VERT_OUT, SI_TRACKED_VGT_GS_MAX_VERT_OUT,
                              shader->ctx_reg.ngg.vgt_gs_max_vert_out);

   gfx10_emit_shader_ngg_tail(sctx, shader, initial_cdw);
}

static void gfx10_emit_shader_ngg_tess_gs(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.gs->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   radeon_opt_set_context_reg(sctx, R_028B38_VGT_GS_MAX_VERT_OUT, SI_TRACKED_VGT_GS_MAX_VERT_OUT,
                              shader->ctx_reg.ngg.vgt_gs_max_vert_out);
   radeon_opt_set_context_reg(sctx, R_028B6C_VGT_TF_PARAM, SI_TRACKED_VGT_TF_PARAM,
                              shader->vgt_tf_param);

   gfx10_emit_shader_ngg_tail(sctx, shader, initial_cdw);
}

unsigned si_get_input_prim(const struct si_shader_selector *gs)
{
   if (gs->info.stage == MESA_SHADER_GEOMETRY)
      return gs->info.base.gs.input_primitive;

   if (gs->info.stage == MESA_SHADER_TESS_EVAL) {
      if (gs->info.base.tess.point_mode)
         return PIPE_PRIM_POINTS;
      if (gs->info.base.tess.primitive_mode == GL_LINES)
         return PIPE_PRIM_LINES;
      return PIPE_PRIM_TRIANGLES;
   }

   /* TODO: Set this correctly if the primitive type is set in the shader key. */
   return PIPE_PRIM_TRIANGLES; /* worst case for all callers */
}

static unsigned si_get_vs_out_cntl(const struct si_shader_selector *sel, bool ngg)
{
   bool misc_vec_ena = sel->info.writes_psize || (sel->info.writes_edgeflag && !ngg) ||
                       sel->info.writes_layer || sel->info.writes_viewport_index;
   return S_02881C_USE_VTX_POINT_SIZE(sel->info.writes_psize) |
          S_02881C_USE_VTX_EDGE_FLAG(sel->info.writes_edgeflag && !ngg) |
          S_02881C_USE_VTX_RENDER_TARGET_INDX(sel->info.writes_layer) |
          S_02881C_USE_VTX_VIEWPORT_INDX(sel->info.writes_viewport_index) |
          S_02881C_VS_OUT_MISC_VEC_ENA(misc_vec_ena) |
          S_02881C_VS_OUT_MISC_SIDE_BUS_ENA(misc_vec_ena);
}

/**
 * Prepare the PM4 image for \p shader, which will run as a merged ESGS shader
 * in NGG mode.
 */
static void gfx10_shader_ngg(struct si_screen *sscreen, struct si_shader *shader)
{
   const struct si_shader_selector *gs_sel = shader->selector;
   const struct si_shader_info *gs_info = &gs_sel->info;
   const gl_shader_stage gs_stage = shader->selector->info.stage;
   const struct si_shader_selector *es_sel =
      shader->previous_stage_sel ? shader->previous_stage_sel : shader->selector;
   const struct si_shader_info *es_info = &es_sel->info;
   const gl_shader_stage es_stage = es_sel->info.stage;
   unsigned num_user_sgprs;
   unsigned nparams, es_vgpr_comp_cnt, gs_vgpr_comp_cnt;
   uint64_t va;
   bool window_space = gs_info->stage == MESA_SHADER_VERTEX ?
                          gs_info->base.vs.window_space_position : 0;
   bool es_enable_prim_id = shader->key.mono.u.vs_export_prim_id || es_info->uses_primid;
   unsigned gs_num_invocations = MAX2(gs_sel->gs_num_invocations, 1);
   unsigned input_prim = si_get_input_prim(gs_sel);
   bool break_wave_at_eoi = false;
   struct si_pm4_state *pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   if (es_stage == MESA_SHADER_TESS_EVAL) {
      pm4->atom.emit = gs_stage == MESA_SHADER_GEOMETRY ? gfx10_emit_shader_ngg_tess_gs
                                                       : gfx10_emit_shader_ngg_tess_nogs;
   } else {
      pm4->atom.emit = gs_stage == MESA_SHADER_GEOMETRY ? gfx10_emit_shader_ngg_notess_gs
                                                       : gfx10_emit_shader_ngg_notess_nogs;
   }

   va = shader->bo->gpu_address;

   if (es_stage == MESA_SHADER_VERTEX) {
      es_vgpr_comp_cnt = si_get_vs_vgpr_comp_cnt(sscreen, shader, false);

      if (es_info->base.vs.blit_sgprs_amd) {
         num_user_sgprs =
            SI_SGPR_VS_BLIT_DATA + es_info->base.vs.blit_sgprs_amd;
      } else {
         num_user_sgprs = si_get_num_vs_user_sgprs(shader, GFX9_VSGS_NUM_USER_SGPR);
      }
   } else {
      assert(es_stage == MESA_SHADER_TESS_EVAL);
      es_vgpr_comp_cnt = es_enable_prim_id ? 3 : 2;
      num_user_sgprs = GFX9_TESGS_NUM_USER_SGPR;

      if (es_enable_prim_id || gs_info->uses_primid)
         break_wave_at_eoi = true;
   }

   /* If offsets 4, 5 are used, GS_VGPR_COMP_CNT is ignored and
    * VGPR[0:4] are always loaded.
    *
    * Vertex shaders always need to load VGPR3, because they need to
    * pass edge flags for decomposed primitives (such as quads) to the PA
    * for the GL_LINE polygon mode to skip rendering lines on inner edges.
    */
   if (gs_info->uses_invocationid ||
       (gs_stage == MESA_SHADER_VERTEX && !gfx10_is_ngg_passthrough(shader)))
      gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID, edge flags. */
   else if ((gs_stage == MESA_SHADER_GEOMETRY && gs_info->uses_primid) ||
            (gs_stage == MESA_SHADER_VERTEX && shader->key.mono.u.vs_export_prim_id))
      gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */
   else if (input_prim >= PIPE_PRIM_TRIANGLES && !gfx10_is_ngg_passthrough(shader))
      gs_vgpr_comp_cnt = 1; /* VGPR1 contains offsets 2, 3 */
   else
      gs_vgpr_comp_cnt = 0; /* VGPR0 contains offsets 0, 1 */

   unsigned wave_size = si_get_shader_wave_size(shader);

   si_pm4_set_reg(pm4, R_00B320_SPI_SHADER_PGM_LO_ES, va >> 8);
   si_pm4_set_reg(pm4, R_00B324_SPI_SHADER_PGM_HI_ES, va >> 40);
   si_pm4_set_reg(
      pm4, R_00B228_SPI_SHADER_PGM_RSRC1_GS,
      S_00B228_VGPRS((shader->config.num_vgprs - 1) / (wave_size == 32 ? 8 : 4)) |
         S_00B228_FLOAT_MODE(shader->config.float_mode) | S_00B228_DX10_CLAMP(1) |
         S_00B228_MEM_ORDERED(1) | S_00B228_WGP_MODE(1) |
         S_00B228_GS_VGPR_COMP_CNT(gs_vgpr_comp_cnt));
   si_pm4_set_reg(pm4, R_00B22C_SPI_SHADER_PGM_RSRC2_GS,
                  S_00B22C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0) |
                     S_00B22C_USER_SGPR(num_user_sgprs) |
                     S_00B22C_ES_VGPR_COMP_CNT(es_vgpr_comp_cnt) |
                     S_00B22C_USER_SGPR_MSB_GFX10(num_user_sgprs >> 5) |
                     S_00B22C_OC_LDS_EN(es_stage == MESA_SHADER_TESS_EVAL) |
                     S_00B22C_LDS_SIZE(shader->config.lds_size));

   /* Determine LATE_ALLOC_GS. */
   unsigned num_cu_per_sh = sscreen->info.min_good_cu_per_sa;
   unsigned late_alloc_wave64; /* The limit is per SA. */

   /* For Wave32, the hw will launch twice the number of late
    * alloc waves, so 1 == 2x wave32.
    *
    * Don't use late alloc for NGG on Navi14 due to a hw bug.
    */
   if (sscreen->info.family == CHIP_NAVI14 || !sscreen->info.use_late_alloc)
      late_alloc_wave64 = 0;
   else if (num_cu_per_sh <= 6)
      late_alloc_wave64 = num_cu_per_sh - 2; /* All CUs enabled */
   else if (shader->key.opt.ngg_culling & SI_NGG_CULL_GS_FAST_LAUNCH_ALL)
      late_alloc_wave64 = (num_cu_per_sh - 2) * 6;
   else
      late_alloc_wave64 = (num_cu_per_sh - 2) * 4;

   /* Limit LATE_ALLOC_GS for prevent a hang (hw bug). */
   if (sscreen->info.chip_class == GFX10)
      late_alloc_wave64 = MIN2(late_alloc_wave64, 64);

   si_pm4_set_reg(
      pm4, R_00B204_SPI_SHADER_PGM_RSRC4_GS,
      S_00B204_CU_EN(0xffff) | S_00B204_SPI_SHADER_LATE_ALLOC_GS_GFX10(late_alloc_wave64));

   nparams = MAX2(shader->info.nr_param_exports, 1);
   shader->ctx_reg.ngg.spi_vs_out_config =
      S_0286C4_VS_EXPORT_COUNT(nparams - 1) |
      S_0286C4_NO_PC_EXPORT(shader->info.nr_param_exports == 0);

   shader->ctx_reg.ngg.spi_shader_idx_format =
      S_028708_IDX0_EXPORT_FORMAT(V_028708_SPI_SHADER_1COMP);
   shader->ctx_reg.ngg.spi_shader_pos_format =
      S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
      S_02870C_POS1_EXPORT_FORMAT(shader->info.nr_pos_exports > 1 ? V_02870C_SPI_SHADER_4COMP
                                                                  : V_02870C_SPI_SHADER_NONE) |
      S_02870C_POS2_EXPORT_FORMAT(shader->info.nr_pos_exports > 2 ? V_02870C_SPI_SHADER_4COMP
                                                                  : V_02870C_SPI_SHADER_NONE) |
      S_02870C_POS3_EXPORT_FORMAT(shader->info.nr_pos_exports > 3 ? V_02870C_SPI_SHADER_4COMP
                                                                  : V_02870C_SPI_SHADER_NONE);

   shader->ctx_reg.ngg.vgt_primitiveid_en =
      S_028A84_PRIMITIVEID_EN(es_enable_prim_id) |
      S_028A84_NGG_DISABLE_PROVOK_REUSE(shader->key.mono.u.vs_export_prim_id ||
                                        gs_sel->info.writes_primid);

   if (gs_stage == MESA_SHADER_GEOMETRY) {
      shader->ctx_reg.ngg.vgt_esgs_ring_itemsize = es_sel->esgs_itemsize / 4;
      shader->ctx_reg.ngg.vgt_gs_max_vert_out = gs_sel->gs_max_out_vertices;
   } else {
      shader->ctx_reg.ngg.vgt_esgs_ring_itemsize = 1;
   }

   if (es_stage == MESA_SHADER_TESS_EVAL)
      si_set_tesseval_regs(sscreen, es_sel, pm4);

   shader->ctx_reg.ngg.vgt_gs_onchip_cntl =
      S_028A44_ES_VERTS_PER_SUBGRP(shader->ngg.hw_max_esverts) |
      S_028A44_GS_PRIMS_PER_SUBGRP(shader->ngg.max_gsprims) |
      S_028A44_GS_INST_PRIMS_IN_SUBGRP(shader->ngg.max_gsprims * gs_num_invocations);
   shader->ctx_reg.ngg.ge_max_output_per_subgroup =
      S_0287FC_MAX_VERTS_PER_SUBGROUP(shader->ngg.max_out_verts);
   shader->ctx_reg.ngg.ge_ngg_subgrp_cntl = S_028B4C_PRIM_AMP_FACTOR(shader->ngg.prim_amp_factor) |
                                            S_028B4C_THDS_PER_SUBGRP(0); /* for fast launch */
   shader->ctx_reg.ngg.vgt_gs_instance_cnt =
      S_028B90_CNT(gs_num_invocations) | S_028B90_ENABLE(gs_num_invocations > 1) |
      S_028B90_EN_MAX_VERT_OUT_PER_GS_INSTANCE(shader->ngg.max_vert_out_per_gs_instance);

   /* Always output hw-generated edge flags and pass them via the prim
    * export to prevent drawing lines on internal edges of decomposed
    * primitives (such as quads) with polygon mode = lines. Only VS needs
    * this.
    */
   shader->ctx_reg.ngg.pa_cl_ngg_cntl =
      S_028838_INDEX_BUF_EDGE_FLAG_ENA(gs_stage == MESA_SHADER_VERTEX) |
      /* Reuse for NGG. */
      S_028838_VERTEX_REUSE_DEPTH(sscreen->info.chip_class >= GFX10_3 ? 30 : 0);
   shader->pa_cl_vs_out_cntl = si_get_vs_out_cntl(gs_sel, true);

   /* Oversubscribe PC. This improves performance when there are too many varyings. */
   float oversub_pc_factor = 0.25;

   if (shader->key.opt.ngg_culling) {
      /* Be more aggressive with NGG culling. */
      if (shader->info.nr_param_exports > 4)
         oversub_pc_factor = 1;
      else if (shader->info.nr_param_exports > 2)
         oversub_pc_factor = 0.75;
      else
         oversub_pc_factor = 0.5;
   }

   unsigned oversub_pc_lines = sscreen->info.pc_lines * oversub_pc_factor;
   shader->ctx_reg.ngg.ge_pc_alloc = S_030980_OVERSUB_EN(sscreen->info.use_late_alloc) |
                                     S_030980_NUM_PC_LINES(oversub_pc_lines - 1);

   if (shader->key.opt.ngg_culling & SI_NGG_CULL_GS_FAST_LAUNCH_TRI_LIST) {
      shader->ge_cntl = S_03096C_PRIM_GRP_SIZE(shader->ngg.max_gsprims) |
                        S_03096C_VERT_GRP_SIZE(shader->ngg.max_gsprims * 3);
   } else if (shader->key.opt.ngg_culling & SI_NGG_CULL_GS_FAST_LAUNCH_TRI_STRIP) {
      shader->ge_cntl = S_03096C_PRIM_GRP_SIZE(shader->ngg.max_gsprims) |
                        S_03096C_VERT_GRP_SIZE(shader->ngg.max_gsprims + 2);
   } else {
      shader->ge_cntl = S_03096C_PRIM_GRP_SIZE(shader->ngg.max_gsprims) |
                        S_03096C_VERT_GRP_SIZE(256) | /* 256 = disable vertex grouping */
                        S_03096C_BREAK_WAVE_AT_EOI(break_wave_at_eoi);

      /* Bug workaround for a possible hang with non-tessellation cases.
       * Tessellation always sets GE_CNTL.VERT_GRP_SIZE = 0
       *
       * Requirement: GE_CNTL.VERT_GRP_SIZE = VGT_GS_ONCHIP_CNTL.ES_VERTS_PER_SUBGRP - 5
       */
      if ((sscreen->info.chip_class == GFX10) &&
          (es_stage == MESA_SHADER_VERTEX || gs_stage == MESA_SHADER_VERTEX) && /* = no tess */
          shader->ngg.hw_max_esverts != 256) {
         shader->ge_cntl &= C_03096C_VERT_GRP_SIZE;

         if (shader->ngg.hw_max_esverts > 5) {
            shader->ge_cntl |= S_03096C_VERT_GRP_SIZE(shader->ngg.hw_max_esverts - 5);
         }
      }
   }

   if (window_space) {
      shader->ctx_reg.ngg.pa_cl_vte_cntl = S_028818_VTX_XY_FMT(1) | S_028818_VTX_Z_FMT(1);
   } else {
      shader->ctx_reg.ngg.pa_cl_vte_cntl =
         S_028818_VTX_W0_FMT(1) | S_028818_VPORT_X_SCALE_ENA(1) | S_028818_VPORT_X_OFFSET_ENA(1) |
         S_028818_VPORT_Y_SCALE_ENA(1) | S_028818_VPORT_Y_OFFSET_ENA(1) |
         S_028818_VPORT_Z_SCALE_ENA(1) | S_028818_VPORT_Z_OFFSET_ENA(1);
   }
}

static void si_emit_shader_vs(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.vs->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   radeon_opt_set_context_reg(sctx, R_028A40_VGT_GS_MODE, SI_TRACKED_VGT_GS_MODE,
                              shader->ctx_reg.vs.vgt_gs_mode);
   radeon_opt_set_context_reg(sctx, R_028A84_VGT_PRIMITIVEID_EN, SI_TRACKED_VGT_PRIMITIVEID_EN,
                              shader->ctx_reg.vs.vgt_primitiveid_en);

   if (sctx->chip_class <= GFX8) {
      radeon_opt_set_context_reg(sctx, R_028AB4_VGT_REUSE_OFF, SI_TRACKED_VGT_REUSE_OFF,
                                 shader->ctx_reg.vs.vgt_reuse_off);
   }

   radeon_opt_set_context_reg(sctx, R_0286C4_SPI_VS_OUT_CONFIG, SI_TRACKED_SPI_VS_OUT_CONFIG,
                              shader->ctx_reg.vs.spi_vs_out_config);

   radeon_opt_set_context_reg(sctx, R_02870C_SPI_SHADER_POS_FORMAT,
                              SI_TRACKED_SPI_SHADER_POS_FORMAT,
                              shader->ctx_reg.vs.spi_shader_pos_format);

   radeon_opt_set_context_reg(sctx, R_028818_PA_CL_VTE_CNTL, SI_TRACKED_PA_CL_VTE_CNTL,
                              shader->ctx_reg.vs.pa_cl_vte_cntl);

   if (shader->selector->info.stage == MESA_SHADER_TESS_EVAL)
      radeon_opt_set_context_reg(sctx, R_028B6C_VGT_TF_PARAM, SI_TRACKED_VGT_TF_PARAM,
                                 shader->vgt_tf_param);

   if (shader->vgt_vertex_reuse_block_cntl)
      radeon_opt_set_context_reg(sctx, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL,
                                 SI_TRACKED_VGT_VERTEX_REUSE_BLOCK_CNTL,
                                 shader->vgt_vertex_reuse_block_cntl);

   /* Required programming for tessellation. (legacy pipeline only) */
   if (sctx->chip_class >= GFX10 && shader->selector->info.stage == MESA_SHADER_TESS_EVAL) {
      radeon_opt_set_context_reg(sctx, R_028A44_VGT_GS_ONCHIP_CNTL,
                                 SI_TRACKED_VGT_GS_ONCHIP_CNTL,
                                 S_028A44_ES_VERTS_PER_SUBGRP(250) |
                                 S_028A44_GS_PRIMS_PER_SUBGRP(126) |
                                 S_028A44_GS_INST_PRIMS_IN_SUBGRP(126));
   }

   if (sctx->chip_class >= GFX10) {
      radeon_opt_set_context_reg_rmw(sctx, R_02881C_PA_CL_VS_OUT_CNTL,
                                     SI_TRACKED_PA_CL_VS_OUT_CNTL__VS, shader->pa_cl_vs_out_cntl,
                                     SI_TRACKED_PA_CL_VS_OUT_CNTL__VS_MASK);
   }

   if (initial_cdw != sctx->gfx_cs->current.cdw)
      sctx->context_roll = true;

   /* GE_PC_ALLOC is not a context register, so it doesn't cause a context roll. */
   if (sctx->chip_class >= GFX10)
      gfx10_emit_ge_pc_alloc(sctx, shader->ctx_reg.vs.ge_pc_alloc);
}

/**
 * Compute the state for \p shader, which will run as a vertex shader on the
 * hardware.
 *
 * If \p gs is non-NULL, it points to the geometry shader for which this shader
 * is the copy shader.
 */
static void si_shader_vs(struct si_screen *sscreen, struct si_shader *shader,
                         struct si_shader_selector *gs)
{
   const struct si_shader_info *info = &shader->selector->info;
   struct si_pm4_state *pm4;
   unsigned num_user_sgprs, vgpr_comp_cnt;
   uint64_t va;
   unsigned nparams, oc_lds_en;
   bool window_space = info->stage == MESA_SHADER_VERTEX ?
                          info->base.vs.window_space_position : 0;
   bool enable_prim_id = shader->key.mono.u.vs_export_prim_id || info->uses_primid;

   pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   pm4->atom.emit = si_emit_shader_vs;

   /* We always write VGT_GS_MODE in the VS state, because every switch
    * between different shader pipelines involving a different GS or no
    * GS at all involves a switch of the VS (different GS use different
    * copy shaders). On the other hand, when the API switches from a GS to
    * no GS and then back to the same GS used originally, the GS state is
    * not sent again.
    */
   if (!gs) {
      unsigned mode = V_028A40_GS_OFF;

      /* PrimID needs GS scenario A. */
      if (enable_prim_id)
         mode = V_028A40_GS_SCENARIO_A;

      shader->ctx_reg.vs.vgt_gs_mode = S_028A40_MODE(mode);
      shader->ctx_reg.vs.vgt_primitiveid_en = enable_prim_id;
   } else {
      shader->ctx_reg.vs.vgt_gs_mode =
         ac_vgt_gs_mode(gs->gs_max_out_vertices, sscreen->info.chip_class);
      shader->ctx_reg.vs.vgt_primitiveid_en = 0;
   }

   if (sscreen->info.chip_class <= GFX8) {
      /* Reuse needs to be set off if we write oViewport. */
      shader->ctx_reg.vs.vgt_reuse_off = S_028AB4_REUSE_OFF(info->writes_viewport_index);
   }

   va = shader->bo->gpu_address;

   if (gs) {
      vgpr_comp_cnt = 0; /* only VertexID is needed for GS-COPY. */
      num_user_sgprs = SI_GSCOPY_NUM_USER_SGPR;
   } else if (shader->selector->info.stage == MESA_SHADER_VERTEX) {
      vgpr_comp_cnt = si_get_vs_vgpr_comp_cnt(sscreen, shader, enable_prim_id);

      if (info->base.vs.blit_sgprs_amd) {
         num_user_sgprs = SI_SGPR_VS_BLIT_DATA + info->base.vs.blit_sgprs_amd;
      } else {
         num_user_sgprs = si_get_num_vs_user_sgprs(shader, SI_VS_NUM_USER_SGPR);
      }
   } else if (shader->selector->info.stage == MESA_SHADER_TESS_EVAL) {
      vgpr_comp_cnt = enable_prim_id ? 3 : 2;
      num_user_sgprs = SI_TES_NUM_USER_SGPR;
   } else
      unreachable("invalid shader selector type");

   /* VS is required to export at least one param. */
   nparams = MAX2(shader->info.nr_param_exports, 1);
   shader->ctx_reg.vs.spi_vs_out_config = S_0286C4_VS_EXPORT_COUNT(nparams - 1);

   if (sscreen->info.chip_class >= GFX10) {
      shader->ctx_reg.vs.spi_vs_out_config |=
         S_0286C4_NO_PC_EXPORT(shader->info.nr_param_exports == 0);
   }

   shader->ctx_reg.vs.spi_shader_pos_format =
      S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
      S_02870C_POS1_EXPORT_FORMAT(shader->info.nr_pos_exports > 1 ? V_02870C_SPI_SHADER_4COMP
                                                                  : V_02870C_SPI_SHADER_NONE) |
      S_02870C_POS2_EXPORT_FORMAT(shader->info.nr_pos_exports > 2 ? V_02870C_SPI_SHADER_4COMP
                                                                  : V_02870C_SPI_SHADER_NONE) |
      S_02870C_POS3_EXPORT_FORMAT(shader->info.nr_pos_exports > 3 ? V_02870C_SPI_SHADER_4COMP
                                                                  : V_02870C_SPI_SHADER_NONE);
   shader->ctx_reg.vs.ge_pc_alloc = S_030980_OVERSUB_EN(sscreen->info.use_late_alloc) |
                                    S_030980_NUM_PC_LINES(sscreen->info.pc_lines / 4 - 1);
   shader->pa_cl_vs_out_cntl = si_get_vs_out_cntl(shader->selector, false);

   oc_lds_en = shader->selector->info.stage == MESA_SHADER_TESS_EVAL ? 1 : 0;

   si_pm4_set_reg(pm4, R_00B120_SPI_SHADER_PGM_LO_VS, va >> 8);
   si_pm4_set_reg(pm4, R_00B124_SPI_SHADER_PGM_HI_VS, S_00B124_MEM_BASE(va >> 40));

   uint32_t rsrc1 =
      S_00B128_VGPRS((shader->config.num_vgprs - 1) / (sscreen->ge_wave_size == 32 ? 8 : 4)) |
      S_00B128_VGPR_COMP_CNT(vgpr_comp_cnt) | S_00B128_DX10_CLAMP(1) |
      S_00B128_MEM_ORDERED(sscreen->info.chip_class >= GFX10) |
      S_00B128_FLOAT_MODE(shader->config.float_mode);
   uint32_t rsrc2 = S_00B12C_USER_SGPR(num_user_sgprs) | S_00B12C_OC_LDS_EN(oc_lds_en) |
                    S_00B12C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0);

   if (sscreen->info.chip_class >= GFX10)
      rsrc2 |= S_00B12C_USER_SGPR_MSB_GFX10(num_user_sgprs >> 5);
   else if (sscreen->info.chip_class == GFX9)
      rsrc2 |= S_00B12C_USER_SGPR_MSB_GFX9(num_user_sgprs >> 5);

   if (sscreen->info.chip_class <= GFX9)
      rsrc1 |= S_00B128_SGPRS((shader->config.num_sgprs - 1) / 8);

   if (!sscreen->use_ngg_streamout) {
      rsrc2 |= S_00B12C_SO_BASE0_EN(!!shader->selector->so.stride[0]) |
               S_00B12C_SO_BASE1_EN(!!shader->selector->so.stride[1]) |
               S_00B12C_SO_BASE2_EN(!!shader->selector->so.stride[2]) |
               S_00B12C_SO_BASE3_EN(!!shader->selector->so.stride[3]) |
               S_00B12C_SO_EN(!!shader->selector->so.num_outputs);
   }

   si_pm4_set_reg(pm4, R_00B128_SPI_SHADER_PGM_RSRC1_VS, rsrc1);
   si_pm4_set_reg(pm4, R_00B12C_SPI_SHADER_PGM_RSRC2_VS, rsrc2);

   if (window_space)
      shader->ctx_reg.vs.pa_cl_vte_cntl = S_028818_VTX_XY_FMT(1) | S_028818_VTX_Z_FMT(1);
   else
      shader->ctx_reg.vs.pa_cl_vte_cntl =
         S_028818_VTX_W0_FMT(1) | S_028818_VPORT_X_SCALE_ENA(1) | S_028818_VPORT_X_OFFSET_ENA(1) |
         S_028818_VPORT_Y_SCALE_ENA(1) | S_028818_VPORT_Y_OFFSET_ENA(1) |
         S_028818_VPORT_Z_SCALE_ENA(1) | S_028818_VPORT_Z_OFFSET_ENA(1);

   if (shader->selector->info.stage == MESA_SHADER_TESS_EVAL)
      si_set_tesseval_regs(sscreen, shader->selector, pm4);

   polaris_set_vgt_vertex_reuse(sscreen, shader->selector, shader, pm4);
}

static unsigned si_get_ps_num_interp(struct si_shader *ps)
{
   struct si_shader_info *info = &ps->selector->info;
   unsigned num_colors = !!(info->colors_read & 0x0f) + !!(info->colors_read & 0xf0);
   unsigned num_interp =
      ps->selector->info.num_inputs + (ps->key.part.ps.prolog.color_two_side ? num_colors : 0);

   assert(num_interp <= 32);
   return MIN2(num_interp, 32);
}

static unsigned si_get_spi_shader_col_format(struct si_shader *shader)
{
   unsigned spi_shader_col_format = shader->key.part.ps.epilog.spi_shader_col_format;
   unsigned value = 0, num_mrts = 0;
   unsigned i, num_targets = (util_last_bit(spi_shader_col_format) + 3) / 4;

   /* Remove holes in spi_shader_col_format. */
   for (i = 0; i < num_targets; i++) {
      unsigned spi_format = (spi_shader_col_format >> (i * 4)) & 0xf;

      if (spi_format) {
         value |= spi_format << (num_mrts * 4);
         num_mrts++;
      }
   }

   return value;
}

static void si_emit_shader_ps(struct si_context *sctx)
{
   struct si_shader *shader = sctx->queued.named.ps->shader;
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;

   if (!shader)
      return;

   /* R_0286CC_SPI_PS_INPUT_ENA, R_0286D0_SPI_PS_INPUT_ADDR*/
   radeon_opt_set_context_reg2(sctx, R_0286CC_SPI_PS_INPUT_ENA, SI_TRACKED_SPI_PS_INPUT_ENA,
                               shader->ctx_reg.ps.spi_ps_input_ena,
                               shader->ctx_reg.ps.spi_ps_input_addr);

   radeon_opt_set_context_reg(sctx, R_0286E0_SPI_BARYC_CNTL, SI_TRACKED_SPI_BARYC_CNTL,
                              shader->ctx_reg.ps.spi_baryc_cntl);
   radeon_opt_set_context_reg(sctx, R_0286D8_SPI_PS_IN_CONTROL, SI_TRACKED_SPI_PS_IN_CONTROL,
                              shader->ctx_reg.ps.spi_ps_in_control);

   /* R_028710_SPI_SHADER_Z_FORMAT, R_028714_SPI_SHADER_COL_FORMAT */
   radeon_opt_set_context_reg2(sctx, R_028710_SPI_SHADER_Z_FORMAT, SI_TRACKED_SPI_SHADER_Z_FORMAT,
                               shader->ctx_reg.ps.spi_shader_z_format,
                               shader->ctx_reg.ps.spi_shader_col_format);

   radeon_opt_set_context_reg(sctx, R_02823C_CB_SHADER_MASK, SI_TRACKED_CB_SHADER_MASK,
                              shader->ctx_reg.ps.cb_shader_mask);

   if (initial_cdw != sctx->gfx_cs->current.cdw)
      sctx->context_roll = true;
}

static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader)
{
   struct si_shader_info *info = &shader->selector->info;
   struct si_pm4_state *pm4;
   unsigned spi_ps_in_control, spi_shader_col_format, cb_shader_mask;
   unsigned spi_baryc_cntl = S_0286E0_FRONT_FACE_ALL_BITS(1);
   uint64_t va;
   unsigned input_ena = shader->config.spi_ps_input_ena;

   /* we need to enable at least one of them, otherwise we hang the GPU */
   assert(G_0286CC_PERSP_SAMPLE_ENA(input_ena) || G_0286CC_PERSP_CENTER_ENA(input_ena) ||
          G_0286CC_PERSP_CENTROID_ENA(input_ena) || G_0286CC_PERSP_PULL_MODEL_ENA(input_ena) ||
          G_0286CC_LINEAR_SAMPLE_ENA(input_ena) || G_0286CC_LINEAR_CENTER_ENA(input_ena) ||
          G_0286CC_LINEAR_CENTROID_ENA(input_ena) || G_0286CC_LINE_STIPPLE_TEX_ENA(input_ena));
   /* POS_W_FLOAT_ENA requires one of the perspective weights. */
   assert(!G_0286CC_POS_W_FLOAT_ENA(input_ena) || G_0286CC_PERSP_SAMPLE_ENA(input_ena) ||
          G_0286CC_PERSP_CENTER_ENA(input_ena) || G_0286CC_PERSP_CENTROID_ENA(input_ena) ||
          G_0286CC_PERSP_PULL_MODEL_ENA(input_ena));

   /* Validate interpolation optimization flags (read as implications). */
   assert(!shader->key.part.ps.prolog.bc_optimize_for_persp ||
          (G_0286CC_PERSP_CENTER_ENA(input_ena) && G_0286CC_PERSP_CENTROID_ENA(input_ena)));
   assert(!shader->key.part.ps.prolog.bc_optimize_for_linear ||
          (G_0286CC_LINEAR_CENTER_ENA(input_ena) && G_0286CC_LINEAR_CENTROID_ENA(input_ena)));
   assert(!shader->key.part.ps.prolog.force_persp_center_interp ||
          (!G_0286CC_PERSP_SAMPLE_ENA(input_ena) && !G_0286CC_PERSP_CENTROID_ENA(input_ena)));
   assert(!shader->key.part.ps.prolog.force_linear_center_interp ||
          (!G_0286CC_LINEAR_SAMPLE_ENA(input_ena) && !G_0286CC_LINEAR_CENTROID_ENA(input_ena)));
   assert(!shader->key.part.ps.prolog.force_persp_sample_interp ||
          (!G_0286CC_PERSP_CENTER_ENA(input_ena) && !G_0286CC_PERSP_CENTROID_ENA(input_ena)));
   assert(!shader->key.part.ps.prolog.force_linear_sample_interp ||
          (!G_0286CC_LINEAR_CENTER_ENA(input_ena) && !G_0286CC_LINEAR_CENTROID_ENA(input_ena)));

   /* Validate cases when the optimizations are off (read as implications). */
   assert(shader->key.part.ps.prolog.bc_optimize_for_persp ||
          !G_0286CC_PERSP_CENTER_ENA(input_ena) || !G_0286CC_PERSP_CENTROID_ENA(input_ena));
   assert(shader->key.part.ps.prolog.bc_optimize_for_linear ||
          !G_0286CC_LINEAR_CENTER_ENA(input_ena) || !G_0286CC_LINEAR_CENTROID_ENA(input_ena));

   pm4 = si_get_shader_pm4_state(shader);
   if (!pm4)
      return;

   pm4->atom.emit = si_emit_shader_ps;

   /* SPI_BARYC_CNTL.POS_FLOAT_LOCATION
    * Possible vaules:
    * 0 -> Position = pixel center
    * 1 -> Position = pixel centroid
    * 2 -> Position = at sample position
    *
    * From GLSL 4.5 specification, section 7.1:
    *   "The variable gl_FragCoord is available as an input variable from
    *    within fragment shaders and it holds the window relative coordinates
    *    (x, y, z, 1/w) values for the fragment. If multi-sampling, this
    *    value can be for any location within the pixel, or one of the
    *    fragment samples. The use of centroid does not further restrict
    *    this value to be inside the current primitive."
    *
    * Meaning that centroid has no effect and we can return anything within
    * the pixel. Thus, return the value at sample position, because that's
    * the most accurate one shaders can get.
    */
   spi_baryc_cntl |= S_0286E0_POS_FLOAT_LOCATION(2);

   if (info->base.fs.pixel_center_integer)
      spi_baryc_cntl |= S_0286E0_POS_FLOAT_ULC(1);

   spi_shader_col_format = si_get_spi_shader_col_format(shader);
   cb_shader_mask = ac_get_cb_shader_mask(shader->key.part.ps.epilog.spi_shader_col_format);

   /* Ensure that some export memory is always allocated, for two reasons:
    *
    * 1) Correctness: The hardware ignores the EXEC mask if no export
    *    memory is allocated, so KILL and alpha test do not work correctly
    *    without this.
    * 2) Performance: Every shader needs at least a NULL export, even when
    *    it writes no color/depth output. The NULL export instruction
    *    stalls without this setting.
    *
    * Don't add this to CB_SHADER_MASK.
    *
    * GFX10 supports pixel shaders without exports by setting both
    * the color and Z formats to SPI_SHADER_ZERO. The hw will skip export
    * instructions if any are present.
    */
   if ((sscreen->info.chip_class <= GFX9 || info->uses_kill ||
        shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS) &&
       !spi_shader_col_format && !info->writes_z && !info->writes_stencil &&
       !info->writes_samplemask)
      spi_shader_col_format = V_028714_SPI_SHADER_32_R;

   shader->ctx_reg.ps.spi_ps_input_ena = input_ena;
   shader->ctx_reg.ps.spi_ps_input_addr = shader->config.spi_ps_input_addr;

   /* Set interpolation controls. */
   spi_ps_in_control = S_0286D8_NUM_INTERP(si_get_ps_num_interp(shader)) |
                       S_0286D8_PS_W32_EN(sscreen->ps_wave_size == 32);

   shader->ctx_reg.ps.spi_baryc_cntl = spi_baryc_cntl;
   shader->ctx_reg.ps.spi_ps_in_control = spi_ps_in_control;
   shader->ctx_reg.ps.spi_shader_z_format =
      ac_get_spi_shader_z_format(info->writes_z, info->writes_stencil, info->writes_samplemask);
   shader->ctx_reg.ps.spi_shader_col_format = spi_shader_col_format;
   shader->ctx_reg.ps.cb_shader_mask = cb_shader_mask;

   va = shader->bo->gpu_address;
   si_pm4_set_reg(pm4, R_00B020_SPI_SHADER_PGM_LO_PS, va >> 8);
   si_pm4_set_reg(pm4, R_00B024_SPI_SHADER_PGM_HI_PS, S_00B024_MEM_BASE(va >> 40));

   uint32_t rsrc1 =
      S_00B028_VGPRS((shader->config.num_vgprs - 1) / (sscreen->ps_wave_size == 32 ? 8 : 4)) |
      S_00B028_DX10_CLAMP(1) | S_00B028_MEM_ORDERED(sscreen->info.chip_class >= GFX10) |
      S_00B028_FLOAT_MODE(shader->config.float_mode);

   if (sscreen->info.chip_class < GFX10) {
      rsrc1 |= S_00B028_SGPRS((shader->config.num_sgprs - 1) / 8);
   }

   si_pm4_set_reg(pm4, R_00B028_SPI_SHADER_PGM_RSRC1_PS, rsrc1);
   si_pm4_set_reg(pm4, R_00B02C_SPI_SHADER_PGM_RSRC2_PS,
                  S_00B02C_EXTRA_LDS_SIZE(shader->config.lds_size) |
                     S_00B02C_USER_SGPR(SI_PS_NUM_USER_SGPR) |
                     S_00B32C_SCRATCH_EN(shader->config.scratch_bytes_per_wave > 0));
}

static void si_shader_init_pm4_state(struct si_screen *sscreen, struct si_shader *shader)
{
   switch (shader->selector->info.stage) {
   case MESA_SHADER_VERTEX:
      if (shader->key.as_ls)
         si_shader_ls(sscreen, shader);
      else if (shader->key.as_es)
         si_shader_es(sscreen, shader);
      else if (shader->key.as_ngg)
         gfx10_shader_ngg(sscreen, shader);
      else
         si_shader_vs(sscreen, shader, NULL);
      break;
   case MESA_SHADER_TESS_CTRL:
      si_shader_hs(sscreen, shader);
      break;
   case MESA_SHADER_TESS_EVAL:
      if (shader->key.as_es)
         si_shader_es(sscreen, shader);
      else if (shader->key.as_ngg)
         gfx10_shader_ngg(sscreen, shader);
      else
         si_shader_vs(sscreen, shader, NULL);
      break;
   case MESA_SHADER_GEOMETRY:
      if (shader->key.as_ngg)
         gfx10_shader_ngg(sscreen, shader);
      else
         si_shader_gs(sscreen, shader);
      break;
   case MESA_SHADER_FRAGMENT:
      si_shader_ps(sscreen, shader);
      break;
   default:
      assert(0);
   }
}

static unsigned si_get_alpha_test_func(struct si_context *sctx)
{
   /* Alpha-test should be disabled if colorbuffer 0 is integer. */
   return sctx->queued.named.dsa->alpha_func;
}

void si_shader_selector_key_vs(struct si_context *sctx, struct si_shader_selector *vs,
                               struct si_shader_key *key, struct si_vs_prolog_bits *prolog_key)
{
   if (!sctx->vertex_elements || vs->info.base.vs.blit_sgprs_amd)
      return;

   struct si_vertex_elements *elts = sctx->vertex_elements;

   prolog_key->instance_divisor_is_one = elts->instance_divisor_is_one;
   prolog_key->instance_divisor_is_fetched = elts->instance_divisor_is_fetched;
   prolog_key->unpack_instance_id_from_vertex_id = sctx->prim_discard_cs_instancing;

   /* Prefer a monolithic shader to allow scheduling divisions around
    * VBO loads. */
   if (prolog_key->instance_divisor_is_fetched)
      key->opt.prefer_mono = 1;

   unsigned count = MIN2(vs->info.num_inputs, elts->count);
   unsigned count_mask = (1 << count) - 1;
   unsigned fix = elts->fix_fetch_always & count_mask;
   unsigned opencode = elts->fix_fetch_opencode & count_mask;

   if (sctx->vertex_buffer_unaligned & elts->vb_alignment_check_mask) {
      uint32_t mask = elts->fix_fetch_unaligned & count_mask;
      while (mask) {
         unsigned i = u_bit_scan(&mask);
         unsigned log_hw_load_size = 1 + ((elts->hw_load_is_dword >> i) & 1);
         unsigned vbidx = elts->vertex_buffer_index[i];
         struct pipe_vertex_buffer *vb = &sctx->vertex_buffer[vbidx];
         unsigned align_mask = (1 << log_hw_load_size) - 1;
         if (vb->buffer_offset & align_mask || vb->stride & align_mask) {
            fix |= 1 << i;
            opencode |= 1 << i;
         }
      }
   }

   while (fix) {
      unsigned i = u_bit_scan(&fix);
      key->mono.vs_fix_fetch[i].bits = elts->fix_fetch[i];
   }
   key->mono.vs_fetch_opencode = opencode;
}

static void si_shader_selector_key_hw_vs(struct si_context *sctx, struct si_shader_selector *vs,
                                         struct si_shader_key *key)
{
   struct si_shader_selector *ps = sctx->ps_shader.cso;

   key->opt.clip_disable = sctx->queued.named.rasterizer->clip_plane_enable == 0 &&
                           (vs->info.clipdist_writemask || vs->info.writes_clipvertex) &&
                           !vs->info.culldist_writemask;

   /* Find out if PS is disabled. */
   bool ps_disabled = true;
   if (ps) {
      bool ps_modifies_zs = ps->info.uses_kill || ps->info.writes_z || ps->info.writes_stencil ||
                            ps->info.writes_samplemask ||
                            sctx->queued.named.blend->alpha_to_coverage ||
                            si_get_alpha_test_func(sctx) != PIPE_FUNC_ALWAYS;
      unsigned ps_colormask = si_get_total_colormask(sctx);

      ps_disabled = sctx->queued.named.rasterizer->rasterizer_discard ||
                    (!ps_colormask && !ps_modifies_zs && !ps->info.writes_memory);
   }

   /* Find out which VS outputs aren't used by the PS. */
   uint64_t outputs_written = vs->outputs_written_before_ps;
   uint64_t inputs_read = 0;

   /* Ignore outputs that are not passed from VS to PS. */
   outputs_written &= ~((1ull << si_shader_io_get_unique_index(VARYING_SLOT_POS, true)) |
                        (1ull << si_shader_io_get_unique_index(VARYING_SLOT_PSIZ, true)) |
                        (1ull << si_shader_io_get_unique_index(VARYING_SLOT_CLIP_VERTEX, true)));

   if (!ps_disabled) {
      inputs_read = ps->inputs_read;
   }

   uint64_t linked = outputs_written & inputs_read;

   key->opt.kill_outputs = ~linked & outputs_written;
   key->opt.ngg_culling = sctx->ngg_culling;
}

/* Compute the key for the hw shader variant */
static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_shader_selector *sel,
                                          union si_vgt_stages_key stages_key,
                                          struct si_shader_key *key)
{
   struct si_context *sctx = (struct si_context *)ctx;

   memset(key, 0, sizeof(*key));

   switch (sel->info.stage) {
   case MESA_SHADER_VERTEX:
      si_shader_selector_key_vs(sctx, sel, key, &key->part.vs.prolog);

      if (sctx->tes_shader.cso)
         key->as_ls = 1;
      else if (sctx->gs_shader.cso) {
         key->as_es = 1;
         key->as_ngg = stages_key.u.ngg;
      } else {
         key->as_ngg = stages_key.u.ngg;
         si_shader_selector_key_hw_vs(sctx, sel, key);

         if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
            key->mono.u.vs_export_prim_id = 1;
      }
      break;
   case MESA_SHADER_TESS_CTRL:
      if (sctx->chip_class >= GFX9) {
         si_shader_selector_key_vs(sctx, sctx->vs_shader.cso, key, &key->part.tcs.ls_prolog);
         key->part.tcs.ls = sctx->vs_shader.cso;

         /* When the LS VGPR fix is needed, monolithic shaders
          * can:
          *  - avoid initializing EXEC in both the LS prolog
          *    and the LS main part when !vs_needs_prolog
          *  - remove the fixup for unused input VGPRs
          */
         key->part.tcs.ls_prolog.ls_vgpr_fix = sctx->ls_vgpr_fix;

         /* The LS output / HS input layout can be communicated
          * directly instead of via user SGPRs for merged LS-HS.
          * The LS VGPR fix prefers this too.
          */
         key->opt.prefer_mono = 1;
      }

      key->part.tcs.epilog.prim_mode =
         sctx->tes_shader.cso->info.base.tess.primitive_mode;
      key->part.tcs.epilog.invoc0_tess_factors_are_def =
         sel->info.tessfactors_are_def_in_all_invocs;
      key->part.tcs.epilog.tes_reads_tess_factors = sctx->tes_shader.cso->info.reads_tess_factors;

      if (sel == sctx->fixed_func_tcs_shader.cso)
         key->mono.u.ff_tcs_inputs_to_copy = sctx->vs_shader.cso->outputs_written;
      break;
   case MESA_SHADER_TESS_EVAL:
      key->as_ngg = stages_key.u.ngg;

      if (sctx->gs_shader.cso)
         key->as_es = 1;
      else {
         si_shader_selector_key_hw_vs(sctx, sel, key);

         if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
            key->mono.u.vs_export_prim_id = 1;
      }
      break;
   case MESA_SHADER_GEOMETRY:
      if (sctx->chip_class >= GFX9) {
         if (sctx->tes_shader.cso) {
            key->part.gs.es = sctx->tes_shader.cso;
         } else {
            si_shader_selector_key_vs(sctx, sctx->vs_shader.cso, key, &key->part.gs.vs_prolog);
            key->part.gs.es = sctx->vs_shader.cso;
            key->part.gs.prolog.gfx9_prev_is_vs = 1;
         }

         key->as_ngg = stages_key.u.ngg;

         /* Merged ES-GS can have unbalanced wave usage.
          *
          * ES threads are per-vertex, while GS threads are
          * per-primitive. So without any amplification, there
          * are fewer GS threads than ES threads, which can result
          * in empty (no-op) GS waves. With too much amplification,
          * there are more GS threads than ES threads, which
          * can result in empty (no-op) ES waves.
          *
          * Non-monolithic shaders are implemented by setting EXEC
          * at the beginning of shader parts, and don't jump to
          * the end if EXEC is 0.
          *
          * Monolithic shaders use conditional blocks, so they can
          * jump and skip empty waves of ES or GS. So set this to
          * always use optimized variants, which are monolithic.
          */
         key->opt.prefer_mono = 1;
      }
      key->part.gs.prolog.tri_strip_adj_fix = sctx->gs_tri_strip_adj_fix;
      break;
   case MESA_SHADER_FRAGMENT: {
      struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
      struct si_state_blend *blend = sctx->queued.named.blend;

      if (sel->info.color0_writes_all_cbufs &&
          sel->info.colors_written == 0x1)
         key->part.ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1;

      /* Select the shader color format based on whether
       * blending or alpha are needed.
       */
      key->part.ps.epilog.spi_shader_col_format =
         (blend->blend_enable_4bit & blend->need_src_alpha_4bit &
          sctx->framebuffer.spi_shader_col_format_blend_alpha) |
         (blend->blend_enable_4bit & ~blend->need_src_alpha_4bit &
          sctx->framebuffer.spi_shader_col_format_blend) |
         (~blend->blend_enable_4bit & blend->need_src_alpha_4bit &
          sctx->framebuffer.spi_shader_col_format_alpha) |
         (~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit &
          sctx->framebuffer.spi_shader_col_format);
      key->part.ps.epilog.spi_shader_col_format &= blend->cb_target_enabled_4bit;

      /* The output for dual source blending should have
       * the same format as the first output.
       */
      if (blend->dual_src_blend) {
         key->part.ps.epilog.spi_shader_col_format |=
            (key->part.ps.epilog.spi_shader_col_format & 0xf) << 4;
      }

      /* If alpha-to-coverage is enabled, we have to export alpha
       * even if there is no color buffer.
       */
      if (!(key->part.ps.epilog.spi_shader_col_format & 0xf) && blend->alpha_to_coverage)
         key->part.ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_32_AR;

      /* On GFX6 and GFX7 except Hawaii, the CB doesn't clamp outputs
       * to the range supported by the type if a channel has less
       * than 16 bits and the export format is 16_ABGR.
       */
      if (sctx->chip_class <= GFX7 && sctx->family != CHIP_HAWAII) {
         key->part.ps.epilog.color_is_int8 = sctx->framebuffer.color_is_int8;
         key->part.ps.epilog.color_is_int10 = sctx->framebuffer.color_is_int10;
      }

      /* Disable unwritten outputs (if WRITE_ALL_CBUFS isn't enabled). */
      if (!key->part.ps.epilog.last_cbuf) {
         key->part.ps.epilog.spi_shader_col_format &= sel->colors_written_4bit;
         key->part.ps.epilog.color_is_int8 &= sel->info.colors_written;
         key->part.ps.epilog.color_is_int10 &= sel->info.colors_written;
      }

      bool is_poly = !util_prim_is_points_or_lines(sctx->current_rast_prim);
      bool is_line = util_prim_is_lines(sctx->current_rast_prim);

      key->part.ps.prolog.color_two_side = rs->two_side && sel->info.colors_read;
      key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.colors_read;

      key->part.ps.epilog.alpha_to_one = blend->alpha_to_one && rs->multisample_enable;

      key->part.ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly;
      key->part.ps.epilog.poly_line_smoothing =
         ((is_poly && rs->poly_smooth) || (is_line && rs->line_smooth)) &&
         sctx->framebuffer.nr_samples <= 1;
      key->part.ps.epilog.clamp_color = rs->clamp_fragment_color;

      if (sctx->ps_iter_samples > 1 && sel->info.reads_samplemask) {
         key->part.ps.prolog.samplemask_log_ps_iter = util_logbase2(sctx->ps_iter_samples);
      }

      if (rs->force_persample_interp && rs->multisample_enable &&
          sctx->framebuffer.nr_samples > 1 && sctx->ps_iter_samples > 1) {
         key->part.ps.prolog.force_persp_sample_interp =
            sel->info.uses_persp_center || sel->info.uses_persp_centroid;

         key->part.ps.prolog.force_linear_sample_interp =
            sel->info.uses_linear_center || sel->info.uses_linear_centroid;
      } else if (rs->multisample_enable && sctx->framebuffer.nr_samples > 1) {
         key->part.ps.prolog.bc_optimize_for_persp =
            sel->info.uses_persp_center && sel->info.uses_persp_centroid;
         key->part.ps.prolog.bc_optimize_for_linear =
            sel->info.uses_linear_center && sel->info.uses_linear_centroid;
      } else {
         /* Make sure SPI doesn't compute more than 1 pair
          * of (i,j), which is the optimization here. */
         key->part.ps.prolog.force_persp_center_interp = sel->info.uses_persp_center +
                                                            sel->info.uses_persp_centroid +
                                                            sel->info.uses_persp_sample >
                                                         1;

         key->part.ps.prolog.force_linear_center_interp = sel->info.uses_linear_center +
                                                             sel->info.uses_linear_centroid +
                                                             sel->info.uses_linear_sample >
                                                          1;

         if (sel->info.uses_persp_opcode_interp_sample ||
             sel->info.uses_linear_opcode_interp_sample)
            key->mono.u.ps.interpolate_at_sample_force_center = 1;
      }

      key->part.ps.epilog.alpha_func = si_get_alpha_test_func(sctx);

      /* ps_uses_fbfetch is true only if the color buffer is bound. */
      if (sctx->ps_uses_fbfetch && !sctx->blitter->running) {
         struct pipe_surface *cb0 = sctx->framebuffer.state.cbufs[0];
         struct pipe_resource *tex = cb0->texture;

         /* 1D textures are allocated and used as 2D on GFX9. */
         key->mono.u.ps.fbfetch_msaa = sctx->framebuffer.nr_samples > 1;
         key->mono.u.ps.fbfetch_is_1D =
            sctx->chip_class != GFX9 &&
            (tex->target == PIPE_TEXTURE_1D || tex->target == PIPE_TEXTURE_1D_ARRAY);
         key->mono.u.ps.fbfetch_layered =
            tex->target == PIPE_TEXTURE_1D_ARRAY || tex->target == PIPE_TEXTURE_2D_ARRAY ||
            tex->target == PIPE_TEXTURE_CUBE || tex->target == PIPE_TEXTURE_CUBE_ARRAY ||
            tex->target == PIPE_TEXTURE_3D;
      }
      break;
   }
   default:
      assert(0);
   }

   if (unlikely(sctx->screen->debug_flags & DBG(NO_OPT_VARIANT)))
      memset(&key->opt, 0, sizeof(key->opt));
}

static void si_build_shader_variant(struct si_shader *shader, int thread_index, bool low_priority)
{
   struct si_shader_selector *sel = shader->selector;
   struct si_screen *sscreen = sel->screen;
   struct ac_llvm_compiler *compiler;
   struct pipe_debug_callback *debug = &shader->compiler_ctx_state.debug;

   if (thread_index >= 0) {
      if (low_priority) {
         assert(thread_index < ARRAY_SIZE(sscreen->compiler_lowp));
         compiler = &sscreen->compiler_lowp[thread_index];
      } else {
         assert(thread_index < ARRAY_SIZE(sscreen->compiler));
         compiler = &sscreen->compiler[thread_index];
      }
      if (!debug->async)
         debug = NULL;
   } else {
      assert(!low_priority);
      compiler = shader->compiler_ctx_state.compiler;
   }

   if (!compiler->passes)
      si_init_compiler(sscreen, compiler);

   if (unlikely(!si_create_shader_variant(sscreen, compiler, shader, debug))) {
      PRINT_ERR("Failed to build shader variant (type=%u)\n", sel->info.stage);
      shader->compilation_failed = true;
      return;
   }

   if (shader->compiler_ctx_state.is_debug_context) {
      FILE *f = open_memstream(&shader->shader_log, &shader->shader_log_size);
      if (f) {
         si_shader_dump(sscreen, shader, NULL, f, false);
         fclose(f);
      }
   }

   si_shader_init_pm4_state(sscreen, shader);
}

static void si_build_shader_variant_low_priority(void *job, int thread_index)
{
   struct si_shader *shader = (struct si_shader *)job;

   assert(thread_index >= 0);

   si_build_shader_variant(shader, thread_index, true);
}

static const struct si_shader_key zeroed;

static bool si_check_missing_main_part(struct si_screen *sscreen, struct si_shader_selector *sel,
                                       struct si_compiler_ctx_state *compiler_state,
                                       struct si_shader_key *key)
{
   struct si_shader **mainp = si_get_main_shader_part(sel, key);

   if (!*mainp) {
      struct si_shader *main_part = CALLOC_STRUCT(si_shader);

      if (!main_part)
         return false;

      /* We can leave the fence as permanently signaled because the
       * main part becomes visible globally only after it has been
       * compiled. */
      util_queue_fence_init(&main_part->ready);

      main_part->selector = sel;
      main_part->key.as_es = key->as_es;
      main_part->key.as_ls = key->as_ls;
      main_part->key.as_ngg = key->as_ngg;
      main_part->is_monolithic = false;

      if (!si_compile_shader(sscreen, compiler_state->compiler, main_part,
                             &compiler_state->debug)) {
         FREE(main_part);
         return false;
      }
      *mainp = main_part;
   }
   return true;
}

/**
 * Select a shader variant according to the shader key.
 *
 * \param optimized_or_none  If the key describes an optimized shader variant and
 *                           the compilation isn't finished, don't select any
 *                           shader and return an error.
 */
int si_shader_select_with_key(struct si_screen *sscreen, struct si_shader_ctx_state *state,
                              struct si_compiler_ctx_state *compiler_state,
                              struct si_shader_key *key, int thread_index, bool optimized_or_none)
{
   struct si_shader_selector *sel = state->cso;
   struct si_shader_selector *previous_stage_sel = NULL;
   struct si_shader *current = state->current;
   struct si_shader *iter, *shader = NULL;

again:
   /* Check if we don't need to change anything.
    * This path is also used for most shaders that don't need multiple
    * variants, it will cost just a computation of the key and this
    * test. */
   if (likely(current && memcmp(&current->key, key, sizeof(*key)) == 0)) {
      if (unlikely(!util_queue_fence_is_signalled(&current->ready))) {
         if (current->is_optimized) {
            if (optimized_or_none)
               return -1;

            memset(&key->opt, 0, sizeof(key->opt));
            goto current_not_ready;
         }

         util_queue_fence_wait(&current->ready);
      }

      return current->compilation_failed ? -1 : 0;
   }
current_not_ready:

   /* This must be done before the mutex is locked, because async GS
    * compilation calls this function too, and therefore must enter
    * the mutex first.
    *
    * Only wait if we are in a draw call. Don't wait if we are
    * in a compiler thread.
    */
   if (thread_index < 0)
      util_queue_fence_wait(&sel->ready);

   simple_mtx_lock(&sel->mutex);

   /* Find the shader variant. */
   for (iter = sel->first_variant; iter; iter = iter->next_variant) {
      /* Don't check the "current" shader. We checked it above. */
      if (current != iter && memcmp(&iter->key, key, sizeof(*key)) == 0) {
         simple_mtx_unlock(&sel->mutex);

         if (unlikely(!util_queue_fence_is_signalled(&iter->ready))) {
            /* If it's an optimized shader and its compilation has
             * been started but isn't done, use the unoptimized
             * shader so as not to cause a stall due to compilation.
             */
            if (iter->is_optimized) {
               if (optimized_or_none)
                  return -1;
               memset(&key->opt, 0, sizeof(key->opt));
               goto again;
            }

            util_queue_fence_wait(&iter->ready);
         }

         if (iter->compilation_failed) {
            return -1; /* skip the draw call */
         }

         state->current = iter;
         return 0;
      }
   }

   /* Build a new shader. */
   shader = CALLOC_STRUCT(si_shader);
   if (!shader) {
      simple_mtx_unlock(&sel->mutex);
      return -ENOMEM;
   }

   util_queue_fence_init(&shader->ready);

   shader->selector = sel;
   shader->key = *key;
   shader->compiler_ctx_state = *compiler_state;

   /* If this is a merged shader, get the first shader's selector. */
   if (sscreen->info.chip_class >= GFX9) {
      if (sel->info.stage == MESA_SHADER_TESS_CTRL)
         previous_stage_sel = key->part.tcs.ls;
      else if (sel->info.stage == MESA_SHADER_GEOMETRY)
         previous_stage_sel = key->part.gs.es;

      /* We need to wait for the previous shader. */
      if (previous_stage_sel && thread_index < 0)
         util_queue_fence_wait(&previous_stage_sel->ready);
   }

   bool is_pure_monolithic =
      sscreen->use_monolithic_shaders || memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0;

   /* Compile the main shader part if it doesn't exist. This can happen
    * if the initial guess was wrong.
    *
    * The prim discard CS doesn't need the main shader part.
    */
   if (!is_pure_monolithic && !key->opt.vs_as_prim_discard_cs) {
      bool ok = true;

      /* Make sure the main shader part is present. This is needed
       * for shaders that can be compiled as VS, LS, or ES, and only
       * one of them is compiled at creation.
       *
       * It is also needed for GS, which can be compiled as non-NGG
       * and NGG.
       *
       * For merged shaders, check that the starting shader's main
       * part is present.
       */
      if (previous_stage_sel) {
         struct si_shader_key shader1_key = zeroed;

         if (sel->info.stage == MESA_SHADER_TESS_CTRL) {
            shader1_key.as_ls = 1;
         } else if (sel->info.stage == MESA_SHADER_GEOMETRY) {
            shader1_key.as_es = 1;
            shader1_key.as_ngg = key->as_ngg; /* for Wave32 vs Wave64 */
         } else {
            assert(0);
         }

         simple_mtx_lock(&previous_stage_sel->mutex);
         ok = si_check_missing_main_part(sscreen, previous_stage_sel, compiler_state, &shader1_key);
         simple_mtx_unlock(&previous_stage_sel->mutex);
      }

      if (ok) {
         ok = si_check_missing_main_part(sscreen, sel, compiler_state, key);
      }

      if (!ok) {
         FREE(shader);
         simple_mtx_unlock(&sel->mutex);
         return -ENOMEM; /* skip the draw call */
      }
   }

   /* Keep the reference to the 1st shader of merged shaders, so that
    * Gallium can't destroy it before we destroy the 2nd shader.
    *
    * Set sctx = NULL, because it's unused if we're not releasing
    * the shader, and we don't have any sctx here.
    */
   si_shader_selector_reference(NULL, &shader->previous_stage_sel, previous_stage_sel);

   /* Monolithic-only shaders don't make a distinction between optimized
    * and unoptimized. */
   shader->is_monolithic =
      is_pure_monolithic || memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;

   /* The prim discard CS is always optimized. */
   shader->is_optimized = (!is_pure_monolithic || key->opt.vs_as_prim_discard_cs) &&
                          memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;

   /* If it's an optimized shader, compile it asynchronously. */
   if (shader->is_optimized && thread_index < 0) {
      /* Compile it asynchronously. */
      util_queue_add_job(&sscreen->shader_compiler_queue_low_priority, shader, &shader->ready,
                         si_build_shader_variant_low_priority, NULL, 0);

      /* Add only after the ready fence was reset, to guard against a
       * race with si_bind_XX_shader. */
      if (!sel->last_variant) {
         sel->first_variant = shader;
         sel->last_variant = shader;
      } else {
         sel->last_variant->next_variant = shader;
         sel->last_variant = shader;
      }

      /* Use the default (unoptimized) shader for now. */
      memset(&key->opt, 0, sizeof(key->opt));
      simple_mtx_unlock(&sel->mutex);

      if (sscreen->options.sync_compile)
         util_queue_fence_wait(&shader->ready);

      if (optimized_or_none)
         return -1;
      goto again;
   }

   /* Reset the fence before adding to the variant list. */
   util_queue_fence_reset(&shader->ready);

   if (!sel->last_variant) {
      sel->first_variant = shader;
      sel->last_variant = shader;
   } else {
      sel->last_variant->next_variant = shader;
      sel->last_variant = shader;
   }

   simple_mtx_unlock(&sel->mutex);

   assert(!shader->is_optimized);
   si_build_shader_variant(shader, thread_index, false);

   util_queue_fence_signal(&shader->ready);

   if (!shader->compilation_failed)
      state->current = shader;

   return shader->compilation_failed ? -1 : 0;
}

static int si_shader_select(struct pipe_context *ctx, struct si_shader_ctx_state *state,
                            union si_vgt_stages_key stages_key,
                            struct si_compiler_ctx_state *compiler_state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_key key;

   si_shader_selector_key(ctx, state->cso, stages_key, &key);
   return si_shader_select_with_key(sctx->screen, state, compiler_state, &key, -1, false);
}

static void si_parse_next_shader_property(const struct si_shader_info *info, bool streamout,
                                          struct si_shader_key *key)
{
   gl_shader_stage next_shader = info->base.next_stage;

   switch (info->stage) {
   case MESA_SHADER_VERTEX:
      switch (next_shader) {
      case MESA_SHADER_GEOMETRY:
         key->as_es = 1;
         break;
      case MESA_SHADER_TESS_CTRL:
      case MESA_SHADER_TESS_EVAL:
         key->as_ls = 1;
         break;
      default:
         /* If POSITION isn't written, it can only be a HW VS
          * if streamout is used. If streamout isn't used,
          * assume that it's a HW LS. (the next shader is TCS)
          * This heuristic is needed for separate shader objects.
          */
         if (!info->writes_position && !streamout)
            key->as_ls = 1;
      }
      break;

   case MESA_SHADER_TESS_EVAL:
      if (next_shader == MESA_SHADER_GEOMETRY || !info->writes_position)
         key->as_es = 1;
      break;

   default:;
   }
}

/**
 * Compile the main shader part or the monolithic shader as part of
 * si_shader_selector initialization. Since it can be done asynchronously,
 * there is no way to report compile failures to applications.
 */
static void si_init_shader_selector_async(void *job, int thread_index)
{
   struct si_shader_selector *sel = (struct si_shader_selector *)job;
   struct si_screen *sscreen = sel->screen;
   struct ac_llvm_compiler *compiler;
   struct pipe_debug_callback *debug = &sel->compiler_ctx_state.debug;

   assert(!debug->debug_message || debug->async);
   assert(thread_index >= 0);
   assert(thread_index < ARRAY_SIZE(sscreen->compiler));
   compiler = &sscreen->compiler[thread_index];

   if (!compiler->passes)
      si_init_compiler(sscreen, compiler);

   /* Serialize NIR to save memory. Monolithic shader variants
    * have to deserialize NIR before compilation.
    */
   if (sel->nir) {
      struct blob blob;
      size_t size;

      blob_init(&blob);
      /* true = remove optional debugging data to increase
       * the likehood of getting more shader cache hits.
       * It also drops variable names, so we'll save more memory.
       */
      nir_serialize(&blob, sel->nir, true);
      blob_finish_get_buffer(&blob, &sel->nir_binary, &size);
      sel->nir_size = size;
   }

   /* Compile the main shader part for use with a prolog and/or epilog.
    * If this fails, the driver will try to compile a monolithic shader
    * on demand.
    */
   if (!sscreen->use_monolithic_shaders) {
      struct si_shader *shader = CALLOC_STRUCT(si_shader);
      unsigned char ir_sha1_cache_key[20];

      if (!shader) {
         fprintf(stderr, "radeonsi: can't allocate a main shader part\n");
         return;
      }

      /* We can leave the fence signaled because use of the default
       * main part is guarded by the selector's ready fence. */
      util_queue_fence_init(&shader->ready);

      shader->selector = sel;
      shader->is_monolithic = false;
      si_parse_next_shader_property(&sel->info, sel->so.num_outputs != 0, &shader->key);

      if (sscreen->use_ngg && (!sel->so.num_outputs || sscreen->use_ngg_streamout) &&
          ((sel->info.stage == MESA_SHADER_VERTEX && !shader->key.as_ls) ||
           sel->info.stage == MESA_SHADER_TESS_EVAL || sel->info.stage == MESA_SHADER_GEOMETRY))
         shader->key.as_ngg = 1;

      if (sel->nir) {
         si_get_ir_cache_key(sel, shader->key.as_ngg, shader->key.as_es, ir_sha1_cache_key);
      }

      /* Try to load the shader from the shader cache. */
      simple_mtx_lock(&sscreen->shader_cache_mutex);

      if (si_shader_cache_load_shader(sscreen, ir_sha1_cache_key, shader)) {
         simple_mtx_unlock(&sscreen->shader_cache_mutex);
         si_shader_dump_stats_for_shader_db(sscreen, shader, debug);
      } else {
         simple_mtx_unlock(&sscreen->shader_cache_mutex);

         /* Compile the shader if it hasn't been loaded from the cache. */
         if (!si_compile_shader(sscreen, compiler, shader, debug)) {
            FREE(shader);
            fprintf(stderr, "radeonsi: can't compile a main shader part\n");
            return;
         }

         simple_mtx_lock(&sscreen->shader_cache_mutex);
         si_shader_cache_insert_shader(sscreen, ir_sha1_cache_key, shader, true);
         simple_mtx_unlock(&sscreen->shader_cache_mutex);
      }

      *si_get_main_shader_part(sel, &shader->key) = shader;

      /* Unset "outputs_written" flags for outputs converted to
       * DEFAULT_VAL, so that later inter-shader optimizations don't
       * try to eliminate outputs that don't exist in the final
       * shader.
       *
       * This is only done if non-monolithic shaders are enabled.
       */
      if ((sel->info.stage == MESA_SHADER_VERTEX || sel->info.stage == MESA_SHADER_TESS_EVAL) &&
          !shader->key.as_ls && !shader->key.as_es) {
         unsigned i;

         for (i = 0; i < sel->info.num_outputs; i++) {
            unsigned offset = shader->info.vs_output_param_offset[i];

            if (offset <= AC_EXP_PARAM_OFFSET_31)
               continue;

            unsigned semantic = sel->info.output_semantic[i];
            unsigned id;

            if (semantic < VARYING_SLOT_MAX &&
                semantic != VARYING_SLOT_POS &&
                semantic != VARYING_SLOT_PSIZ &&
                semantic != VARYING_SLOT_CLIP_VERTEX &&
                semantic != VARYING_SLOT_EDGE) {
               id = si_shader_io_get_unique_index(semantic, true);
               sel->outputs_written_before_ps &= ~(1ull << id);
            }
         }
      }
   }

   /* The GS copy shader is always pre-compiled. */
   if (sel->info.stage == MESA_SHADER_GEOMETRY &&
       (!sscreen->use_ngg || !sscreen->use_ngg_streamout || /* also for PRIMITIVES_GENERATED */
        sel->tess_turns_off_ngg)) {
      sel->gs_copy_shader = si_generate_gs_copy_shader(sscreen, compiler, sel, debug);
      if (!sel->gs_copy_shader) {
         fprintf(stderr, "radeonsi: can't create GS copy shader\n");
         return;
      }

      si_shader_vs(sscreen, sel->gs_copy_shader, sel);
   }

   /* Free NIR. We only keep serialized NIR after this point. */
   if (sel->nir) {
      ralloc_free(sel->nir);
      sel->nir = NULL;
   }
}

void si_schedule_initial_compile(struct si_context *sctx, gl_shader_stage stage,
                                 struct util_queue_fence *ready_fence,
                                 struct si_compiler_ctx_state *compiler_ctx_state, void *job,
                                 util_queue_execute_func execute)
{
   util_queue_fence_init(ready_fence);

   struct util_async_debug_callback async_debug;
   bool debug = (sctx->debug.debug_message && !sctx->debug.async) || sctx->is_debug ||
                si_can_dump_shader(sctx->screen, stage);

   if (debug) {
      u_async_debug_init(&async_debug);
      compiler_ctx_state->debug = async_debug.base;
   }

   util_queue_add_job(&sctx->screen->shader_compiler_queue, job, ready_fence, execute, NULL, 0);

   if (debug) {
      util_queue_fence_wait(ready_fence);
      u_async_debug_drain(&async_debug, &sctx->debug);
      u_async_debug_cleanup(&async_debug);
   }

   if (sctx->screen->options.sync_compile)
      util_queue_fence_wait(ready_fence);
}

/* Return descriptor slot usage masks from the given shader info. */
void si_get_active_slot_masks(const struct si_shader_info *info, uint64_t *const_and_shader_buffers,
                              uint64_t *samplers_and_images)
{
   unsigned start, num_shaderbufs, num_constbufs, num_images, num_msaa_images, num_samplers;

   num_shaderbufs = info->base.num_ssbos;
   num_constbufs = info->base.num_ubos;
   /* two 8-byte images share one 16-byte slot */
   num_images = align(info->base.num_images, 2);
   num_msaa_images = align(util_last_bit(info->base.msaa_images), 2);
   num_samplers = util_last_bit(info->base.textures_used);

   /* The layout is: sb[last] ... sb[0], cb[0] ... cb[last] */
   start = si_get_shaderbuf_slot(num_shaderbufs - 1);
   *const_and_shader_buffers = u_bit_consecutive64(start, num_shaderbufs + num_constbufs);

   /* The layout is:
    *   - fmask[last] ... fmask[0]     go to [15-last .. 15]
    *   - image[last] ... image[0]     go to [31-last .. 31]
    *   - sampler[0] ... sampler[last] go to [32 .. 32+last*2]
    *
    * FMASKs for images are placed separately, because MSAA images are rare,
    * and so we can benefit from a better cache hit rate if we keep image
    * descriptors together.
    */
   if (num_msaa_images)
      num_images = SI_NUM_IMAGES + num_msaa_images; /* add FMASK descriptors */

   start = si_get_image_slot(num_images - 1) / 2;
   *samplers_and_images = u_bit_consecutive64(start, num_images / 2 + num_samplers);
}

static void *si_create_shader_selector(struct pipe_context *ctx,
                                       const struct pipe_shader_state *state)
{
   struct si_screen *sscreen = (struct si_screen *)ctx->screen;
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *sel = CALLOC_STRUCT(si_shader_selector);
   int i;

   if (!sel)
      return NULL;

   sel->screen = sscreen;
   sel->compiler_ctx_state.debug = sctx->debug;
   sel->compiler_ctx_state.is_debug_context = sctx->is_debug;

   sel->so = state->stream_output;

   if (state->type == PIPE_SHADER_IR_TGSI) {
      sel->nir = tgsi_to_nir(state->tokens, ctx->screen, true);
   } else {
      assert(state->type == PIPE_SHADER_IR_NIR);
      sel->nir = state->ir.nir;
   }

   si_nir_scan_shader(sel->nir, &sel->info);

   const enum pipe_shader_type type = pipe_shader_type_from_mesa(sel->info.stage);
   sel->const_and_shader_buf_descriptors_index =
      si_const_and_shader_buffer_descriptors_idx(type);
   sel->sampler_and_images_descriptors_index =
      si_sampler_and_image_descriptors_idx(type);

   p_atomic_inc(&sscreen->num_shaders_created);
   si_get_active_slot_masks(&sel->info, &sel->active_const_and_shader_buffers,
                            &sel->active_samplers_and_images);

   /* Record which streamout buffers are enabled. */
   for (i = 0; i < sel->so.num_outputs; i++) {
      sel->enabled_streamout_buffer_mask |= (1 << sel->so.output[i].output_buffer)
                                            << (sel->so.output[i].stream * 4);
   }

   sel->num_vs_inputs =
      sel->info.stage == MESA_SHADER_VERTEX && !sel->info.base.vs.blit_sgprs_amd
         ? sel->info.num_inputs
         : 0;
   sel->num_vbos_in_user_sgprs = MIN2(sel->num_vs_inputs, sscreen->num_vbos_in_user_sgprs);

   /* The prolog is a no-op if there are no inputs. */
   sel->vs_needs_prolog = sel->info.stage == MESA_SHADER_VERTEX && sel->info.num_inputs &&
                          !sel->info.base.vs.blit_sgprs_amd;

   sel->prim_discard_cs_allowed =
      sel->info.stage == MESA_SHADER_VERTEX && !sel->info.uses_bindless_images &&
      !sel->info.uses_bindless_samplers && !sel->info.writes_memory &&
      !sel->info.writes_viewport_index &&
      !sel->info.base.vs.window_space_position && !sel->so.num_outputs;

   switch (sel->info.stage) {
   case MESA_SHADER_GEOMETRY:
      sel->gs_output_prim = sel->info.base.gs.output_primitive;

      /* Only possibilities: POINTS, LINE_STRIP, TRIANGLES */
      sel->rast_prim = sel->gs_output_prim;
      if (util_rast_prim_is_triangles(sel->rast_prim))
         sel->rast_prim = PIPE_PRIM_TRIANGLES;

      sel->gs_max_out_vertices = sel->info.base.gs.vertices_out;
      sel->gs_num_invocations = sel->info.base.gs.invocations;
      sel->gsvs_vertex_size = sel->info.num_outputs * 16;
      sel->max_gsvs_emit_size = sel->gsvs_vertex_size * sel->gs_max_out_vertices;

      sel->max_gs_stream = 0;
      for (i = 0; i < sel->so.num_outputs; i++)
         sel->max_gs_stream = MAX2(sel->max_gs_stream, sel->so.output[i].stream);

      sel->gs_input_verts_per_prim =
         u_vertices_per_prim(sel->info.base.gs.input_primitive);

      /* EN_MAX_VERT_OUT_PER_GS_INSTANCE does not work with tesselation so
       * we can't split workgroups. Disable ngg if any of the following conditions is true:
       * - num_invocations * gs_max_out_vertices > 256
       * - LDS usage is too high
       */
      sel->tess_turns_off_ngg = sscreen->info.chip_class >= GFX10 &&
                                (sel->gs_num_invocations * sel->gs_max_out_vertices > 256 ||
                                 sel->gs_num_invocations * sel->gs_max_out_vertices *
                                 (sel->info.num_outputs * 4 + 1) > 6500 /* max dw per GS primitive */);
      break;

   case MESA_SHADER_TESS_CTRL:
      /* Always reserve space for these. */
      sel->patch_outputs_written |=
         (1ull << si_shader_io_get_unique_index_patch(VARYING_SLOT_TESS_LEVEL_INNER)) |
         (1ull << si_shader_io_get_unique_index_patch(VARYING_SLOT_TESS_LEVEL_OUTER));
      /* fall through */
   case MESA_SHADER_VERTEX:
   case MESA_SHADER_TESS_EVAL:
      for (i = 0; i < sel->info.num_outputs; i++) {
         unsigned semantic = sel->info.output_semantic[i];

         if (semantic == VARYING_SLOT_TESS_LEVEL_INNER ||
             semantic == VARYING_SLOT_TESS_LEVEL_OUTER ||
             (semantic >= VARYING_SLOT_PATCH0 && semantic < VARYING_SLOT_TESS_MAX)) {
            sel->patch_outputs_written |= 1ull << si_shader_io_get_unique_index_patch(semantic);
         } else if (semantic < VARYING_SLOT_MAX &&
                    semantic != VARYING_SLOT_EDGE) {
            sel->outputs_written |= 1ull << si_shader_io_get_unique_index(semantic, false);
            sel->outputs_written_before_ps |= 1ull
                                              << si_shader_io_get_unique_index(semantic, true);
         }
      }
      sel->esgs_itemsize = util_last_bit64(sel->outputs_written) * 16;
      sel->lshs_vertex_stride = sel->esgs_itemsize;

      /* Add 1 dword to reduce LDS bank conflicts, so that each vertex
       * will start on a different bank. (except for the maximum 32*16).
       */
      if (sel->lshs_vertex_stride < 32 * 16)
         sel->lshs_vertex_stride += 4;

      /* For the ESGS ring in LDS, add 1 dword to reduce LDS bank
       * conflicts, i.e. each vertex will start at a different bank.
       */
      if (sctx->chip_class >= GFX9)
         sel->esgs_itemsize += 4;

      assert(((sel->esgs_itemsize / 4) & C_028AAC_ITEMSIZE) == 0);

      /* Only for TES: */
      if (sel->info.stage == MESA_SHADER_TESS_EVAL) {
         if (sel->info.base.tess.point_mode)
            sel->rast_prim = PIPE_PRIM_POINTS;
         else if (sel->info.base.tess.primitive_mode == GL_LINES)
            sel->rast_prim = PIPE_PRIM_LINE_STRIP;
         else
            sel->rast_prim = PIPE_PRIM_TRIANGLES;
      } else {
         sel->rast_prim = PIPE_PRIM_TRIANGLES;
      }
      break;

   case MESA_SHADER_FRAGMENT:
      for (i = 0; i < sel->info.num_inputs; i++) {
         unsigned semantic = sel->info.input_semantic[i];

         if (semantic < VARYING_SLOT_MAX &&
             semantic != VARYING_SLOT_PNTC) {
            sel->inputs_read |= 1ull << si_shader_io_get_unique_index(semantic, true);
         }
      }

      for (i = 0; i < 8; i++)
         if (sel->info.colors_written & (1 << i))
            sel->colors_written_4bit |= 0xf << (4 * i);

      for (i = 0; i < sel->info.num_inputs; i++) {
         if (sel->info.input_semantic[i] == VARYING_SLOT_COL0)
            sel->color_attr_index[0] = i;
         else if (sel->info.input_semantic[i] == VARYING_SLOT_COL1)
            sel->color_attr_index[1] = i;
      }
      break;
   default:;
   }

   sel->ngg_culling_allowed =
      sscreen->info.chip_class >= GFX10 &&
      sscreen->info.has_dedicated_vram &&
      sscreen->use_ngg_culling &&
      (sel->info.stage == MESA_SHADER_VERTEX ||
       (sel->info.stage == MESA_SHADER_TESS_EVAL &&
        (sscreen->always_use_ngg_culling_all ||
         sscreen->always_use_ngg_culling_tess))) &&
      sel->info.writes_position &&
      !sel->info.writes_viewport_index && /* cull only against viewport 0 */
      !sel->info.writes_memory && !sel->so.num_outputs &&
      (sel->info.stage != MESA_SHADER_VERTEX ||
       (!sel->info.base.vs.blit_sgprs_amd &&
        !sel->info.base.vs.window_space_position));

   /* PA_CL_VS_OUT_CNTL */
   if (sctx->chip_class <= GFX9)
      sel->pa_cl_vs_out_cntl = si_get_vs_out_cntl(sel, false);

   sel->clipdist_mask = sel->info.writes_clipvertex ? SIX_BITS : sel->info.clipdist_writemask;
   sel->culldist_mask = sel->info.culldist_writemask << sel->info.num_written_clipdistance;

   /* DB_SHADER_CONTROL */
   sel->db_shader_control = S_02880C_Z_EXPORT_ENABLE(sel->info.writes_z) |
                            S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(sel->info.writes_stencil) |
                            S_02880C_MASK_EXPORT_ENABLE(sel->info.writes_samplemask) |
                            S_02880C_KILL_ENABLE(sel->info.uses_kill);

   if (sel->info.stage == MESA_SHADER_FRAGMENT) {
      switch (sel->info.base.fs.depth_layout) {
      case FRAG_DEPTH_LAYOUT_GREATER:
         sel->db_shader_control |= S_02880C_CONSERVATIVE_Z_EXPORT(V_02880C_EXPORT_GREATER_THAN_Z);
         break;
      case FRAG_DEPTH_LAYOUT_LESS:
         sel->db_shader_control |= S_02880C_CONSERVATIVE_Z_EXPORT(V_02880C_EXPORT_LESS_THAN_Z);
         break;
      default:;
      }

      /* Z_ORDER, EXEC_ON_HIER_FAIL and EXEC_ON_NOOP should be set as following:
       *
       *   | early Z/S | writes_mem | allow_ReZ? |      Z_ORDER       | EXEC_ON_HIER_FAIL | EXEC_ON_NOOP
       * --|-----------|------------|------------|--------------------|-------------------|-------------
       * 1a|   false   |   false    |   true     | EarlyZ_Then_ReZ    |         0         |     0
       * 1b|   false   |   false    |   false    | EarlyZ_Then_LateZ  |         0         |     0
       * 2 |   false   |   true     |   n/a      |       LateZ        |         1         |     0
       * 3 |   true    |   false    |   n/a      | EarlyZ_Then_LateZ  |         0         |     0
       * 4 |   true    |   true     |   n/a      | EarlyZ_Then_LateZ  |         0         |     1
       *
       * In cases 3 and 4, HW will force Z_ORDER to EarlyZ regardless of what's set in the register.
       * In case 2, NOOP_CULL is a don't care field. In case 2, 3 and 4, ReZ doesn't make sense.
       *
       * Don't use ReZ without profiling !!!
       *
       * ReZ decreases performance by 15% in DiRT: Showdown on Ultra settings, which has pretty complex
       * shaders.
       */
      if (sel->info.base.fs.early_fragment_tests) {
         /* Cases 3, 4. */
         sel->db_shader_control |= S_02880C_DEPTH_BEFORE_SHADER(1) |
                                   S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z) |
                                   S_02880C_EXEC_ON_NOOP(sel->info.writes_memory);
      } else if (sel->info.writes_memory) {
         /* Case 2. */
         sel->db_shader_control |= S_02880C_Z_ORDER(V_02880C_LATE_Z) | S_02880C_EXEC_ON_HIER_FAIL(1);
      } else {
         /* Case 1. */
         sel->db_shader_control |= S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
      }

      if (sel->info.base.fs.post_depth_coverage)
         sel->db_shader_control |= S_02880C_PRE_SHADER_DEPTH_COVERAGE_ENABLE(1);
   }

   (void)simple_mtx_init(&sel->mutex, mtx_plain);

   si_schedule_initial_compile(sctx, sel->info.stage, &sel->ready, &sel->compiler_ctx_state,
                               sel, si_init_shader_selector_async);
   return sel;
}

static void *si_create_shader(struct pipe_context *ctx, const struct pipe_shader_state *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_screen *sscreen = (struct si_screen *)ctx->screen;
   bool cache_hit;
   struct si_shader_selector *sel = (struct si_shader_selector *)util_live_shader_cache_get(
      ctx, &sscreen->live_shader_cache, state, &cache_hit);

   if (sel && cache_hit && sctx->debug.debug_message) {
      if (sel->main_shader_part)
         si_shader_dump_stats_for_shader_db(sscreen, sel->main_shader_part, &sctx->debug);
      if (sel->main_shader_part_ls)
         si_shader_dump_stats_for_shader_db(sscreen, sel->main_shader_part_ls, &sctx->debug);
      if (sel->main_shader_part_es)
         si_shader_dump_stats_for_shader_db(sscreen, sel->main_shader_part_es, &sctx->debug);
      if (sel->main_shader_part_ngg)
         si_shader_dump_stats_for_shader_db(sscreen, sel->main_shader_part_ngg, &sctx->debug);
      if (sel->main_shader_part_ngg_es)
         si_shader_dump_stats_for_shader_db(sscreen, sel->main_shader_part_ngg_es, &sctx->debug);
   }
   return sel;
}

static void si_update_streamout_state(struct si_context *sctx)
{
   struct si_shader_selector *shader_with_so = si_get_vs(sctx)->cso;

   if (!shader_with_so)
      return;

   sctx->streamout.enabled_stream_buffers_mask = shader_with_so->enabled_streamout_buffer_mask;
   sctx->streamout.stride_in_dw = shader_with_so->so.stride;
}

static void si_update_clip_regs(struct si_context *sctx, struct si_shader_selector *old_hw_vs,
                                struct si_shader *old_hw_vs_variant,
                                struct si_shader_selector *next_hw_vs,
                                struct si_shader *next_hw_vs_variant)
{
   if (next_hw_vs &&
       (!old_hw_vs ||
        (old_hw_vs->info.stage == MESA_SHADER_VERTEX && old_hw_vs->info.base.vs.window_space_position) !=
        (next_hw_vs->info.stage == MESA_SHADER_VERTEX && next_hw_vs->info.base.vs.window_space_position) ||
        old_hw_vs->pa_cl_vs_out_cntl != next_hw_vs->pa_cl_vs_out_cntl ||
        old_hw_vs->clipdist_mask != next_hw_vs->clipdist_mask ||
        old_hw_vs->culldist_mask != next_hw_vs->culldist_mask || !old_hw_vs_variant ||
        !next_hw_vs_variant ||
        old_hw_vs_variant->key.opt.clip_disable != next_hw_vs_variant->key.opt.clip_disable))
      si_mark_atom_dirty(sctx, &sctx->atoms.s.clip_regs);
}

static void si_update_common_shader_state(struct si_context *sctx)
{
   sctx->uses_bindless_samplers = si_shader_uses_bindless_samplers(sctx->vs_shader.cso) ||
                                  si_shader_uses_bindless_samplers(sctx->gs_shader.cso) ||
                                  si_shader_uses_bindless_samplers(sctx->ps_shader.cso) ||
                                  si_shader_uses_bindless_samplers(sctx->tcs_shader.cso) ||
                                  si_shader_uses_bindless_samplers(sctx->tes_shader.cso);
   sctx->uses_bindless_images = si_shader_uses_bindless_images(sctx->vs_shader.cso) ||
                                si_shader_uses_bindless_images(sctx->gs_shader.cso) ||
                                si_shader_uses_bindless_images(sctx->ps_shader.cso) ||
                                si_shader_uses_bindless_images(sctx->tcs_shader.cso) ||
                                si_shader_uses_bindless_images(sctx->tes_shader.cso);
   sctx->do_update_shaders = true;
}

static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *old_hw_vs = si_get_vs(sctx)->cso;
   struct si_shader *old_hw_vs_variant = si_get_vs_state(sctx);
   struct si_shader_selector *sel = state;

   if (sctx->vs_shader.cso == sel)
      return;

   sctx->vs_shader.cso = sel;
   sctx->vs_shader.current = sel ? sel->first_variant : NULL;
   sctx->num_vs_blit_sgprs = sel ? sel->info.base.vs.blit_sgprs_amd : 0;

   if (si_update_ngg(sctx))
      si_shader_change_notify(sctx);

   si_update_common_shader_state(sctx);
   si_update_vs_viewport_state(sctx);
   si_set_active_descriptors_for_shader(sctx, sel);
   si_update_streamout_state(sctx);
   si_update_clip_regs(sctx, old_hw_vs, old_hw_vs_variant, si_get_vs(sctx)->cso,
                       si_get_vs_state(sctx));
}

static void si_update_tess_uses_prim_id(struct si_context *sctx)
{
   sctx->ia_multi_vgt_param_key.u.tess_uses_prim_id =
      (sctx->tes_shader.cso && sctx->tes_shader.cso->info.uses_primid) ||
      (sctx->tcs_shader.cso && sctx->tcs_shader.cso->info.uses_primid) ||
      (sctx->gs_shader.cso && sctx->gs_shader.cso->info.uses_primid) ||
      (sctx->ps_shader.cso && !sctx->gs_shader.cso && sctx->ps_shader.cso->info.uses_primid);
}

bool si_update_ngg(struct si_context *sctx)
{
   if (!sctx->screen->use_ngg) {
      assert(!sctx->ngg);
      return false;
   }

   bool new_ngg = true;

   if (sctx->gs_shader.cso && sctx->tes_shader.cso && sctx->gs_shader.cso->tess_turns_off_ngg) {
      new_ngg = false;
   } else if (!sctx->screen->use_ngg_streamout) {
      struct si_shader_selector *last = si_get_vs(sctx)->cso;

      if ((last && last->so.num_outputs) || sctx->streamout.prims_gen_query_enabled)
         new_ngg = false;
   }

   if (new_ngg != sctx->ngg) {
      /* Transitioning from NGG to legacy GS requires VGT_FLUSH on Navi10-14.
       * VGT_FLUSH is also emitted at the beginning of IBs when legacy GS ring
       * pointers are set.
       */
      if (sctx->chip_class == GFX10 && !new_ngg)
         sctx->flags |= SI_CONTEXT_VGT_FLUSH;

      sctx->ngg = new_ngg;
      sctx->last_gs_out_prim = -1; /* reset this so that it gets updated */
      return true;
   }
   return false;
}

static void si_bind_gs_shader(struct pipe_context *ctx, void *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *old_hw_vs = si_get_vs(sctx)->cso;
   struct si_shader *old_hw_vs_variant = si_get_vs_state(sctx);
   struct si_shader_selector *sel = state;
   bool enable_changed = !!sctx->gs_shader.cso != !!sel;
   bool ngg_changed;

   if (sctx->gs_shader.cso == sel)
      return;

   sctx->gs_shader.cso = sel;
   sctx->gs_shader.current = sel ? sel->first_variant : NULL;
   sctx->ia_multi_vgt_param_key.u.uses_gs = sel != NULL;

   si_update_common_shader_state(sctx);
   sctx->last_gs_out_prim = -1; /* reset this so that it gets updated */

   ngg_changed = si_update_ngg(sctx);
   if (ngg_changed || enable_changed)
      si_shader_change_notify(sctx);
   if (enable_changed) {
      if (sctx->ia_multi_vgt_param_key.u.uses_tess)
         si_update_tess_uses_prim_id(sctx);
   }
   si_update_vs_viewport_state(sctx);
   si_set_active_descriptors_for_shader(sctx, sel);
   si_update_streamout_state(sctx);
   si_update_clip_regs(sctx, old_hw_vs, old_hw_vs_variant, si_get_vs(sctx)->cso,
                       si_get_vs_state(sctx));
}

static void si_bind_tcs_shader(struct pipe_context *ctx, void *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *sel = state;
   bool enable_changed = !!sctx->tcs_shader.cso != !!sel;

   if (sctx->tcs_shader.cso == sel)
      return;

   sctx->tcs_shader.cso = sel;
   sctx->tcs_shader.current = sel ? sel->first_variant : NULL;
   si_update_tess_uses_prim_id(sctx);

   si_update_common_shader_state(sctx);

   if (enable_changed)
      sctx->last_tcs = NULL; /* invalidate derived tess state */

   si_set_active_descriptors_for_shader(sctx, sel);
}

static void si_bind_tes_shader(struct pipe_context *ctx, void *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *old_hw_vs = si_get_vs(sctx)->cso;
   struct si_shader *old_hw_vs_variant = si_get_vs_state(sctx);
   struct si_shader_selector *sel = state;
   bool enable_changed = !!sctx->tes_shader.cso != !!sel;

   if (sctx->tes_shader.cso == sel)
      return;

   sctx->tes_shader.cso = sel;
   sctx->tes_shader.current = sel ? sel->first_variant : NULL;
   sctx->ia_multi_vgt_param_key.u.uses_tess = sel != NULL;
   si_update_tess_uses_prim_id(sctx);

   si_update_common_shader_state(sctx);
   sctx->last_gs_out_prim = -1; /* reset this so that it gets updated */

   bool ngg_changed = si_update_ngg(sctx);
   if (ngg_changed || enable_changed)
      si_shader_change_notify(sctx);
   if (enable_changed)
      sctx->last_tes_sh_base = -1; /* invalidate derived tess state */
   si_update_vs_viewport_state(sctx);
   si_set_active_descriptors_for_shader(sctx, sel);
   si_update_streamout_state(sctx);
   si_update_clip_regs(sctx, old_hw_vs, old_hw_vs_variant, si_get_vs(sctx)->cso,
                       si_get_vs_state(sctx));
}

static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *old_sel = sctx->ps_shader.cso;
   struct si_shader_selector *sel = state;

   /* skip if supplied shader is one already in use */
   if (old_sel == sel)
      return;

   sctx->ps_shader.cso = sel;
   sctx->ps_shader.current = sel ? sel->first_variant : NULL;

   si_update_common_shader_state(sctx);
   if (sel) {
      if (sctx->ia_multi_vgt_param_key.u.uses_tess)
         si_update_tess_uses_prim_id(sctx);

      if (!old_sel || old_sel->info.colors_written != sel->info.colors_written)
         si_mark_atom_dirty(sctx, &sctx->atoms.s.cb_render_state);

      if (sctx->screen->has_out_of_order_rast &&
          (!old_sel || old_sel->info.writes_memory != sel->info.writes_memory ||
           old_sel->info.base.fs.early_fragment_tests !=
              sel->info.base.fs.early_fragment_tests))
         si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_config);
   }
   si_set_active_descriptors_for_shader(sctx, sel);
   si_update_ps_colorbuf0_slot(sctx);
}

static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
{
   if (shader->is_optimized) {
      util_queue_drop_job(&sctx->screen->shader_compiler_queue_low_priority, &shader->ready);
   }

   util_queue_fence_destroy(&shader->ready);

   if (shader->pm4) {
      /* If destroyed shaders were not unbound, the next compiled
       * shader variant could get the same pointer address and so
       * binding it to the same shader stage would be considered
       * a no-op, causing random behavior.
       */
      switch (shader->selector->info.stage) {
      case MESA_SHADER_VERTEX:
         if (shader->key.as_ls) {
            assert(sctx->chip_class <= GFX8);
            si_pm4_delete_state(sctx, ls, shader->pm4);
         } else if (shader->key.as_es) {
            assert(sctx->chip_class <= GFX8);
            si_pm4_delete_state(sctx, es, shader->pm4);
         } else if (shader->key.as_ngg) {
            si_pm4_delete_state(sctx, gs, shader->pm4);
         } else {
            si_pm4_delete_state(sctx, vs, shader->pm4);
         }
         break;
      case MESA_SHADER_TESS_CTRL:
         si_pm4_delete_state(sctx, hs, shader->pm4);
         break;
      case MESA_SHADER_TESS_EVAL:
         if (shader->key.as_es) {
            assert(sctx->chip_class <= GFX8);
            si_pm4_delete_state(sctx, es, shader->pm4);
         } else if (shader->key.as_ngg) {
            si_pm4_delete_state(sctx, gs, shader->pm4);
         } else {
            si_pm4_delete_state(sctx, vs, shader->pm4);
         }
         break;
      case MESA_SHADER_GEOMETRY:
         if (shader->is_gs_copy_shader)
            si_pm4_delete_state(sctx, vs, shader->pm4);
         else
            si_pm4_delete_state(sctx, gs, shader->pm4);
         break;
      case MESA_SHADER_FRAGMENT:
         si_pm4_delete_state(sctx, ps, shader->pm4);
         break;
      default:;
      }
   }

   si_shader_selector_reference(sctx, &shader->previous_stage_sel, NULL);
   si_shader_destroy(shader);
   free(shader);
}

static void si_destroy_shader_selector(struct pipe_context *ctx, void *cso)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *sel = (struct si_shader_selector *)cso;
   struct si_shader *p = sel->first_variant, *c;
   struct si_shader_ctx_state *current_shader[SI_NUM_SHADERS] = {
      [MESA_SHADER_VERTEX] = &sctx->vs_shader,
      [MESA_SHADER_TESS_CTRL] = &sctx->tcs_shader,
      [MESA_SHADER_TESS_EVAL] = &sctx->tes_shader,
      [MESA_SHADER_GEOMETRY] = &sctx->gs_shader,
      [MESA_SHADER_FRAGMENT] = &sctx->ps_shader,
   };

   util_queue_drop_job(&sctx->screen->shader_compiler_queue, &sel->ready);

   if (current_shader[sel->info.stage]->cso == sel) {
      current_shader[sel->info.stage]->cso = NULL;
      current_shader[sel->info.stage]->current = NULL;
   }

   while (p) {
      c = p->next_variant;
      si_delete_shader(sctx, p);
      p = c;
   }

   if (sel->main_shader_part)
      si_delete_shader(sctx, sel->main_shader_part);
   if (sel->main_shader_part_ls)
      si_delete_shader(sctx, sel->main_shader_part_ls);
   if (sel->main_shader_part_es)
      si_delete_shader(sctx, sel->main_shader_part_es);
   if (sel->main_shader_part_ngg)
      si_delete_shader(sctx, sel->main_shader_part_ngg);
   if (sel->gs_copy_shader)
      si_delete_shader(sctx, sel->gs_copy_shader);

   util_queue_fence_destroy(&sel->ready);
   simple_mtx_destroy(&sel->mutex);
   ralloc_free(sel->nir);
   free(sel->nir_binary);
   free(sel);
}

static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
{
   struct si_context *sctx = (struct si_context *)ctx;
   struct si_shader_selector *sel = (struct si_shader_selector *)state;

   si_shader_selector_reference(sctx, &sel, NULL);
}

static unsigned si_get_ps_input_cntl(struct si_context *sctx, struct si_shader *vs,
                                     unsigned semantic, enum glsl_interp_mode interpolate)
{
   struct si_shader_info *vsinfo = &vs->selector->info;
   unsigned offset, ps_input_cntl = 0;

   if (interpolate == INTERP_MODE_FLAT ||
       (interpolate == INTERP_MODE_COLOR && sctx->flatshade) ||
       semantic == VARYING_SLOT_PRIMITIVE_ID)
      ps_input_cntl |= S_028644_FLAT_SHADE(1);

   if (semantic == VARYING_SLOT_PNTC ||
       (semantic >= VARYING_SLOT_TEX0 && semantic <= VARYING_SLOT_TEX7 &&
        sctx->sprite_coord_enable & (1 << (semantic - VARYING_SLOT_TEX0)))) {
      ps_input_cntl |= S_028644_PT_SPRITE_TEX(1);
   }

   int vs_slot = vsinfo->output_semantic_to_slot[semantic];
   if (vs_slot >= 0) {
      offset = vs->info.vs_output_param_offset[vs_slot];

      if (offset <= AC_EXP_PARAM_OFFSET_31) {
         /* The input is loaded from parameter memory. */
         ps_input_cntl |= S_028644_OFFSET(offset);
      } else if (!G_028644_PT_SPRITE_TEX(ps_input_cntl)) {
         if (offset == AC_EXP_PARAM_UNDEFINED) {
            /* This can happen with depth-only rendering. */
            offset = 0;
         } else {
            /* The input is a DEFAULT_VAL constant. */
            assert(offset >= AC_EXP_PARAM_DEFAULT_VAL_0000 &&
                   offset <= AC_EXP_PARAM_DEFAULT_VAL_1111);
            offset -= AC_EXP_PARAM_DEFAULT_VAL_0000;
         }

         ps_input_cntl = S_028644_OFFSET(0x20) | S_028644_DEFAULT_VAL(offset);
      }
   } else {
      /* VS output not found. */
      if (semantic == VARYING_SLOT_PRIMITIVE_ID) {
         /* PrimID is written after the last output when HW VS is used. */
         ps_input_cntl |= S_028644_OFFSET(vs->info.vs_output_param_offset[vsinfo->num_outputs]);
      } else if (!G_028644_PT_SPRITE_TEX(ps_input_cntl)) {
         /* No corresponding output found, load defaults into input.
          * Don't set any other bits.
          * (FLAT_SHADE=1 completely changes behavior) */
         ps_input_cntl = S_028644_OFFSET(0x20);
         /* D3D 9 behaviour. GL is undefined */
         if (semantic == VARYING_SLOT_COL0)
            ps_input_cntl |= S_028644_DEFAULT_VAL(3);
      }
   }

   return ps_input_cntl;
}

static void si_emit_spi_map(struct si_context *sctx)
{
   struct si_shader *ps = sctx->ps_shader.current;
   struct si_shader *vs = si_get_vs_state(sctx);
   struct si_shader_info *psinfo = ps ? &ps->selector->info : NULL;
   unsigned i, num_interp, num_written = 0;
   unsigned spi_ps_input_cntl[32];

   if (!ps || !ps->selector->info.num_inputs)
      return;

   num_interp = si_get_ps_num_interp(ps);
   assert(num_interp > 0);

   for (i = 0; i < psinfo->num_inputs; i++) {
      unsigned semantic = psinfo->input_semantic[i];
      unsigned interpolate = psinfo->input_interpolate[i];

      spi_ps_input_cntl[num_written++] = si_get_ps_input_cntl(sctx, vs, semantic, interpolate);
   }

   if (ps->key.part.ps.prolog.color_two_side) {
      for (i = 0; i < 2; i++) {
         if (!(psinfo->colors_read & (0xf << (i * 4))))
            continue;

         unsigned semantic = VARYING_SLOT_BFC0 + i;
         spi_ps_input_cntl[num_written++] = si_get_ps_input_cntl(sctx, vs, semantic,
                                                                 psinfo->color_interpolate[i]);
      }
   }
   assert(num_interp == num_written);

   /* R_028644_SPI_PS_INPUT_CNTL_0 */
   /* Dota 2: Only ~16% of SPI map updates set different values. */
   /* Talos: Only ~9% of SPI map updates set different values. */
   unsigned initial_cdw = sctx->gfx_cs->current.cdw;
   radeon_opt_set_context_regn(sctx, R_028644_SPI_PS_INPUT_CNTL_0, spi_ps_input_cntl,
                               sctx->tracked_regs.spi_ps_input_cntl, num_interp);

   if (initial_cdw != sctx->gfx_cs->current.cdw)
      sctx->context_roll = true;
}

/**
 * Writing CONFIG or UCONFIG VGT registers requires VGT_FLUSH before that.
 */
static void si_cs_preamble_add_vgt_flush(struct si_context *sctx)
{
   /* We shouldn't get here if registers are shadowed. */
   assert(!sctx->shadowed_regs);

   if (sctx->cs_preamble_has_vgt_flush)
      return;

   /* Done by Vulkan before VGT_FLUSH. */
   si_pm4_cmd_add(sctx->cs_preamble_state, PKT3(PKT3_EVENT_WRITE, 0, 0));
   si_pm4_cmd_add(sctx->cs_preamble_state, EVENT_TYPE(V_028A90_VS_PARTIAL_FLUSH) | EVENT_INDEX(4));

   /* VGT_FLUSH is required even if VGT is idle. It resets VGT pointers. */
   si_pm4_cmd_add(sctx->cs_preamble_state, PKT3(PKT3_EVENT_WRITE, 0, 0));
   si_pm4_cmd_add(sctx->cs_preamble_state, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0));
   sctx->cs_preamble_has_vgt_flush = true;
}

/**
 * Writing CONFIG or UCONFIG VGT registers requires VGT_FLUSH before that.
 */
static void si_emit_vgt_flush(struct radeon_cmdbuf *cs)
{
   /* This is required before VGT_FLUSH. */
   radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
   radeon_emit(cs, EVENT_TYPE(V_028A90_VS_PARTIAL_FLUSH) | EVENT_INDEX(4));

   /* VGT_FLUSH is required even if VGT is idle. It resets VGT pointers. */
   radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
   radeon_emit(cs, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0));
}

/* Initialize state related to ESGS / GSVS ring buffers */
static bool si_update_gs_ring_buffers(struct si_context *sctx)
{
   struct si_shader_selector *es =
      sctx->tes_shader.cso ? sctx->tes_shader.cso : sctx->vs_shader.cso;
   struct si_shader_selector *gs = sctx->gs_shader.cso;
   struct si_pm4_state *pm4;

   /* Chip constants. */
   unsigned num_se = sctx->screen->info.max_se;
   unsigned wave_size = 64;
   unsigned max_gs_waves = 32 * num_se; /* max 32 per SE on GCN */
   /* On GFX6-GFX7, the value comes from VGT_GS_VERTEX_REUSE = 16.
    * On GFX8+, the value comes from VGT_VERTEX_REUSE_BLOCK_CNTL = 30 (+2).
    */
   unsigned gs_vertex_reuse = (sctx->chip_class >= GFX8 ? 32 : 16) * num_se;
   unsigned alignment = 256 * num_se;
   /* The maximum size is 63.999 MB per SE. */
   unsigned max_size = ((unsigned)(63.999 * 1024 * 1024) & ~255) * num_se;

   /* Calculate the minimum size. */
   unsigned min_esgs_ring_size = align(es->esgs_itemsize * gs_vertex_reuse * wave_size, alignment);

   /* These are recommended sizes, not minimum sizes. */
   unsigned esgs_ring_size =
      max_gs_waves * 2 * wave_size * es->esgs_itemsize * gs->gs_input_verts_per_prim;
   unsigned gsvs_ring_size = max_gs_waves * 2 * wave_size * gs->max_gsvs_emit_size;

   min_esgs_ring_size = align(min_esgs_ring_size, alignment);
   esgs_ring_size = align(esgs_ring_size, alignment);
   gsvs_ring_size = align(gsvs_ring_size, alignment);

   esgs_ring_size = CLAMP(esgs_ring_size, min_esgs_ring_size, max_size);
   gsvs_ring_size = MIN2(gsvs_ring_size, max_size);

   /* Some rings don't have to be allocated if shaders don't use them.
    * (e.g. no varyings between ES and GS or GS and VS)
    *
    * GFX9 doesn't have the ESGS ring.
    */
   bool update_esgs = sctx->chip_class <= GFX8 && esgs_ring_size &&
                      (!sctx->esgs_ring || sctx->esgs_ring->width0 < esgs_ring_size);
   bool update_gsvs =
      gsvs_ring_size && (!sctx->gsvs_ring || sctx->gsvs_ring->width0 < gsvs_ring_size);

   if (!update_esgs && !update_gsvs)
      return true;

   if (update_esgs) {
      pipe_resource_reference(&sctx->esgs_ring, NULL);
      sctx->esgs_ring =
         pipe_aligned_buffer_create(sctx->b.screen, SI_RESOURCE_FLAG_UNMAPPABLE, PIPE_USAGE_DEFAULT,
                                    esgs_ring_size, sctx->screen->info.pte_fragment_size);
      if (!sctx->esgs_ring)
         return false;
   }

   if (update_gsvs) {
      pipe_resource_reference(&sctx->gsvs_ring, NULL);
      sctx->gsvs_ring =
         pipe_aligned_buffer_create(sctx->b.screen, SI_RESOURCE_FLAG_UNMAPPABLE, PIPE_USAGE_DEFAULT,
                                    gsvs_ring_size, sctx->screen->info.pte_fragment_size);
      if (!sctx->gsvs_ring)
         return false;
   }

   /* Set ring bindings. */
   if (sctx->esgs_ring) {
      assert(sctx->chip_class <= GFX8);
      si_set_ring_buffer(sctx, SI_ES_RING_ESGS, sctx->esgs_ring, 0, sctx->esgs_ring->width0, true,
                         true, 4, 64, 0);
      si_set_ring_buffer(sctx, SI_GS_RING_ESGS, sctx->esgs_ring, 0, sctx->esgs_ring->width0, false,
                         false, 0, 0, 0);
   }
   if (sctx->gsvs_ring) {
      si_set_ring_buffer(sctx, SI_RING_GSVS, sctx->gsvs_ring, 0, sctx->gsvs_ring->width0, false,
                         false, 0, 0, 0);
   }

   if (sctx->shadowed_regs) {
      /* These registers will be shadowed, so set them only once. */
      struct radeon_cmdbuf *cs = sctx->gfx_cs;

      assert(sctx->chip_class >= GFX7);

      si_emit_vgt_flush(cs);

      /* Set the GS registers. */
      if (sctx->esgs_ring) {
         assert(sctx->chip_class <= GFX8);
         radeon_set_uconfig_reg(cs, R_030900_VGT_ESGS_RING_SIZE,
                                sctx->esgs_ring->width0 / 256);
      }
      if (sctx->gsvs_ring) {
         radeon_set_uconfig_reg(cs, R_030904_VGT_GSVS_RING_SIZE,
                                sctx->gsvs_ring->width0 / 256);
      }
      return true;
   }

   /* The codepath without register shadowing. */
   /* Create the "cs_preamble_gs_rings" state. */
   pm4 = CALLOC_STRUCT(si_pm4_state);
   if (!pm4)
      return false;

   if (sctx->chip_class >= GFX7) {
      if (sctx->esgs_ring) {
         assert(sctx->chip_class <= GFX8);
         si_pm4_set_reg(pm4, R_030900_VGT_ESGS_RING_SIZE, sctx->esgs_ring->width0 / 256);
      }
      if (sctx->gsvs_ring)
         si_pm4_set_reg(pm4, R_030904_VGT_GSVS_RING_SIZE, sctx->gsvs_ring->width0 / 256);
   } else {
      if (sctx->esgs_ring)
         si_pm4_set_reg(pm4, R_0088C8_VGT_ESGS_RING_SIZE, sctx->esgs_ring->width0 / 256);
      if (sctx->gsvs_ring)
         si_pm4_set_reg(pm4, R_0088CC_VGT_GSVS_RING_SIZE, sctx->gsvs_ring->width0 / 256);
   }

   /* Set the state. */
   if (sctx->cs_preamble_gs_rings)
      si_pm4_free_state(sctx, sctx->cs_preamble_gs_rings, ~0);
   sctx->cs_preamble_gs_rings = pm4;

   si_cs_preamble_add_vgt_flush(sctx);

   /* Flush the context to re-emit both cs_preamble states. */
   sctx->initial_gfx_cs_size = 0; /* force flush */
   si_flush_gfx_cs(sctx, RADEON_FLUSH_ASYNC_START_NEXT_GFX_IB_NOW, NULL);

   return true;
}

static void si_shader_lock(struct si_shader *shader)
{
   simple_mtx_lock(&shader->selector->mutex);
   if (shader->previous_stage_sel) {
      assert(shader->previous_stage_sel != shader->selector);
      simple_mtx_lock(&shader->previous_stage_sel->mutex);
   }
}

static void si_shader_unlock(struct si_shader *shader)
{
   if (shader->previous_stage_sel)
      simple_mtx_unlock(&shader->previous_stage_sel->mutex);
   simple_mtx_unlock(&shader->selector->mutex);
}

/**
 * @returns 1 if \p sel has been updated to use a new scratch buffer
 *          0 if not
 *          < 0 if there was a failure
 */
static int si_update_scratch_buffer(struct si_context *sctx, struct si_shader *shader)
{
   uint64_t scratch_va = sctx->scratch_buffer->gpu_address;

   if (!shader)
      return 0;

   /* This shader doesn't need a scratch buffer */
   if (shader->config.scratch_bytes_per_wave == 0)
      return 0;

   /* Prevent race conditions when updating:
    * - si_shader::scratch_bo
    * - si_shader::binary::code
    * - si_shader::previous_stage::binary::code.
    */
   si_shader_lock(shader);

   /* This shader is already configured to use the current
    * scratch buffer. */
   if (shader->scratch_bo == sctx->scratch_buffer) {
      si_shader_unlock(shader);
      return 0;
   }

   assert(sctx->scratch_buffer);

   /* Replace the shader bo with a new bo that has the relocs applied. */
   if (!si_shader_binary_upload(sctx->screen, shader, scratch_va)) {
      si_shader_unlock(shader);
      return -1;
   }

   /* Update the shader state to use the new shader bo. */
   si_shader_init_pm4_state(sctx->screen, shader);

   si_resource_reference(&shader->scratch_bo, sctx->scratch_buffer);

   si_shader_unlock(shader);
   return 1;
}

static unsigned si_get_scratch_buffer_bytes_per_wave(struct si_shader *shader)
{
   return shader ? shader->config.scratch_bytes_per_wave : 0;
}

static struct si_shader *si_get_tcs_current(struct si_context *sctx)
{
   if (!sctx->tes_shader.cso)
      return NULL; /* tessellation disabled */

   return sctx->tcs_shader.cso ? sctx->tcs_shader.current : sctx->fixed_func_tcs_shader.current;
}

static bool si_update_scratch_relocs(struct si_context *sctx)
{
   struct si_shader *tcs = si_get_tcs_current(sctx);
   int r;

   /* Update the shaders, so that they are using the latest scratch.
    * The scratch buffer may have been changed since these shaders were
    * last used, so we still need to try to update them, even if they
    * require scratch buffers smaller than the current size.
    */
   r = si_update_scratch_buffer(sctx, sctx->ps_shader.current);
   if (r < 0)
      return false;
   if (r == 1)
      si_pm4_bind_state(sctx, ps, sctx->ps_shader.current->pm4);

   r = si_update_scratch_buffer(sctx, sctx->gs_shader.current);
   if (r < 0)
      return false;
   if (r == 1)
      si_pm4_bind_state(sctx, gs, sctx->gs_shader.current->pm4);

   r = si_update_scratch_buffer(sctx, tcs);
   if (r < 0)
      return false;
   if (r == 1)
      si_pm4_bind_state(sctx, hs, tcs->pm4);

   /* VS can be bound as LS, ES, or VS. */
   r = si_update_scratch_buffer(sctx, sctx->vs_shader.current);
   if (r < 0)
      return false;
   if (r == 1) {
      if (sctx->vs_shader.current->key.as_ls)
         si_pm4_bind_state(sctx, ls, sctx->vs_shader.current->pm4);
      else if (sctx->vs_shader.current->key.as_es)
         si_pm4_bind_state(sctx, es, sctx->vs_shader.current->pm4);
      else if (sctx->vs_shader.current->key.as_ngg)
         si_pm4_bind_state(sctx, gs, sctx->vs_shader.current->pm4);
      else
         si_pm4_bind_state(sctx, vs, sctx->vs_shader.current->pm4);
   }

   /* TES can be bound as ES or VS. */
   r = si_update_scratch_buffer(sctx, sctx->tes_shader.current);
   if (r < 0)
      return false;
   if (r == 1) {
      if (sctx->tes_shader.current->key.as_es)
         si_pm4_bind_state(sctx, es, sctx->tes_shader.current->pm4);
      else if (sctx->tes_shader.current->key.as_ngg)
         si_pm4_bind_state(sctx, gs, sctx->tes_shader.current->pm4);
      else
         si_pm4_bind_state(sctx, vs, sctx->tes_shader.current->pm4);
   }

   return true;
}

static bool si_update_spi_tmpring_size(struct si_context *sctx)
{
   /* SPI_TMPRING_SIZE.WAVESIZE must be constant for each scratch buffer.
    * There are 2 cases to handle:
    *
    * - If the current needed size is less than the maximum seen size,
    *   use the maximum seen size, so that WAVESIZE remains the same.
    *
    * - If the current needed size is greater than the maximum seen size,
    *   the scratch buffer is reallocated, so we can increase WAVESIZE.
    *
    * Shaders that set SCRATCH_EN=0 don't allocate scratch space.
    * Otherwise, the number of waves that can use scratch is
    * SPI_TMPRING_SIZE.WAVES.
    */
   unsigned bytes = 0;

   bytes = MAX2(bytes, si_get_scratch_buffer_bytes_per_wave(sctx->ps_shader.current));
   bytes = MAX2(bytes, si_get_scratch_buffer_bytes_per_wave(sctx->gs_shader.current));
   bytes = MAX2(bytes, si_get_scratch_buffer_bytes_per_wave(sctx->vs_shader.current));

   if (sctx->tes_shader.cso) {
      bytes = MAX2(bytes, si_get_scratch_buffer_bytes_per_wave(sctx->tes_shader.current));
      bytes = MAX2(bytes, si_get_scratch_buffer_bytes_per_wave(si_get_tcs_current(sctx)));
   }

   sctx->max_seen_scratch_bytes_per_wave = MAX2(sctx->max_seen_scratch_bytes_per_wave, bytes);

   unsigned scratch_needed_size = sctx->max_seen_scratch_bytes_per_wave * sctx->scratch_waves;
   unsigned spi_tmpring_size;

   if (scratch_needed_size > 0) {
      if (!sctx->scratch_buffer || scratch_needed_size > sctx->scratch_buffer->b.b.width0) {
         /* Create a bigger scratch buffer */
         si_resource_reference(&sctx->scratch_buffer, NULL);

         sctx->scratch_buffer = si_aligned_buffer_create(
            &sctx->screen->b, SI_RESOURCE_FLAG_UNMAPPABLE, PIPE_USAGE_DEFAULT, scratch_needed_size,
            sctx->screen->info.pte_fragment_size);
         if (!sctx->scratch_buffer)
            return false;

         si_mark_atom_dirty(sctx, &sctx->atoms.s.scratch_state);
         si_context_add_resource_size(sctx, &sctx->scratch_buffer->b.b);
      }

      if (!si_update_scratch_relocs(sctx))
         return false;
   }

   /* The LLVM shader backend should be reporting aligned scratch_sizes. */
   assert((scratch_needed_size & ~0x3FF) == scratch_needed_size &&
          "scratch size should already be aligned correctly.");

   spi_tmpring_size = S_0286E8_WAVES(sctx->scratch_waves) |
                      S_0286E8_WAVESIZE(sctx->max_seen_scratch_bytes_per_wave >> 10);
   if (spi_tmpring_size != sctx->spi_tmpring_size) {
      sctx->spi_tmpring_size = spi_tmpring_size;
      si_mark_atom_dirty(sctx, &sctx->atoms.s.scratch_state);
   }
   return true;
}

static void si_init_tess_factor_ring(struct si_context *sctx)
{
   assert(!sctx->tess_rings);
   assert(((sctx->screen->tess_factor_ring_size / 4) & C_030938_SIZE) == 0);

   /* The address must be aligned to 2^19, because the shader only
    * receives the high 13 bits.
    */
   sctx->tess_rings = pipe_aligned_buffer_create(
      sctx->b.screen, SI_RESOURCE_FLAG_32BIT, PIPE_USAGE_DEFAULT,
      sctx->screen->tess_offchip_ring_size + sctx->screen->tess_factor_ring_size, 1 << 19);
   if (!sctx->tess_rings)
      return;

   uint64_t factor_va =
      si_resource(sctx->tess_rings)->gpu_address + sctx->screen->tess_offchip_ring_size;

   if (sctx->shadowed_regs) {
      /* These registers will be shadowed, so set them only once. */
      struct radeon_cmdbuf *cs = sctx->gfx_cs;

      assert(sctx->chip_class >= GFX7);

      radeon_add_to_buffer_list(sctx, sctx->gfx_cs, si_resource(sctx->tess_rings),
                                RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_RINGS);
      si_emit_vgt_flush(cs);

      /* Set tessellation registers. */
      radeon_set_uconfig_reg(cs, R_030938_VGT_TF_RING_SIZE,
                             S_030938_SIZE(sctx->screen->tess_factor_ring_size / 4));
      radeon_set_uconfig_reg(cs, R_030940_VGT_TF_MEMORY_BASE, factor_va >> 8);
      if (sctx->chip_class >= GFX10) {
         radeon_set_uconfig_reg(cs, R_030984_VGT_TF_MEMORY_BASE_HI_UMD,
                                S_030984_BASE_HI(factor_va >> 40));
      } else if (sctx->chip_class == GFX9) {
         radeon_set_uconfig_reg(cs, R_030944_VGT_TF_MEMORY_BASE_HI,
                                S_030944_BASE_HI(factor_va >> 40));
      }
      radeon_set_uconfig_reg(cs, R_03093C_VGT_HS_OFFCHIP_PARAM,
                             sctx->screen->vgt_hs_offchip_param);
      return;
   }

   /* The codepath without register shadowing. */
   si_cs_preamble_add_vgt_flush(sctx);

   /* Append these registers to the init config state. */
   if (sctx->chip_class >= GFX7) {
      si_pm4_set_reg(sctx->cs_preamble_state, R_030938_VGT_TF_RING_SIZE,
                     S_030938_SIZE(sctx->screen->tess_factor_ring_size / 4));
      si_pm4_set_reg(sctx->cs_preamble_state, R_030940_VGT_TF_MEMORY_BASE, factor_va >> 8);
      if (sctx->chip_class >= GFX10)
         si_pm4_set_reg(sctx->cs_preamble_state, R_030984_VGT_TF_MEMORY_BASE_HI_UMD,
                        S_030984_BASE_HI(factor_va >> 40));
      else if (sctx->chip_class == GFX9)
         si_pm4_set_reg(sctx->cs_preamble_state, R_030944_VGT_TF_MEMORY_BASE_HI,
                        S_030944_BASE_HI(factor_va >> 40));
      si_pm4_set_reg(sctx->cs_preamble_state, R_03093C_VGT_HS_OFFCHIP_PARAM,
                     sctx->screen->vgt_hs_offchip_param);
   } else {
      si_pm4_set_reg(sctx->cs_preamble_state, R_008988_VGT_TF_RING_SIZE,
                     S_008988_SIZE(sctx->screen->tess_factor_ring_size / 4));
      si_pm4_set_reg(sctx->cs_preamble_state, R_0089B8_VGT_TF_MEMORY_BASE, factor_va >> 8);
      si_pm4_set_reg(sctx->cs_preamble_state, R_0089B0_VGT_HS_OFFCHIP_PARAM,
                     sctx->screen->vgt_hs_offchip_param);
   }

   /* Flush the context to re-emit the cs_preamble state.
    * This is done only once in a lifetime of a context.
    */
   sctx->initial_gfx_cs_size = 0; /* force flush */
   si_flush_gfx_cs(sctx, RADEON_FLUSH_ASYNC_START_NEXT_GFX_IB_NOW, NULL);
}

static struct si_pm4_state *si_build_vgt_shader_config(struct si_screen *screen,
                                                       union si_vgt_stages_key key)
{
   struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
   uint32_t stages = 0;

   if (key.u.tess) {
      stages |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) | S_028B54_HS_EN(1) | S_028B54_DYNAMIC_HS(1);

      if (key.u.gs)
         stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_DS) | S_028B54_GS_EN(1);
      else if (key.u.ngg)
         stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_DS);
      else
         stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_DS);
   } else if (key.u.gs) {
      stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) | S_028B54_GS_EN(1);
   } else if (key.u.ngg) {
      stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_REAL);
   }

   if (key.u.ngg) {
      stages |= S_028B54_PRIMGEN_EN(1) | S_028B54_GS_FAST_LAUNCH(key.u.ngg_gs_fast_launch) |
                S_028B54_NGG_WAVE_ID_EN(key.u.streamout) |
                S_028B54_PRIMGEN_PASSTHRU_EN(key.u.ngg_passthrough);
   } else if (key.u.gs)
      stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);

   if (screen->info.chip_class >= GFX9)
      stages |= S_028B54_MAX_PRIMGRP_IN_WAVE(2);

   if (screen->info.chip_class >= GFX10 &&
       /* GS fast launch hangs with Wave64, so always use Wave32. */
       (screen->ge_wave_size == 32 || (key.u.ngg && key.u.ngg_gs_fast_launch))) {
      stages |= S_028B54_HS_W32_EN(1) |
                S_028B54_GS_W32_EN(key.u.ngg) | /* legacy GS only supports Wave64 */
                S_028B54_VS_W32_EN(1);
   }

   si_pm4_set_reg(pm4, R_028B54_VGT_SHADER_STAGES_EN, stages);
   return pm4;
}

static void si_update_vgt_shader_config(struct si_context *sctx, union si_vgt_stages_key key)
{
   struct si_pm4_state **pm4 = &sctx->vgt_shader_config[key.index];

   if (unlikely(!*pm4))
      *pm4 = si_build_vgt_shader_config(sctx->screen, key);
   si_pm4_bind_state(sctx, vgt_shader_config, *pm4);
}

bool si_update_shaders(struct si_context *sctx)
{
   struct pipe_context *ctx = (struct pipe_context *)sctx;
   struct si_compiler_ctx_state compiler_state;
   struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
   struct si_shader *old_vs = si_get_vs_state(sctx);
   bool old_clip_disable = old_vs ? old_vs->key.opt.clip_disable : false;
   struct si_shader *old_ps = sctx->ps_shader.current;
   union si_vgt_stages_key key;
   unsigned old_spi_shader_col_format =
      old_ps ? old_ps->key.part.ps.epilog.spi_shader_col_format : 0;
   int r;

   if (!sctx->compiler.passes)
      si_init_compiler(sctx->screen, &sctx->compiler);

   compiler_state.compiler = &sctx->compiler;
   compiler_state.debug = sctx->debug;
   compiler_state.is_debug_context = sctx->is_debug;

   key.index = 0;

   if (sctx->tes_shader.cso)
      key.u.tess = 1;
   if (sctx->gs_shader.cso)
      key.u.gs = 1;

   if (sctx->ngg) {
      key.u.ngg = 1;
      key.u.streamout = !!si_get_vs(sctx)->cso->so.num_outputs;
   }

   /* Update TCS and TES. */
   if (sctx->tes_shader.cso) {
      if (!sctx->tess_rings) {
         si_init_tess_factor_ring(sctx);
         if (!sctx->tess_rings)
            return false;
      }

      if (sctx->tcs_shader.cso) {
         r = si_shader_select(ctx, &sctx->tcs_shader, key, &compiler_state);
         if (r)
            return false;
         si_pm4_bind_state(sctx, hs, sctx->tcs_shader.current->pm4);
      } else {
         if (!sctx->fixed_func_tcs_shader.cso) {
            sctx->fixed_func_tcs_shader.cso = si_create_fixed_func_tcs(sctx);
            if (!sctx->fixed_func_tcs_shader.cso)
               return false;
         }

         r = si_shader_select(ctx, &sctx->fixed_func_tcs_shader, key, &compiler_state);
         if (r)
            return false;
         si_pm4_bind_state(sctx, hs, sctx->fixed_func_tcs_shader.current->pm4);
      }

      if (!sctx->gs_shader.cso || sctx->chip_class <= GFX8) {
         r = si_shader_select(ctx, &sctx->tes_shader, key, &compiler_state);
         if (r)
            return false;

         if (sctx->gs_shader.cso) {
            /* TES as ES */
            assert(sctx->chip_class <= GFX8);
            si_pm4_bind_state(sctx, es, sctx->tes_shader.current->pm4);
         } else if (key.u.ngg) {
            si_pm4_bind_state(sctx, gs, sctx->tes_shader.current->pm4);
         } else {
            si_pm4_bind_state(sctx, vs, sctx->tes_shader.current->pm4);
         }
      }
   } else {
      if (sctx->chip_class <= GFX8)
         si_pm4_bind_state(sctx, ls, NULL);
      si_pm4_bind_state(sctx, hs, NULL);
   }

   /* Update GS. */
   if (sctx->gs_shader.cso) {
      r = si_shader_select(ctx, &sctx->gs_shader, key, &compiler_state);
      if (r)
         return false;
      si_pm4_bind_state(sctx, gs, sctx->gs_shader.current->pm4);
      if (!key.u.ngg) {
         si_pm4_bind_state(sctx, vs, sctx->gs_shader.cso->gs_copy_shader->pm4);

         if (!si_update_gs_ring_buffers(sctx))
            return false;
      } else {
         si_pm4_bind_state(sctx, vs, NULL);
      }
   } else {
      if (!key.u.ngg) {
         si_pm4_bind_state(sctx, gs, NULL);
         if (sctx->chip_class <= GFX8)
            si_pm4_bind_state(sctx, es, NULL);
      }
   }

   /* Update VS. */
   if ((!key.u.tess && !key.u.gs) || sctx->chip_class <= GFX8) {
      r = si_shader_select(ctx, &sctx->vs_shader, key, &compiler_state);
      if (r)
         return false;

      if (!key.u.tess && !key.u.gs) {
         if (key.u.ngg) {
            si_pm4_bind_state(sctx, gs, sctx->vs_shader.current->pm4);
            si_pm4_bind_state(sctx, vs, NULL);
         } else {
            si_pm4_bind_state(sctx, vs, sctx->vs_shader.current->pm4);
         }
      } else if (sctx->tes_shader.cso) {
         si_pm4_bind_state(sctx, ls, sctx->vs_shader.current->pm4);
      } else {
         assert(sctx->gs_shader.cso);
         si_pm4_bind_state(sctx, es, sctx->vs_shader.current->pm4);
      }
   }

   /* This must be done after the shader variant is selected. */
   if (sctx->ngg) {
      struct si_shader *vs = si_get_vs(sctx)->current;

      key.u.ngg_passthrough = gfx10_is_ngg_passthrough(vs);
      key.u.ngg_gs_fast_launch = !!(vs->key.opt.ngg_culling & SI_NGG_CULL_GS_FAST_LAUNCH_ALL);
   }

   si_update_vgt_shader_config(sctx, key);

   if (old_clip_disable != si_get_vs_state(sctx)->key.opt.clip_disable)
      si_mark_atom_dirty(sctx, &sctx->atoms.s.clip_regs);

   if (sctx->ps_shader.cso) {
      unsigned db_shader_control;

      r = si_shader_select(ctx, &sctx->ps_shader, key, &compiler_state);
      if (r)
         return false;
      si_pm4_bind_state(sctx, ps, sctx->ps_shader.current->pm4);

      db_shader_control = sctx->ps_shader.cso->db_shader_control |
                          S_02880C_KILL_ENABLE(si_get_alpha_test_func(sctx) != PIPE_FUNC_ALWAYS);

      if (si_pm4_state_changed(sctx, ps) || si_pm4_state_changed(sctx, vs) ||
          (key.u.ngg && si_pm4_state_changed(sctx, gs)) ||
          sctx->sprite_coord_enable != rs->sprite_coord_enable ||
          sctx->flatshade != rs->flatshade) {
         sctx->sprite_coord_enable = rs->sprite_coord_enable;
         sctx->flatshade = rs->flatshade;
         si_mark_atom_dirty(sctx, &sctx->atoms.s.spi_map);
      }

      if (sctx->screen->info.rbplus_allowed && si_pm4_state_changed(sctx, ps) &&
          (!old_ps || old_spi_shader_col_format !=
                         sctx->ps_shader.current->key.part.ps.epilog.spi_shader_col_format))
         si_mark_atom_dirty(sctx, &sctx->atoms.s.cb_render_state);

      if (sctx->ps_db_shader_control != db_shader_control) {
         sctx->ps_db_shader_control = db_shader_control;
         si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
         if (sctx->screen->dpbb_allowed)
            si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state);
      }

      if (sctx->smoothing_enabled !=
          sctx->ps_shader.current->key.part.ps.epilog.poly_line_smoothing) {
         sctx->smoothing_enabled = sctx->ps_shader.current->key.part.ps.epilog.poly_line_smoothing;
         si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_config);

         if (sctx->chip_class == GFX6)
            si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);

         if (sctx->framebuffer.nr_samples <= 1)
            si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_sample_locs);
      }
   }

   if (si_pm4_state_enabled_and_changed(sctx, ls) || si_pm4_state_enabled_and_changed(sctx, hs) ||
       si_pm4_state_enabled_and_changed(sctx, es) || si_pm4_state_enabled_and_changed(sctx, gs) ||
       si_pm4_state_enabled_and_changed(sctx, vs) || si_pm4_state_enabled_and_changed(sctx, ps)) {
      if (!si_update_spi_tmpring_size(sctx))
         return false;
   }

   if (sctx->chip_class >= GFX7) {
      if (si_pm4_state_enabled_and_changed(sctx, ls))
         sctx->prefetch_L2_mask |= SI_PREFETCH_LS;
      else if (!sctx->queued.named.ls)
         sctx->prefetch_L2_mask &= ~SI_PREFETCH_LS;

      if (si_pm4_state_enabled_and_changed(sctx, hs))
         sctx->prefetch_L2_mask |= SI_PREFETCH_HS;
      else if (!sctx->queued.named.hs)
         sctx->prefetch_L2_mask &= ~SI_PREFETCH_HS;

      if (si_pm4_state_enabled_and_changed(sctx, es))
         sctx->prefetch_L2_mask |= SI_PREFETCH_ES;
      else if (!sctx->queued.named.es)
         sctx->prefetch_L2_mask &= ~SI_PREFETCH_ES;

      if (si_pm4_state_enabled_and_changed(sctx, gs))
         sctx->prefetch_L2_mask |= SI_PREFETCH_GS;
      else if (!sctx->queued.named.gs)
         sctx->prefetch_L2_mask &= ~SI_PREFETCH_GS;

      if (si_pm4_state_enabled_and_changed(sctx, vs))
         sctx->prefetch_L2_mask |= SI_PREFETCH_VS;
      else if (!sctx->queued.named.vs)
         sctx->prefetch_L2_mask &= ~SI_PREFETCH_VS;

      if (si_pm4_state_enabled_and_changed(sctx, ps))
         sctx->prefetch_L2_mask |= SI_PREFETCH_PS;
      else if (!sctx->queued.named.ps)
         sctx->prefetch_L2_mask &= ~SI_PREFETCH_PS;
   }

   sctx->do_update_shaders = false;
   return true;
}

static void si_emit_scratch_state(struct si_context *sctx)
{
   struct radeon_cmdbuf *cs = sctx->gfx_cs;

   radeon_set_context_reg(cs, R_0286E8_SPI_TMPRING_SIZE, sctx->spi_tmpring_size);

   if (sctx->scratch_buffer) {
      radeon_add_to_buffer_list(sctx, sctx->gfx_cs, sctx->scratch_buffer, RADEON_USAGE_READWRITE,
                                RADEON_PRIO_SCRATCH_BUFFER);
   }
}

void si_init_screen_live_shader_cache(struct si_screen *sscreen)
{
   util_live_shader_cache_init(&sscreen->live_shader_cache, si_create_shader_selector,
                               si_destroy_shader_selector);
}

void si_init_shader_functions(struct si_context *sctx)
{
   sctx->atoms.s.spi_map.emit = si_emit_spi_map;
   sctx->atoms.s.scratch_state.emit = si_emit_scratch_state;

   sctx->b.create_vs_state = si_create_shader;
   sctx->b.create_tcs_state = si_create_shader;
   sctx->b.create_tes_state = si_create_shader;
   sctx->b.create_gs_state = si_create_shader;
   sctx->b.create_fs_state = si_create_shader;

   sctx->b.bind_vs_state = si_bind_vs_shader;
   sctx->b.bind_tcs_state = si_bind_tcs_shader;
   sctx->b.bind_tes_state = si_bind_tes_shader;
   sctx->b.bind_gs_state = si_bind_gs_shader;
   sctx->b.bind_fs_state = si_bind_ps_shader;

   sctx->b.delete_vs_state = si_delete_shader_selector;
   sctx->b.delete_tcs_state = si_delete_shader_selector;
   sctx->b.delete_tes_state = si_delete_shader_selector;
   sctx->b.delete_gs_state = si_delete_shader_selector;
   sctx->b.delete_fs_state = si_delete_shader_selector;
}
