1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2014 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg * 23b8e80941Smrg * Authors: 24b8e80941Smrg * Connor Abbott (cwabbott0@gmail.com) 25b8e80941Smrg * 26b8e80941Smrg */ 27b8e80941Smrg 28b8e80941Smrg#include "float64_glsl.h" 29b8e80941Smrg#include "glsl_to_nir.h" 30b8e80941Smrg#include "ir_visitor.h" 31b8e80941Smrg#include "ir_hierarchical_visitor.h" 32b8e80941Smrg#include "ir.h" 33b8e80941Smrg#include "ir_optimization.h" 34b8e80941Smrg#include "program.h" 35b8e80941Smrg#include "compiler/nir/nir_control_flow.h" 36b8e80941Smrg#include "compiler/nir/nir_builder.h" 37b8e80941Smrg#include "main/errors.h" 38b8e80941Smrg#include "main/imports.h" 39b8e80941Smrg#include "main/mtypes.h" 40b8e80941Smrg#include "main/shaderobj.h" 41b8e80941Smrg#include "util/u_math.h" 42b8e80941Smrg 43b8e80941Smrg/* 44b8e80941Smrg * pass to lower GLSL IR to NIR 45b8e80941Smrg * 46b8e80941Smrg * This will lower variable dereferences to loads/stores of corresponding 47b8e80941Smrg * variables in NIR - the variables will be converted to registers in a later 48b8e80941Smrg * pass. 49b8e80941Smrg */ 50b8e80941Smrg 51b8e80941Smrgnamespace { 52b8e80941Smrg 53b8e80941Smrgclass nir_visitor : public ir_visitor 54b8e80941Smrg{ 55b8e80941Smrgpublic: 56b8e80941Smrg nir_visitor(gl_context *ctx, nir_shader *shader); 57b8e80941Smrg ~nir_visitor(); 58b8e80941Smrg 59b8e80941Smrg virtual void visit(ir_variable *); 60b8e80941Smrg virtual void visit(ir_function *); 61b8e80941Smrg virtual void visit(ir_function_signature *); 62b8e80941Smrg virtual void visit(ir_loop *); 63b8e80941Smrg virtual void visit(ir_if *); 64b8e80941Smrg virtual void visit(ir_discard *); 65b8e80941Smrg virtual void visit(ir_loop_jump *); 66b8e80941Smrg virtual void visit(ir_return *); 67b8e80941Smrg virtual void visit(ir_call *); 68b8e80941Smrg virtual void visit(ir_assignment *); 69b8e80941Smrg virtual void visit(ir_emit_vertex *); 70b8e80941Smrg virtual void visit(ir_end_primitive *); 71b8e80941Smrg virtual void visit(ir_expression *); 72b8e80941Smrg virtual void visit(ir_swizzle *); 73b8e80941Smrg virtual void visit(ir_texture *); 74b8e80941Smrg virtual void visit(ir_constant *); 75b8e80941Smrg virtual void visit(ir_dereference_variable *); 76b8e80941Smrg virtual void visit(ir_dereference_record *); 77b8e80941Smrg virtual void visit(ir_dereference_array *); 78b8e80941Smrg virtual void visit(ir_barrier *); 79b8e80941Smrg 80b8e80941Smrg void create_function(ir_function_signature *ir); 81b8e80941Smrg 82b8e80941Smrgprivate: 83b8e80941Smrg void add_instr(nir_instr *instr, unsigned num_components, unsigned bit_size); 84b8e80941Smrg nir_ssa_def *evaluate_rvalue(ir_rvalue *ir); 85b8e80941Smrg 86b8e80941Smrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def **srcs); 87b8e80941Smrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1); 88b8e80941Smrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1, 89b8e80941Smrg nir_ssa_def *src2); 90b8e80941Smrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1, 91b8e80941Smrg nir_ssa_def *src2, nir_ssa_def *src3); 92b8e80941Smrg 93b8e80941Smrg bool supports_ints; 94b8e80941Smrg bool supports_std430; 95b8e80941Smrg 96b8e80941Smrg nir_shader *shader; 97b8e80941Smrg nir_function_impl *impl; 98b8e80941Smrg nir_builder b; 99b8e80941Smrg nir_ssa_def *result; /* result of the expression tree last visited */ 100b8e80941Smrg 101b8e80941Smrg nir_deref_instr *evaluate_deref(ir_instruction *ir); 102b8e80941Smrg 103b8e80941Smrg nir_constant *constant_copy(ir_constant *ir, void *mem_ctx); 104b8e80941Smrg 105b8e80941Smrg /* most recent deref instruction created */ 106b8e80941Smrg nir_deref_instr *deref; 107b8e80941Smrg 108b8e80941Smrg /* whether the IR we're operating on is per-function or global */ 109b8e80941Smrg bool is_global; 110b8e80941Smrg 111b8e80941Smrg ir_function_signature *sig; 112b8e80941Smrg 113b8e80941Smrg /* map of ir_variable -> nir_variable */ 114b8e80941Smrg struct hash_table *var_table; 115b8e80941Smrg 116b8e80941Smrg /* map of ir_function_signature -> nir_function_overload */ 117b8e80941Smrg struct hash_table *overload_table; 118b8e80941Smrg}; 119b8e80941Smrg 120b8e80941Smrg/* 121b8e80941Smrg * This visitor runs before the main visitor, calling create_function() for 122b8e80941Smrg * each function so that the main visitor can resolve forward references in 123b8e80941Smrg * calls. 124b8e80941Smrg */ 125b8e80941Smrg 126b8e80941Smrgclass nir_function_visitor : public ir_hierarchical_visitor 127b8e80941Smrg{ 128b8e80941Smrgpublic: 129b8e80941Smrg nir_function_visitor(nir_visitor *v) : visitor(v) 130b8e80941Smrg { 131b8e80941Smrg } 132b8e80941Smrg virtual ir_visitor_status visit_enter(ir_function *); 133b8e80941Smrg 134b8e80941Smrgprivate: 135b8e80941Smrg nir_visitor *visitor; 136b8e80941Smrg}; 137b8e80941Smrg 138b8e80941Smrg/* glsl_to_nir can only handle converting certain function paramaters 139b8e80941Smrg * to NIR. This visitor checks for parameters it can't currently handle. 140b8e80941Smrg */ 141b8e80941Smrgclass ir_function_param_visitor : public ir_hierarchical_visitor 142b8e80941Smrg{ 143b8e80941Smrgpublic: 144b8e80941Smrg ir_function_param_visitor() 145b8e80941Smrg : unsupported(false) 146b8e80941Smrg { 147b8e80941Smrg } 148b8e80941Smrg 149b8e80941Smrg virtual ir_visitor_status visit_enter(ir_function_signature *ir) 150b8e80941Smrg { 151b8e80941Smrg 152b8e80941Smrg if (ir->is_intrinsic()) 153b8e80941Smrg return visit_continue; 154b8e80941Smrg 155b8e80941Smrg foreach_in_list(ir_variable, param, &ir->parameters) { 156b8e80941Smrg if (!param->type->is_vector() || !param->type->is_scalar()) { 157b8e80941Smrg unsupported = true; 158b8e80941Smrg return visit_stop; 159b8e80941Smrg } 160b8e80941Smrg 161b8e80941Smrg if (param->data.mode == ir_var_function_inout) { 162b8e80941Smrg unsupported = true; 163b8e80941Smrg return visit_stop; 164b8e80941Smrg } 165b8e80941Smrg } 166b8e80941Smrg 167b8e80941Smrg return visit_continue; 168b8e80941Smrg } 169b8e80941Smrg 170b8e80941Smrg bool unsupported; 171b8e80941Smrg}; 172b8e80941Smrg 173b8e80941Smrg} /* end of anonymous namespace */ 174b8e80941Smrg 175b8e80941Smrg 176b8e80941Smrgstatic bool 177b8e80941Smrghas_unsupported_function_param(exec_list *ir) 178b8e80941Smrg{ 179b8e80941Smrg ir_function_param_visitor visitor; 180b8e80941Smrg visit_list_elements(&visitor, ir); 181b8e80941Smrg return visitor.unsupported; 182b8e80941Smrg} 183b8e80941Smrg 184b8e80941Smrgnir_shader * 185b8e80941Smrgglsl_to_nir(struct gl_context *ctx, 186b8e80941Smrg const struct gl_shader_program *shader_prog, 187b8e80941Smrg gl_shader_stage stage, 188b8e80941Smrg const nir_shader_compiler_options *options) 189b8e80941Smrg{ 190b8e80941Smrg struct gl_linked_shader *sh = shader_prog->_LinkedShaders[stage]; 191b8e80941Smrg 192b8e80941Smrg const struct gl_shader_compiler_options *gl_options = 193b8e80941Smrg &ctx->Const.ShaderCompilerOptions[stage]; 194b8e80941Smrg 195b8e80941Smrg /* glsl_to_nir can only handle converting certain function paramaters 196b8e80941Smrg * to NIR. If we find something we can't handle then we get the GLSL IR 197b8e80941Smrg * opts to remove it before we continue on. 198b8e80941Smrg * 199b8e80941Smrg * TODO: add missing glsl ir to nir support and remove this loop. 200b8e80941Smrg */ 201b8e80941Smrg while (has_unsupported_function_param(sh->ir)) { 202b8e80941Smrg do_common_optimization(sh->ir, true, true, gl_options, 203b8e80941Smrg ctx->Const.NativeIntegers); 204b8e80941Smrg } 205b8e80941Smrg 206b8e80941Smrg nir_shader *shader = nir_shader_create(NULL, stage, options, 207b8e80941Smrg &sh->Program->info); 208b8e80941Smrg 209b8e80941Smrg nir_visitor v1(ctx, shader); 210b8e80941Smrg nir_function_visitor v2(&v1); 211b8e80941Smrg v2.run(sh->ir); 212b8e80941Smrg visit_exec_list(sh->ir, &v1); 213b8e80941Smrg 214b8e80941Smrg nir_validate_shader(shader, "after glsl to nir, before function inline"); 215b8e80941Smrg 216b8e80941Smrg /* We have to lower away local constant initializers right before we 217b8e80941Smrg * inline functions. That way they get properly initialized at the top 218b8e80941Smrg * of the function and not at the top of its caller. 219b8e80941Smrg */ 220b8e80941Smrg nir_lower_constant_initializers(shader, (nir_variable_mode)~0); 221b8e80941Smrg nir_lower_returns(shader); 222b8e80941Smrg nir_inline_functions(shader); 223b8e80941Smrg nir_opt_deref(shader); 224b8e80941Smrg 225b8e80941Smrg nir_validate_shader(shader, "after function inlining and return lowering"); 226b8e80941Smrg 227b8e80941Smrg /* Now that we have inlined everything remove all of the functions except 228b8e80941Smrg * main(). 229b8e80941Smrg */ 230b8e80941Smrg foreach_list_typed_safe(nir_function, function, node, &(shader)->functions){ 231b8e80941Smrg if (strcmp("main", function->name) != 0) { 232b8e80941Smrg exec_node_remove(&function->node); 233b8e80941Smrg } 234b8e80941Smrg } 235b8e80941Smrg 236b8e80941Smrg /* Remap the locations to slots so those requiring two slots will occupy 237b8e80941Smrg * two locations. For instance, if we have in the IR code a dvec3 attr0 in 238b8e80941Smrg * location 0 and vec4 attr1 in location 1, in NIR attr0 will use 239b8e80941Smrg * locations/slots 0 and 1, and attr1 will use location/slot 2 */ 240b8e80941Smrg if (shader->info.stage == MESA_SHADER_VERTEX) 241b8e80941Smrg nir_remap_dual_slot_attributes(shader, &sh->Program->DualSlotInputs); 242b8e80941Smrg 243b8e80941Smrg shader->info.name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name); 244b8e80941Smrg if (shader_prog->Label) 245b8e80941Smrg shader->info.label = ralloc_strdup(shader, shader_prog->Label); 246b8e80941Smrg 247b8e80941Smrg /* Check for transform feedback varyings specified via the API */ 248b8e80941Smrg shader->info.has_transform_feedback_varyings = 249b8e80941Smrg shader_prog->TransformFeedback.NumVarying > 0; 250b8e80941Smrg 251b8e80941Smrg /* Check for transform feedback varyings specified in the Shader */ 252b8e80941Smrg if (shader_prog->last_vert_prog) 253b8e80941Smrg shader->info.has_transform_feedback_varyings |= 254b8e80941Smrg shader_prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying > 0; 255b8e80941Smrg 256b8e80941Smrg if (shader->info.stage == MESA_SHADER_FRAGMENT) { 257b8e80941Smrg shader->info.fs.pixel_center_integer = sh->Program->info.fs.pixel_center_integer; 258b8e80941Smrg shader->info.fs.origin_upper_left = sh->Program->info.fs.origin_upper_left; 259b8e80941Smrg } 260b8e80941Smrg 261b8e80941Smrg return shader; 262b8e80941Smrg} 263b8e80941Smrg 264b8e80941Smrgnir_visitor::nir_visitor(gl_context *ctx, nir_shader *shader) 265b8e80941Smrg{ 266b8e80941Smrg this->supports_ints = shader->options->native_integers; 267b8e80941Smrg this->supports_std430 = ctx->Const.UseSTD430AsDefaultPacking; 268b8e80941Smrg this->shader = shader; 269b8e80941Smrg this->is_global = true; 270b8e80941Smrg this->var_table = _mesa_pointer_hash_table_create(NULL); 271b8e80941Smrg this->overload_table = _mesa_pointer_hash_table_create(NULL); 272b8e80941Smrg this->result = NULL; 273b8e80941Smrg this->impl = NULL; 274b8e80941Smrg this->deref = NULL; 275b8e80941Smrg memset(&this->b, 0, sizeof(this->b)); 276b8e80941Smrg} 277b8e80941Smrg 278b8e80941Smrgnir_visitor::~nir_visitor() 279b8e80941Smrg{ 280b8e80941Smrg _mesa_hash_table_destroy(this->var_table, NULL); 281b8e80941Smrg _mesa_hash_table_destroy(this->overload_table, NULL); 282b8e80941Smrg} 283b8e80941Smrg 284b8e80941Smrgnir_deref_instr * 285b8e80941Smrgnir_visitor::evaluate_deref(ir_instruction *ir) 286b8e80941Smrg{ 287b8e80941Smrg ir->accept(this); 288b8e80941Smrg return this->deref; 289b8e80941Smrg} 290b8e80941Smrg 291b8e80941Smrgnir_constant * 292b8e80941Smrgnir_visitor::constant_copy(ir_constant *ir, void *mem_ctx) 293b8e80941Smrg{ 294b8e80941Smrg if (ir == NULL) 295b8e80941Smrg return NULL; 296b8e80941Smrg 297b8e80941Smrg nir_constant *ret = rzalloc(mem_ctx, nir_constant); 298b8e80941Smrg 299b8e80941Smrg const unsigned rows = ir->type->vector_elements; 300b8e80941Smrg const unsigned cols = ir->type->matrix_columns; 301b8e80941Smrg unsigned i; 302b8e80941Smrg 303b8e80941Smrg ret->num_elements = 0; 304b8e80941Smrg switch (ir->type->base_type) { 305b8e80941Smrg case GLSL_TYPE_UINT: 306b8e80941Smrg /* Only float base types can be matrices. */ 307b8e80941Smrg assert(cols == 1); 308b8e80941Smrg 309b8e80941Smrg for (unsigned r = 0; r < rows; r++) 310b8e80941Smrg if (supports_ints) 311b8e80941Smrg ret->values[0][r].u32 = ir->value.u[r]; 312b8e80941Smrg else 313b8e80941Smrg ret->values[0][r].f32 = ir->value.u[r]; 314b8e80941Smrg 315b8e80941Smrg break; 316b8e80941Smrg 317b8e80941Smrg case GLSL_TYPE_INT: 318b8e80941Smrg /* Only float base types can be matrices. */ 319b8e80941Smrg assert(cols == 1); 320b8e80941Smrg 321b8e80941Smrg for (unsigned r = 0; r < rows; r++) 322b8e80941Smrg if (supports_ints) 323b8e80941Smrg ret->values[0][r].i32 = ir->value.i[r]; 324b8e80941Smrg else 325b8e80941Smrg ret->values[0][r].f32 = ir->value.i[r]; 326b8e80941Smrg 327b8e80941Smrg break; 328b8e80941Smrg 329b8e80941Smrg case GLSL_TYPE_FLOAT: 330b8e80941Smrg for (unsigned c = 0; c < cols; c++) { 331b8e80941Smrg for (unsigned r = 0; r < rows; r++) 332b8e80941Smrg ret->values[c][r].f32 = ir->value.f[c * rows + r]; 333b8e80941Smrg } 334b8e80941Smrg break; 335b8e80941Smrg 336b8e80941Smrg case GLSL_TYPE_DOUBLE: 337b8e80941Smrg for (unsigned c = 0; c < cols; c++) { 338b8e80941Smrg for (unsigned r = 0; r < rows; r++) 339b8e80941Smrg ret->values[c][r].f64 = ir->value.d[c * rows + r]; 340b8e80941Smrg } 341b8e80941Smrg break; 342b8e80941Smrg 343b8e80941Smrg case GLSL_TYPE_UINT64: 344b8e80941Smrg /* Only float base types can be matrices. */ 345b8e80941Smrg assert(cols == 1); 346b8e80941Smrg 347b8e80941Smrg for (unsigned r = 0; r < rows; r++) 348b8e80941Smrg ret->values[0][r].u64 = ir->value.u64[r]; 349b8e80941Smrg break; 350b8e80941Smrg 351b8e80941Smrg case GLSL_TYPE_INT64: 352b8e80941Smrg /* Only float base types can be matrices. */ 353b8e80941Smrg assert(cols == 1); 354b8e80941Smrg 355b8e80941Smrg for (unsigned r = 0; r < rows; r++) 356b8e80941Smrg ret->values[0][r].i64 = ir->value.i64[r]; 357b8e80941Smrg break; 358b8e80941Smrg 359b8e80941Smrg case GLSL_TYPE_BOOL: 360b8e80941Smrg /* Only float base types can be matrices. */ 361b8e80941Smrg assert(cols == 1); 362b8e80941Smrg 363b8e80941Smrg for (unsigned r = 0; r < rows; r++) 364b8e80941Smrg ret->values[0][r].b = ir->value.b[r]; 365b8e80941Smrg 366b8e80941Smrg break; 367b8e80941Smrg 368b8e80941Smrg case GLSL_TYPE_STRUCT: 369b8e80941Smrg case GLSL_TYPE_ARRAY: 370b8e80941Smrg ret->elements = ralloc_array(mem_ctx, nir_constant *, 371b8e80941Smrg ir->type->length); 372b8e80941Smrg ret->num_elements = ir->type->length; 373b8e80941Smrg 374b8e80941Smrg for (i = 0; i < ir->type->length; i++) 375b8e80941Smrg ret->elements[i] = constant_copy(ir->const_elements[i], mem_ctx); 376b8e80941Smrg break; 377b8e80941Smrg 378b8e80941Smrg default: 379b8e80941Smrg unreachable("not reached"); 380b8e80941Smrg } 381b8e80941Smrg 382b8e80941Smrg return ret; 383b8e80941Smrg} 384b8e80941Smrg 385b8e80941Smrgstatic const glsl_type * 386b8e80941Smrgwrap_type_in_array(const glsl_type *elem_type, const glsl_type *array_type) 387b8e80941Smrg{ 388b8e80941Smrg if (!array_type->is_array()) 389b8e80941Smrg return elem_type; 390b8e80941Smrg 391b8e80941Smrg elem_type = wrap_type_in_array(elem_type, array_type->fields.array); 392b8e80941Smrg 393b8e80941Smrg return glsl_type::get_array_instance(elem_type, array_type->length); 394b8e80941Smrg} 395b8e80941Smrg 396b8e80941Smrgvoid 397b8e80941Smrgnir_visitor::visit(ir_variable *ir) 398b8e80941Smrg{ 399b8e80941Smrg /* TODO: In future we should switch to using the NIR lowering pass but for 400b8e80941Smrg * now just ignore these variables as GLSL IR should have lowered them. 401b8e80941Smrg * Anything remaining are just dead vars that weren't cleaned up. 402b8e80941Smrg */ 403b8e80941Smrg if (ir->data.mode == ir_var_shader_shared) 404b8e80941Smrg return; 405b8e80941Smrg 406b8e80941Smrg /* FINISHME: inout parameters */ 407b8e80941Smrg assert(ir->data.mode != ir_var_function_inout); 408b8e80941Smrg 409b8e80941Smrg if (ir->data.mode == ir_var_function_out) 410b8e80941Smrg return; 411b8e80941Smrg 412b8e80941Smrg nir_variable *var = rzalloc(shader, nir_variable); 413b8e80941Smrg var->type = ir->type; 414b8e80941Smrg var->name = ralloc_strdup(var, ir->name); 415b8e80941Smrg 416b8e80941Smrg var->data.always_active_io = ir->data.always_active_io; 417b8e80941Smrg var->data.read_only = ir->data.read_only; 418b8e80941Smrg var->data.centroid = ir->data.centroid; 419b8e80941Smrg var->data.sample = ir->data.sample; 420b8e80941Smrg var->data.patch = ir->data.patch; 421b8e80941Smrg var->data.invariant = ir->data.invariant; 422b8e80941Smrg var->data.location = ir->data.location; 423b8e80941Smrg var->data.stream = ir->data.stream; 424b8e80941Smrg var->data.compact = false; 425b8e80941Smrg 426b8e80941Smrg switch(ir->data.mode) { 427b8e80941Smrg case ir_var_auto: 428b8e80941Smrg case ir_var_temporary: 429b8e80941Smrg if (is_global) 430b8e80941Smrg var->data.mode = nir_var_shader_temp; 431b8e80941Smrg else 432b8e80941Smrg var->data.mode = nir_var_function_temp; 433b8e80941Smrg break; 434b8e80941Smrg 435b8e80941Smrg case ir_var_function_in: 436b8e80941Smrg case ir_var_const_in: 437b8e80941Smrg var->data.mode = nir_var_function_temp; 438b8e80941Smrg break; 439b8e80941Smrg 440b8e80941Smrg case ir_var_shader_in: 441b8e80941Smrg if (shader->info.stage == MESA_SHADER_FRAGMENT && 442b8e80941Smrg ir->data.location == VARYING_SLOT_FACE) { 443b8e80941Smrg /* For whatever reason, GLSL IR makes gl_FrontFacing an input */ 444b8e80941Smrg var->data.location = SYSTEM_VALUE_FRONT_FACE; 445b8e80941Smrg var->data.mode = nir_var_system_value; 446b8e80941Smrg } else if (shader->info.stage == MESA_SHADER_GEOMETRY && 447b8e80941Smrg ir->data.location == VARYING_SLOT_PRIMITIVE_ID) { 448b8e80941Smrg /* For whatever reason, GLSL IR makes gl_PrimitiveIDIn an input */ 449b8e80941Smrg var->data.location = SYSTEM_VALUE_PRIMITIVE_ID; 450b8e80941Smrg var->data.mode = nir_var_system_value; 451b8e80941Smrg } else { 452b8e80941Smrg var->data.mode = nir_var_shader_in; 453b8e80941Smrg 454b8e80941Smrg if (shader->info.stage == MESA_SHADER_TESS_EVAL && 455b8e80941Smrg (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER || 456b8e80941Smrg ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) { 457b8e80941Smrg var->data.compact = ir->type->without_array()->is_scalar(); 458b8e80941Smrg } 459b8e80941Smrg 460b8e80941Smrg if (shader->info.stage > MESA_SHADER_VERTEX && 461b8e80941Smrg ir->data.location >= VARYING_SLOT_CLIP_DIST0 && 462b8e80941Smrg ir->data.location <= VARYING_SLOT_CULL_DIST1) { 463b8e80941Smrg var->data.compact = ir->type->without_array()->is_scalar(); 464b8e80941Smrg } 465b8e80941Smrg } 466b8e80941Smrg break; 467b8e80941Smrg 468b8e80941Smrg case ir_var_shader_out: 469b8e80941Smrg var->data.mode = nir_var_shader_out; 470b8e80941Smrg if (shader->info.stage == MESA_SHADER_TESS_CTRL && 471b8e80941Smrg (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER || 472b8e80941Smrg ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) { 473b8e80941Smrg var->data.compact = ir->type->without_array()->is_scalar(); 474b8e80941Smrg } 475b8e80941Smrg 476b8e80941Smrg if (shader->info.stage <= MESA_SHADER_GEOMETRY && 477b8e80941Smrg ir->data.location >= VARYING_SLOT_CLIP_DIST0 && 478b8e80941Smrg ir->data.location <= VARYING_SLOT_CULL_DIST1) { 479b8e80941Smrg var->data.compact = ir->type->without_array()->is_scalar(); 480b8e80941Smrg } 481b8e80941Smrg break; 482b8e80941Smrg 483b8e80941Smrg case ir_var_uniform: 484b8e80941Smrg if (ir->get_interface_type()) 485b8e80941Smrg var->data.mode = nir_var_mem_ubo; 486b8e80941Smrg else 487b8e80941Smrg var->data.mode = nir_var_uniform; 488b8e80941Smrg break; 489b8e80941Smrg 490b8e80941Smrg case ir_var_shader_storage: 491b8e80941Smrg var->data.mode = nir_var_mem_ssbo; 492b8e80941Smrg break; 493b8e80941Smrg 494b8e80941Smrg case ir_var_system_value: 495b8e80941Smrg var->data.mode = nir_var_system_value; 496b8e80941Smrg break; 497b8e80941Smrg 498b8e80941Smrg default: 499b8e80941Smrg unreachable("not reached"); 500b8e80941Smrg } 501b8e80941Smrg 502b8e80941Smrg unsigned image_access = 0; 503b8e80941Smrg if (ir->data.memory_read_only) 504b8e80941Smrg image_access |= ACCESS_NON_WRITEABLE; 505b8e80941Smrg if (ir->data.memory_write_only) 506b8e80941Smrg image_access |= ACCESS_NON_READABLE; 507b8e80941Smrg if (ir->data.memory_coherent) 508b8e80941Smrg image_access |= ACCESS_COHERENT; 509b8e80941Smrg if (ir->data.memory_volatile) 510b8e80941Smrg image_access |= ACCESS_VOLATILE; 511b8e80941Smrg if (ir->data.memory_restrict) 512b8e80941Smrg image_access |= ACCESS_RESTRICT; 513b8e80941Smrg 514b8e80941Smrg /* For UBO and SSBO variables, we need explicit types */ 515b8e80941Smrg if (var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo)) { 516b8e80941Smrg const glsl_type *explicit_ifc_type = 517b8e80941Smrg ir->get_interface_type()->get_explicit_interface_type(supports_std430); 518b8e80941Smrg 519b8e80941Smrg if (ir->type->without_array()->is_interface()) { 520b8e80941Smrg /* If the type contains the interface, wrap the explicit type in the 521b8e80941Smrg * right number of arrays. 522b8e80941Smrg */ 523b8e80941Smrg var->type = wrap_type_in_array(explicit_ifc_type, ir->type); 524b8e80941Smrg } else { 525b8e80941Smrg /* Otherwise, this variable is one entry in the interface */ 526b8e80941Smrg UNUSED bool found = false; 527b8e80941Smrg for (unsigned i = 0; i < explicit_ifc_type->length; i++) { 528b8e80941Smrg const glsl_struct_field *field = 529b8e80941Smrg &explicit_ifc_type->fields.structure[i]; 530b8e80941Smrg if (strcmp(ir->name, field->name) != 0) 531b8e80941Smrg continue; 532b8e80941Smrg 533b8e80941Smrg var->type = field->type; 534b8e80941Smrg if (field->memory_read_only) 535b8e80941Smrg image_access |= ACCESS_NON_WRITEABLE; 536b8e80941Smrg if (field->memory_write_only) 537b8e80941Smrg image_access |= ACCESS_NON_READABLE; 538b8e80941Smrg if (field->memory_coherent) 539b8e80941Smrg image_access |= ACCESS_COHERENT; 540b8e80941Smrg if (field->memory_volatile) 541b8e80941Smrg image_access |= ACCESS_VOLATILE; 542b8e80941Smrg if (field->memory_restrict) 543b8e80941Smrg image_access |= ACCESS_RESTRICT; 544b8e80941Smrg 545b8e80941Smrg found = true; 546b8e80941Smrg break; 547b8e80941Smrg } 548b8e80941Smrg assert(found); 549b8e80941Smrg } 550b8e80941Smrg } 551b8e80941Smrg 552b8e80941Smrg var->data.interpolation = ir->data.interpolation; 553b8e80941Smrg var->data.location_frac = ir->data.location_frac; 554b8e80941Smrg 555b8e80941Smrg switch (ir->data.depth_layout) { 556b8e80941Smrg case ir_depth_layout_none: 557b8e80941Smrg var->data.depth_layout = nir_depth_layout_none; 558b8e80941Smrg break; 559b8e80941Smrg case ir_depth_layout_any: 560b8e80941Smrg var->data.depth_layout = nir_depth_layout_any; 561b8e80941Smrg break; 562b8e80941Smrg case ir_depth_layout_greater: 563b8e80941Smrg var->data.depth_layout = nir_depth_layout_greater; 564b8e80941Smrg break; 565b8e80941Smrg case ir_depth_layout_less: 566b8e80941Smrg var->data.depth_layout = nir_depth_layout_less; 567b8e80941Smrg break; 568b8e80941Smrg case ir_depth_layout_unchanged: 569b8e80941Smrg var->data.depth_layout = nir_depth_layout_unchanged; 570b8e80941Smrg break; 571b8e80941Smrg default: 572b8e80941Smrg unreachable("not reached"); 573b8e80941Smrg } 574b8e80941Smrg 575b8e80941Smrg var->data.index = ir->data.index; 576b8e80941Smrg var->data.descriptor_set = 0; 577b8e80941Smrg var->data.binding = ir->data.binding; 578b8e80941Smrg var->data.explicit_binding = ir->data.explicit_binding; 579b8e80941Smrg var->data.bindless = ir->data.bindless; 580b8e80941Smrg var->data.offset = ir->data.offset; 581b8e80941Smrg 582b8e80941Smrg var->data.image.access = (gl_access_qualifier)image_access; 583b8e80941Smrg var->data.image.format = ir->data.image_format; 584b8e80941Smrg 585b8e80941Smrg var->data.fb_fetch_output = ir->data.fb_fetch_output; 586b8e80941Smrg var->data.explicit_xfb_buffer = ir->data.explicit_xfb_buffer; 587b8e80941Smrg var->data.explicit_xfb_stride = ir->data.explicit_xfb_stride; 588b8e80941Smrg var->data.xfb_buffer = ir->data.xfb_buffer; 589b8e80941Smrg var->data.xfb_stride = ir->data.xfb_stride; 590b8e80941Smrg 591b8e80941Smrg var->num_state_slots = ir->get_num_state_slots(); 592b8e80941Smrg if (var->num_state_slots > 0) { 593b8e80941Smrg var->state_slots = rzalloc_array(var, nir_state_slot, 594b8e80941Smrg var->num_state_slots); 595b8e80941Smrg 596b8e80941Smrg ir_state_slot *state_slots = ir->get_state_slots(); 597b8e80941Smrg for (unsigned i = 0; i < var->num_state_slots; i++) { 598b8e80941Smrg for (unsigned j = 0; j < 5; j++) 599b8e80941Smrg var->state_slots[i].tokens[j] = state_slots[i].tokens[j]; 600b8e80941Smrg var->state_slots[i].swizzle = state_slots[i].swizzle; 601b8e80941Smrg } 602b8e80941Smrg } else { 603b8e80941Smrg var->state_slots = NULL; 604b8e80941Smrg } 605b8e80941Smrg 606b8e80941Smrg var->constant_initializer = constant_copy(ir->constant_initializer, var); 607b8e80941Smrg 608b8e80941Smrg var->interface_type = ir->get_interface_type(); 609b8e80941Smrg 610b8e80941Smrg if (var->data.mode == nir_var_function_temp) 611b8e80941Smrg nir_function_impl_add_variable(impl, var); 612b8e80941Smrg else 613b8e80941Smrg nir_shader_add_variable(shader, var); 614b8e80941Smrg 615b8e80941Smrg _mesa_hash_table_insert(var_table, ir, var); 616b8e80941Smrg} 617b8e80941Smrg 618b8e80941Smrgir_visitor_status 619b8e80941Smrgnir_function_visitor::visit_enter(ir_function *ir) 620b8e80941Smrg{ 621b8e80941Smrg foreach_in_list(ir_function_signature, sig, &ir->signatures) { 622b8e80941Smrg visitor->create_function(sig); 623b8e80941Smrg } 624b8e80941Smrg return visit_continue_with_parent; 625b8e80941Smrg} 626b8e80941Smrg 627b8e80941Smrgvoid 628b8e80941Smrgnir_visitor::create_function(ir_function_signature *ir) 629b8e80941Smrg{ 630b8e80941Smrg if (ir->is_intrinsic()) 631b8e80941Smrg return; 632b8e80941Smrg 633b8e80941Smrg nir_function *func = nir_function_create(shader, ir->function_name()); 634b8e80941Smrg if (strcmp(ir->function_name(), "main") == 0) 635b8e80941Smrg func->is_entrypoint = true; 636b8e80941Smrg 637b8e80941Smrg func->num_params = ir->parameters.length() + 638b8e80941Smrg (ir->return_type != glsl_type::void_type); 639b8e80941Smrg func->params = ralloc_array(shader, nir_parameter, func->num_params); 640b8e80941Smrg 641b8e80941Smrg unsigned np = 0; 642b8e80941Smrg 643b8e80941Smrg if (ir->return_type != glsl_type::void_type) { 644b8e80941Smrg /* The return value is a variable deref (basically an out parameter) */ 645b8e80941Smrg func->params[np].num_components = 1; 646b8e80941Smrg func->params[np].bit_size = 32; 647b8e80941Smrg np++; 648b8e80941Smrg } 649b8e80941Smrg 650b8e80941Smrg foreach_in_list(ir_variable, param, &ir->parameters) { 651b8e80941Smrg /* FINISHME: pass arrays, structs, etc by reference? */ 652b8e80941Smrg assert(param->type->is_vector() || param->type->is_scalar()); 653b8e80941Smrg 654b8e80941Smrg if (param->data.mode == ir_var_function_in) { 655b8e80941Smrg func->params[np].num_components = param->type->vector_elements; 656b8e80941Smrg func->params[np].bit_size = glsl_get_bit_size(param->type); 657b8e80941Smrg } else { 658b8e80941Smrg func->params[np].num_components = 1; 659b8e80941Smrg func->params[np].bit_size = 32; 660b8e80941Smrg } 661b8e80941Smrg np++; 662b8e80941Smrg } 663b8e80941Smrg assert(np == func->num_params); 664b8e80941Smrg 665b8e80941Smrg _mesa_hash_table_insert(this->overload_table, ir, func); 666b8e80941Smrg} 667b8e80941Smrg 668b8e80941Smrgvoid 669b8e80941Smrgnir_visitor::visit(ir_function *ir) 670b8e80941Smrg{ 671b8e80941Smrg foreach_in_list(ir_function_signature, sig, &ir->signatures) 672b8e80941Smrg sig->accept(this); 673b8e80941Smrg} 674b8e80941Smrg 675b8e80941Smrgvoid 676b8e80941Smrgnir_visitor::visit(ir_function_signature *ir) 677b8e80941Smrg{ 678b8e80941Smrg if (ir->is_intrinsic()) 679b8e80941Smrg return; 680b8e80941Smrg 681b8e80941Smrg this->sig = ir; 682b8e80941Smrg 683b8e80941Smrg struct hash_entry *entry = 684b8e80941Smrg _mesa_hash_table_search(this->overload_table, ir); 685b8e80941Smrg 686b8e80941Smrg assert(entry); 687b8e80941Smrg nir_function *func = (nir_function *) entry->data; 688b8e80941Smrg 689b8e80941Smrg if (ir->is_defined) { 690b8e80941Smrg nir_function_impl *impl = nir_function_impl_create(func); 691b8e80941Smrg this->impl = impl; 692b8e80941Smrg 693b8e80941Smrg this->is_global = false; 694b8e80941Smrg 695b8e80941Smrg nir_builder_init(&b, impl); 696b8e80941Smrg b.cursor = nir_after_cf_list(&impl->body); 697b8e80941Smrg 698b8e80941Smrg unsigned i = (ir->return_type != glsl_type::void_type) ? 1 : 0; 699b8e80941Smrg 700b8e80941Smrg foreach_in_list(ir_variable, param, &ir->parameters) { 701b8e80941Smrg nir_variable *var = 702b8e80941Smrg nir_local_variable_create(impl, param->type, param->name); 703b8e80941Smrg 704b8e80941Smrg if (param->data.mode == ir_var_function_in) { 705b8e80941Smrg nir_store_var(&b, var, nir_load_param(&b, i), ~0); 706b8e80941Smrg } 707b8e80941Smrg 708b8e80941Smrg _mesa_hash_table_insert(var_table, param, var); 709b8e80941Smrg i++; 710b8e80941Smrg } 711b8e80941Smrg 712b8e80941Smrg visit_exec_list(&ir->body, this); 713b8e80941Smrg 714b8e80941Smrg this->is_global = true; 715b8e80941Smrg } else { 716b8e80941Smrg func->impl = NULL; 717b8e80941Smrg } 718b8e80941Smrg} 719b8e80941Smrg 720b8e80941Smrgvoid 721b8e80941Smrgnir_visitor::visit(ir_loop *ir) 722b8e80941Smrg{ 723b8e80941Smrg nir_push_loop(&b); 724b8e80941Smrg visit_exec_list(&ir->body_instructions, this); 725b8e80941Smrg nir_pop_loop(&b, NULL); 726b8e80941Smrg} 727b8e80941Smrg 728b8e80941Smrgvoid 729b8e80941Smrgnir_visitor::visit(ir_if *ir) 730b8e80941Smrg{ 731b8e80941Smrg nir_push_if(&b, evaluate_rvalue(ir->condition)); 732b8e80941Smrg visit_exec_list(&ir->then_instructions, this); 733b8e80941Smrg nir_push_else(&b, NULL); 734b8e80941Smrg visit_exec_list(&ir->else_instructions, this); 735b8e80941Smrg nir_pop_if(&b, NULL); 736b8e80941Smrg} 737b8e80941Smrg 738b8e80941Smrgvoid 739b8e80941Smrgnir_visitor::visit(ir_discard *ir) 740b8e80941Smrg{ 741b8e80941Smrg /* 742b8e80941Smrg * discards aren't treated as control flow, because before we lower them 743b8e80941Smrg * they can appear anywhere in the shader and the stuff after them may still 744b8e80941Smrg * be executed (yay, crazy GLSL rules!). However, after lowering, all the 745b8e80941Smrg * discards will be immediately followed by a return. 746b8e80941Smrg */ 747b8e80941Smrg 748b8e80941Smrg nir_intrinsic_instr *discard; 749b8e80941Smrg if (ir->condition) { 750b8e80941Smrg discard = nir_intrinsic_instr_create(this->shader, 751b8e80941Smrg nir_intrinsic_discard_if); 752b8e80941Smrg discard->src[0] = 753b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->condition)); 754b8e80941Smrg } else { 755b8e80941Smrg discard = nir_intrinsic_instr_create(this->shader, nir_intrinsic_discard); 756b8e80941Smrg } 757b8e80941Smrg 758b8e80941Smrg nir_builder_instr_insert(&b, &discard->instr); 759b8e80941Smrg} 760b8e80941Smrg 761b8e80941Smrgvoid 762b8e80941Smrgnir_visitor::visit(ir_emit_vertex *ir) 763b8e80941Smrg{ 764b8e80941Smrg nir_intrinsic_instr *instr = 765b8e80941Smrg nir_intrinsic_instr_create(this->shader, nir_intrinsic_emit_vertex); 766b8e80941Smrg nir_intrinsic_set_stream_id(instr, ir->stream_id()); 767b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 768b8e80941Smrg} 769b8e80941Smrg 770b8e80941Smrgvoid 771b8e80941Smrgnir_visitor::visit(ir_end_primitive *ir) 772b8e80941Smrg{ 773b8e80941Smrg nir_intrinsic_instr *instr = 774b8e80941Smrg nir_intrinsic_instr_create(this->shader, nir_intrinsic_end_primitive); 775b8e80941Smrg nir_intrinsic_set_stream_id(instr, ir->stream_id()); 776b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 777b8e80941Smrg} 778b8e80941Smrg 779b8e80941Smrgvoid 780b8e80941Smrgnir_visitor::visit(ir_loop_jump *ir) 781b8e80941Smrg{ 782b8e80941Smrg nir_jump_type type; 783b8e80941Smrg switch (ir->mode) { 784b8e80941Smrg case ir_loop_jump::jump_break: 785b8e80941Smrg type = nir_jump_break; 786b8e80941Smrg break; 787b8e80941Smrg case ir_loop_jump::jump_continue: 788b8e80941Smrg type = nir_jump_continue; 789b8e80941Smrg break; 790b8e80941Smrg default: 791b8e80941Smrg unreachable("not reached"); 792b8e80941Smrg } 793b8e80941Smrg 794b8e80941Smrg nir_jump_instr *instr = nir_jump_instr_create(this->shader, type); 795b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 796b8e80941Smrg} 797b8e80941Smrg 798b8e80941Smrgvoid 799b8e80941Smrgnir_visitor::visit(ir_return *ir) 800b8e80941Smrg{ 801b8e80941Smrg if (ir->value != NULL) { 802b8e80941Smrg nir_deref_instr *ret_deref = 803b8e80941Smrg nir_build_deref_cast(&b, nir_load_param(&b, 0), 804b8e80941Smrg nir_var_function_temp, ir->value->type, 0); 805b8e80941Smrg 806b8e80941Smrg nir_ssa_def *val = evaluate_rvalue(ir->value); 807b8e80941Smrg nir_store_deref(&b, ret_deref, val, ~0); 808b8e80941Smrg } 809b8e80941Smrg 810b8e80941Smrg nir_jump_instr *instr = nir_jump_instr_create(this->shader, nir_jump_return); 811b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 812b8e80941Smrg} 813b8e80941Smrg 814b8e80941Smrgstatic void 815b8e80941Smrgintrinsic_set_std430_align(nir_intrinsic_instr *intrin, const glsl_type *type) 816b8e80941Smrg{ 817b8e80941Smrg unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type); 818b8e80941Smrg unsigned pow2_components = util_next_power_of_two(type->vector_elements); 819b8e80941Smrg nir_intrinsic_set_align(intrin, (bit_size / 8) * pow2_components, 0); 820b8e80941Smrg} 821b8e80941Smrg 822b8e80941Smrgvoid 823b8e80941Smrgnir_visitor::visit(ir_call *ir) 824b8e80941Smrg{ 825b8e80941Smrg if (ir->callee->is_intrinsic()) { 826b8e80941Smrg nir_intrinsic_op op; 827b8e80941Smrg 828b8e80941Smrg switch (ir->callee->intrinsic_id) { 829b8e80941Smrg case ir_intrinsic_generic_atomic_add: 830b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 831b8e80941Smrg ? nir_intrinsic_deref_atomic_add : nir_intrinsic_deref_atomic_fadd; 832b8e80941Smrg break; 833b8e80941Smrg case ir_intrinsic_generic_atomic_and: 834b8e80941Smrg op = nir_intrinsic_deref_atomic_and; 835b8e80941Smrg break; 836b8e80941Smrg case ir_intrinsic_generic_atomic_or: 837b8e80941Smrg op = nir_intrinsic_deref_atomic_or; 838b8e80941Smrg break; 839b8e80941Smrg case ir_intrinsic_generic_atomic_xor: 840b8e80941Smrg op = nir_intrinsic_deref_atomic_xor; 841b8e80941Smrg break; 842b8e80941Smrg case ir_intrinsic_generic_atomic_min: 843b8e80941Smrg assert(ir->return_deref); 844b8e80941Smrg if (ir->return_deref->type == glsl_type::int_type) 845b8e80941Smrg op = nir_intrinsic_deref_atomic_imin; 846b8e80941Smrg else if (ir->return_deref->type == glsl_type::uint_type) 847b8e80941Smrg op = nir_intrinsic_deref_atomic_umin; 848b8e80941Smrg else if (ir->return_deref->type == glsl_type::float_type) 849b8e80941Smrg op = nir_intrinsic_deref_atomic_fmin; 850b8e80941Smrg else 851b8e80941Smrg unreachable("Invalid type"); 852b8e80941Smrg break; 853b8e80941Smrg case ir_intrinsic_generic_atomic_max: 854b8e80941Smrg assert(ir->return_deref); 855b8e80941Smrg if (ir->return_deref->type == glsl_type::int_type) 856b8e80941Smrg op = nir_intrinsic_deref_atomic_imax; 857b8e80941Smrg else if (ir->return_deref->type == glsl_type::uint_type) 858b8e80941Smrg op = nir_intrinsic_deref_atomic_umax; 859b8e80941Smrg else if (ir->return_deref->type == glsl_type::float_type) 860b8e80941Smrg op = nir_intrinsic_deref_atomic_fmax; 861b8e80941Smrg else 862b8e80941Smrg unreachable("Invalid type"); 863b8e80941Smrg break; 864b8e80941Smrg case ir_intrinsic_generic_atomic_exchange: 865b8e80941Smrg op = nir_intrinsic_deref_atomic_exchange; 866b8e80941Smrg break; 867b8e80941Smrg case ir_intrinsic_generic_atomic_comp_swap: 868b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 869b8e80941Smrg ? nir_intrinsic_deref_atomic_comp_swap 870b8e80941Smrg : nir_intrinsic_deref_atomic_fcomp_swap; 871b8e80941Smrg break; 872b8e80941Smrg case ir_intrinsic_atomic_counter_read: 873b8e80941Smrg op = nir_intrinsic_atomic_counter_read_deref; 874b8e80941Smrg break; 875b8e80941Smrg case ir_intrinsic_atomic_counter_increment: 876b8e80941Smrg op = nir_intrinsic_atomic_counter_inc_deref; 877b8e80941Smrg break; 878b8e80941Smrg case ir_intrinsic_atomic_counter_predecrement: 879b8e80941Smrg op = nir_intrinsic_atomic_counter_pre_dec_deref; 880b8e80941Smrg break; 881b8e80941Smrg case ir_intrinsic_atomic_counter_add: 882b8e80941Smrg op = nir_intrinsic_atomic_counter_add_deref; 883b8e80941Smrg break; 884b8e80941Smrg case ir_intrinsic_atomic_counter_and: 885b8e80941Smrg op = nir_intrinsic_atomic_counter_and_deref; 886b8e80941Smrg break; 887b8e80941Smrg case ir_intrinsic_atomic_counter_or: 888b8e80941Smrg op = nir_intrinsic_atomic_counter_or_deref; 889b8e80941Smrg break; 890b8e80941Smrg case ir_intrinsic_atomic_counter_xor: 891b8e80941Smrg op = nir_intrinsic_atomic_counter_xor_deref; 892b8e80941Smrg break; 893b8e80941Smrg case ir_intrinsic_atomic_counter_min: 894b8e80941Smrg op = nir_intrinsic_atomic_counter_min_deref; 895b8e80941Smrg break; 896b8e80941Smrg case ir_intrinsic_atomic_counter_max: 897b8e80941Smrg op = nir_intrinsic_atomic_counter_max_deref; 898b8e80941Smrg break; 899b8e80941Smrg case ir_intrinsic_atomic_counter_exchange: 900b8e80941Smrg op = nir_intrinsic_atomic_counter_exchange_deref; 901b8e80941Smrg break; 902b8e80941Smrg case ir_intrinsic_atomic_counter_comp_swap: 903b8e80941Smrg op = nir_intrinsic_atomic_counter_comp_swap_deref; 904b8e80941Smrg break; 905b8e80941Smrg case ir_intrinsic_image_load: 906b8e80941Smrg op = nir_intrinsic_image_deref_load; 907b8e80941Smrg break; 908b8e80941Smrg case ir_intrinsic_image_store: 909b8e80941Smrg op = nir_intrinsic_image_deref_store; 910b8e80941Smrg break; 911b8e80941Smrg case ir_intrinsic_image_atomic_add: 912b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 913b8e80941Smrg ? nir_intrinsic_image_deref_atomic_add 914b8e80941Smrg : nir_intrinsic_image_deref_atomic_fadd; 915b8e80941Smrg break; 916b8e80941Smrg case ir_intrinsic_image_atomic_min: 917b8e80941Smrg op = nir_intrinsic_image_deref_atomic_min; 918b8e80941Smrg break; 919b8e80941Smrg case ir_intrinsic_image_atomic_max: 920b8e80941Smrg op = nir_intrinsic_image_deref_atomic_max; 921b8e80941Smrg break; 922b8e80941Smrg case ir_intrinsic_image_atomic_and: 923b8e80941Smrg op = nir_intrinsic_image_deref_atomic_and; 924b8e80941Smrg break; 925b8e80941Smrg case ir_intrinsic_image_atomic_or: 926b8e80941Smrg op = nir_intrinsic_image_deref_atomic_or; 927b8e80941Smrg break; 928b8e80941Smrg case ir_intrinsic_image_atomic_xor: 929b8e80941Smrg op = nir_intrinsic_image_deref_atomic_xor; 930b8e80941Smrg break; 931b8e80941Smrg case ir_intrinsic_image_atomic_exchange: 932b8e80941Smrg op = nir_intrinsic_image_deref_atomic_exchange; 933b8e80941Smrg break; 934b8e80941Smrg case ir_intrinsic_image_atomic_comp_swap: 935b8e80941Smrg op = nir_intrinsic_image_deref_atomic_comp_swap; 936b8e80941Smrg break; 937b8e80941Smrg case ir_intrinsic_memory_barrier: 938b8e80941Smrg op = nir_intrinsic_memory_barrier; 939b8e80941Smrg break; 940b8e80941Smrg case ir_intrinsic_image_size: 941b8e80941Smrg op = nir_intrinsic_image_deref_size; 942b8e80941Smrg break; 943b8e80941Smrg case ir_intrinsic_image_samples: 944b8e80941Smrg op = nir_intrinsic_image_deref_samples; 945b8e80941Smrg break; 946b8e80941Smrg case ir_intrinsic_ssbo_store: 947b8e80941Smrg op = nir_intrinsic_store_ssbo; 948b8e80941Smrg break; 949b8e80941Smrg case ir_intrinsic_ssbo_load: 950b8e80941Smrg op = nir_intrinsic_load_ssbo; 951b8e80941Smrg break; 952b8e80941Smrg case ir_intrinsic_ssbo_atomic_add: 953b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 954b8e80941Smrg ? nir_intrinsic_ssbo_atomic_add : nir_intrinsic_ssbo_atomic_fadd; 955b8e80941Smrg break; 956b8e80941Smrg case ir_intrinsic_ssbo_atomic_and: 957b8e80941Smrg op = nir_intrinsic_ssbo_atomic_and; 958b8e80941Smrg break; 959b8e80941Smrg case ir_intrinsic_ssbo_atomic_or: 960b8e80941Smrg op = nir_intrinsic_ssbo_atomic_or; 961b8e80941Smrg break; 962b8e80941Smrg case ir_intrinsic_ssbo_atomic_xor: 963b8e80941Smrg op = nir_intrinsic_ssbo_atomic_xor; 964b8e80941Smrg break; 965b8e80941Smrg case ir_intrinsic_ssbo_atomic_min: 966b8e80941Smrg assert(ir->return_deref); 967b8e80941Smrg if (ir->return_deref->type == glsl_type::int_type) 968b8e80941Smrg op = nir_intrinsic_ssbo_atomic_imin; 969b8e80941Smrg else if (ir->return_deref->type == glsl_type::uint_type) 970b8e80941Smrg op = nir_intrinsic_ssbo_atomic_umin; 971b8e80941Smrg else if (ir->return_deref->type == glsl_type::float_type) 972b8e80941Smrg op = nir_intrinsic_ssbo_atomic_fmin; 973b8e80941Smrg else 974b8e80941Smrg unreachable("Invalid type"); 975b8e80941Smrg break; 976b8e80941Smrg case ir_intrinsic_ssbo_atomic_max: 977b8e80941Smrg assert(ir->return_deref); 978b8e80941Smrg if (ir->return_deref->type == glsl_type::int_type) 979b8e80941Smrg op = nir_intrinsic_ssbo_atomic_imax; 980b8e80941Smrg else if (ir->return_deref->type == glsl_type::uint_type) 981b8e80941Smrg op = nir_intrinsic_ssbo_atomic_umax; 982b8e80941Smrg else if (ir->return_deref->type == glsl_type::float_type) 983b8e80941Smrg op = nir_intrinsic_ssbo_atomic_fmax; 984b8e80941Smrg else 985b8e80941Smrg unreachable("Invalid type"); 986b8e80941Smrg break; 987b8e80941Smrg case ir_intrinsic_ssbo_atomic_exchange: 988b8e80941Smrg op = nir_intrinsic_ssbo_atomic_exchange; 989b8e80941Smrg break; 990b8e80941Smrg case ir_intrinsic_ssbo_atomic_comp_swap: 991b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 992b8e80941Smrg ? nir_intrinsic_ssbo_atomic_comp_swap 993b8e80941Smrg : nir_intrinsic_ssbo_atomic_fcomp_swap; 994b8e80941Smrg break; 995b8e80941Smrg case ir_intrinsic_shader_clock: 996b8e80941Smrg op = nir_intrinsic_shader_clock; 997b8e80941Smrg break; 998b8e80941Smrg case ir_intrinsic_begin_invocation_interlock: 999b8e80941Smrg op = nir_intrinsic_begin_invocation_interlock; 1000b8e80941Smrg break; 1001b8e80941Smrg case ir_intrinsic_end_invocation_interlock: 1002b8e80941Smrg op = nir_intrinsic_end_invocation_interlock; 1003b8e80941Smrg break; 1004b8e80941Smrg case ir_intrinsic_group_memory_barrier: 1005b8e80941Smrg op = nir_intrinsic_group_memory_barrier; 1006b8e80941Smrg break; 1007b8e80941Smrg case ir_intrinsic_memory_barrier_atomic_counter: 1008b8e80941Smrg op = nir_intrinsic_memory_barrier_atomic_counter; 1009b8e80941Smrg break; 1010b8e80941Smrg case ir_intrinsic_memory_barrier_buffer: 1011b8e80941Smrg op = nir_intrinsic_memory_barrier_buffer; 1012b8e80941Smrg break; 1013b8e80941Smrg case ir_intrinsic_memory_barrier_image: 1014b8e80941Smrg op = nir_intrinsic_memory_barrier_image; 1015b8e80941Smrg break; 1016b8e80941Smrg case ir_intrinsic_memory_barrier_shared: 1017b8e80941Smrg op = nir_intrinsic_memory_barrier_shared; 1018b8e80941Smrg break; 1019b8e80941Smrg case ir_intrinsic_shared_load: 1020b8e80941Smrg op = nir_intrinsic_load_shared; 1021b8e80941Smrg break; 1022b8e80941Smrg case ir_intrinsic_shared_store: 1023b8e80941Smrg op = nir_intrinsic_store_shared; 1024b8e80941Smrg break; 1025b8e80941Smrg case ir_intrinsic_shared_atomic_add: 1026b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 1027b8e80941Smrg ? nir_intrinsic_shared_atomic_add 1028b8e80941Smrg : nir_intrinsic_shared_atomic_fadd; 1029b8e80941Smrg break; 1030b8e80941Smrg case ir_intrinsic_shared_atomic_and: 1031b8e80941Smrg op = nir_intrinsic_shared_atomic_and; 1032b8e80941Smrg break; 1033b8e80941Smrg case ir_intrinsic_shared_atomic_or: 1034b8e80941Smrg op = nir_intrinsic_shared_atomic_or; 1035b8e80941Smrg break; 1036b8e80941Smrg case ir_intrinsic_shared_atomic_xor: 1037b8e80941Smrg op = nir_intrinsic_shared_atomic_xor; 1038b8e80941Smrg break; 1039b8e80941Smrg case ir_intrinsic_shared_atomic_min: 1040b8e80941Smrg assert(ir->return_deref); 1041b8e80941Smrg if (ir->return_deref->type == glsl_type::int_type) 1042b8e80941Smrg op = nir_intrinsic_shared_atomic_imin; 1043b8e80941Smrg else if (ir->return_deref->type == glsl_type::uint_type) 1044b8e80941Smrg op = nir_intrinsic_shared_atomic_umin; 1045b8e80941Smrg else if (ir->return_deref->type == glsl_type::float_type) 1046b8e80941Smrg op = nir_intrinsic_shared_atomic_fmin; 1047b8e80941Smrg else 1048b8e80941Smrg unreachable("Invalid type"); 1049b8e80941Smrg break; 1050b8e80941Smrg case ir_intrinsic_shared_atomic_max: 1051b8e80941Smrg assert(ir->return_deref); 1052b8e80941Smrg if (ir->return_deref->type == glsl_type::int_type) 1053b8e80941Smrg op = nir_intrinsic_shared_atomic_imax; 1054b8e80941Smrg else if (ir->return_deref->type == glsl_type::uint_type) 1055b8e80941Smrg op = nir_intrinsic_shared_atomic_umax; 1056b8e80941Smrg else if (ir->return_deref->type == glsl_type::float_type) 1057b8e80941Smrg op = nir_intrinsic_shared_atomic_fmax; 1058b8e80941Smrg else 1059b8e80941Smrg unreachable("Invalid type"); 1060b8e80941Smrg break; 1061b8e80941Smrg case ir_intrinsic_shared_atomic_exchange: 1062b8e80941Smrg op = nir_intrinsic_shared_atomic_exchange; 1063b8e80941Smrg break; 1064b8e80941Smrg case ir_intrinsic_shared_atomic_comp_swap: 1065b8e80941Smrg op = ir->return_deref->type->is_integer_32_64() 1066b8e80941Smrg ? nir_intrinsic_shared_atomic_comp_swap 1067b8e80941Smrg : nir_intrinsic_shared_atomic_fcomp_swap; 1068b8e80941Smrg break; 1069b8e80941Smrg case ir_intrinsic_vote_any: 1070b8e80941Smrg op = nir_intrinsic_vote_any; 1071b8e80941Smrg break; 1072b8e80941Smrg case ir_intrinsic_vote_all: 1073b8e80941Smrg op = nir_intrinsic_vote_all; 1074b8e80941Smrg break; 1075b8e80941Smrg case ir_intrinsic_vote_eq: 1076b8e80941Smrg op = nir_intrinsic_vote_ieq; 1077b8e80941Smrg break; 1078b8e80941Smrg case ir_intrinsic_ballot: 1079b8e80941Smrg op = nir_intrinsic_ballot; 1080b8e80941Smrg break; 1081b8e80941Smrg case ir_intrinsic_read_invocation: 1082b8e80941Smrg op = nir_intrinsic_read_invocation; 1083b8e80941Smrg break; 1084b8e80941Smrg case ir_intrinsic_read_first_invocation: 1085b8e80941Smrg op = nir_intrinsic_read_first_invocation; 1086b8e80941Smrg break; 1087b8e80941Smrg default: 1088b8e80941Smrg unreachable("not reached"); 1089b8e80941Smrg } 1090b8e80941Smrg 1091b8e80941Smrg nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op); 1092b8e80941Smrg nir_ssa_def *ret = &instr->dest.ssa; 1093b8e80941Smrg 1094b8e80941Smrg switch (op) { 1095b8e80941Smrg case nir_intrinsic_deref_atomic_add: 1096b8e80941Smrg case nir_intrinsic_deref_atomic_imin: 1097b8e80941Smrg case nir_intrinsic_deref_atomic_umin: 1098b8e80941Smrg case nir_intrinsic_deref_atomic_imax: 1099b8e80941Smrg case nir_intrinsic_deref_atomic_umax: 1100b8e80941Smrg case nir_intrinsic_deref_atomic_and: 1101b8e80941Smrg case nir_intrinsic_deref_atomic_or: 1102b8e80941Smrg case nir_intrinsic_deref_atomic_xor: 1103b8e80941Smrg case nir_intrinsic_deref_atomic_exchange: 1104b8e80941Smrg case nir_intrinsic_deref_atomic_comp_swap: 1105b8e80941Smrg case nir_intrinsic_deref_atomic_fadd: 1106b8e80941Smrg case nir_intrinsic_deref_atomic_fmin: 1107b8e80941Smrg case nir_intrinsic_deref_atomic_fmax: 1108b8e80941Smrg case nir_intrinsic_deref_atomic_fcomp_swap: { 1109b8e80941Smrg int param_count = ir->actual_parameters.length(); 1110b8e80941Smrg assert(param_count == 2 || param_count == 3); 1111b8e80941Smrg 1112b8e80941Smrg /* Deref */ 1113b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1114b8e80941Smrg ir_rvalue *rvalue = (ir_rvalue *) param; 1115b8e80941Smrg ir_dereference *deref = rvalue->as_dereference(); 1116b8e80941Smrg ir_swizzle *swizzle = NULL; 1117b8e80941Smrg if (!deref) { 1118b8e80941Smrg /* We may have a swizzle to pick off a single vec4 component */ 1119b8e80941Smrg swizzle = rvalue->as_swizzle(); 1120b8e80941Smrg assert(swizzle && swizzle->type->vector_elements == 1); 1121b8e80941Smrg deref = swizzle->val->as_dereference(); 1122b8e80941Smrg assert(deref); 1123b8e80941Smrg } 1124b8e80941Smrg nir_deref_instr *nir_deref = evaluate_deref(deref); 1125b8e80941Smrg if (swizzle) { 1126b8e80941Smrg nir_deref = nir_build_deref_array_imm(&b, nir_deref, 1127b8e80941Smrg swizzle->mask.x); 1128b8e80941Smrg } 1129b8e80941Smrg instr->src[0] = nir_src_for_ssa(&nir_deref->dest.ssa); 1130b8e80941Smrg 1131b8e80941Smrg /* data1 parameter (this is always present) */ 1132b8e80941Smrg param = param->get_next(); 1133b8e80941Smrg ir_instruction *inst = (ir_instruction *) param; 1134b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1135b8e80941Smrg 1136b8e80941Smrg /* data2 parameter (only with atomic_comp_swap) */ 1137b8e80941Smrg if (param_count == 3) { 1138b8e80941Smrg assert(op == nir_intrinsic_deref_atomic_comp_swap || 1139b8e80941Smrg op == nir_intrinsic_deref_atomic_fcomp_swap); 1140b8e80941Smrg param = param->get_next(); 1141b8e80941Smrg inst = (ir_instruction *) param; 1142b8e80941Smrg instr->src[2] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1143b8e80941Smrg } 1144b8e80941Smrg 1145b8e80941Smrg /* Atomic result */ 1146b8e80941Smrg assert(ir->return_deref); 1147b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1148b8e80941Smrg ir->return_deref->type->vector_elements, 32, NULL); 1149b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1150b8e80941Smrg break; 1151b8e80941Smrg } 1152b8e80941Smrg case nir_intrinsic_atomic_counter_read_deref: 1153b8e80941Smrg case nir_intrinsic_atomic_counter_inc_deref: 1154b8e80941Smrg case nir_intrinsic_atomic_counter_pre_dec_deref: 1155b8e80941Smrg case nir_intrinsic_atomic_counter_add_deref: 1156b8e80941Smrg case nir_intrinsic_atomic_counter_min_deref: 1157b8e80941Smrg case nir_intrinsic_atomic_counter_max_deref: 1158b8e80941Smrg case nir_intrinsic_atomic_counter_and_deref: 1159b8e80941Smrg case nir_intrinsic_atomic_counter_or_deref: 1160b8e80941Smrg case nir_intrinsic_atomic_counter_xor_deref: 1161b8e80941Smrg case nir_intrinsic_atomic_counter_exchange_deref: 1162b8e80941Smrg case nir_intrinsic_atomic_counter_comp_swap_deref: { 1163b8e80941Smrg /* Set the counter variable dereference. */ 1164b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1165b8e80941Smrg ir_dereference *counter = (ir_dereference *)param; 1166b8e80941Smrg 1167b8e80941Smrg instr->src[0] = nir_src_for_ssa(&evaluate_deref(counter)->dest.ssa); 1168b8e80941Smrg param = param->get_next(); 1169b8e80941Smrg 1170b8e80941Smrg /* Set the intrinsic destination. */ 1171b8e80941Smrg if (ir->return_deref) { 1172b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL); 1173b8e80941Smrg } 1174b8e80941Smrg 1175b8e80941Smrg /* Set the intrinsic parameters. */ 1176b8e80941Smrg if (!param->is_tail_sentinel()) { 1177b8e80941Smrg instr->src[1] = 1178b8e80941Smrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 1179b8e80941Smrg param = param->get_next(); 1180b8e80941Smrg } 1181b8e80941Smrg 1182b8e80941Smrg if (!param->is_tail_sentinel()) { 1183b8e80941Smrg instr->src[2] = 1184b8e80941Smrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 1185b8e80941Smrg param = param->get_next(); 1186b8e80941Smrg } 1187b8e80941Smrg 1188b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1189b8e80941Smrg break; 1190b8e80941Smrg } 1191b8e80941Smrg case nir_intrinsic_image_deref_load: 1192b8e80941Smrg case nir_intrinsic_image_deref_store: 1193b8e80941Smrg case nir_intrinsic_image_deref_atomic_add: 1194b8e80941Smrg case nir_intrinsic_image_deref_atomic_min: 1195b8e80941Smrg case nir_intrinsic_image_deref_atomic_max: 1196b8e80941Smrg case nir_intrinsic_image_deref_atomic_and: 1197b8e80941Smrg case nir_intrinsic_image_deref_atomic_or: 1198b8e80941Smrg case nir_intrinsic_image_deref_atomic_xor: 1199b8e80941Smrg case nir_intrinsic_image_deref_atomic_exchange: 1200b8e80941Smrg case nir_intrinsic_image_deref_atomic_comp_swap: 1201b8e80941Smrg case nir_intrinsic_image_deref_atomic_fadd: 1202b8e80941Smrg case nir_intrinsic_image_deref_samples: 1203b8e80941Smrg case nir_intrinsic_image_deref_size: { 1204b8e80941Smrg nir_ssa_undef_instr *instr_undef = 1205b8e80941Smrg nir_ssa_undef_instr_create(shader, 1, 32); 1206b8e80941Smrg nir_builder_instr_insert(&b, &instr_undef->instr); 1207b8e80941Smrg 1208b8e80941Smrg /* Set the image variable dereference. */ 1209b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1210b8e80941Smrg ir_dereference *image = (ir_dereference *)param; 1211b8e80941Smrg nir_deref_instr *deref = evaluate_deref(image); 1212b8e80941Smrg const glsl_type *type = deref->type; 1213b8e80941Smrg 1214b8e80941Smrg instr->src[0] = nir_src_for_ssa(&deref->dest.ssa); 1215b8e80941Smrg param = param->get_next(); 1216b8e80941Smrg 1217b8e80941Smrg /* Set the intrinsic destination. */ 1218b8e80941Smrg if (ir->return_deref) { 1219b8e80941Smrg unsigned num_components = ir->return_deref->type->vector_elements; 1220b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1221b8e80941Smrg num_components, 32, NULL); 1222b8e80941Smrg } 1223b8e80941Smrg 1224b8e80941Smrg if (op == nir_intrinsic_image_deref_size) { 1225b8e80941Smrg instr->num_components = instr->dest.ssa.num_components; 1226b8e80941Smrg } else if (op == nir_intrinsic_image_deref_load || 1227b8e80941Smrg op == nir_intrinsic_image_deref_store) { 1228b8e80941Smrg instr->num_components = 4; 1229b8e80941Smrg } 1230b8e80941Smrg 1231b8e80941Smrg if (op == nir_intrinsic_image_deref_size || 1232b8e80941Smrg op == nir_intrinsic_image_deref_samples) { 1233b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1234b8e80941Smrg break; 1235b8e80941Smrg } 1236b8e80941Smrg 1237b8e80941Smrg /* Set the address argument, extending the coordinate vector to four 1238b8e80941Smrg * components. 1239b8e80941Smrg */ 1240b8e80941Smrg nir_ssa_def *src_addr = 1241b8e80941Smrg evaluate_rvalue((ir_dereference *)param); 1242b8e80941Smrg nir_ssa_def *srcs[4]; 1243b8e80941Smrg 1244b8e80941Smrg for (int i = 0; i < 4; i++) { 1245b8e80941Smrg if (i < type->coordinate_components()) 1246b8e80941Smrg srcs[i] = nir_channel(&b, src_addr, i); 1247b8e80941Smrg else 1248b8e80941Smrg srcs[i] = &instr_undef->def; 1249b8e80941Smrg } 1250b8e80941Smrg 1251b8e80941Smrg instr->src[1] = nir_src_for_ssa(nir_vec(&b, srcs, 4)); 1252b8e80941Smrg param = param->get_next(); 1253b8e80941Smrg 1254b8e80941Smrg /* Set the sample argument, which is undefined for single-sample 1255b8e80941Smrg * images. 1256b8e80941Smrg */ 1257b8e80941Smrg if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) { 1258b8e80941Smrg instr->src[2] = 1259b8e80941Smrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 1260b8e80941Smrg param = param->get_next(); 1261b8e80941Smrg } else { 1262b8e80941Smrg instr->src[2] = nir_src_for_ssa(&instr_undef->def); 1263b8e80941Smrg } 1264b8e80941Smrg 1265b8e80941Smrg /* Set the intrinsic parameters. */ 1266b8e80941Smrg if (!param->is_tail_sentinel()) { 1267b8e80941Smrg instr->src[3] = 1268b8e80941Smrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 1269b8e80941Smrg param = param->get_next(); 1270b8e80941Smrg } 1271b8e80941Smrg 1272b8e80941Smrg if (!param->is_tail_sentinel()) { 1273b8e80941Smrg instr->src[4] = 1274b8e80941Smrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 1275b8e80941Smrg param = param->get_next(); 1276b8e80941Smrg } 1277b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1278b8e80941Smrg break; 1279b8e80941Smrg } 1280b8e80941Smrg case nir_intrinsic_memory_barrier: 1281b8e80941Smrg case nir_intrinsic_group_memory_barrier: 1282b8e80941Smrg case nir_intrinsic_memory_barrier_atomic_counter: 1283b8e80941Smrg case nir_intrinsic_memory_barrier_buffer: 1284b8e80941Smrg case nir_intrinsic_memory_barrier_image: 1285b8e80941Smrg case nir_intrinsic_memory_barrier_shared: 1286b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1287b8e80941Smrg break; 1288b8e80941Smrg case nir_intrinsic_shader_clock: 1289b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 2, 32, NULL); 1290b8e80941Smrg instr->num_components = 2; 1291b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1292b8e80941Smrg break; 1293b8e80941Smrg case nir_intrinsic_begin_invocation_interlock: 1294b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1295b8e80941Smrg break; 1296b8e80941Smrg case nir_intrinsic_end_invocation_interlock: 1297b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1298b8e80941Smrg break; 1299b8e80941Smrg case nir_intrinsic_store_ssbo: { 1300b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1301b8e80941Smrg ir_rvalue *block = ((ir_instruction *)param)->as_rvalue(); 1302b8e80941Smrg 1303b8e80941Smrg param = param->get_next(); 1304b8e80941Smrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 1305b8e80941Smrg 1306b8e80941Smrg param = param->get_next(); 1307b8e80941Smrg ir_rvalue *val = ((ir_instruction *)param)->as_rvalue(); 1308b8e80941Smrg 1309b8e80941Smrg param = param->get_next(); 1310b8e80941Smrg ir_constant *write_mask = ((ir_instruction *)param)->as_constant(); 1311b8e80941Smrg assert(write_mask); 1312b8e80941Smrg 1313b8e80941Smrg nir_ssa_def *nir_val = evaluate_rvalue(val); 1314b8e80941Smrg if (val->type->is_boolean()) 1315b8e80941Smrg nir_val = nir_b2i32(&b, nir_val); 1316b8e80941Smrg 1317b8e80941Smrg instr->src[0] = nir_src_for_ssa(nir_val); 1318b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(block)); 1319b8e80941Smrg instr->src[2] = nir_src_for_ssa(evaluate_rvalue(offset)); 1320b8e80941Smrg intrinsic_set_std430_align(instr, val->type); 1321b8e80941Smrg nir_intrinsic_set_write_mask(instr, write_mask->value.u[0]); 1322b8e80941Smrg instr->num_components = val->type->vector_elements; 1323b8e80941Smrg 1324b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1325b8e80941Smrg break; 1326b8e80941Smrg } 1327b8e80941Smrg case nir_intrinsic_load_ssbo: { 1328b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1329b8e80941Smrg ir_rvalue *block = ((ir_instruction *)param)->as_rvalue(); 1330b8e80941Smrg 1331b8e80941Smrg param = param->get_next(); 1332b8e80941Smrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 1333b8e80941Smrg 1334b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(block)); 1335b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset)); 1336b8e80941Smrg 1337b8e80941Smrg const glsl_type *type = ir->return_deref->var->type; 1338b8e80941Smrg instr->num_components = type->vector_elements; 1339b8e80941Smrg intrinsic_set_std430_align(instr, type); 1340b8e80941Smrg 1341b8e80941Smrg /* Setup destination register */ 1342b8e80941Smrg unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type); 1343b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1344b8e80941Smrg type->vector_elements, bit_size, NULL); 1345b8e80941Smrg 1346b8e80941Smrg /* Insert the created nir instruction now since in the case of boolean 1347b8e80941Smrg * result we will need to emit another instruction after it 1348b8e80941Smrg */ 1349b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1350b8e80941Smrg 1351b8e80941Smrg /* 1352b8e80941Smrg * In SSBO/UBO's, a true boolean value is any non-zero value, but we 1353b8e80941Smrg * consider a true boolean to be ~0. Fix this up with a != 0 1354b8e80941Smrg * comparison. 1355b8e80941Smrg */ 1356b8e80941Smrg if (type->is_boolean()) 1357b8e80941Smrg ret = nir_i2b(&b, &instr->dest.ssa); 1358b8e80941Smrg break; 1359b8e80941Smrg } 1360b8e80941Smrg case nir_intrinsic_ssbo_atomic_add: 1361b8e80941Smrg case nir_intrinsic_ssbo_atomic_imin: 1362b8e80941Smrg case nir_intrinsic_ssbo_atomic_umin: 1363b8e80941Smrg case nir_intrinsic_ssbo_atomic_imax: 1364b8e80941Smrg case nir_intrinsic_ssbo_atomic_umax: 1365b8e80941Smrg case nir_intrinsic_ssbo_atomic_and: 1366b8e80941Smrg case nir_intrinsic_ssbo_atomic_or: 1367b8e80941Smrg case nir_intrinsic_ssbo_atomic_xor: 1368b8e80941Smrg case nir_intrinsic_ssbo_atomic_exchange: 1369b8e80941Smrg case nir_intrinsic_ssbo_atomic_comp_swap: 1370b8e80941Smrg case nir_intrinsic_ssbo_atomic_fadd: 1371b8e80941Smrg case nir_intrinsic_ssbo_atomic_fmin: 1372b8e80941Smrg case nir_intrinsic_ssbo_atomic_fmax: 1373b8e80941Smrg case nir_intrinsic_ssbo_atomic_fcomp_swap: { 1374b8e80941Smrg int param_count = ir->actual_parameters.length(); 1375b8e80941Smrg assert(param_count == 3 || param_count == 4); 1376b8e80941Smrg 1377b8e80941Smrg /* Block index */ 1378b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1379b8e80941Smrg ir_instruction *inst = (ir_instruction *) param; 1380b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1381b8e80941Smrg 1382b8e80941Smrg /* Offset */ 1383b8e80941Smrg param = param->get_next(); 1384b8e80941Smrg inst = (ir_instruction *) param; 1385b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1386b8e80941Smrg 1387b8e80941Smrg /* data1 parameter (this is always present) */ 1388b8e80941Smrg param = param->get_next(); 1389b8e80941Smrg inst = (ir_instruction *) param; 1390b8e80941Smrg instr->src[2] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1391b8e80941Smrg 1392b8e80941Smrg /* data2 parameter (only with atomic_comp_swap) */ 1393b8e80941Smrg if (param_count == 4) { 1394b8e80941Smrg assert(op == nir_intrinsic_ssbo_atomic_comp_swap || 1395b8e80941Smrg op == nir_intrinsic_ssbo_atomic_fcomp_swap); 1396b8e80941Smrg param = param->get_next(); 1397b8e80941Smrg inst = (ir_instruction *) param; 1398b8e80941Smrg instr->src[3] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1399b8e80941Smrg } 1400b8e80941Smrg 1401b8e80941Smrg /* Atomic result */ 1402b8e80941Smrg assert(ir->return_deref); 1403b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1404b8e80941Smrg ir->return_deref->type->vector_elements, 32, NULL); 1405b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1406b8e80941Smrg break; 1407b8e80941Smrg } 1408b8e80941Smrg case nir_intrinsic_load_shared: { 1409b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1410b8e80941Smrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 1411b8e80941Smrg 1412b8e80941Smrg nir_intrinsic_set_base(instr, 0); 1413b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(offset)); 1414b8e80941Smrg 1415b8e80941Smrg const glsl_type *type = ir->return_deref->var->type; 1416b8e80941Smrg instr->num_components = type->vector_elements; 1417b8e80941Smrg intrinsic_set_std430_align(instr, type); 1418b8e80941Smrg 1419b8e80941Smrg /* Setup destination register */ 1420b8e80941Smrg unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type); 1421b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1422b8e80941Smrg type->vector_elements, bit_size, NULL); 1423b8e80941Smrg 1424b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1425b8e80941Smrg 1426b8e80941Smrg /* The value in shared memory is a 32-bit value */ 1427b8e80941Smrg if (type->is_boolean()) 1428b8e80941Smrg ret = nir_i2b(&b, &instr->dest.ssa); 1429b8e80941Smrg break; 1430b8e80941Smrg } 1431b8e80941Smrg case nir_intrinsic_store_shared: { 1432b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1433b8e80941Smrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 1434b8e80941Smrg 1435b8e80941Smrg param = param->get_next(); 1436b8e80941Smrg ir_rvalue *val = ((ir_instruction *)param)->as_rvalue(); 1437b8e80941Smrg 1438b8e80941Smrg param = param->get_next(); 1439b8e80941Smrg ir_constant *write_mask = ((ir_instruction *)param)->as_constant(); 1440b8e80941Smrg assert(write_mask); 1441b8e80941Smrg 1442b8e80941Smrg nir_intrinsic_set_base(instr, 0); 1443b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset)); 1444b8e80941Smrg 1445b8e80941Smrg nir_intrinsic_set_write_mask(instr, write_mask->value.u[0]); 1446b8e80941Smrg 1447b8e80941Smrg nir_ssa_def *nir_val = evaluate_rvalue(val); 1448b8e80941Smrg /* The value in shared memory is a 32-bit value */ 1449b8e80941Smrg if (val->type->is_boolean()) 1450b8e80941Smrg nir_val = nir_b2i32(&b, nir_val); 1451b8e80941Smrg 1452b8e80941Smrg instr->src[0] = nir_src_for_ssa(nir_val); 1453b8e80941Smrg instr->num_components = val->type->vector_elements; 1454b8e80941Smrg intrinsic_set_std430_align(instr, val->type); 1455b8e80941Smrg 1456b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1457b8e80941Smrg break; 1458b8e80941Smrg } 1459b8e80941Smrg case nir_intrinsic_shared_atomic_add: 1460b8e80941Smrg case nir_intrinsic_shared_atomic_imin: 1461b8e80941Smrg case nir_intrinsic_shared_atomic_umin: 1462b8e80941Smrg case nir_intrinsic_shared_atomic_imax: 1463b8e80941Smrg case nir_intrinsic_shared_atomic_umax: 1464b8e80941Smrg case nir_intrinsic_shared_atomic_and: 1465b8e80941Smrg case nir_intrinsic_shared_atomic_or: 1466b8e80941Smrg case nir_intrinsic_shared_atomic_xor: 1467b8e80941Smrg case nir_intrinsic_shared_atomic_exchange: 1468b8e80941Smrg case nir_intrinsic_shared_atomic_comp_swap: 1469b8e80941Smrg case nir_intrinsic_shared_atomic_fadd: 1470b8e80941Smrg case nir_intrinsic_shared_atomic_fmin: 1471b8e80941Smrg case nir_intrinsic_shared_atomic_fmax: 1472b8e80941Smrg case nir_intrinsic_shared_atomic_fcomp_swap: { 1473b8e80941Smrg int param_count = ir->actual_parameters.length(); 1474b8e80941Smrg assert(param_count == 2 || param_count == 3); 1475b8e80941Smrg 1476b8e80941Smrg /* Offset */ 1477b8e80941Smrg exec_node *param = ir->actual_parameters.get_head(); 1478b8e80941Smrg ir_instruction *inst = (ir_instruction *) param; 1479b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1480b8e80941Smrg 1481b8e80941Smrg /* data1 parameter (this is always present) */ 1482b8e80941Smrg param = param->get_next(); 1483b8e80941Smrg inst = (ir_instruction *) param; 1484b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1485b8e80941Smrg 1486b8e80941Smrg /* data2 parameter (only with atomic_comp_swap) */ 1487b8e80941Smrg if (param_count == 3) { 1488b8e80941Smrg assert(op == nir_intrinsic_shared_atomic_comp_swap || 1489b8e80941Smrg op == nir_intrinsic_shared_atomic_fcomp_swap); 1490b8e80941Smrg param = param->get_next(); 1491b8e80941Smrg inst = (ir_instruction *) param; 1492b8e80941Smrg instr->src[2] = 1493b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 1494b8e80941Smrg } 1495b8e80941Smrg 1496b8e80941Smrg /* Atomic result */ 1497b8e80941Smrg assert(ir->return_deref); 1498b8e80941Smrg unsigned bit_size = glsl_get_bit_size(ir->return_deref->type); 1499b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1500b8e80941Smrg ir->return_deref->type->vector_elements, 1501b8e80941Smrg bit_size, NULL); 1502b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1503b8e80941Smrg break; 1504b8e80941Smrg } 1505b8e80941Smrg case nir_intrinsic_vote_any: 1506b8e80941Smrg case nir_intrinsic_vote_all: 1507b8e80941Smrg case nir_intrinsic_vote_ieq: { 1508b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL); 1509b8e80941Smrg instr->num_components = 1; 1510b8e80941Smrg 1511b8e80941Smrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 1512b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 1513b8e80941Smrg 1514b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1515b8e80941Smrg break; 1516b8e80941Smrg } 1517b8e80941Smrg 1518b8e80941Smrg case nir_intrinsic_ballot: { 1519b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1520b8e80941Smrg ir->return_deref->type->vector_elements, 64, NULL); 1521b8e80941Smrg instr->num_components = ir->return_deref->type->vector_elements; 1522b8e80941Smrg 1523b8e80941Smrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 1524b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 1525b8e80941Smrg 1526b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1527b8e80941Smrg break; 1528b8e80941Smrg } 1529b8e80941Smrg case nir_intrinsic_read_invocation: { 1530b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1531b8e80941Smrg ir->return_deref->type->vector_elements, 32, NULL); 1532b8e80941Smrg instr->num_components = ir->return_deref->type->vector_elements; 1533b8e80941Smrg 1534b8e80941Smrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 1535b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 1536b8e80941Smrg 1537b8e80941Smrg ir_rvalue *invocation = (ir_rvalue *) ir->actual_parameters.get_head()->next; 1538b8e80941Smrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(invocation)); 1539b8e80941Smrg 1540b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1541b8e80941Smrg break; 1542b8e80941Smrg } 1543b8e80941Smrg case nir_intrinsic_read_first_invocation: { 1544b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1545b8e80941Smrg ir->return_deref->type->vector_elements, 32, NULL); 1546b8e80941Smrg instr->num_components = ir->return_deref->type->vector_elements; 1547b8e80941Smrg 1548b8e80941Smrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 1549b8e80941Smrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 1550b8e80941Smrg 1551b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 1552b8e80941Smrg break; 1553b8e80941Smrg } 1554b8e80941Smrg default: 1555b8e80941Smrg unreachable("not reached"); 1556b8e80941Smrg } 1557b8e80941Smrg 1558b8e80941Smrg if (ir->return_deref) 1559b8e80941Smrg nir_store_deref(&b, evaluate_deref(ir->return_deref), ret, ~0); 1560b8e80941Smrg 1561b8e80941Smrg return; 1562b8e80941Smrg } 1563b8e80941Smrg 1564b8e80941Smrg struct hash_entry *entry = 1565b8e80941Smrg _mesa_hash_table_search(this->overload_table, ir->callee); 1566b8e80941Smrg assert(entry); 1567b8e80941Smrg nir_function *callee = (nir_function *) entry->data; 1568b8e80941Smrg 1569b8e80941Smrg nir_call_instr *call = nir_call_instr_create(this->shader, callee); 1570b8e80941Smrg 1571b8e80941Smrg unsigned i = 0; 1572b8e80941Smrg nir_deref_instr *ret_deref = NULL; 1573b8e80941Smrg if (ir->return_deref) { 1574b8e80941Smrg nir_variable *ret_tmp = 1575b8e80941Smrg nir_local_variable_create(this->impl, ir->return_deref->type, 1576b8e80941Smrg "return_tmp"); 1577b8e80941Smrg ret_deref = nir_build_deref_var(&b, ret_tmp); 1578b8e80941Smrg call->params[i++] = nir_src_for_ssa(&ret_deref->dest.ssa); 1579b8e80941Smrg } 1580b8e80941Smrg 1581b8e80941Smrg foreach_two_lists(formal_node, &ir->callee->parameters, 1582b8e80941Smrg actual_node, &ir->actual_parameters) { 1583b8e80941Smrg ir_rvalue *param_rvalue = (ir_rvalue *) actual_node; 1584b8e80941Smrg ir_variable *sig_param = (ir_variable *) formal_node; 1585b8e80941Smrg 1586b8e80941Smrg if (sig_param->data.mode == ir_var_function_out) { 1587b8e80941Smrg nir_deref_instr *out_deref = evaluate_deref(param_rvalue); 1588b8e80941Smrg call->params[i] = nir_src_for_ssa(&out_deref->dest.ssa); 1589b8e80941Smrg } else if (sig_param->data.mode == ir_var_function_in) { 1590b8e80941Smrg nir_ssa_def *val = evaluate_rvalue(param_rvalue); 1591b8e80941Smrg nir_src src = nir_src_for_ssa(val); 1592b8e80941Smrg 1593b8e80941Smrg nir_src_copy(&call->params[i], &src, call); 1594b8e80941Smrg } else if (sig_param->data.mode == ir_var_function_inout) { 1595b8e80941Smrg unreachable("unimplemented: inout parameters"); 1596b8e80941Smrg } 1597b8e80941Smrg 1598b8e80941Smrg i++; 1599b8e80941Smrg } 1600b8e80941Smrg 1601b8e80941Smrg nir_builder_instr_insert(&b, &call->instr); 1602b8e80941Smrg 1603b8e80941Smrg if (ir->return_deref) 1604b8e80941Smrg nir_store_deref(&b, evaluate_deref(ir->return_deref), nir_load_deref(&b, ret_deref), ~0); 1605b8e80941Smrg} 1606b8e80941Smrg 1607b8e80941Smrgvoid 1608b8e80941Smrgnir_visitor::visit(ir_assignment *ir) 1609b8e80941Smrg{ 1610b8e80941Smrg unsigned num_components = ir->lhs->type->vector_elements; 1611b8e80941Smrg 1612b8e80941Smrg b.exact = ir->lhs->variable_referenced()->data.invariant || 1613b8e80941Smrg ir->lhs->variable_referenced()->data.precise; 1614b8e80941Smrg 1615b8e80941Smrg if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) && 1616b8e80941Smrg (ir->write_mask == (1 << num_components) - 1 || ir->write_mask == 0)) { 1617b8e80941Smrg if (ir->condition) { 1618b8e80941Smrg nir_push_if(&b, evaluate_rvalue(ir->condition)); 1619b8e80941Smrg nir_copy_deref(&b, evaluate_deref(ir->lhs), evaluate_deref(ir->rhs)); 1620b8e80941Smrg nir_pop_if(&b, NULL); 1621b8e80941Smrg } else { 1622b8e80941Smrg nir_copy_deref(&b, evaluate_deref(ir->lhs), evaluate_deref(ir->rhs)); 1623b8e80941Smrg } 1624b8e80941Smrg return; 1625b8e80941Smrg } 1626b8e80941Smrg 1627b8e80941Smrg assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector()); 1628b8e80941Smrg 1629b8e80941Smrg ir->lhs->accept(this); 1630b8e80941Smrg nir_deref_instr *lhs_deref = this->deref; 1631b8e80941Smrg nir_ssa_def *src = evaluate_rvalue(ir->rhs); 1632b8e80941Smrg 1633b8e80941Smrg if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != 0) { 1634b8e80941Smrg /* GLSL IR will give us the input to the write-masked assignment in a 1635b8e80941Smrg * single packed vector. So, for example, if the writemask is xzw, then 1636b8e80941Smrg * we have to swizzle x -> x, y -> z, and z -> w and get the y component 1637b8e80941Smrg * from the load. 1638b8e80941Smrg */ 1639b8e80941Smrg unsigned swiz[4]; 1640b8e80941Smrg unsigned component = 0; 1641b8e80941Smrg for (unsigned i = 0; i < 4; i++) { 1642b8e80941Smrg swiz[i] = ir->write_mask & (1 << i) ? component++ : 0; 1643b8e80941Smrg } 1644b8e80941Smrg src = nir_swizzle(&b, src, swiz, num_components, false); 1645b8e80941Smrg } 1646b8e80941Smrg 1647b8e80941Smrg if (ir->condition) { 1648b8e80941Smrg nir_push_if(&b, evaluate_rvalue(ir->condition)); 1649b8e80941Smrg nir_store_deref(&b, lhs_deref, src, ir->write_mask); 1650b8e80941Smrg nir_pop_if(&b, NULL); 1651b8e80941Smrg } else { 1652b8e80941Smrg nir_store_deref(&b, lhs_deref, src, ir->write_mask); 1653b8e80941Smrg } 1654b8e80941Smrg} 1655b8e80941Smrg 1656b8e80941Smrg/* 1657b8e80941Smrg * Given an instruction, returns a pointer to its destination or NULL if there 1658b8e80941Smrg * is no destination. 1659b8e80941Smrg * 1660b8e80941Smrg * Note that this only handles instructions we generate at this level. 1661b8e80941Smrg */ 1662b8e80941Smrgstatic nir_dest * 1663b8e80941Smrgget_instr_dest(nir_instr *instr) 1664b8e80941Smrg{ 1665b8e80941Smrg nir_alu_instr *alu_instr; 1666b8e80941Smrg nir_intrinsic_instr *intrinsic_instr; 1667b8e80941Smrg nir_tex_instr *tex_instr; 1668b8e80941Smrg 1669b8e80941Smrg switch (instr->type) { 1670b8e80941Smrg case nir_instr_type_alu: 1671b8e80941Smrg alu_instr = nir_instr_as_alu(instr); 1672b8e80941Smrg return &alu_instr->dest.dest; 1673b8e80941Smrg 1674b8e80941Smrg case nir_instr_type_intrinsic: 1675b8e80941Smrg intrinsic_instr = nir_instr_as_intrinsic(instr); 1676b8e80941Smrg if (nir_intrinsic_infos[intrinsic_instr->intrinsic].has_dest) 1677b8e80941Smrg return &intrinsic_instr->dest; 1678b8e80941Smrg else 1679b8e80941Smrg return NULL; 1680b8e80941Smrg 1681b8e80941Smrg case nir_instr_type_tex: 1682b8e80941Smrg tex_instr = nir_instr_as_tex(instr); 1683b8e80941Smrg return &tex_instr->dest; 1684b8e80941Smrg 1685b8e80941Smrg default: 1686b8e80941Smrg unreachable("not reached"); 1687b8e80941Smrg } 1688b8e80941Smrg 1689b8e80941Smrg return NULL; 1690b8e80941Smrg} 1691b8e80941Smrg 1692b8e80941Smrgvoid 1693b8e80941Smrgnir_visitor::add_instr(nir_instr *instr, unsigned num_components, 1694b8e80941Smrg unsigned bit_size) 1695b8e80941Smrg{ 1696b8e80941Smrg nir_dest *dest = get_instr_dest(instr); 1697b8e80941Smrg 1698b8e80941Smrg if (dest) 1699b8e80941Smrg nir_ssa_dest_init(instr, dest, num_components, bit_size, NULL); 1700b8e80941Smrg 1701b8e80941Smrg nir_builder_instr_insert(&b, instr); 1702b8e80941Smrg 1703b8e80941Smrg if (dest) { 1704b8e80941Smrg assert(dest->is_ssa); 1705b8e80941Smrg this->result = &dest->ssa; 1706b8e80941Smrg } 1707b8e80941Smrg} 1708b8e80941Smrg 1709b8e80941Smrgnir_ssa_def * 1710b8e80941Smrgnir_visitor::evaluate_rvalue(ir_rvalue* ir) 1711b8e80941Smrg{ 1712b8e80941Smrg ir->accept(this); 1713b8e80941Smrg if (ir->as_dereference() || ir->as_constant()) { 1714b8e80941Smrg /* 1715b8e80941Smrg * A dereference is being used on the right hand side, which means we 1716b8e80941Smrg * must emit a variable load. 1717b8e80941Smrg */ 1718b8e80941Smrg 1719b8e80941Smrg this->result = nir_load_deref(&b, this->deref); 1720b8e80941Smrg } 1721b8e80941Smrg 1722b8e80941Smrg return this->result; 1723b8e80941Smrg} 1724b8e80941Smrg 1725b8e80941Smrgstatic bool 1726b8e80941Smrgtype_is_float(glsl_base_type type) 1727b8e80941Smrg{ 1728b8e80941Smrg return type == GLSL_TYPE_FLOAT || type == GLSL_TYPE_DOUBLE || 1729b8e80941Smrg type == GLSL_TYPE_FLOAT16; 1730b8e80941Smrg} 1731b8e80941Smrg 1732b8e80941Smrgstatic bool 1733b8e80941Smrgtype_is_signed(glsl_base_type type) 1734b8e80941Smrg{ 1735b8e80941Smrg return type == GLSL_TYPE_INT || type == GLSL_TYPE_INT64 || 1736b8e80941Smrg type == GLSL_TYPE_INT16; 1737b8e80941Smrg} 1738b8e80941Smrg 1739b8e80941Smrgstatic bool 1740b8e80941Smrgtype_is_int(glsl_base_type type) 1741b8e80941Smrg{ 1742b8e80941Smrg return type == GLSL_TYPE_UINT || type == GLSL_TYPE_INT || 1743b8e80941Smrg type == GLSL_TYPE_UINT8 || type == GLSL_TYPE_INT8 || 1744b8e80941Smrg type == GLSL_TYPE_UINT16 || type == GLSL_TYPE_INT16 || 1745b8e80941Smrg type == GLSL_TYPE_UINT64 || type == GLSL_TYPE_INT64; 1746b8e80941Smrg} 1747b8e80941Smrg 1748b8e80941Smrgvoid 1749b8e80941Smrgnir_visitor::visit(ir_expression *ir) 1750b8e80941Smrg{ 1751b8e80941Smrg /* Some special cases */ 1752b8e80941Smrg switch (ir->operation) { 1753b8e80941Smrg case ir_binop_ubo_load: { 1754b8e80941Smrg nir_intrinsic_instr *load = 1755b8e80941Smrg nir_intrinsic_instr_create(this->shader, nir_intrinsic_load_ubo); 1756b8e80941Smrg unsigned bit_size = ir->type->is_boolean() ? 32 : 1757b8e80941Smrg glsl_get_bit_size(ir->type); 1758b8e80941Smrg load->num_components = ir->type->vector_elements; 1759b8e80941Smrg load->src[0] = nir_src_for_ssa(evaluate_rvalue(ir->operands[0])); 1760b8e80941Smrg load->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1])); 1761b8e80941Smrg intrinsic_set_std430_align(load, ir->type); 1762b8e80941Smrg add_instr(&load->instr, ir->type->vector_elements, bit_size); 1763b8e80941Smrg 1764b8e80941Smrg /* 1765b8e80941Smrg * In UBO's, a true boolean value is any non-zero value, but we consider 1766b8e80941Smrg * a true boolean to be ~0. Fix this up with a != 0 comparison. 1767b8e80941Smrg */ 1768b8e80941Smrg 1769b8e80941Smrg if (ir->type->is_boolean()) 1770b8e80941Smrg this->result = nir_i2b(&b, &load->dest.ssa); 1771b8e80941Smrg 1772b8e80941Smrg return; 1773b8e80941Smrg } 1774b8e80941Smrg 1775b8e80941Smrg case ir_unop_interpolate_at_centroid: 1776b8e80941Smrg case ir_binop_interpolate_at_offset: 1777b8e80941Smrg case ir_binop_interpolate_at_sample: { 1778b8e80941Smrg ir_dereference *deref = ir->operands[0]->as_dereference(); 1779b8e80941Smrg ir_swizzle *swizzle = NULL; 1780b8e80941Smrg if (!deref) { 1781b8e80941Smrg /* the api does not allow a swizzle here, but the varying packing code 1782b8e80941Smrg * may have pushed one into here. 1783b8e80941Smrg */ 1784b8e80941Smrg swizzle = ir->operands[0]->as_swizzle(); 1785b8e80941Smrg assert(swizzle); 1786b8e80941Smrg deref = swizzle->val->as_dereference(); 1787b8e80941Smrg assert(deref); 1788b8e80941Smrg } 1789b8e80941Smrg 1790b8e80941Smrg deref->accept(this); 1791b8e80941Smrg 1792b8e80941Smrg nir_intrinsic_op op; 1793b8e80941Smrg if (this->deref->mode == nir_var_shader_in) { 1794b8e80941Smrg switch (ir->operation) { 1795b8e80941Smrg case ir_unop_interpolate_at_centroid: 1796b8e80941Smrg op = nir_intrinsic_interp_deref_at_centroid; 1797b8e80941Smrg break; 1798b8e80941Smrg case ir_binop_interpolate_at_offset: 1799b8e80941Smrg op = nir_intrinsic_interp_deref_at_offset; 1800b8e80941Smrg break; 1801b8e80941Smrg case ir_binop_interpolate_at_sample: 1802b8e80941Smrg op = nir_intrinsic_interp_deref_at_sample; 1803b8e80941Smrg break; 1804b8e80941Smrg default: 1805b8e80941Smrg unreachable("Invalid interpolation intrinsic"); 1806b8e80941Smrg } 1807b8e80941Smrg } else { 1808b8e80941Smrg /* This case can happen if the vertex shader does not write the 1809b8e80941Smrg * given varying. In this case, the linker will lower it to a 1810b8e80941Smrg * global variable. Since interpolating a variable makes no 1811b8e80941Smrg * sense, we'll just turn it into a load which will probably 1812b8e80941Smrg * eventually end up as an SSA definition. 1813b8e80941Smrg */ 1814b8e80941Smrg assert(this->deref->mode == nir_var_shader_temp); 1815b8e80941Smrg op = nir_intrinsic_load_deref; 1816b8e80941Smrg } 1817b8e80941Smrg 1818b8e80941Smrg nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(shader, op); 1819b8e80941Smrg intrin->num_components = deref->type->vector_elements; 1820b8e80941Smrg intrin->src[0] = nir_src_for_ssa(&this->deref->dest.ssa); 1821b8e80941Smrg 1822b8e80941Smrg if (intrin->intrinsic == nir_intrinsic_interp_deref_at_offset || 1823b8e80941Smrg intrin->intrinsic == nir_intrinsic_interp_deref_at_sample) 1824b8e80941Smrg intrin->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1])); 1825b8e80941Smrg 1826b8e80941Smrg unsigned bit_size = glsl_get_bit_size(deref->type); 1827b8e80941Smrg add_instr(&intrin->instr, deref->type->vector_elements, bit_size); 1828b8e80941Smrg 1829b8e80941Smrg if (swizzle) { 1830b8e80941Smrg unsigned swiz[4] = { 1831b8e80941Smrg swizzle->mask.x, swizzle->mask.y, swizzle->mask.z, swizzle->mask.w 1832b8e80941Smrg }; 1833b8e80941Smrg 1834b8e80941Smrg result = nir_swizzle(&b, result, swiz, 1835b8e80941Smrg swizzle->type->vector_elements, false); 1836b8e80941Smrg } 1837b8e80941Smrg 1838b8e80941Smrg return; 1839b8e80941Smrg } 1840b8e80941Smrg 1841b8e80941Smrg case ir_unop_ssbo_unsized_array_length: { 1842b8e80941Smrg nir_intrinsic_instr *intrin = 1843b8e80941Smrg nir_intrinsic_instr_create(b.shader, 1844b8e80941Smrg nir_intrinsic_deref_buffer_array_length); 1845b8e80941Smrg 1846b8e80941Smrg ir_dereference *deref = ir->operands[0]->as_dereference(); 1847b8e80941Smrg intrin->src[0] = nir_src_for_ssa(&evaluate_deref(deref)->dest.ssa); 1848b8e80941Smrg 1849b8e80941Smrg add_instr(&intrin->instr, 1, 32); 1850b8e80941Smrg return; 1851b8e80941Smrg } 1852b8e80941Smrg 1853b8e80941Smrg default: 1854b8e80941Smrg break; 1855b8e80941Smrg } 1856b8e80941Smrg 1857b8e80941Smrg nir_ssa_def *srcs[4]; 1858b8e80941Smrg for (unsigned i = 0; i < ir->num_operands; i++) 1859b8e80941Smrg srcs[i] = evaluate_rvalue(ir->operands[i]); 1860b8e80941Smrg 1861b8e80941Smrg glsl_base_type types[4]; 1862b8e80941Smrg for (unsigned i = 0; i < ir->num_operands; i++) 1863b8e80941Smrg if (supports_ints || !type_is_int(ir->operands[i]->type->base_type)) 1864b8e80941Smrg types[i] = ir->operands[i]->type->base_type; 1865b8e80941Smrg else 1866b8e80941Smrg types[i] = GLSL_TYPE_FLOAT; 1867b8e80941Smrg 1868b8e80941Smrg glsl_base_type out_type; 1869b8e80941Smrg if (supports_ints || !type_is_int(ir->type->base_type)) 1870b8e80941Smrg out_type = ir->type->base_type; 1871b8e80941Smrg else 1872b8e80941Smrg out_type = GLSL_TYPE_FLOAT; 1873b8e80941Smrg 1874b8e80941Smrg switch (ir->operation) { 1875b8e80941Smrg case ir_unop_bit_not: result = nir_inot(&b, srcs[0]); break; 1876b8e80941Smrg case ir_unop_logic_not: 1877b8e80941Smrg result = nir_inot(&b, srcs[0]); 1878b8e80941Smrg break; 1879b8e80941Smrg case ir_unop_neg: 1880b8e80941Smrg result = type_is_float(types[0]) ? nir_fneg(&b, srcs[0]) 1881b8e80941Smrg : nir_ineg(&b, srcs[0]); 1882b8e80941Smrg break; 1883b8e80941Smrg case ir_unop_abs: 1884b8e80941Smrg result = type_is_float(types[0]) ? nir_fabs(&b, srcs[0]) 1885b8e80941Smrg : nir_iabs(&b, srcs[0]); 1886b8e80941Smrg break; 1887b8e80941Smrg case ir_unop_saturate: 1888b8e80941Smrg assert(type_is_float(types[0])); 1889b8e80941Smrg result = nir_fsat(&b, srcs[0]); 1890b8e80941Smrg break; 1891b8e80941Smrg case ir_unop_sign: 1892b8e80941Smrg result = type_is_float(types[0]) ? nir_fsign(&b, srcs[0]) 1893b8e80941Smrg : nir_isign(&b, srcs[0]); 1894b8e80941Smrg break; 1895b8e80941Smrg case ir_unop_rcp: result = nir_frcp(&b, srcs[0]); break; 1896b8e80941Smrg case ir_unop_rsq: result = nir_frsq(&b, srcs[0]); break; 1897b8e80941Smrg case ir_unop_sqrt: result = nir_fsqrt(&b, srcs[0]); break; 1898b8e80941Smrg case ir_unop_exp: unreachable("ir_unop_exp should have been lowered"); 1899b8e80941Smrg case ir_unop_log: unreachable("ir_unop_log should have been lowered"); 1900b8e80941Smrg case ir_unop_exp2: result = nir_fexp2(&b, srcs[0]); break; 1901b8e80941Smrg case ir_unop_log2: result = nir_flog2(&b, srcs[0]); break; 1902b8e80941Smrg case ir_unop_i2f: 1903b8e80941Smrg result = supports_ints ? nir_i2f32(&b, srcs[0]) : nir_fmov(&b, srcs[0]); 1904b8e80941Smrg break; 1905b8e80941Smrg case ir_unop_u2f: 1906b8e80941Smrg result = supports_ints ? nir_u2f32(&b, srcs[0]) : nir_fmov(&b, srcs[0]); 1907b8e80941Smrg break; 1908b8e80941Smrg case ir_unop_b2f: 1909b8e80941Smrg result = nir_b2f32(&b, srcs[0]); 1910b8e80941Smrg break; 1911b8e80941Smrg case ir_unop_f2i: 1912b8e80941Smrg result = supports_ints ? nir_f2i32(&b, srcs[0]) : nir_ftrunc(&b, srcs[0]); 1913b8e80941Smrg break; 1914b8e80941Smrg case ir_unop_f2u: 1915b8e80941Smrg result = supports_ints ? nir_f2u32(&b, srcs[0]) : nir_ftrunc(&b, srcs[0]); 1916b8e80941Smrg break; 1917b8e80941Smrg case ir_unop_f2b: 1918b8e80941Smrg case ir_unop_i2b: 1919b8e80941Smrg case ir_unop_b2i: 1920b8e80941Smrg case ir_unop_b2i64: 1921b8e80941Smrg case ir_unop_d2f: 1922b8e80941Smrg case ir_unop_f2d: 1923b8e80941Smrg case ir_unop_d2i: 1924b8e80941Smrg case ir_unop_d2u: 1925b8e80941Smrg case ir_unop_d2b: 1926b8e80941Smrg case ir_unop_i2d: 1927b8e80941Smrg case ir_unop_u2d: 1928b8e80941Smrg case ir_unop_i642i: 1929b8e80941Smrg case ir_unop_i642u: 1930b8e80941Smrg case ir_unop_i642f: 1931b8e80941Smrg case ir_unop_i642b: 1932b8e80941Smrg case ir_unop_i642d: 1933b8e80941Smrg case ir_unop_u642i: 1934b8e80941Smrg case ir_unop_u642u: 1935b8e80941Smrg case ir_unop_u642f: 1936b8e80941Smrg case ir_unop_u642d: 1937b8e80941Smrg case ir_unop_i2i64: 1938b8e80941Smrg case ir_unop_u2i64: 1939b8e80941Smrg case ir_unop_f2i64: 1940b8e80941Smrg case ir_unop_d2i64: 1941b8e80941Smrg case ir_unop_i2u64: 1942b8e80941Smrg case ir_unop_u2u64: 1943b8e80941Smrg case ir_unop_f2u64: 1944b8e80941Smrg case ir_unop_d2u64: 1945b8e80941Smrg case ir_unop_i2u: 1946b8e80941Smrg case ir_unop_u2i: 1947b8e80941Smrg case ir_unop_i642u64: 1948b8e80941Smrg case ir_unop_u642i64: { 1949b8e80941Smrg nir_alu_type src_type = nir_get_nir_type_for_glsl_base_type(types[0]); 1950b8e80941Smrg nir_alu_type dst_type = nir_get_nir_type_for_glsl_base_type(out_type); 1951b8e80941Smrg result = nir_build_alu(&b, nir_type_conversion_op(src_type, dst_type, 1952b8e80941Smrg nir_rounding_mode_undef), 1953b8e80941Smrg srcs[0], NULL, NULL, NULL); 1954b8e80941Smrg /* b2i and b2f don't have fixed bit-size versions so the builder will 1955b8e80941Smrg * just assume 32 and we have to fix it up here. 1956b8e80941Smrg */ 1957b8e80941Smrg result->bit_size = nir_alu_type_get_type_size(dst_type); 1958b8e80941Smrg break; 1959b8e80941Smrg } 1960b8e80941Smrg 1961b8e80941Smrg case ir_unop_bitcast_i2f: 1962b8e80941Smrg case ir_unop_bitcast_f2i: 1963b8e80941Smrg case ir_unop_bitcast_u2f: 1964b8e80941Smrg case ir_unop_bitcast_f2u: 1965b8e80941Smrg case ir_unop_bitcast_i642d: 1966b8e80941Smrg case ir_unop_bitcast_d2i64: 1967b8e80941Smrg case ir_unop_bitcast_u642d: 1968b8e80941Smrg case ir_unop_bitcast_d2u64: 1969b8e80941Smrg case ir_unop_subroutine_to_int: 1970b8e80941Smrg /* no-op */ 1971b8e80941Smrg result = nir_imov(&b, srcs[0]); 1972b8e80941Smrg break; 1973b8e80941Smrg case ir_unop_trunc: result = nir_ftrunc(&b, srcs[0]); break; 1974b8e80941Smrg case ir_unop_ceil: result = nir_fceil(&b, srcs[0]); break; 1975b8e80941Smrg case ir_unop_floor: result = nir_ffloor(&b, srcs[0]); break; 1976b8e80941Smrg case ir_unop_fract: result = nir_ffract(&b, srcs[0]); break; 1977b8e80941Smrg case ir_unop_frexp_exp: result = nir_frexp_exp(&b, srcs[0]); break; 1978b8e80941Smrg case ir_unop_frexp_sig: result = nir_frexp_sig(&b, srcs[0]); break; 1979b8e80941Smrg case ir_unop_round_even: result = nir_fround_even(&b, srcs[0]); break; 1980b8e80941Smrg case ir_unop_sin: result = nir_fsin(&b, srcs[0]); break; 1981b8e80941Smrg case ir_unop_cos: result = nir_fcos(&b, srcs[0]); break; 1982b8e80941Smrg case ir_unop_dFdx: result = nir_fddx(&b, srcs[0]); break; 1983b8e80941Smrg case ir_unop_dFdy: result = nir_fddy(&b, srcs[0]); break; 1984b8e80941Smrg case ir_unop_dFdx_fine: result = nir_fddx_fine(&b, srcs[0]); break; 1985b8e80941Smrg case ir_unop_dFdy_fine: result = nir_fddy_fine(&b, srcs[0]); break; 1986b8e80941Smrg case ir_unop_dFdx_coarse: result = nir_fddx_coarse(&b, srcs[0]); break; 1987b8e80941Smrg case ir_unop_dFdy_coarse: result = nir_fddy_coarse(&b, srcs[0]); break; 1988b8e80941Smrg case ir_unop_pack_snorm_2x16: 1989b8e80941Smrg result = nir_pack_snorm_2x16(&b, srcs[0]); 1990b8e80941Smrg break; 1991b8e80941Smrg case ir_unop_pack_snorm_4x8: 1992b8e80941Smrg result = nir_pack_snorm_4x8(&b, srcs[0]); 1993b8e80941Smrg break; 1994b8e80941Smrg case ir_unop_pack_unorm_2x16: 1995b8e80941Smrg result = nir_pack_unorm_2x16(&b, srcs[0]); 1996b8e80941Smrg break; 1997b8e80941Smrg case ir_unop_pack_unorm_4x8: 1998b8e80941Smrg result = nir_pack_unorm_4x8(&b, srcs[0]); 1999b8e80941Smrg break; 2000b8e80941Smrg case ir_unop_pack_half_2x16: 2001b8e80941Smrg result = nir_pack_half_2x16(&b, srcs[0]); 2002b8e80941Smrg break; 2003b8e80941Smrg case ir_unop_unpack_snorm_2x16: 2004b8e80941Smrg result = nir_unpack_snorm_2x16(&b, srcs[0]); 2005b8e80941Smrg break; 2006b8e80941Smrg case ir_unop_unpack_snorm_4x8: 2007b8e80941Smrg result = nir_unpack_snorm_4x8(&b, srcs[0]); 2008b8e80941Smrg break; 2009b8e80941Smrg case ir_unop_unpack_unorm_2x16: 2010b8e80941Smrg result = nir_unpack_unorm_2x16(&b, srcs[0]); 2011b8e80941Smrg break; 2012b8e80941Smrg case ir_unop_unpack_unorm_4x8: 2013b8e80941Smrg result = nir_unpack_unorm_4x8(&b, srcs[0]); 2014b8e80941Smrg break; 2015b8e80941Smrg case ir_unop_unpack_half_2x16: 2016b8e80941Smrg result = nir_unpack_half_2x16(&b, srcs[0]); 2017b8e80941Smrg break; 2018b8e80941Smrg case ir_unop_pack_sampler_2x32: 2019b8e80941Smrg case ir_unop_pack_image_2x32: 2020b8e80941Smrg case ir_unop_pack_double_2x32: 2021b8e80941Smrg case ir_unop_pack_int_2x32: 2022b8e80941Smrg case ir_unop_pack_uint_2x32: 2023b8e80941Smrg result = nir_pack_64_2x32(&b, srcs[0]); 2024b8e80941Smrg break; 2025b8e80941Smrg case ir_unop_unpack_sampler_2x32: 2026b8e80941Smrg case ir_unop_unpack_image_2x32: 2027b8e80941Smrg case ir_unop_unpack_double_2x32: 2028b8e80941Smrg case ir_unop_unpack_int_2x32: 2029b8e80941Smrg case ir_unop_unpack_uint_2x32: 2030b8e80941Smrg result = nir_unpack_64_2x32(&b, srcs[0]); 2031b8e80941Smrg break; 2032b8e80941Smrg case ir_unop_bitfield_reverse: 2033b8e80941Smrg result = nir_bitfield_reverse(&b, srcs[0]); 2034b8e80941Smrg break; 2035b8e80941Smrg case ir_unop_bit_count: 2036b8e80941Smrg result = nir_bit_count(&b, srcs[0]); 2037b8e80941Smrg break; 2038b8e80941Smrg case ir_unop_find_msb: 2039b8e80941Smrg switch (types[0]) { 2040b8e80941Smrg case GLSL_TYPE_UINT: 2041b8e80941Smrg result = nir_ufind_msb(&b, srcs[0]); 2042b8e80941Smrg break; 2043b8e80941Smrg case GLSL_TYPE_INT: 2044b8e80941Smrg result = nir_ifind_msb(&b, srcs[0]); 2045b8e80941Smrg break; 2046b8e80941Smrg default: 2047b8e80941Smrg unreachable("Invalid type for findMSB()"); 2048b8e80941Smrg } 2049b8e80941Smrg break; 2050b8e80941Smrg case ir_unop_find_lsb: 2051b8e80941Smrg result = nir_find_lsb(&b, srcs[0]); 2052b8e80941Smrg break; 2053b8e80941Smrg 2054b8e80941Smrg case ir_unop_noise: 2055b8e80941Smrg switch (ir->type->vector_elements) { 2056b8e80941Smrg case 1: 2057b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2058b8e80941Smrg case 1: result = nir_fnoise1_1(&b, srcs[0]); break; 2059b8e80941Smrg case 2: result = nir_fnoise1_2(&b, srcs[0]); break; 2060b8e80941Smrg case 3: result = nir_fnoise1_3(&b, srcs[0]); break; 2061b8e80941Smrg case 4: result = nir_fnoise1_4(&b, srcs[0]); break; 2062b8e80941Smrg default: unreachable("not reached"); 2063b8e80941Smrg } 2064b8e80941Smrg break; 2065b8e80941Smrg case 2: 2066b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2067b8e80941Smrg case 1: result = nir_fnoise2_1(&b, srcs[0]); break; 2068b8e80941Smrg case 2: result = nir_fnoise2_2(&b, srcs[0]); break; 2069b8e80941Smrg case 3: result = nir_fnoise2_3(&b, srcs[0]); break; 2070b8e80941Smrg case 4: result = nir_fnoise2_4(&b, srcs[0]); break; 2071b8e80941Smrg default: unreachable("not reached"); 2072b8e80941Smrg } 2073b8e80941Smrg break; 2074b8e80941Smrg case 3: 2075b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2076b8e80941Smrg case 1: result = nir_fnoise3_1(&b, srcs[0]); break; 2077b8e80941Smrg case 2: result = nir_fnoise3_2(&b, srcs[0]); break; 2078b8e80941Smrg case 3: result = nir_fnoise3_3(&b, srcs[0]); break; 2079b8e80941Smrg case 4: result = nir_fnoise3_4(&b, srcs[0]); break; 2080b8e80941Smrg default: unreachable("not reached"); 2081b8e80941Smrg } 2082b8e80941Smrg break; 2083b8e80941Smrg case 4: 2084b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2085b8e80941Smrg case 1: result = nir_fnoise4_1(&b, srcs[0]); break; 2086b8e80941Smrg case 2: result = nir_fnoise4_2(&b, srcs[0]); break; 2087b8e80941Smrg case 3: result = nir_fnoise4_3(&b, srcs[0]); break; 2088b8e80941Smrg case 4: result = nir_fnoise4_4(&b, srcs[0]); break; 2089b8e80941Smrg default: unreachable("not reached"); 2090b8e80941Smrg } 2091b8e80941Smrg break; 2092b8e80941Smrg default: 2093b8e80941Smrg unreachable("not reached"); 2094b8e80941Smrg } 2095b8e80941Smrg break; 2096b8e80941Smrg case ir_unop_get_buffer_size: { 2097b8e80941Smrg nir_intrinsic_instr *load = nir_intrinsic_instr_create( 2098b8e80941Smrg this->shader, 2099b8e80941Smrg nir_intrinsic_get_buffer_size); 2100b8e80941Smrg load->num_components = ir->type->vector_elements; 2101b8e80941Smrg load->src[0] = nir_src_for_ssa(evaluate_rvalue(ir->operands[0])); 2102b8e80941Smrg unsigned bit_size = glsl_get_bit_size(ir->type); 2103b8e80941Smrg add_instr(&load->instr, ir->type->vector_elements, bit_size); 2104b8e80941Smrg return; 2105b8e80941Smrg } 2106b8e80941Smrg 2107b8e80941Smrg case ir_binop_add: 2108b8e80941Smrg result = type_is_float(out_type) ? nir_fadd(&b, srcs[0], srcs[1]) 2109b8e80941Smrg : nir_iadd(&b, srcs[0], srcs[1]); 2110b8e80941Smrg break; 2111b8e80941Smrg case ir_binop_sub: 2112b8e80941Smrg result = type_is_float(out_type) ? nir_fsub(&b, srcs[0], srcs[1]) 2113b8e80941Smrg : nir_isub(&b, srcs[0], srcs[1]); 2114b8e80941Smrg break; 2115b8e80941Smrg case ir_binop_mul: 2116b8e80941Smrg if (type_is_float(out_type)) 2117b8e80941Smrg result = nir_fmul(&b, srcs[0], srcs[1]); 2118b8e80941Smrg else if (out_type == GLSL_TYPE_INT64 && 2119b8e80941Smrg (ir->operands[0]->type->base_type == GLSL_TYPE_INT || 2120b8e80941Smrg ir->operands[1]->type->base_type == GLSL_TYPE_INT)) 2121b8e80941Smrg result = nir_imul_2x32_64(&b, srcs[0], srcs[1]); 2122b8e80941Smrg else if (out_type == GLSL_TYPE_UINT64 && 2123b8e80941Smrg (ir->operands[0]->type->base_type == GLSL_TYPE_UINT || 2124b8e80941Smrg ir->operands[1]->type->base_type == GLSL_TYPE_UINT)) 2125b8e80941Smrg result = nir_umul_2x32_64(&b, srcs[0], srcs[1]); 2126b8e80941Smrg else 2127b8e80941Smrg result = nir_imul(&b, srcs[0], srcs[1]); 2128b8e80941Smrg break; 2129b8e80941Smrg case ir_binop_div: 2130b8e80941Smrg if (type_is_float(out_type)) 2131b8e80941Smrg result = nir_fdiv(&b, srcs[0], srcs[1]); 2132b8e80941Smrg else if (type_is_signed(out_type)) 2133b8e80941Smrg result = nir_idiv(&b, srcs[0], srcs[1]); 2134b8e80941Smrg else 2135b8e80941Smrg result = nir_udiv(&b, srcs[0], srcs[1]); 2136b8e80941Smrg break; 2137b8e80941Smrg case ir_binop_mod: 2138b8e80941Smrg result = type_is_float(out_type) ? nir_fmod(&b, srcs[0], srcs[1]) 2139b8e80941Smrg : nir_umod(&b, srcs[0], srcs[1]); 2140b8e80941Smrg break; 2141b8e80941Smrg case ir_binop_min: 2142b8e80941Smrg if (type_is_float(out_type)) 2143b8e80941Smrg result = nir_fmin(&b, srcs[0], srcs[1]); 2144b8e80941Smrg else if (type_is_signed(out_type)) 2145b8e80941Smrg result = nir_imin(&b, srcs[0], srcs[1]); 2146b8e80941Smrg else 2147b8e80941Smrg result = nir_umin(&b, srcs[0], srcs[1]); 2148b8e80941Smrg break; 2149b8e80941Smrg case ir_binop_max: 2150b8e80941Smrg if (type_is_float(out_type)) 2151b8e80941Smrg result = nir_fmax(&b, srcs[0], srcs[1]); 2152b8e80941Smrg else if (type_is_signed(out_type)) 2153b8e80941Smrg result = nir_imax(&b, srcs[0], srcs[1]); 2154b8e80941Smrg else 2155b8e80941Smrg result = nir_umax(&b, srcs[0], srcs[1]); 2156b8e80941Smrg break; 2157b8e80941Smrg case ir_binop_pow: result = nir_fpow(&b, srcs[0], srcs[1]); break; 2158b8e80941Smrg case ir_binop_bit_and: result = nir_iand(&b, srcs[0], srcs[1]); break; 2159b8e80941Smrg case ir_binop_bit_or: result = nir_ior(&b, srcs[0], srcs[1]); break; 2160b8e80941Smrg case ir_binop_bit_xor: result = nir_ixor(&b, srcs[0], srcs[1]); break; 2161b8e80941Smrg case ir_binop_logic_and: 2162b8e80941Smrg result = nir_iand(&b, srcs[0], srcs[1]); 2163b8e80941Smrg break; 2164b8e80941Smrg case ir_binop_logic_or: 2165b8e80941Smrg result = nir_ior(&b, srcs[0], srcs[1]); 2166b8e80941Smrg break; 2167b8e80941Smrg case ir_binop_logic_xor: 2168b8e80941Smrg result = nir_ixor(&b, srcs[0], srcs[1]); 2169b8e80941Smrg break; 2170b8e80941Smrg case ir_binop_lshift: result = nir_ishl(&b, srcs[0], srcs[1]); break; 2171b8e80941Smrg case ir_binop_rshift: 2172b8e80941Smrg result = (type_is_signed(out_type)) ? nir_ishr(&b, srcs[0], srcs[1]) 2173b8e80941Smrg : nir_ushr(&b, srcs[0], srcs[1]); 2174b8e80941Smrg break; 2175b8e80941Smrg case ir_binop_imul_high: 2176b8e80941Smrg result = (out_type == GLSL_TYPE_INT) ? nir_imul_high(&b, srcs[0], srcs[1]) 2177b8e80941Smrg : nir_umul_high(&b, srcs[0], srcs[1]); 2178b8e80941Smrg break; 2179b8e80941Smrg case ir_binop_carry: result = nir_uadd_carry(&b, srcs[0], srcs[1]); break; 2180b8e80941Smrg case ir_binop_borrow: result = nir_usub_borrow(&b, srcs[0], srcs[1]); break; 2181b8e80941Smrg case ir_binop_less: 2182b8e80941Smrg if (type_is_float(types[0])) 2183b8e80941Smrg result = nir_flt(&b, srcs[0], srcs[1]); 2184b8e80941Smrg else if (type_is_signed(types[0])) 2185b8e80941Smrg result = nir_ilt(&b, srcs[0], srcs[1]); 2186b8e80941Smrg else 2187b8e80941Smrg result = nir_ult(&b, srcs[0], srcs[1]); 2188b8e80941Smrg break; 2189b8e80941Smrg case ir_binop_gequal: 2190b8e80941Smrg if (type_is_float(types[0])) 2191b8e80941Smrg result = nir_fge(&b, srcs[0], srcs[1]); 2192b8e80941Smrg else if (type_is_signed(types[0])) 2193b8e80941Smrg result = nir_ige(&b, srcs[0], srcs[1]); 2194b8e80941Smrg else 2195b8e80941Smrg result = nir_uge(&b, srcs[0], srcs[1]); 2196b8e80941Smrg break; 2197b8e80941Smrg case ir_binop_equal: 2198b8e80941Smrg if (type_is_float(types[0])) 2199b8e80941Smrg result = nir_feq(&b, srcs[0], srcs[1]); 2200b8e80941Smrg else 2201b8e80941Smrg result = nir_ieq(&b, srcs[0], srcs[1]); 2202b8e80941Smrg break; 2203b8e80941Smrg case ir_binop_nequal: 2204b8e80941Smrg if (type_is_float(types[0])) 2205b8e80941Smrg result = nir_fne(&b, srcs[0], srcs[1]); 2206b8e80941Smrg else 2207b8e80941Smrg result = nir_ine(&b, srcs[0], srcs[1]); 2208b8e80941Smrg break; 2209b8e80941Smrg case ir_binop_all_equal: 2210b8e80941Smrg if (type_is_float(types[0])) { 2211b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2212b8e80941Smrg case 1: result = nir_feq(&b, srcs[0], srcs[1]); break; 2213b8e80941Smrg case 2: result = nir_ball_fequal2(&b, srcs[0], srcs[1]); break; 2214b8e80941Smrg case 3: result = nir_ball_fequal3(&b, srcs[0], srcs[1]); break; 2215b8e80941Smrg case 4: result = nir_ball_fequal4(&b, srcs[0], srcs[1]); break; 2216b8e80941Smrg default: 2217b8e80941Smrg unreachable("not reached"); 2218b8e80941Smrg } 2219b8e80941Smrg } else { 2220b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2221b8e80941Smrg case 1: result = nir_ieq(&b, srcs[0], srcs[1]); break; 2222b8e80941Smrg case 2: result = nir_ball_iequal2(&b, srcs[0], srcs[1]); break; 2223b8e80941Smrg case 3: result = nir_ball_iequal3(&b, srcs[0], srcs[1]); break; 2224b8e80941Smrg case 4: result = nir_ball_iequal4(&b, srcs[0], srcs[1]); break; 2225b8e80941Smrg default: 2226b8e80941Smrg unreachable("not reached"); 2227b8e80941Smrg } 2228b8e80941Smrg } 2229b8e80941Smrg break; 2230b8e80941Smrg case ir_binop_any_nequal: 2231b8e80941Smrg if (type_is_float(types[0])) { 2232b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2233b8e80941Smrg case 1: result = nir_fne(&b, srcs[0], srcs[1]); break; 2234b8e80941Smrg case 2: result = nir_bany_fnequal2(&b, srcs[0], srcs[1]); break; 2235b8e80941Smrg case 3: result = nir_bany_fnequal3(&b, srcs[0], srcs[1]); break; 2236b8e80941Smrg case 4: result = nir_bany_fnequal4(&b, srcs[0], srcs[1]); break; 2237b8e80941Smrg default: 2238b8e80941Smrg unreachable("not reached"); 2239b8e80941Smrg } 2240b8e80941Smrg } else { 2241b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2242b8e80941Smrg case 1: result = nir_ine(&b, srcs[0], srcs[1]); break; 2243b8e80941Smrg case 2: result = nir_bany_inequal2(&b, srcs[0], srcs[1]); break; 2244b8e80941Smrg case 3: result = nir_bany_inequal3(&b, srcs[0], srcs[1]); break; 2245b8e80941Smrg case 4: result = nir_bany_inequal4(&b, srcs[0], srcs[1]); break; 2246b8e80941Smrg default: 2247b8e80941Smrg unreachable("not reached"); 2248b8e80941Smrg } 2249b8e80941Smrg } 2250b8e80941Smrg break; 2251b8e80941Smrg case ir_binop_dot: 2252b8e80941Smrg switch (ir->operands[0]->type->vector_elements) { 2253b8e80941Smrg case 2: result = nir_fdot2(&b, srcs[0], srcs[1]); break; 2254b8e80941Smrg case 3: result = nir_fdot3(&b, srcs[0], srcs[1]); break; 2255b8e80941Smrg case 4: result = nir_fdot4(&b, srcs[0], srcs[1]); break; 2256b8e80941Smrg default: 2257b8e80941Smrg unreachable("not reached"); 2258b8e80941Smrg } 2259b8e80941Smrg break; 2260b8e80941Smrg case ir_binop_vector_extract: { 2261b8e80941Smrg result = nir_channel(&b, srcs[0], 0); 2262b8e80941Smrg for (unsigned i = 1; i < ir->operands[0]->type->vector_elements; i++) { 2263b8e80941Smrg nir_ssa_def *swizzled = nir_channel(&b, srcs[0], i); 2264b8e80941Smrg result = nir_bcsel(&b, nir_ieq(&b, srcs[1], nir_imm_int(&b, i)), 2265b8e80941Smrg swizzled, result); 2266b8e80941Smrg } 2267b8e80941Smrg break; 2268b8e80941Smrg } 2269b8e80941Smrg 2270b8e80941Smrg case ir_binop_ldexp: result = nir_ldexp(&b, srcs[0], srcs[1]); break; 2271b8e80941Smrg case ir_triop_fma: 2272b8e80941Smrg result = nir_ffma(&b, srcs[0], srcs[1], srcs[2]); 2273b8e80941Smrg break; 2274b8e80941Smrg case ir_triop_lrp: 2275b8e80941Smrg result = nir_flrp(&b, srcs[0], srcs[1], srcs[2]); 2276b8e80941Smrg break; 2277b8e80941Smrg case ir_triop_csel: 2278b8e80941Smrg result = nir_bcsel(&b, srcs[0], srcs[1], srcs[2]); 2279b8e80941Smrg break; 2280b8e80941Smrg case ir_triop_bitfield_extract: 2281b8e80941Smrg result = (out_type == GLSL_TYPE_INT) ? 2282b8e80941Smrg nir_ibitfield_extract(&b, srcs[0], srcs[1], srcs[2]) : 2283b8e80941Smrg nir_ubitfield_extract(&b, srcs[0], srcs[1], srcs[2]); 2284b8e80941Smrg break; 2285b8e80941Smrg case ir_quadop_bitfield_insert: 2286b8e80941Smrg result = nir_bitfield_insert(&b, srcs[0], srcs[1], srcs[2], srcs[3]); 2287b8e80941Smrg break; 2288b8e80941Smrg case ir_quadop_vector: 2289b8e80941Smrg result = nir_vec(&b, srcs, ir->type->vector_elements); 2290b8e80941Smrg break; 2291b8e80941Smrg 2292b8e80941Smrg default: 2293b8e80941Smrg unreachable("not reached"); 2294b8e80941Smrg } 2295b8e80941Smrg} 2296b8e80941Smrg 2297b8e80941Smrgvoid 2298b8e80941Smrgnir_visitor::visit(ir_swizzle *ir) 2299b8e80941Smrg{ 2300b8e80941Smrg unsigned swizzle[4] = { ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w }; 2301b8e80941Smrg result = nir_swizzle(&b, evaluate_rvalue(ir->val), swizzle, 2302b8e80941Smrg ir->type->vector_elements, false); 2303b8e80941Smrg} 2304b8e80941Smrg 2305b8e80941Smrgvoid 2306b8e80941Smrgnir_visitor::visit(ir_texture *ir) 2307b8e80941Smrg{ 2308b8e80941Smrg unsigned num_srcs; 2309b8e80941Smrg nir_texop op; 2310b8e80941Smrg switch (ir->op) { 2311b8e80941Smrg case ir_tex: 2312b8e80941Smrg op = nir_texop_tex; 2313b8e80941Smrg num_srcs = 1; /* coordinate */ 2314b8e80941Smrg break; 2315b8e80941Smrg 2316b8e80941Smrg case ir_txb: 2317b8e80941Smrg case ir_txl: 2318b8e80941Smrg op = (ir->op == ir_txb) ? nir_texop_txb : nir_texop_txl; 2319b8e80941Smrg num_srcs = 2; /* coordinate, bias/lod */ 2320b8e80941Smrg break; 2321b8e80941Smrg 2322b8e80941Smrg case ir_txd: 2323b8e80941Smrg op = nir_texop_txd; /* coordinate, dPdx, dPdy */ 2324b8e80941Smrg num_srcs = 3; 2325b8e80941Smrg break; 2326b8e80941Smrg 2327b8e80941Smrg case ir_txf: 2328b8e80941Smrg op = nir_texop_txf; 2329b8e80941Smrg if (ir->lod_info.lod != NULL) 2330b8e80941Smrg num_srcs = 2; /* coordinate, lod */ 2331b8e80941Smrg else 2332b8e80941Smrg num_srcs = 1; /* coordinate */ 2333b8e80941Smrg break; 2334b8e80941Smrg 2335b8e80941Smrg case ir_txf_ms: 2336b8e80941Smrg op = nir_texop_txf_ms; 2337b8e80941Smrg num_srcs = 2; /* coordinate, sample_index */ 2338b8e80941Smrg break; 2339b8e80941Smrg 2340b8e80941Smrg case ir_txs: 2341b8e80941Smrg op = nir_texop_txs; 2342b8e80941Smrg if (ir->lod_info.lod != NULL) 2343b8e80941Smrg num_srcs = 1; /* lod */ 2344b8e80941Smrg else 2345b8e80941Smrg num_srcs = 0; 2346b8e80941Smrg break; 2347b8e80941Smrg 2348b8e80941Smrg case ir_lod: 2349b8e80941Smrg op = nir_texop_lod; 2350b8e80941Smrg num_srcs = 1; /* coordinate */ 2351b8e80941Smrg break; 2352b8e80941Smrg 2353b8e80941Smrg case ir_tg4: 2354b8e80941Smrg op = nir_texop_tg4; 2355b8e80941Smrg num_srcs = 1; /* coordinate */ 2356b8e80941Smrg break; 2357b8e80941Smrg 2358b8e80941Smrg case ir_query_levels: 2359b8e80941Smrg op = nir_texop_query_levels; 2360b8e80941Smrg num_srcs = 0; 2361b8e80941Smrg break; 2362b8e80941Smrg 2363b8e80941Smrg case ir_texture_samples: 2364b8e80941Smrg op = nir_texop_texture_samples; 2365b8e80941Smrg num_srcs = 0; 2366b8e80941Smrg break; 2367b8e80941Smrg 2368b8e80941Smrg case ir_samples_identical: 2369b8e80941Smrg op = nir_texop_samples_identical; 2370b8e80941Smrg num_srcs = 1; /* coordinate */ 2371b8e80941Smrg break; 2372b8e80941Smrg 2373b8e80941Smrg default: 2374b8e80941Smrg unreachable("not reached"); 2375b8e80941Smrg } 2376b8e80941Smrg 2377b8e80941Smrg if (ir->projector != NULL) 2378b8e80941Smrg num_srcs++; 2379b8e80941Smrg if (ir->shadow_comparator != NULL) 2380b8e80941Smrg num_srcs++; 2381b8e80941Smrg /* offsets are constants we store inside nir_tex_intrs.offsets */ 2382b8e80941Smrg if (ir->offset != NULL && !ir->offset->type->is_array()) 2383b8e80941Smrg num_srcs++; 2384b8e80941Smrg 2385b8e80941Smrg /* Add one for the texture deref */ 2386b8e80941Smrg num_srcs += 2; 2387b8e80941Smrg 2388b8e80941Smrg nir_tex_instr *instr = nir_tex_instr_create(this->shader, num_srcs); 2389b8e80941Smrg 2390b8e80941Smrg instr->op = op; 2391b8e80941Smrg instr->sampler_dim = 2392b8e80941Smrg (glsl_sampler_dim) ir->sampler->type->sampler_dimensionality; 2393b8e80941Smrg instr->is_array = ir->sampler->type->sampler_array; 2394b8e80941Smrg instr->is_shadow = ir->sampler->type->sampler_shadow; 2395b8e80941Smrg if (instr->is_shadow) 2396b8e80941Smrg instr->is_new_style_shadow = (ir->type->vector_elements == 1); 2397b8e80941Smrg switch (ir->type->base_type) { 2398b8e80941Smrg case GLSL_TYPE_FLOAT: 2399b8e80941Smrg instr->dest_type = nir_type_float; 2400b8e80941Smrg break; 2401b8e80941Smrg case GLSL_TYPE_INT: 2402b8e80941Smrg instr->dest_type = nir_type_int; 2403b8e80941Smrg break; 2404b8e80941Smrg case GLSL_TYPE_BOOL: 2405b8e80941Smrg case GLSL_TYPE_UINT: 2406b8e80941Smrg instr->dest_type = nir_type_uint; 2407b8e80941Smrg break; 2408b8e80941Smrg default: 2409b8e80941Smrg unreachable("not reached"); 2410b8e80941Smrg } 2411b8e80941Smrg 2412b8e80941Smrg nir_deref_instr *sampler_deref = evaluate_deref(ir->sampler); 2413b8e80941Smrg 2414b8e80941Smrg /* check for bindless handles */ 2415b8e80941Smrg if (sampler_deref->mode != nir_var_uniform || 2416b8e80941Smrg nir_deref_instr_get_variable(sampler_deref)->data.bindless) { 2417b8e80941Smrg nir_ssa_def *load = nir_load_deref(&b, sampler_deref); 2418b8e80941Smrg instr->src[0].src = nir_src_for_ssa(load); 2419b8e80941Smrg instr->src[0].src_type = nir_tex_src_texture_handle; 2420b8e80941Smrg instr->src[1].src = nir_src_for_ssa(load); 2421b8e80941Smrg instr->src[1].src_type = nir_tex_src_sampler_handle; 2422b8e80941Smrg } else { 2423b8e80941Smrg instr->src[0].src = nir_src_for_ssa(&sampler_deref->dest.ssa); 2424b8e80941Smrg instr->src[0].src_type = nir_tex_src_texture_deref; 2425b8e80941Smrg instr->src[1].src = nir_src_for_ssa(&sampler_deref->dest.ssa); 2426b8e80941Smrg instr->src[1].src_type = nir_tex_src_sampler_deref; 2427b8e80941Smrg } 2428b8e80941Smrg 2429b8e80941Smrg unsigned src_number = 2; 2430b8e80941Smrg 2431b8e80941Smrg if (ir->coordinate != NULL) { 2432b8e80941Smrg instr->coord_components = ir->coordinate->type->vector_elements; 2433b8e80941Smrg instr->src[src_number].src = 2434b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->coordinate)); 2435b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_coord; 2436b8e80941Smrg src_number++; 2437b8e80941Smrg } 2438b8e80941Smrg 2439b8e80941Smrg if (ir->projector != NULL) { 2440b8e80941Smrg instr->src[src_number].src = 2441b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->projector)); 2442b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_projector; 2443b8e80941Smrg src_number++; 2444b8e80941Smrg } 2445b8e80941Smrg 2446b8e80941Smrg if (ir->shadow_comparator != NULL) { 2447b8e80941Smrg instr->src[src_number].src = 2448b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->shadow_comparator)); 2449b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_comparator; 2450b8e80941Smrg src_number++; 2451b8e80941Smrg } 2452b8e80941Smrg 2453b8e80941Smrg if (ir->offset != NULL) { 2454b8e80941Smrg if (ir->offset->type->is_array()) { 2455b8e80941Smrg for (int i = 0; i < ir->offset->type->array_size(); i++) { 2456b8e80941Smrg const ir_constant *c = 2457b8e80941Smrg ir->offset->as_constant()->get_array_element(i); 2458b8e80941Smrg 2459b8e80941Smrg for (unsigned j = 0; j < 2; ++j) { 2460b8e80941Smrg int val = c->get_int_component(j); 2461b8e80941Smrg assert(val <= 31 && val >= -32); 2462b8e80941Smrg instr->tg4_offsets[i][j] = val; 2463b8e80941Smrg } 2464b8e80941Smrg } 2465b8e80941Smrg } else { 2466b8e80941Smrg assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar()); 2467b8e80941Smrg 2468b8e80941Smrg instr->src[src_number].src = 2469b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->offset)); 2470b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_offset; 2471b8e80941Smrg src_number++; 2472b8e80941Smrg } 2473b8e80941Smrg } 2474b8e80941Smrg 2475b8e80941Smrg switch (ir->op) { 2476b8e80941Smrg case ir_txb: 2477b8e80941Smrg instr->src[src_number].src = 2478b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.bias)); 2479b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_bias; 2480b8e80941Smrg src_number++; 2481b8e80941Smrg break; 2482b8e80941Smrg 2483b8e80941Smrg case ir_txl: 2484b8e80941Smrg case ir_txf: 2485b8e80941Smrg case ir_txs: 2486b8e80941Smrg if (ir->lod_info.lod != NULL) { 2487b8e80941Smrg instr->src[src_number].src = 2488b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.lod)); 2489b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_lod; 2490b8e80941Smrg src_number++; 2491b8e80941Smrg } 2492b8e80941Smrg break; 2493b8e80941Smrg 2494b8e80941Smrg case ir_txd: 2495b8e80941Smrg instr->src[src_number].src = 2496b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.grad.dPdx)); 2497b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_ddx; 2498b8e80941Smrg src_number++; 2499b8e80941Smrg instr->src[src_number].src = 2500b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.grad.dPdy)); 2501b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_ddy; 2502b8e80941Smrg src_number++; 2503b8e80941Smrg break; 2504b8e80941Smrg 2505b8e80941Smrg case ir_txf_ms: 2506b8e80941Smrg instr->src[src_number].src = 2507b8e80941Smrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.sample_index)); 2508b8e80941Smrg instr->src[src_number].src_type = nir_tex_src_ms_index; 2509b8e80941Smrg src_number++; 2510b8e80941Smrg break; 2511b8e80941Smrg 2512b8e80941Smrg case ir_tg4: 2513b8e80941Smrg instr->component = ir->lod_info.component->as_constant()->value.u[0]; 2514b8e80941Smrg break; 2515b8e80941Smrg 2516b8e80941Smrg default: 2517b8e80941Smrg break; 2518b8e80941Smrg } 2519b8e80941Smrg 2520b8e80941Smrg assert(src_number == num_srcs); 2521b8e80941Smrg 2522b8e80941Smrg unsigned bit_size = glsl_get_bit_size(ir->type); 2523b8e80941Smrg add_instr(&instr->instr, nir_tex_instr_dest_size(instr), bit_size); 2524b8e80941Smrg} 2525b8e80941Smrg 2526b8e80941Smrgvoid 2527b8e80941Smrgnir_visitor::visit(ir_constant *ir) 2528b8e80941Smrg{ 2529b8e80941Smrg /* 2530b8e80941Smrg * We don't know if this variable is an array or struct that gets 2531b8e80941Smrg * dereferenced, so do the safe thing an make it a variable with a 2532b8e80941Smrg * constant initializer and return a dereference. 2533b8e80941Smrg */ 2534b8e80941Smrg 2535b8e80941Smrg nir_variable *var = 2536b8e80941Smrg nir_local_variable_create(this->impl, ir->type, "const_temp"); 2537b8e80941Smrg var->data.read_only = true; 2538b8e80941Smrg var->constant_initializer = constant_copy(ir, var); 2539b8e80941Smrg 2540b8e80941Smrg this->deref = nir_build_deref_var(&b, var); 2541b8e80941Smrg} 2542b8e80941Smrg 2543b8e80941Smrgvoid 2544b8e80941Smrgnir_visitor::visit(ir_dereference_variable *ir) 2545b8e80941Smrg{ 2546b8e80941Smrg if (ir->variable_referenced()->data.mode == ir_var_function_out) { 2547b8e80941Smrg unsigned i = (sig->return_type != glsl_type::void_type) ? 1 : 0; 2548b8e80941Smrg 2549b8e80941Smrg foreach_in_list(ir_variable, param, &sig->parameters) { 2550b8e80941Smrg if (param == ir->variable_referenced()) { 2551b8e80941Smrg break; 2552b8e80941Smrg } 2553b8e80941Smrg i++; 2554b8e80941Smrg } 2555b8e80941Smrg 2556b8e80941Smrg this->deref = nir_build_deref_cast(&b, nir_load_param(&b, i), 2557b8e80941Smrg nir_var_function_temp, ir->type, 0); 2558b8e80941Smrg return; 2559b8e80941Smrg } 2560b8e80941Smrg 2561b8e80941Smrg assert(ir->variable_referenced()->data.mode != ir_var_function_inout); 2562b8e80941Smrg 2563b8e80941Smrg struct hash_entry *entry = 2564b8e80941Smrg _mesa_hash_table_search(this->var_table, ir->var); 2565b8e80941Smrg assert(entry); 2566b8e80941Smrg nir_variable *var = (nir_variable *) entry->data; 2567b8e80941Smrg 2568b8e80941Smrg this->deref = nir_build_deref_var(&b, var); 2569b8e80941Smrg} 2570b8e80941Smrg 2571b8e80941Smrgvoid 2572b8e80941Smrgnir_visitor::visit(ir_dereference_record *ir) 2573b8e80941Smrg{ 2574b8e80941Smrg ir->record->accept(this); 2575b8e80941Smrg 2576b8e80941Smrg int field_index = ir->field_idx; 2577b8e80941Smrg assert(field_index >= 0); 2578b8e80941Smrg 2579b8e80941Smrg this->deref = nir_build_deref_struct(&b, this->deref, field_index); 2580b8e80941Smrg} 2581b8e80941Smrg 2582b8e80941Smrgvoid 2583b8e80941Smrgnir_visitor::visit(ir_dereference_array *ir) 2584b8e80941Smrg{ 2585b8e80941Smrg nir_ssa_def *index = evaluate_rvalue(ir->array_index); 2586b8e80941Smrg 2587b8e80941Smrg ir->array->accept(this); 2588b8e80941Smrg 2589b8e80941Smrg this->deref = nir_build_deref_array(&b, this->deref, index); 2590b8e80941Smrg} 2591b8e80941Smrg 2592b8e80941Smrgvoid 2593b8e80941Smrgnir_visitor::visit(ir_barrier *) 2594b8e80941Smrg{ 2595b8e80941Smrg nir_intrinsic_instr *instr = 2596b8e80941Smrg nir_intrinsic_instr_create(this->shader, nir_intrinsic_barrier); 2597b8e80941Smrg nir_builder_instr_insert(&b, &instr->instr); 2598b8e80941Smrg} 2599b8e80941Smrg 2600b8e80941Smrgnir_shader * 2601b8e80941Smrgglsl_float64_funcs_to_nir(struct gl_context *ctx, 2602b8e80941Smrg const nir_shader_compiler_options *options) 2603b8e80941Smrg{ 2604b8e80941Smrg /* We pretend it's a vertex shader. Ultimately, the stage shouldn't 2605b8e80941Smrg * matter because we're not optimizing anything here. 2606b8e80941Smrg */ 2607b8e80941Smrg struct gl_shader *sh = _mesa_new_shader(-1, MESA_SHADER_VERTEX); 2608b8e80941Smrg sh->Source = float64_source; 2609b8e80941Smrg sh->CompileStatus = COMPILE_FAILURE; 2610b8e80941Smrg _mesa_glsl_compile_shader(ctx, sh, false, false, true); 2611b8e80941Smrg 2612b8e80941Smrg if (!sh->CompileStatus) { 2613b8e80941Smrg if (sh->InfoLog) { 2614b8e80941Smrg _mesa_problem(ctx, 2615b8e80941Smrg "fp64 software impl compile failed:\n%s\nsource:\n%s\n", 2616b8e80941Smrg sh->InfoLog, float64_source); 2617b8e80941Smrg } 2618b8e80941Smrg return NULL; 2619b8e80941Smrg } 2620b8e80941Smrg 2621b8e80941Smrg nir_shader *nir = nir_shader_create(NULL, MESA_SHADER_VERTEX, options, NULL); 2622b8e80941Smrg 2623b8e80941Smrg nir_visitor v1(ctx, nir); 2624b8e80941Smrg nir_function_visitor v2(&v1); 2625b8e80941Smrg v2.run(sh->ir); 2626b8e80941Smrg visit_exec_list(sh->ir, &v1); 2627b8e80941Smrg 2628b8e80941Smrg /* _mesa_delete_shader will try to free sh->Source but it's static const */ 2629b8e80941Smrg sh->Source = NULL; 2630b8e80941Smrg _mesa_delete_shader(ctx, sh); 2631b8e80941Smrg 2632b8e80941Smrg nir_validate_shader(nir, "float64_funcs_to_nir"); 2633b8e80941Smrg 2634b8e80941Smrg NIR_PASS_V(nir, nir_lower_constant_initializers, nir_var_function_temp); 2635b8e80941Smrg NIR_PASS_V(nir, nir_lower_returns); 2636b8e80941Smrg NIR_PASS_V(nir, nir_inline_functions); 2637b8e80941Smrg NIR_PASS_V(nir, nir_opt_deref); 2638b8e80941Smrg 2639b8e80941Smrg return nir; 2640b8e80941Smrg} 2641