/* * Copyright 2024 Valve Corporation * SPDX-License-Identifier: MIT */ #pragma once #include #include "agx_pack.h" #include "shader_enums.h" struct nir_shader; /* Matches the hardware order */ enum uvs_group { UVS_POSITION, UVS_VARYINGS, UVS_PSIZ, UVS_LAYER_VIEWPORT, UVS_CLIP_DIST, UVS_NUM_GROUP, }; /** * Represents an "unlinked" UVS layout. This is computable from an unlinked * vertex shader without knowing the associated fragment shader. The various UVS * groups have fixed offsets, but the varyings within the varying group have * indeterminate order since we don't yet know the fragment shader interpolation * qualifiers. */ struct agx_unlinked_uvs_layout { /* Bit i set <===> components[i] != 0 && i != POS && i != PSIZ. For fast * iteration of user varyings. */ uint64_t written; /* Fully packed data structure */ struct agx_vdm_state_vertex_outputs_packed vdm; /* Partial data structure, must be merged with FS selects */ struct agx_output_select_packed osel; /* Offset of each group in the UVS in words. */ uint8_t group_offs[UVS_NUM_GROUP]; /* Size of the UVS allocation in words. >= last group_offs element */ uint8_t size; /* Size of the UVS_VARYINGS */ uint8_t user_size; uint8_t pad; /* Number of 32-bit components written for each slot. TODO: Model 16-bit. * * Invariant: sum_{slot} (components[slot]) = * group_offs[PSIZ] - group_offs[VARYINGS] */ uint8_t components[VARYING_SLOT_MAX]; }; static_assert(sizeof(struct agx_unlinked_uvs_layout) == 88, "packed"); bool agx_nir_lower_uvs(struct nir_shader *s, struct agx_unlinked_uvs_layout *layout); /** * Represents a linked UVS layout. */ struct agx_varyings_vs { /* Associated linked hardware data structures */ struct agx_varying_counts_packed counts_32, counts_16; /* If the user varying slot is written, this is the base index that the first * component of the slot is written to. The next components are found in the * next indices. Otherwise 0, aliasing position. */ unsigned slots[VARYING_SLOT_MAX]; }; void agx_assign_uvs(struct agx_varyings_vs *varyings, struct agx_unlinked_uvs_layout *layout, uint64_t flat_mask, uint64_t linear_mask); struct agx_varyings_fs; void agx_link_varyings_vs_fs(void *out, struct agx_varyings_vs *vs, unsigned nr_user_indices, struct agx_varyings_fs *fs, unsigned provoking_vertex, uint8_t sprite_coord_enable, bool *generate_primitive_id);