1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2018 Advanced Micro Devices, Inc. 3bf215546Sopenharmony_ci * All Rights Reserved. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#define AC_SURFACE_INCLUDE_NIR 26bf215546Sopenharmony_ci#include "ac_surface.h" 27bf215546Sopenharmony_ci#include "si_pipe.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_cistatic void *create_shader_state(struct si_context *sctx, nir_shader *nir) 30bf215546Sopenharmony_ci{ 31bf215546Sopenharmony_ci sctx->b.screen->finalize_nir(sctx->b.screen, (void*)nir); 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 34bf215546Sopenharmony_ci state.type = PIPE_SHADER_IR_NIR; 35bf215546Sopenharmony_ci state.ir.nir = nir; 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci switch (nir->info.stage) { 38bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 39bf215546Sopenharmony_ci return sctx->b.create_vs_state(&sctx->b, &state); 40bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 41bf215546Sopenharmony_ci return sctx->b.create_tcs_state(&sctx->b, &state); 42bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 43bf215546Sopenharmony_ci return sctx->b.create_tes_state(&sctx->b, &state); 44bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 45bf215546Sopenharmony_ci return sctx->b.create_fs_state(&sctx->b, &state); 46bf215546Sopenharmony_ci case MESA_SHADER_COMPUTE: { 47bf215546Sopenharmony_ci struct pipe_compute_state cs_state = {0}; 48bf215546Sopenharmony_ci cs_state.ir_type = PIPE_SHADER_IR_NIR; 49bf215546Sopenharmony_ci cs_state.prog = nir; 50bf215546Sopenharmony_ci return sctx->b.create_compute_state(&sctx->b, &cs_state); 51bf215546Sopenharmony_ci } 52bf215546Sopenharmony_ci default: 53bf215546Sopenharmony_ci unreachable("invalid shader stage"); 54bf215546Sopenharmony_ci return NULL; 55bf215546Sopenharmony_ci } 56bf215546Sopenharmony_ci} 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_cistatic nir_ssa_def *get_global_ids(nir_builder *b, unsigned num_components) 59bf215546Sopenharmony_ci{ 60bf215546Sopenharmony_ci unsigned mask = BITFIELD_MASK(num_components); 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci nir_ssa_def *local_ids = nir_channels(b, nir_load_local_invocation_id(b), mask); 63bf215546Sopenharmony_ci nir_ssa_def *block_ids = nir_channels(b, nir_load_workgroup_id(b, 32), mask); 64bf215546Sopenharmony_ci nir_ssa_def *block_size = nir_channels(b, nir_load_workgroup_size(b), mask); 65bf215546Sopenharmony_ci return nir_iadd(b, nir_imul(b, block_ids, block_size), local_ids); 66bf215546Sopenharmony_ci} 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_cistatic void unpack_2x16(nir_builder *b, nir_ssa_def *src, nir_ssa_def **x, nir_ssa_def **y) 69bf215546Sopenharmony_ci{ 70bf215546Sopenharmony_ci *x = nir_iand(b, src, nir_imm_int(b, 0xffff)); 71bf215546Sopenharmony_ci *y = nir_ushr(b, src, nir_imm_int(b, 16)); 72bf215546Sopenharmony_ci} 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_cistatic nir_ssa_def * 75bf215546Sopenharmony_cideref_ssa(nir_builder *b, nir_variable *var) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci return &nir_build_deref_var(b, var)->dest.ssa; 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci/* Create a NIR compute shader implementing copy_image. 81bf215546Sopenharmony_ci * 82bf215546Sopenharmony_ci * This shader can handle 1D and 2D, linear and non-linear images. 83bf215546Sopenharmony_ci * It expects the source and destination (x,y,z) coords as user_data_amd, 84bf215546Sopenharmony_ci * packed into 3 SGPRs as 2x16bits per component. 85bf215546Sopenharmony_ci */ 86bf215546Sopenharmony_civoid *si_create_copy_image_cs(struct si_context *sctx, bool src_is_1d_array, bool dst_is_1d_array) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci const nir_shader_compiler_options *options = 89bf215546Sopenharmony_ci sctx->b.screen->get_compiler_options(sctx->b.screen, PIPE_SHADER_IR_NIR, PIPE_SHADER_COMPUTE); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, options, "copy_image_cs"); 92bf215546Sopenharmony_ci b.shader->info.num_images = 2; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci /* The workgroup size is either 8x8 for normal (non-linear) 2D images, 95bf215546Sopenharmony_ci * or 64x1 for 1D and linear-2D images. 96bf215546Sopenharmony_ci */ 97bf215546Sopenharmony_ci b.shader->info.workgroup_size_variable = true; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci b.shader->info.cs.user_data_components_amd = 3; 100bf215546Sopenharmony_ci nir_ssa_def *ids = get_global_ids(&b, 3); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci nir_ssa_def *coord_src = NULL, *coord_dst = NULL; 103bf215546Sopenharmony_ci unpack_2x16(&b, nir_load_user_data_amd(&b), &coord_src, &coord_dst); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci coord_src = nir_iadd(&b, coord_src, ids); 106bf215546Sopenharmony_ci coord_dst = nir_iadd(&b, coord_dst, ids); 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci static unsigned swizzle_xz[] = {0, 2, 0, 0}; 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci if (src_is_1d_array) 111bf215546Sopenharmony_ci coord_src = nir_swizzle(&b, coord_src, swizzle_xz, 4); 112bf215546Sopenharmony_ci if (dst_is_1d_array) 113bf215546Sopenharmony_ci coord_dst = nir_swizzle(&b, coord_dst, swizzle_xz, 4); 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci const struct glsl_type *src_img_type = glsl_image_type(src_is_1d_array ? GLSL_SAMPLER_DIM_1D 116bf215546Sopenharmony_ci : GLSL_SAMPLER_DIM_2D, 117bf215546Sopenharmony_ci /*is_array*/ true, GLSL_TYPE_FLOAT); 118bf215546Sopenharmony_ci const struct glsl_type *dst_img_type = glsl_image_type(dst_is_1d_array ? GLSL_SAMPLER_DIM_1D 119bf215546Sopenharmony_ci : GLSL_SAMPLER_DIM_2D, 120bf215546Sopenharmony_ci /*is_array*/ true, GLSL_TYPE_FLOAT); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci nir_variable *img_src = nir_variable_create(b.shader, nir_var_image, src_img_type, "img_src"); 123bf215546Sopenharmony_ci img_src->data.binding = 0; 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci nir_variable *img_dst = nir_variable_create(b.shader, nir_var_image, dst_img_type, "img_dst"); 126bf215546Sopenharmony_ci img_dst->data.binding = 1; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci nir_ssa_def *undef32 = nir_ssa_undef(&b, 1, 32); 129bf215546Sopenharmony_ci nir_ssa_def *zero = nir_imm_int(&b, 0); 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci nir_ssa_def *data = nir_image_deref_load(&b, /*num_components*/ 4, /*bit_size*/ 32, 132bf215546Sopenharmony_ci deref_ssa(&b, img_src), coord_src, undef32, zero); 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci nir_image_deref_store(&b, deref_ssa(&b, img_dst), coord_dst, undef32, data, zero); 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci return create_shader_state(sctx, b.shader); 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_civoid *si_create_dcc_retile_cs(struct si_context *sctx, struct radeon_surf *surf) 140bf215546Sopenharmony_ci{ 141bf215546Sopenharmony_ci const nir_shader_compiler_options *options = 142bf215546Sopenharmony_ci sctx->b.screen->get_compiler_options(sctx->b.screen, PIPE_SHADER_IR_NIR, PIPE_SHADER_COMPUTE); 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, options, "dcc_retile"); 145bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 8; 146bf215546Sopenharmony_ci b.shader->info.workgroup_size[1] = 8; 147bf215546Sopenharmony_ci b.shader->info.workgroup_size[2] = 1; 148bf215546Sopenharmony_ci b.shader->info.cs.user_data_components_amd = 3; 149bf215546Sopenharmony_ci b.shader->info.num_ssbos = 1; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci /* Get user data SGPRs. */ 152bf215546Sopenharmony_ci nir_ssa_def *user_sgprs = nir_load_user_data_amd(&b); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci /* Relative offset from the displayable DCC to the non-displayable DCC in the same buffer. */ 155bf215546Sopenharmony_ci nir_ssa_def *src_dcc_offset = nir_channel(&b, user_sgprs, 0); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci nir_ssa_def *src_dcc_pitch, *dst_dcc_pitch, *src_dcc_height, *dst_dcc_height; 158bf215546Sopenharmony_ci unpack_2x16(&b, nir_channel(&b, user_sgprs, 1), &src_dcc_pitch, &src_dcc_height); 159bf215546Sopenharmony_ci unpack_2x16(&b, nir_channel(&b, user_sgprs, 2), &dst_dcc_pitch, &dst_dcc_height); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci /* Get the 2D coordinates. */ 162bf215546Sopenharmony_ci nir_ssa_def *coord = get_global_ids(&b, 2); 163bf215546Sopenharmony_ci nir_ssa_def *zero = nir_imm_int(&b, 0); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci /* Multiply the coordinates by the DCC block size (they are DCC block coordinates). */ 166bf215546Sopenharmony_ci coord = nir_imul(&b, coord, nir_imm_ivec2(&b, surf->u.gfx9.color.dcc_block_width, 167bf215546Sopenharmony_ci surf->u.gfx9.color.dcc_block_height)); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci nir_ssa_def *src_offset = 170bf215546Sopenharmony_ci ac_nir_dcc_addr_from_coord(&b, &sctx->screen->info, surf->bpe, &surf->u.gfx9.color.dcc_equation, 171bf215546Sopenharmony_ci src_dcc_pitch, src_dcc_height, zero, /* DCC slice size */ 172bf215546Sopenharmony_ci nir_channel(&b, coord, 0), nir_channel(&b, coord, 1), /* x, y */ 173bf215546Sopenharmony_ci zero, zero, zero); /* z, sample, pipe_xor */ 174bf215546Sopenharmony_ci src_offset = nir_iadd(&b, src_offset, src_dcc_offset); 175bf215546Sopenharmony_ci nir_ssa_def *value = nir_load_ssbo(&b, 1, 8, zero, src_offset, .align_mul=1); 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci nir_ssa_def *dst_offset = 178bf215546Sopenharmony_ci ac_nir_dcc_addr_from_coord(&b, &sctx->screen->info, surf->bpe, &surf->u.gfx9.color.display_dcc_equation, 179bf215546Sopenharmony_ci dst_dcc_pitch, dst_dcc_height, zero, /* DCC slice size */ 180bf215546Sopenharmony_ci nir_channel(&b, coord, 0), nir_channel(&b, coord, 1), /* x, y */ 181bf215546Sopenharmony_ci zero, zero, zero); /* z, sample, pipe_xor */ 182bf215546Sopenharmony_ci nir_store_ssbo(&b, value, zero, dst_offset, .write_mask=0x1, .align_mul=1); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci return create_shader_state(sctx, b.shader); 185bf215546Sopenharmony_ci} 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_civoid *gfx9_create_clear_dcc_msaa_cs(struct si_context *sctx, struct si_texture *tex) 188bf215546Sopenharmony_ci{ 189bf215546Sopenharmony_ci const nir_shader_compiler_options *options = 190bf215546Sopenharmony_ci sctx->b.screen->get_compiler_options(sctx->b.screen, PIPE_SHADER_IR_NIR, PIPE_SHADER_COMPUTE); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, options, "clear_dcc_msaa"); 193bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 8; 194bf215546Sopenharmony_ci b.shader->info.workgroup_size[1] = 8; 195bf215546Sopenharmony_ci b.shader->info.workgroup_size[2] = 1; 196bf215546Sopenharmony_ci b.shader->info.cs.user_data_components_amd = 2; 197bf215546Sopenharmony_ci b.shader->info.num_ssbos = 1; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci /* Get user data SGPRs. */ 200bf215546Sopenharmony_ci nir_ssa_def *user_sgprs = nir_load_user_data_amd(&b); 201bf215546Sopenharmony_ci nir_ssa_def *dcc_pitch, *dcc_height, *clear_value, *pipe_xor; 202bf215546Sopenharmony_ci unpack_2x16(&b, nir_channel(&b, user_sgprs, 0), &dcc_pitch, &dcc_height); 203bf215546Sopenharmony_ci unpack_2x16(&b, nir_channel(&b, user_sgprs, 1), &clear_value, &pipe_xor); 204bf215546Sopenharmony_ci clear_value = nir_u2u16(&b, clear_value); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci /* Get the 2D coordinates. */ 207bf215546Sopenharmony_ci nir_ssa_def *coord = get_global_ids(&b, 3); 208bf215546Sopenharmony_ci nir_ssa_def *zero = nir_imm_int(&b, 0); 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci /* Multiply the coordinates by the DCC block size (they are DCC block coordinates). */ 211bf215546Sopenharmony_ci coord = nir_imul(&b, coord, 212bf215546Sopenharmony_ci nir_channels(&b, nir_imm_ivec4(&b, tex->surface.u.gfx9.color.dcc_block_width, 213bf215546Sopenharmony_ci tex->surface.u.gfx9.color.dcc_block_height, 214bf215546Sopenharmony_ci tex->surface.u.gfx9.color.dcc_block_depth, 0), 0x7)); 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci nir_ssa_def *offset = 217bf215546Sopenharmony_ci ac_nir_dcc_addr_from_coord(&b, &sctx->screen->info, tex->surface.bpe, 218bf215546Sopenharmony_ci &tex->surface.u.gfx9.color.dcc_equation, 219bf215546Sopenharmony_ci dcc_pitch, dcc_height, zero, /* DCC slice size */ 220bf215546Sopenharmony_ci nir_channel(&b, coord, 0), nir_channel(&b, coord, 1), /* x, y */ 221bf215546Sopenharmony_ci tex->buffer.b.b.array_size > 1 ? nir_channel(&b, coord, 2) : zero, /* z */ 222bf215546Sopenharmony_ci zero, pipe_xor); /* sample, pipe_xor */ 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci /* The trick here is that DCC elements for an even and the next odd sample are next to each other 225bf215546Sopenharmony_ci * in memory, so we only need to compute the address for sample 0 and the next DCC byte is always 226bf215546Sopenharmony_ci * sample 1. That's why the clear value has 2 bytes - we're clearing 2 samples at the same time. 227bf215546Sopenharmony_ci */ 228bf215546Sopenharmony_ci nir_store_ssbo(&b, clear_value, zero, offset, .write_mask=0x1, .align_mul=2); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci return create_shader_state(sctx, b.shader); 231bf215546Sopenharmony_ci} 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci/* Create a compute shader implementing clear_buffer or copy_buffer. */ 234bf215546Sopenharmony_civoid *si_create_clear_buffer_rmw_cs(struct si_context *sctx) 235bf215546Sopenharmony_ci{ 236bf215546Sopenharmony_ci const nir_shader_compiler_options *options = 237bf215546Sopenharmony_ci sctx->b.screen->get_compiler_options(sctx->b.screen, PIPE_SHADER_IR_NIR, PIPE_SHADER_COMPUTE); 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci nir_builder b = 240bf215546Sopenharmony_ci nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, options, "clear_buffer_rmw_cs"); 241bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 64; 242bf215546Sopenharmony_ci b.shader->info.workgroup_size[1] = 1; 243bf215546Sopenharmony_ci b.shader->info.workgroup_size[2] = 1; 244bf215546Sopenharmony_ci b.shader->info.cs.user_data_components_amd = 2; 245bf215546Sopenharmony_ci b.shader->info.num_ssbos = 1; 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci /* address = blockID * 64 + threadID; */ 248bf215546Sopenharmony_ci nir_ssa_def *address = get_global_ids(&b, 1); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci /* address = address * 16; (byte offset, loading one vec4 per thread) */ 251bf215546Sopenharmony_ci address = nir_ishl(&b, address, nir_imm_int(&b, 4)); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci nir_ssa_def *zero = nir_imm_int(&b, 0); 254bf215546Sopenharmony_ci nir_ssa_def *data = nir_load_ssbo(&b, 4, 32, zero, address, .align_mul = 4); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci /* Get user data SGPRs. */ 257bf215546Sopenharmony_ci nir_ssa_def *user_sgprs = nir_load_user_data_amd(&b); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci /* data &= inverted_writemask; */ 260bf215546Sopenharmony_ci data = nir_iand(&b, data, nir_channel(&b, user_sgprs, 1)); 261bf215546Sopenharmony_ci /* data |= clear_value_masked; */ 262bf215546Sopenharmony_ci data = nir_ior(&b, data, nir_channel(&b, user_sgprs, 0)); 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci nir_store_ssbo(&b, data, zero, address, 265bf215546Sopenharmony_ci .access = SI_COMPUTE_DST_CACHE_POLICY != L2_LRU ? ACCESS_STREAM_CACHE_POLICY : 0, 266bf215546Sopenharmony_ci .align_mul = 4); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci return create_shader_state(sctx, b.shader); 269bf215546Sopenharmony_ci} 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci/* This is used when TCS is NULL in the VS->TCS->TES chain. In this case, 272bf215546Sopenharmony_ci * VS passes its outputs to TES directly, so the fixed-function shader only 273bf215546Sopenharmony_ci * has to write TESSOUTER and TESSINNER. 274bf215546Sopenharmony_ci */ 275bf215546Sopenharmony_civoid *si_create_passthrough_tcs(struct si_context *sctx) 276bf215546Sopenharmony_ci{ 277bf215546Sopenharmony_ci const nir_shader_compiler_options *options = 278bf215546Sopenharmony_ci sctx->b.screen->get_compiler_options(sctx->b.screen, PIPE_SHADER_IR_NIR, 279bf215546Sopenharmony_ci PIPE_SHADER_TESS_CTRL); 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_TESS_CTRL, options, 282bf215546Sopenharmony_ci "tcs passthrough"); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci unsigned num_inputs = 0; 285bf215546Sopenharmony_ci unsigned num_outputs = 0; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci nir_variable *in_inner = 288bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_system_value, glsl_vec_type(2), 289bf215546Sopenharmony_ci "tess inner default"); 290bf215546Sopenharmony_ci in_inner->data.location = SYSTEM_VALUE_TESS_LEVEL_INNER_DEFAULT; 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci nir_variable *out_inner = 293bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_out, glsl_vec_type(2), 294bf215546Sopenharmony_ci "tess inner"); 295bf215546Sopenharmony_ci out_inner->data.location = VARYING_SLOT_TESS_LEVEL_INNER; 296bf215546Sopenharmony_ci out_inner->data.driver_location = num_outputs++; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci nir_ssa_def *inner = nir_load_var(&b, in_inner); 299bf215546Sopenharmony_ci nir_store_var(&b, out_inner, inner, 0x3); 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci nir_variable *in_outer = 302bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_system_value, glsl_vec4_type(), 303bf215546Sopenharmony_ci "tess outer default"); 304bf215546Sopenharmony_ci in_outer->data.location = SYSTEM_VALUE_TESS_LEVEL_OUTER_DEFAULT; 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci nir_variable *out_outer = 307bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_out, glsl_vec4_type(), 308bf215546Sopenharmony_ci "tess outer"); 309bf215546Sopenharmony_ci out_outer->data.location = VARYING_SLOT_TESS_LEVEL_OUTER; 310bf215546Sopenharmony_ci out_outer->data.driver_location = num_outputs++; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci nir_ssa_def *outer = nir_load_var(&b, in_outer); 313bf215546Sopenharmony_ci nir_store_var(&b, out_outer, outer, 0xf); 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci nir_ssa_def *id = nir_load_invocation_id(&b); 316bf215546Sopenharmony_ci struct si_shader_info *info = &sctx->shader.vs.cso->info; 317bf215546Sopenharmony_ci for (unsigned i = 0; i < info->num_outputs; i++) { 318bf215546Sopenharmony_ci const struct glsl_type *type; 319bf215546Sopenharmony_ci unsigned semantic = info->output_semantic[i]; 320bf215546Sopenharmony_ci if (semantic < VARYING_SLOT_VAR31 && semantic != VARYING_SLOT_EDGE) 321bf215546Sopenharmony_ci type = glsl_array_type(glsl_vec4_type(), 0, 0); 322bf215546Sopenharmony_ci else if (semantic >= VARYING_SLOT_VAR0_16BIT) 323bf215546Sopenharmony_ci type = glsl_array_type(glsl_vector_type(GLSL_TYPE_FLOAT16, 4), 0, 0); 324bf215546Sopenharmony_ci else 325bf215546Sopenharmony_ci continue; 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci char name[10]; 328bf215546Sopenharmony_ci snprintf(name, sizeof(name), "in_%u", i); 329bf215546Sopenharmony_ci nir_variable *in = nir_variable_create(b.shader, nir_var_shader_in, type, name); 330bf215546Sopenharmony_ci in->data.location = semantic; 331bf215546Sopenharmony_ci in->data.driver_location = num_inputs++; 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci snprintf(name, sizeof(name), "out_%u", i); 334bf215546Sopenharmony_ci nir_variable *out = nir_variable_create(b.shader, nir_var_shader_out, type, name); 335bf215546Sopenharmony_ci out->data.location = semantic; 336bf215546Sopenharmony_ci out->data.driver_location = num_outputs++; 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci /* no need to use copy_var to save a lower pass */ 339bf215546Sopenharmony_ci nir_ssa_def *value = nir_load_array_var(&b, in, id); 340bf215546Sopenharmony_ci nir_store_array_var(&b, out, id, value, 0xf); 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci b.shader->num_inputs = num_inputs; 344bf215546Sopenharmony_ci b.shader->num_outputs = num_outputs; 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci b.shader->info.tess.tcs_vertices_out = sctx->patch_vertices; 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci return create_shader_state(sctx, b.shader); 349bf215546Sopenharmony_ci} 350