+static inline struct si_shader_ctx_state *si_get_vs(struct si_context *sctx)
+{
+ if (sctx->gs_shader.cso)
+ return &sctx->gs_shader;
+ if (sctx->tes_shader.cso)
+ return &sctx->tes_shader;
+
+ return &sctx->vs_shader;
+}
+
+static inline struct tgsi_shader_info *si_get_vs_info(struct si_context *sctx)
+{
+ struct si_shader_ctx_state *vs = si_get_vs(sctx);
+
+ return vs->cso ? &vs->cso->info : NULL;
+}
+
+static inline struct si_shader* si_get_vs_state(struct si_context *sctx)
+{
+ if (sctx->gs_shader.cso)
+ return sctx->gs_shader.cso->gs_copy_shader;
+
+ struct si_shader_ctx_state *vs = si_get_vs(sctx);
+ return vs->current ? vs->current : NULL;
+}
+
+static inline bool si_get_strmout_en(struct si_context *sctx)
+{
+ return sctx->streamout.streamout_enabled ||
+ sctx->streamout.prims_gen_query_enabled;
+}
+
+static inline unsigned
+si_optimal_tcc_alignment(struct si_context *sctx, unsigned upload_size)
+{
+ unsigned alignment, tcc_cache_line_size;
+
+ /* If the upload size is less than the cache line size (e.g. 16, 32),
+ * the whole thing will fit into a cache line if we align it to its size.
+ * The idea is that multiple small uploads can share a cache line.
+ * If the upload size is greater, align it to the cache line size.
+ */
+ alignment = util_next_power_of_two(upload_size);
+ tcc_cache_line_size = sctx->screen->b.info.tcc_cache_line_size;
+ return MIN2(alignment, tcc_cache_line_size);
+}
+
+static inline void
+si_saved_cs_reference(struct si_saved_cs **dst, struct si_saved_cs *src)
+{
+ if (pipe_reference(&(*dst)->reference, &src->reference))
+ si_destroy_saved_cs(*dst);
+
+ *dst = src;
+}
+
+static inline void
+si_make_CB_shader_coherent(struct si_context *sctx, unsigned num_samples,
+ bool shaders_read_metadata)
+{
+ sctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_CB |
+ SI_CONTEXT_INV_VMEM_L1;
+
+ if (sctx->b.chip_class >= GFX9) {
+ /* Single-sample color is coherent with shaders on GFX9, but
+ * L2 metadata must be flushed if shaders read metadata.
+ * (DCC, CMASK).
+ */
+ if (num_samples >= 2)
+ sctx->b.flags |= SI_CONTEXT_INV_GLOBAL_L2;
+ else if (shaders_read_metadata)
+ sctx->b.flags |= SI_CONTEXT_INV_L2_METADATA;
+ } else {
+ /* SI-CI-VI */
+ sctx->b.flags |= SI_CONTEXT_INV_GLOBAL_L2;
+ }
+}
+
+static inline void
+si_make_DB_shader_coherent(struct si_context *sctx, unsigned num_samples,
+ bool include_stencil, bool shaders_read_metadata)
+{
+ sctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_DB |
+ SI_CONTEXT_INV_VMEM_L1;
+
+ if (sctx->b.chip_class >= GFX9) {
+ /* Single-sample depth (not stencil) is coherent with shaders
+ * on GFX9, but L2 metadata must be flushed if shaders read
+ * metadata.
+ */
+ if (num_samples >= 2 || include_stencil)
+ sctx->b.flags |= SI_CONTEXT_INV_GLOBAL_L2;
+ else if (shaders_read_metadata)
+ sctx->b.flags |= SI_CONTEXT_INV_L2_METADATA;
+ } else {
+ /* SI-CI-VI */
+ sctx->b.flags |= SI_CONTEXT_INV_GLOBAL_L2;
+ }
+}
+