Path: blob/21.2-virgl/src/gallium/auxiliary/nir/nir_to_tgsi_info.c
4561 views
/*1* Copyright 2017 Advanced Micro Devices, Inc.2* All Rights Reserved.3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* on the rights to use, copy, modify, merge, publish, distribute, sub8* license, and/or sell copies of the Software, and to permit persons to whom9* the Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL18* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,19* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR20* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE21* USE OR OTHER DEALINGS IN THE SOFTWARE.22*/2324/*25* This is ported mostly out of radeonsi, if we can drop TGSI, we can likely26* make a lot this go away.27*/2829#include "nir_to_tgsi_info.h"30#include "util/u_math.h"31#include "nir.h"32#include "nir_deref.h"33#include "tgsi/tgsi_scan.h"34#include "tgsi/tgsi_from_mesa.h"3536static nir_variable* tex_get_texture_var(nir_tex_instr *instr)37{38for (unsigned i = 0; i < instr->num_srcs; i++) {39switch (instr->src[i].src_type) {40case nir_tex_src_texture_deref:41return nir_deref_instr_get_variable(nir_src_as_deref(instr->src[i].src));42default:43break;44}45}4647return NULL;48}4950static nir_variable* intrinsic_get_var(nir_intrinsic_instr *instr)51{52return nir_deref_instr_get_variable(nir_src_as_deref(instr->src[0]));53}545556static void gather_usage_helper(const nir_deref_instr **deref_ptr,57unsigned location,58uint8_t mask,59uint8_t *usage_mask)60{61for (; *deref_ptr; deref_ptr++) {62const nir_deref_instr *deref = *deref_ptr;63switch (deref->deref_type) {64case nir_deref_type_array: {65bool is_compact = nir_deref_instr_get_variable(deref)->data.compact;66unsigned elem_size = is_compact ? DIV_ROUND_UP(glsl_get_length(deref->type), 4) :67glsl_count_attribute_slots(deref->type, false);68if (nir_src_is_const(deref->arr.index)) {69if (is_compact) {70location += nir_src_as_uint(deref->arr.index) / 4;71mask <<= nir_src_as_uint(deref->arr.index) % 4;72} else73location += elem_size * nir_src_as_uint(deref->arr.index);74} else {75unsigned array_elems =76glsl_get_length(deref_ptr[-1]->type);77for (unsigned i = 0; i < array_elems; i++) {78gather_usage_helper(deref_ptr + 1,79location + elem_size * i,80mask, usage_mask);81}82return;83}84break;85}86case nir_deref_type_struct: {87const struct glsl_type *parent_type =88deref_ptr[-1]->type;89unsigned index = deref->strct.index;90for (unsigned i = 0; i < index; i++) {91const struct glsl_type *ft = glsl_get_struct_field(parent_type, i);92location += glsl_count_attribute_slots(ft, false);93}94break;95}96default:97unreachable("Unhandled deref type in gather_components_used_helper");98}99}100101usage_mask[location] |= mask & 0xf;102if (mask & 0xf0)103usage_mask[location + 1] |= (mask >> 4) & 0xf;104}105106static void gather_usage(const nir_deref_instr *deref,107uint8_t mask,108uint8_t *usage_mask)109{110nir_deref_path path;111nir_deref_path_init(&path, (nir_deref_instr *)deref, NULL);112113unsigned location_frac = path.path[0]->var->data.location_frac;114if (glsl_type_is_64bit(deref->type)) {115uint8_t new_mask = 0;116for (unsigned i = 0; i < 4; i++) {117if (mask & (1 << i))118new_mask |= 0x3 << (2 * i);119}120mask = new_mask << location_frac;121} else {122mask <<= location_frac;123mask &= 0xf;124}125126gather_usage_helper((const nir_deref_instr **)&path.path[1],127path.path[0]->var->data.driver_location,128mask, usage_mask);129130nir_deref_path_finish(&path);131}132133static void gather_intrinsic_load_deref_info(const nir_shader *nir,134const nir_intrinsic_instr *instr,135const nir_deref_instr *deref,136bool need_texcoord,137nir_variable *var,138struct tgsi_shader_info *info)139{140assert(var && var->data.mode == nir_var_shader_in);141142if (nir->info.stage == MESA_SHADER_FRAGMENT)143gather_usage(deref, nir_ssa_def_components_read(&instr->dest.ssa),144info->input_usage_mask);145146switch (nir->info.stage) {147case MESA_SHADER_VERTEX: {148149break;150}151default: {152unsigned semantic_name, semantic_index;153tgsi_get_gl_varying_semantic(var->data.location, need_texcoord,154&semantic_name, &semantic_index);155156if (semantic_name == TGSI_SEMANTIC_COLOR) {157uint8_t mask = nir_ssa_def_components_read(&instr->dest.ssa);158info->colors_read |= mask << (semantic_index * 4);159}160if (semantic_name == TGSI_SEMANTIC_FACE) {161info->uses_frontface = true;162}163break;164}165}166}167168static void scan_instruction(const struct nir_shader *nir,169bool need_texcoord,170struct tgsi_shader_info *info,171nir_instr *instr)172{173if (instr->type == nir_instr_type_alu) {174nir_alu_instr *alu = nir_instr_as_alu(instr);175176switch (alu->op) {177case nir_op_fddx:178case nir_op_fddy:179case nir_op_fddx_fine:180case nir_op_fddy_fine:181case nir_op_fddx_coarse:182case nir_op_fddy_coarse:183info->uses_derivatives = true;184break;185default:186break;187}188} else if (instr->type == nir_instr_type_tex) {189nir_tex_instr *tex = nir_instr_as_tex(instr);190nir_variable *texture = tex_get_texture_var(tex);191192if (!texture) {193info->samplers_declared |=194u_bit_consecutive(tex->sampler_index, 1);195} else {196if (texture->data.bindless)197info->uses_bindless_samplers = true;198}199200switch (tex->op) {201case nir_texop_tex:202case nir_texop_txb:203case nir_texop_lod:204info->uses_derivatives = true;205break;206default:207break;208}209} else if (instr->type == nir_instr_type_intrinsic) {210nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);211212switch (intr->intrinsic) {213case nir_intrinsic_load_front_face:214info->uses_frontface = 1;215break;216case nir_intrinsic_load_instance_id:217info->uses_instanceid = 1;218break;219case nir_intrinsic_load_invocation_id:220info->uses_invocationid = true;221break;222case nir_intrinsic_load_num_workgroups:223info->uses_grid_size = true;224break;225case nir_intrinsic_load_workgroup_size:226/* The block size is translated to IMM with a fixed block size. */227if (info->properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] == 0)228info->uses_block_size = true;229break;230case nir_intrinsic_load_local_invocation_id:231case nir_intrinsic_load_workgroup_id: {232unsigned mask = nir_ssa_def_components_read(&intr->dest.ssa);233while (mask) {234unsigned i = u_bit_scan(&mask);235236if (intr->intrinsic == nir_intrinsic_load_workgroup_id)237info->uses_block_id[i] = true;238else239info->uses_thread_id[i] = true;240}241break;242}243case nir_intrinsic_load_vertex_id:244info->uses_vertexid = 1;245break;246case nir_intrinsic_load_vertex_id_zero_base:247info->uses_vertexid_nobase = 1;248break;249case nir_intrinsic_load_base_vertex:250info->uses_basevertex = 1;251break;252case nir_intrinsic_load_draw_id:253info->uses_drawid = 1;254break;255case nir_intrinsic_load_primitive_id:256info->uses_primid = 1;257break;258case nir_intrinsic_load_sample_mask_in:259info->reads_samplemask = true;260break;261case nir_intrinsic_load_tess_level_inner:262case nir_intrinsic_load_tess_level_outer:263info->reads_tess_factors = true;264break;265case nir_intrinsic_bindless_image_load:266info->uses_bindless_images = true;267268if (nir_intrinsic_image_dim(intr) == GLSL_SAMPLER_DIM_BUF)269info->uses_bindless_buffer_load = true;270else271info->uses_bindless_image_load = true;272break;273case nir_intrinsic_bindless_image_size:274case nir_intrinsic_bindless_image_samples:275info->uses_bindless_images = true;276break;277case nir_intrinsic_bindless_image_store:278info->uses_bindless_images = true;279280if (nir_intrinsic_image_dim(intr) == GLSL_SAMPLER_DIM_BUF)281info->uses_bindless_buffer_store = true;282else283info->uses_bindless_image_store = true;284285info->writes_memory = true;286break;287case nir_intrinsic_image_deref_store:288info->writes_memory = true;289break;290case nir_intrinsic_bindless_image_atomic_add:291case nir_intrinsic_bindless_image_atomic_imin:292case nir_intrinsic_bindless_image_atomic_imax:293case nir_intrinsic_bindless_image_atomic_umin:294case nir_intrinsic_bindless_image_atomic_umax:295case nir_intrinsic_bindless_image_atomic_and:296case nir_intrinsic_bindless_image_atomic_or:297case nir_intrinsic_bindless_image_atomic_xor:298case nir_intrinsic_bindless_image_atomic_exchange:299case nir_intrinsic_bindless_image_atomic_comp_swap:300info->uses_bindless_images = true;301302if (nir_intrinsic_image_dim(intr) == GLSL_SAMPLER_DIM_BUF)303info->uses_bindless_buffer_atomic = true;304else305info->uses_bindless_image_atomic = true;306307info->writes_memory = true;308break;309case nir_intrinsic_image_deref_atomic_add:310case nir_intrinsic_image_deref_atomic_imin:311case nir_intrinsic_image_deref_atomic_imax:312case nir_intrinsic_image_deref_atomic_umin:313case nir_intrinsic_image_deref_atomic_umax:314case nir_intrinsic_image_deref_atomic_and:315case nir_intrinsic_image_deref_atomic_or:316case nir_intrinsic_image_deref_atomic_xor:317case nir_intrinsic_image_deref_atomic_exchange:318case nir_intrinsic_image_deref_atomic_comp_swap:319info->writes_memory = true;320break;321case nir_intrinsic_store_ssbo:322case nir_intrinsic_ssbo_atomic_add:323case nir_intrinsic_ssbo_atomic_imin:324case nir_intrinsic_ssbo_atomic_umin:325case nir_intrinsic_ssbo_atomic_imax:326case nir_intrinsic_ssbo_atomic_umax:327case nir_intrinsic_ssbo_atomic_and:328case nir_intrinsic_ssbo_atomic_or:329case nir_intrinsic_ssbo_atomic_xor:330case nir_intrinsic_ssbo_atomic_exchange:331case nir_intrinsic_ssbo_atomic_comp_swap:332info->writes_memory = true;333break;334case nir_intrinsic_load_deref: {335nir_variable *var = intrinsic_get_var(intr);336nir_variable_mode mode = var->data.mode;337nir_deref_instr *const deref = nir_src_as_deref(intr->src[0]);338enum glsl_base_type base_type =339glsl_get_base_type(glsl_without_array(var->type));340341if (nir_deref_instr_has_indirect(deref)) {342if (mode == nir_var_shader_in)343info->indirect_files |= (1 << TGSI_FILE_INPUT);344}345if (mode == nir_var_shader_in) {346gather_intrinsic_load_deref_info(nir, intr, deref, need_texcoord, var, info);347348switch (var->data.interpolation) {349case INTERP_MODE_NONE:350if (glsl_base_type_is_integer(base_type))351break;352353FALLTHROUGH;354case INTERP_MODE_SMOOTH:355if (var->data.sample)356info->uses_persp_sample = true;357else if (var->data.centroid)358info->uses_persp_centroid = true;359else360info->uses_persp_center = true;361break;362363case INTERP_MODE_NOPERSPECTIVE:364if (var->data.sample)365info->uses_linear_sample = true;366else if (var->data.centroid)367info->uses_linear_centroid = true;368else369info->uses_linear_center = true;370break;371}372}373break;374}375case nir_intrinsic_interp_deref_at_centroid:376case nir_intrinsic_interp_deref_at_sample:377case nir_intrinsic_interp_deref_at_offset: {378enum glsl_interp_mode interp = intrinsic_get_var(intr)->data.interpolation;379switch (interp) {380case INTERP_MODE_SMOOTH:381case INTERP_MODE_NONE:382if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid)383info->uses_persp_opcode_interp_centroid = true;384else if (intr->intrinsic == nir_intrinsic_interp_deref_at_sample)385info->uses_persp_opcode_interp_sample = true;386else387info->uses_persp_opcode_interp_offset = true;388break;389case INTERP_MODE_NOPERSPECTIVE:390if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid)391info->uses_linear_opcode_interp_centroid = true;392else if (intr->intrinsic == nir_intrinsic_interp_deref_at_sample)393info->uses_linear_opcode_interp_sample = true;394else395info->uses_linear_opcode_interp_offset = true;396break;397case INTERP_MODE_FLAT:398break;399default:400unreachable("Unsupported interpoation type");401}402break;403}404default:405break;406}407}408}409410void nir_tgsi_scan_shader(const struct nir_shader *nir,411struct tgsi_shader_info *info,412bool need_texcoord)413{414nir_function *func;415unsigned i;416417info->processor = pipe_shader_type_from_mesa(nir->info.stage);418info->num_tokens = 2; /* indicate that the shader is non-empty */419info->num_instructions = 2;420421info->properties[TGSI_PROPERTY_NEXT_SHADER] =422pipe_shader_type_from_mesa(nir->info.next_stage);423424if (nir->info.stage == MESA_SHADER_VERTEX) {425info->properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION] =426nir->info.vs.window_space_position;427}428429if (nir->info.stage == MESA_SHADER_TESS_CTRL) {430info->properties[TGSI_PROPERTY_TCS_VERTICES_OUT] =431nir->info.tess.tcs_vertices_out;432}433434if (nir->info.stage == MESA_SHADER_TESS_EVAL) {435if (nir->info.tess.primitive_mode == GL_ISOLINES)436info->properties[TGSI_PROPERTY_TES_PRIM_MODE] = PIPE_PRIM_LINES;437else438info->properties[TGSI_PROPERTY_TES_PRIM_MODE] = nir->info.tess.primitive_mode;439440STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL);441STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 ==442PIPE_TESS_SPACING_FRACTIONAL_ODD);443STATIC_ASSERT((TESS_SPACING_FRACTIONAL_EVEN + 1) % 3 ==444PIPE_TESS_SPACING_FRACTIONAL_EVEN);445446info->properties[TGSI_PROPERTY_TES_SPACING] = (nir->info.tess.spacing + 1) % 3;447info->properties[TGSI_PROPERTY_TES_VERTEX_ORDER_CW] = !nir->info.tess.ccw;448info->properties[TGSI_PROPERTY_TES_POINT_MODE] = nir->info.tess.point_mode;449}450451if (nir->info.stage == MESA_SHADER_GEOMETRY) {452info->properties[TGSI_PROPERTY_GS_INPUT_PRIM] = nir->info.gs.input_primitive;453info->properties[TGSI_PROPERTY_GS_OUTPUT_PRIM] = nir->info.gs.output_primitive;454info->properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES] = nir->info.gs.vertices_out;455info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = nir->info.gs.invocations;456}457458if (nir->info.stage == MESA_SHADER_FRAGMENT) {459info->properties[TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL] =460nir->info.fs.early_fragment_tests | nir->info.fs.post_depth_coverage;461info->properties[TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE] = nir->info.fs.post_depth_coverage;462463if (nir->info.fs.pixel_center_integer) {464info->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER] =465TGSI_FS_COORD_PIXEL_CENTER_INTEGER;466}467468if (nir->info.fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) {469switch (nir->info.fs.depth_layout) {470case FRAG_DEPTH_LAYOUT_ANY:471info->properties[TGSI_PROPERTY_FS_DEPTH_LAYOUT] = TGSI_FS_DEPTH_LAYOUT_ANY;472break;473case FRAG_DEPTH_LAYOUT_GREATER:474info->properties[TGSI_PROPERTY_FS_DEPTH_LAYOUT] = TGSI_FS_DEPTH_LAYOUT_GREATER;475break;476case FRAG_DEPTH_LAYOUT_LESS:477info->properties[TGSI_PROPERTY_FS_DEPTH_LAYOUT] = TGSI_FS_DEPTH_LAYOUT_LESS;478break;479case FRAG_DEPTH_LAYOUT_UNCHANGED:480info->properties[TGSI_PROPERTY_FS_DEPTH_LAYOUT] = TGSI_FS_DEPTH_LAYOUT_UNCHANGED;481break;482default:483unreachable("Unknow depth layout");484}485}486}487488if (gl_shader_stage_is_compute(nir->info.stage)) {489info->properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] = nir->info.workgroup_size[0];490info->properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT] = nir->info.workgroup_size[1];491info->properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH] = nir->info.workgroup_size[2];492}493494i = 0;495uint64_t processed_inputs = 0;496nir_foreach_shader_in_variable(variable, nir) {497unsigned semantic_name, semantic_index;498499const struct glsl_type *type = variable->type;500if (nir_is_arrayed_io(variable, nir->info.stage)) {501assert(glsl_type_is_array(type));502type = glsl_get_array_element(type);503}504505unsigned attrib_count = variable->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4) :506glsl_count_attribute_slots(type, nir->info.stage == MESA_SHADER_VERTEX);507508i = variable->data.driver_location;509510/* Vertex shader inputs don't have semantics. The state511* tracker has already mapped them to attributes via512* variable->data.driver_location.513*/514if (nir->info.stage == MESA_SHADER_VERTEX) {515continue;516}517518for (unsigned j = 0; j < attrib_count; j++, i++) {519520if (processed_inputs & ((uint64_t)1 << i))521continue;522523processed_inputs |= ((uint64_t)1 << i);524525tgsi_get_gl_varying_semantic(variable->data.location + j, need_texcoord,526&semantic_name, &semantic_index);527528info->input_semantic_name[i] = semantic_name;529info->input_semantic_index[i] = semantic_index;530531if (semantic_name == TGSI_SEMANTIC_PRIMID)532info->uses_primid = true;533534enum glsl_base_type base_type =535glsl_get_base_type(glsl_without_array(variable->type));536537if (variable->data.centroid)538info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTROID;539if (variable->data.sample)540info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_SAMPLE;541542switch (variable->data.interpolation) {543case INTERP_MODE_NONE:544if (glsl_base_type_is_integer(base_type)) {545info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT;546break;547}548549if (semantic_name == TGSI_SEMANTIC_COLOR) {550info->input_interpolate[i] = TGSI_INTERPOLATE_COLOR;551break;552}553FALLTHROUGH;554555case INTERP_MODE_SMOOTH:556assert(!glsl_base_type_is_integer(base_type));557558info->input_interpolate[i] = TGSI_INTERPOLATE_PERSPECTIVE;559break;560561case INTERP_MODE_NOPERSPECTIVE:562assert(!glsl_base_type_is_integer(base_type));563564info->input_interpolate[i] = TGSI_INTERPOLATE_LINEAR;565break;566567case INTERP_MODE_FLAT:568info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT;569break;570}571}572}573574info->num_inputs = nir->num_inputs;575if (nir->info.io_lowered) {576info->num_inputs = util_bitcount64(nir->info.inputs_read);577if (nir->info.inputs_read_indirectly)578info->indirect_files |= 1 << TGSI_FILE_INPUT;579info->file_max[TGSI_FILE_INPUT] = info->num_inputs - 1;580} else {581int max = -1;582nir_foreach_shader_in_variable(var, nir) {583int slots = glsl_count_attribute_slots(var->type, false);584int tmax = var->data.driver_location + slots - 1;585if (tmax > max)586max = tmax;587info->file_max[TGSI_FILE_INPUT] = max;588}589}590591i = 0;592uint64_t processed_outputs = 0;593unsigned num_outputs = 0;594nir_foreach_shader_out_variable(variable, nir) {595unsigned semantic_name, semantic_index;596597i = variable->data.driver_location;598599const struct glsl_type *type = variable->type;600if (nir_is_arrayed_io(variable, nir->info.stage)) {601assert(glsl_type_is_array(type));602type = glsl_get_array_element(type);603}604605unsigned attrib_count = variable->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4) :606glsl_count_attribute_slots(type, false);607for (unsigned k = 0; k < attrib_count; k++, i++) {608609if (nir->info.stage == MESA_SHADER_FRAGMENT) {610tgsi_get_gl_frag_result_semantic(variable->data.location + k,611&semantic_name, &semantic_index);612613/* Adjust for dual source blending */614if (variable->data.index > 0) {615semantic_index++;616}617} else {618tgsi_get_gl_varying_semantic(variable->data.location + k, need_texcoord,619&semantic_name, &semantic_index);620}621622unsigned num_components = 4;623unsigned vector_elements = glsl_get_vector_elements(glsl_without_array(variable->type));624if (vector_elements)625num_components = vector_elements;626627unsigned component = variable->data.location_frac;628if (glsl_type_is_64bit(glsl_without_array(variable->type))) {629if (glsl_type_is_dual_slot(glsl_without_array(variable->type)) && k % 2) {630num_components = (num_components * 2) - 4;631component = 0;632} else {633num_components = MIN2(num_components * 2, 4);634}635}636637ubyte usagemask = 0;638for (unsigned j = component; j < num_components + component; j++) {639switch (j) {640case 0:641usagemask |= TGSI_WRITEMASK_X;642break;643case 1:644usagemask |= TGSI_WRITEMASK_Y;645break;646case 2:647usagemask |= TGSI_WRITEMASK_Z;648break;649case 3:650usagemask |= TGSI_WRITEMASK_W;651break;652default:653unreachable("error calculating component index");654}655}656657unsigned gs_out_streams;658if (variable->data.stream & NIR_STREAM_PACKED) {659gs_out_streams = variable->data.stream & ~NIR_STREAM_PACKED;660} else {661assert(variable->data.stream < 4);662gs_out_streams = 0;663for (unsigned j = 0; j < num_components; ++j)664gs_out_streams |= variable->data.stream << (2 * (component + j));665}666667unsigned streamx = gs_out_streams & 3;668unsigned streamy = (gs_out_streams >> 2) & 3;669unsigned streamz = (gs_out_streams >> 4) & 3;670unsigned streamw = (gs_out_streams >> 6) & 3;671672if (usagemask & TGSI_WRITEMASK_X) {673info->output_usagemask[i] |= TGSI_WRITEMASK_X;674info->output_streams[i] |= streamx;675info->num_stream_output_components[streamx]++;676}677if (usagemask & TGSI_WRITEMASK_Y) {678info->output_usagemask[i] |= TGSI_WRITEMASK_Y;679info->output_streams[i] |= streamy << 2;680info->num_stream_output_components[streamy]++;681}682if (usagemask & TGSI_WRITEMASK_Z) {683info->output_usagemask[i] |= TGSI_WRITEMASK_Z;684info->output_streams[i] |= streamz << 4;685info->num_stream_output_components[streamz]++;686}687if (usagemask & TGSI_WRITEMASK_W) {688info->output_usagemask[i] |= TGSI_WRITEMASK_W;689info->output_streams[i] |= streamw << 6;690info->num_stream_output_components[streamw]++;691}692693/* make sure we only count this location once against694* the num_outputs counter.695*/696if (processed_outputs & ((uint64_t)1 << i))697continue;698699processed_outputs |= ((uint64_t)1 << i);700num_outputs++;701702info->output_semantic_name[i] = semantic_name;703info->output_semantic_index[i] = semantic_index;704705switch (semantic_name) {706case TGSI_SEMANTIC_PRIMID:707info->writes_primid = true;708break;709case TGSI_SEMANTIC_VIEWPORT_INDEX:710info->writes_viewport_index = true;711break;712case TGSI_SEMANTIC_LAYER:713info->writes_layer = true;714break;715case TGSI_SEMANTIC_PSIZE:716info->writes_psize = true;717break;718case TGSI_SEMANTIC_CLIPVERTEX:719info->writes_clipvertex = true;720break;721case TGSI_SEMANTIC_COLOR:722info->colors_written |= 1 << semantic_index;723break;724case TGSI_SEMANTIC_STENCIL:725info->writes_stencil = true;726break;727case TGSI_SEMANTIC_SAMPLEMASK:728info->writes_samplemask = true;729break;730case TGSI_SEMANTIC_EDGEFLAG:731info->writes_edgeflag = true;732break;733case TGSI_SEMANTIC_POSITION:734if (info->processor == PIPE_SHADER_FRAGMENT)735info->writes_z = true;736else737info->writes_position = true;738break;739}740741if (nir->info.stage == MESA_SHADER_TESS_CTRL) {742switch (semantic_name) {743case TGSI_SEMANTIC_PATCH:744info->reads_perpatch_outputs = true;745break;746case TGSI_SEMANTIC_TESSINNER:747case TGSI_SEMANTIC_TESSOUTER:748info->reads_tessfactor_outputs = true;749break;750default:751info->reads_pervertex_outputs = true;752}753}754}755756unsigned loc = variable->data.location;757if (nir->info.stage == MESA_SHADER_FRAGMENT &&758loc == FRAG_RESULT_COLOR &&759nir->info.outputs_written & (1ull << loc)) {760assert(attrib_count == 1);761info->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS] = true;762}763}764765if (nir->info.io_lowered) {766uint64_t outputs_written = nir->info.outputs_written;767768while (outputs_written) {769unsigned location = u_bit_scan64(&outputs_written);770unsigned i = util_bitcount64(nir->info.outputs_written &771BITFIELD64_MASK(location));772unsigned semantic_name, semantic_index;773774tgsi_get_gl_varying_semantic(location, need_texcoord,775&semantic_name, &semantic_index);776777info->output_semantic_name[i] = semantic_name;778info->output_semantic_index[i] = semantic_index;779info->output_usagemask[i] = 0xf;780}781num_outputs = util_bitcount64(nir->info.outputs_written);782if (nir->info.outputs_accessed_indirectly)783info->indirect_files |= 1 << TGSI_FILE_OUTPUT;784}785786uint32_t sampler_mask = 0, image_mask = 0;787nir_foreach_uniform_variable(var, nir) {788uint32_t sampler_count = glsl_type_get_sampler_count(var->type);789uint32_t image_count = glsl_type_get_image_count(var->type);790sampler_mask |= ((1ull << sampler_count) - 1) << var->data.binding;791image_mask |= ((1ull << image_count) - 1) << var->data.binding;792}793info->num_outputs = num_outputs;794795info->const_file_max[0] = nir->num_uniforms - 1;796info->const_buffers_declared = u_bit_consecutive(1, nir->info.num_ubos);797if (nir->num_uniforms > 0)798info->const_buffers_declared |= 1;799info->images_declared = image_mask;800info->samplers_declared = sampler_mask;801802info->file_max[TGSI_FILE_SAMPLER] = util_last_bit(info->samplers_declared) - 1;803info->file_max[TGSI_FILE_SAMPLER_VIEW] = BITSET_LAST_BIT(nir->info.textures_used) - 1;804info->file_mask[TGSI_FILE_SAMPLER] = info->samplers_declared;805info->file_mask[TGSI_FILE_SAMPLER_VIEW] = nir->info.textures_used[0];806info->file_max[TGSI_FILE_IMAGE] = util_last_bit(info->images_declared) - 1;807info->file_mask[TGSI_FILE_IMAGE] = info->images_declared;808809info->num_written_clipdistance = nir->info.clip_distance_array_size;810info->num_written_culldistance = nir->info.cull_distance_array_size;811info->clipdist_writemask = u_bit_consecutive(0, info->num_written_clipdistance);812info->culldist_writemask = u_bit_consecutive(0, info->num_written_culldistance);813814if (info->processor == PIPE_SHADER_FRAGMENT)815info->uses_kill = nir->info.fs.uses_discard;816817func = (struct nir_function *)exec_list_get_head_const(&nir->functions);818nir_foreach_block(block, func->impl) {819nir_foreach_instr(instr, block)820scan_instruction(nir, need_texcoord, info, instr);821}822}823824825