101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2014 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg * 2301e04c3fSmrg * Authors: 2401e04c3fSmrg * Connor Abbott (cwabbott0@gmail.com) 2501e04c3fSmrg * 2601e04c3fSmrg */ 2701e04c3fSmrg 287e102996Smaya#include "float64_glsl.h" 2901e04c3fSmrg#include "glsl_to_nir.h" 3001e04c3fSmrg#include "ir_visitor.h" 3101e04c3fSmrg#include "ir_hierarchical_visitor.h" 3201e04c3fSmrg#include "ir.h" 337e102996Smaya#include "ir_optimization.h" 347e102996Smaya#include "program.h" 3501e04c3fSmrg#include "compiler/nir/nir_control_flow.h" 3601e04c3fSmrg#include "compiler/nir/nir_builder.h" 377ec681f3Smrg#include "compiler/nir/nir_builtin_builder.h" 387ec681f3Smrg#include "compiler/nir/nir_deref.h" 397e102996Smaya#include "main/errors.h" 4001e04c3fSmrg#include "main/mtypes.h" 417e102996Smaya#include "main/shaderobj.h" 427ec681f3Smrg#include "main/context.h" 437e102996Smaya#include "util/u_math.h" 4401e04c3fSmrg 4501e04c3fSmrg/* 4601e04c3fSmrg * pass to lower GLSL IR to NIR 4701e04c3fSmrg * 4801e04c3fSmrg * This will lower variable dereferences to loads/stores of corresponding 4901e04c3fSmrg * variables in NIR - the variables will be converted to registers in a later 5001e04c3fSmrg * pass. 5101e04c3fSmrg */ 5201e04c3fSmrg 5301e04c3fSmrgnamespace { 5401e04c3fSmrg 5501e04c3fSmrgclass nir_visitor : public ir_visitor 5601e04c3fSmrg{ 5701e04c3fSmrgpublic: 587e102996Smaya nir_visitor(gl_context *ctx, nir_shader *shader); 5901e04c3fSmrg ~nir_visitor(); 6001e04c3fSmrg 6101e04c3fSmrg virtual void visit(ir_variable *); 6201e04c3fSmrg virtual void visit(ir_function *); 6301e04c3fSmrg virtual void visit(ir_function_signature *); 6401e04c3fSmrg virtual void visit(ir_loop *); 6501e04c3fSmrg virtual void visit(ir_if *); 6601e04c3fSmrg virtual void visit(ir_discard *); 677ec681f3Smrg virtual void visit(ir_demote *); 6801e04c3fSmrg virtual void visit(ir_loop_jump *); 6901e04c3fSmrg virtual void visit(ir_return *); 7001e04c3fSmrg virtual void visit(ir_call *); 7101e04c3fSmrg virtual void visit(ir_assignment *); 7201e04c3fSmrg virtual void visit(ir_emit_vertex *); 7301e04c3fSmrg virtual void visit(ir_end_primitive *); 7401e04c3fSmrg virtual void visit(ir_expression *); 7501e04c3fSmrg virtual void visit(ir_swizzle *); 7601e04c3fSmrg virtual void visit(ir_texture *); 7701e04c3fSmrg virtual void visit(ir_constant *); 7801e04c3fSmrg virtual void visit(ir_dereference_variable *); 7901e04c3fSmrg virtual void visit(ir_dereference_record *); 8001e04c3fSmrg virtual void visit(ir_dereference_array *); 8101e04c3fSmrg virtual void visit(ir_barrier *); 8201e04c3fSmrg 8301e04c3fSmrg void create_function(ir_function_signature *ir); 8401e04c3fSmrg 8501e04c3fSmrgprivate: 8601e04c3fSmrg void add_instr(nir_instr *instr, unsigned num_components, unsigned bit_size); 8701e04c3fSmrg nir_ssa_def *evaluate_rvalue(ir_rvalue *ir); 8801e04c3fSmrg 8901e04c3fSmrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def **srcs); 9001e04c3fSmrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1); 9101e04c3fSmrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1, 9201e04c3fSmrg nir_ssa_def *src2); 9301e04c3fSmrg nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1, 9401e04c3fSmrg nir_ssa_def *src2, nir_ssa_def *src3); 9501e04c3fSmrg 967e102996Smaya bool supports_std430; 9701e04c3fSmrg 9801e04c3fSmrg nir_shader *shader; 9901e04c3fSmrg nir_function_impl *impl; 10001e04c3fSmrg nir_builder b; 10101e04c3fSmrg nir_ssa_def *result; /* result of the expression tree last visited */ 10201e04c3fSmrg 10301e04c3fSmrg nir_deref_instr *evaluate_deref(ir_instruction *ir); 10401e04c3fSmrg 1057e102996Smaya nir_constant *constant_copy(ir_constant *ir, void *mem_ctx); 1067e102996Smaya 10701e04c3fSmrg /* most recent deref instruction created */ 10801e04c3fSmrg nir_deref_instr *deref; 10901e04c3fSmrg 11001e04c3fSmrg /* whether the IR we're operating on is per-function or global */ 11101e04c3fSmrg bool is_global; 11201e04c3fSmrg 1137e102996Smaya ir_function_signature *sig; 1147e102996Smaya 11501e04c3fSmrg /* map of ir_variable -> nir_variable */ 11601e04c3fSmrg struct hash_table *var_table; 11701e04c3fSmrg 11801e04c3fSmrg /* map of ir_function_signature -> nir_function_overload */ 11901e04c3fSmrg struct hash_table *overload_table; 12001e04c3fSmrg}; 12101e04c3fSmrg 12201e04c3fSmrg/* 12301e04c3fSmrg * This visitor runs before the main visitor, calling create_function() for 12401e04c3fSmrg * each function so that the main visitor can resolve forward references in 12501e04c3fSmrg * calls. 12601e04c3fSmrg */ 12701e04c3fSmrg 12801e04c3fSmrgclass nir_function_visitor : public ir_hierarchical_visitor 12901e04c3fSmrg{ 13001e04c3fSmrgpublic: 13101e04c3fSmrg nir_function_visitor(nir_visitor *v) : visitor(v) 13201e04c3fSmrg { 13301e04c3fSmrg } 13401e04c3fSmrg virtual ir_visitor_status visit_enter(ir_function *); 13501e04c3fSmrg 13601e04c3fSmrgprivate: 13701e04c3fSmrg nir_visitor *visitor; 13801e04c3fSmrg}; 13901e04c3fSmrg 1407e102996Smaya/* glsl_to_nir can only handle converting certain function paramaters 1417e102996Smaya * to NIR. This visitor checks for parameters it can't currently handle. 1427e102996Smaya */ 1437e102996Smayaclass ir_function_param_visitor : public ir_hierarchical_visitor 1447e102996Smaya{ 1457e102996Smayapublic: 1467e102996Smaya ir_function_param_visitor() 1477e102996Smaya : unsupported(false) 1487e102996Smaya { 1497e102996Smaya } 1507e102996Smaya 1517e102996Smaya virtual ir_visitor_status visit_enter(ir_function_signature *ir) 1527e102996Smaya { 1537e102996Smaya 1547e102996Smaya if (ir->is_intrinsic()) 1557e102996Smaya return visit_continue; 1567e102996Smaya 1577e102996Smaya foreach_in_list(ir_variable, param, &ir->parameters) { 1587e102996Smaya if (!param->type->is_vector() || !param->type->is_scalar()) { 1597e102996Smaya unsupported = true; 1607e102996Smaya return visit_stop; 1617e102996Smaya } 1627e102996Smaya 1637e102996Smaya if (param->data.mode == ir_var_function_inout) { 1647e102996Smaya unsupported = true; 1657e102996Smaya return visit_stop; 1667e102996Smaya } 1677e102996Smaya } 1687e102996Smaya 1697ec681f3Smrg if (!glsl_type_is_vector_or_scalar(ir->return_type) && 1707ec681f3Smrg !ir->return_type->is_void()) { 1717ec681f3Smrg unsupported = true; 1727ec681f3Smrg return visit_stop; 1737ec681f3Smrg } 1747ec681f3Smrg 1757e102996Smaya return visit_continue; 1767e102996Smaya } 1777e102996Smaya 1787e102996Smaya bool unsupported; 1797e102996Smaya}; 1807e102996Smaya 18101e04c3fSmrg} /* end of anonymous namespace */ 18201e04c3fSmrg 1837e102996Smaya 1847e102996Smayastatic bool 1857e102996Smayahas_unsupported_function_param(exec_list *ir) 1867e102996Smaya{ 1877e102996Smaya ir_function_param_visitor visitor; 1887e102996Smaya visit_list_elements(&visitor, ir); 1897e102996Smaya return visitor.unsupported; 1907e102996Smaya} 1917e102996Smaya 19201e04c3fSmrgnir_shader * 1937e102996Smayaglsl_to_nir(struct gl_context *ctx, 1947e102996Smaya const struct gl_shader_program *shader_prog, 19501e04c3fSmrg gl_shader_stage stage, 19601e04c3fSmrg const nir_shader_compiler_options *options) 19701e04c3fSmrg{ 19801e04c3fSmrg struct gl_linked_shader *sh = shader_prog->_LinkedShaders[stage]; 19901e04c3fSmrg 2007e102996Smaya const struct gl_shader_compiler_options *gl_options = 2017e102996Smaya &ctx->Const.ShaderCompilerOptions[stage]; 2027e102996Smaya 2037e102996Smaya /* glsl_to_nir can only handle converting certain function paramaters 2047e102996Smaya * to NIR. If we find something we can't handle then we get the GLSL IR 2057e102996Smaya * opts to remove it before we continue on. 2067e102996Smaya * 2077e102996Smaya * TODO: add missing glsl ir to nir support and remove this loop. 2087e102996Smaya */ 2097e102996Smaya while (has_unsupported_function_param(sh->ir)) { 2107e102996Smaya do_common_optimization(sh->ir, true, true, gl_options, 2117e102996Smaya ctx->Const.NativeIntegers); 2127e102996Smaya } 2137e102996Smaya 21401e04c3fSmrg nir_shader *shader = nir_shader_create(NULL, stage, options, 21501e04c3fSmrg &sh->Program->info); 21601e04c3fSmrg 2177e102996Smaya nir_visitor v1(ctx, shader); 21801e04c3fSmrg nir_function_visitor v2(&v1); 21901e04c3fSmrg v2.run(sh->ir); 22001e04c3fSmrg visit_exec_list(sh->ir, &v1); 22101e04c3fSmrg 2227e102996Smaya nir_validate_shader(shader, "after glsl to nir, before function inline"); 2237e102996Smaya 2247e102996Smaya /* We have to lower away local constant initializers right before we 2257e102996Smaya * inline functions. That way they get properly initialized at the top 2267e102996Smaya * of the function and not at the top of its caller. 2277e102996Smaya */ 2287ec681f3Smrg nir_lower_variable_initializers(shader, nir_var_all); 2297e102996Smaya nir_lower_returns(shader); 2307e102996Smaya nir_inline_functions(shader); 2317e102996Smaya nir_opt_deref(shader); 2327e102996Smaya 2337e102996Smaya nir_validate_shader(shader, "after function inlining and return lowering"); 2347e102996Smaya 2357e102996Smaya /* Now that we have inlined everything remove all of the functions except 2367e102996Smaya * main(). 2377e102996Smaya */ 2387e102996Smaya foreach_list_typed_safe(nir_function, function, node, &(shader)->functions){ 2397e102996Smaya if (strcmp("main", function->name) != 0) { 2407e102996Smaya exec_node_remove(&function->node); 2417e102996Smaya } 2427e102996Smaya } 24301e04c3fSmrg 24401e04c3fSmrg shader->info.name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name); 24501e04c3fSmrg if (shader_prog->Label) 24601e04c3fSmrg shader->info.label = ralloc_strdup(shader, shader_prog->Label); 24701e04c3fSmrg 24801e04c3fSmrg /* Check for transform feedback varyings specified via the API */ 24901e04c3fSmrg shader->info.has_transform_feedback_varyings = 25001e04c3fSmrg shader_prog->TransformFeedback.NumVarying > 0; 25101e04c3fSmrg 25201e04c3fSmrg /* Check for transform feedback varyings specified in the Shader */ 25301e04c3fSmrg if (shader_prog->last_vert_prog) 25401e04c3fSmrg shader->info.has_transform_feedback_varyings |= 25501e04c3fSmrg shader_prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying > 0; 25601e04c3fSmrg 2577e102996Smaya if (shader->info.stage == MESA_SHADER_FRAGMENT) { 2587e102996Smaya shader->info.fs.pixel_center_integer = sh->Program->info.fs.pixel_center_integer; 2597e102996Smaya shader->info.fs.origin_upper_left = sh->Program->info.fs.origin_upper_left; 2607ec681f3Smrg shader->info.fs.advanced_blend_modes = sh->Program->info.fs.advanced_blend_modes; 2617e102996Smaya } 2627e102996Smaya 26301e04c3fSmrg return shader; 26401e04c3fSmrg} 26501e04c3fSmrg 2667e102996Smayanir_visitor::nir_visitor(gl_context *ctx, nir_shader *shader) 26701e04c3fSmrg{ 2687e102996Smaya this->supports_std430 = ctx->Const.UseSTD430AsDefaultPacking; 26901e04c3fSmrg this->shader = shader; 27001e04c3fSmrg this->is_global = true; 2717e102996Smaya this->var_table = _mesa_pointer_hash_table_create(NULL); 2727e102996Smaya this->overload_table = _mesa_pointer_hash_table_create(NULL); 27301e04c3fSmrg this->result = NULL; 27401e04c3fSmrg this->impl = NULL; 2757e102996Smaya this->deref = NULL; 2767ec681f3Smrg this->sig = NULL; 27701e04c3fSmrg memset(&this->b, 0, sizeof(this->b)); 27801e04c3fSmrg} 27901e04c3fSmrg 28001e04c3fSmrgnir_visitor::~nir_visitor() 28101e04c3fSmrg{ 28201e04c3fSmrg _mesa_hash_table_destroy(this->var_table, NULL); 28301e04c3fSmrg _mesa_hash_table_destroy(this->overload_table, NULL); 28401e04c3fSmrg} 28501e04c3fSmrg 28601e04c3fSmrgnir_deref_instr * 28701e04c3fSmrgnir_visitor::evaluate_deref(ir_instruction *ir) 28801e04c3fSmrg{ 28901e04c3fSmrg ir->accept(this); 29001e04c3fSmrg return this->deref; 29101e04c3fSmrg} 29201e04c3fSmrg 2937e102996Smayanir_constant * 2947e102996Smayanir_visitor::constant_copy(ir_constant *ir, void *mem_ctx) 29501e04c3fSmrg{ 29601e04c3fSmrg if (ir == NULL) 29701e04c3fSmrg return NULL; 29801e04c3fSmrg 29901e04c3fSmrg nir_constant *ret = rzalloc(mem_ctx, nir_constant); 30001e04c3fSmrg 30101e04c3fSmrg const unsigned rows = ir->type->vector_elements; 30201e04c3fSmrg const unsigned cols = ir->type->matrix_columns; 30301e04c3fSmrg unsigned i; 30401e04c3fSmrg 30501e04c3fSmrg ret->num_elements = 0; 30601e04c3fSmrg switch (ir->type->base_type) { 30701e04c3fSmrg case GLSL_TYPE_UINT: 30801e04c3fSmrg /* Only float base types can be matrices. */ 30901e04c3fSmrg assert(cols == 1); 31001e04c3fSmrg 31101e04c3fSmrg for (unsigned r = 0; r < rows; r++) 3127ec681f3Smrg ret->values[r].u32 = ir->value.u[r]; 3137ec681f3Smrg 3147ec681f3Smrg break; 3157ec681f3Smrg 3167ec681f3Smrg case GLSL_TYPE_UINT16: 3177ec681f3Smrg /* Only float base types can be matrices. */ 3187ec681f3Smrg assert(cols == 1); 31901e04c3fSmrg 3207ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3217ec681f3Smrg ret->values[r].u16 = ir->value.u16[r]; 32201e04c3fSmrg break; 32301e04c3fSmrg 32401e04c3fSmrg case GLSL_TYPE_INT: 32501e04c3fSmrg /* Only float base types can be matrices. */ 32601e04c3fSmrg assert(cols == 1); 32701e04c3fSmrg 32801e04c3fSmrg for (unsigned r = 0; r < rows; r++) 3297ec681f3Smrg ret->values[r].i32 = ir->value.i[r]; 33001e04c3fSmrg 33101e04c3fSmrg break; 33201e04c3fSmrg 3337ec681f3Smrg case GLSL_TYPE_INT16: 3347ec681f3Smrg /* Only float base types can be matrices. */ 3357ec681f3Smrg assert(cols == 1); 3367ec681f3Smrg 3377ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3387ec681f3Smrg ret->values[r].i16 = ir->value.i16[r]; 33901e04c3fSmrg break; 34001e04c3fSmrg 3417ec681f3Smrg case GLSL_TYPE_FLOAT: 3427ec681f3Smrg case GLSL_TYPE_FLOAT16: 34301e04c3fSmrg case GLSL_TYPE_DOUBLE: 3447ec681f3Smrg if (cols > 1) { 3457ec681f3Smrg ret->elements = ralloc_array(mem_ctx, nir_constant *, cols); 3467ec681f3Smrg ret->num_elements = cols; 3477ec681f3Smrg for (unsigned c = 0; c < cols; c++) { 3487ec681f3Smrg nir_constant *col_const = rzalloc(mem_ctx, nir_constant); 3497ec681f3Smrg col_const->num_elements = 0; 3507ec681f3Smrg switch (ir->type->base_type) { 3517ec681f3Smrg case GLSL_TYPE_FLOAT: 3527ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3537ec681f3Smrg col_const->values[r].f32 = ir->value.f[c * rows + r]; 3547ec681f3Smrg break; 3557ec681f3Smrg 3567ec681f3Smrg case GLSL_TYPE_FLOAT16: 3577ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3587ec681f3Smrg col_const->values[r].u16 = ir->value.f16[c * rows + r]; 3597ec681f3Smrg break; 3607ec681f3Smrg 3617ec681f3Smrg case GLSL_TYPE_DOUBLE: 3627ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3637ec681f3Smrg col_const->values[r].f64 = ir->value.d[c * rows + r]; 3647ec681f3Smrg break; 3657ec681f3Smrg 3667ec681f3Smrg default: 3677ec681f3Smrg unreachable("Cannot get here from the first level switch"); 3687ec681f3Smrg } 3697ec681f3Smrg ret->elements[c] = col_const; 3707ec681f3Smrg } 3717ec681f3Smrg } else { 3727ec681f3Smrg switch (ir->type->base_type) { 3737ec681f3Smrg case GLSL_TYPE_FLOAT: 3747ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3757ec681f3Smrg ret->values[r].f32 = ir->value.f[r]; 3767ec681f3Smrg break; 3777ec681f3Smrg 3787ec681f3Smrg case GLSL_TYPE_FLOAT16: 3797ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3807ec681f3Smrg ret->values[r].u16 = ir->value.f16[r]; 3817ec681f3Smrg break; 3827ec681f3Smrg 3837ec681f3Smrg case GLSL_TYPE_DOUBLE: 3847ec681f3Smrg for (unsigned r = 0; r < rows; r++) 3857ec681f3Smrg ret->values[r].f64 = ir->value.d[r]; 3867ec681f3Smrg break; 3877ec681f3Smrg 3887ec681f3Smrg default: 3897ec681f3Smrg unreachable("Cannot get here from the first level switch"); 3907ec681f3Smrg } 39101e04c3fSmrg } 39201e04c3fSmrg break; 39301e04c3fSmrg 39401e04c3fSmrg case GLSL_TYPE_UINT64: 39501e04c3fSmrg /* Only float base types can be matrices. */ 39601e04c3fSmrg assert(cols == 1); 39701e04c3fSmrg 39801e04c3fSmrg for (unsigned r = 0; r < rows; r++) 3997ec681f3Smrg ret->values[r].u64 = ir->value.u64[r]; 40001e04c3fSmrg break; 40101e04c3fSmrg 40201e04c3fSmrg case GLSL_TYPE_INT64: 40301e04c3fSmrg /* Only float base types can be matrices. */ 40401e04c3fSmrg assert(cols == 1); 40501e04c3fSmrg 40601e04c3fSmrg for (unsigned r = 0; r < rows; r++) 4077ec681f3Smrg ret->values[r].i64 = ir->value.i64[r]; 40801e04c3fSmrg break; 40901e04c3fSmrg 41001e04c3fSmrg case GLSL_TYPE_BOOL: 41101e04c3fSmrg /* Only float base types can be matrices. */ 41201e04c3fSmrg assert(cols == 1); 41301e04c3fSmrg 41401e04c3fSmrg for (unsigned r = 0; r < rows; r++) 4157ec681f3Smrg ret->values[r].b = ir->value.b[r]; 41601e04c3fSmrg 41701e04c3fSmrg break; 41801e04c3fSmrg 41901e04c3fSmrg case GLSL_TYPE_STRUCT: 42001e04c3fSmrg case GLSL_TYPE_ARRAY: 42101e04c3fSmrg ret->elements = ralloc_array(mem_ctx, nir_constant *, 42201e04c3fSmrg ir->type->length); 42301e04c3fSmrg ret->num_elements = ir->type->length; 42401e04c3fSmrg 42501e04c3fSmrg for (i = 0; i < ir->type->length; i++) 42601e04c3fSmrg ret->elements[i] = constant_copy(ir->const_elements[i], mem_ctx); 42701e04c3fSmrg break; 42801e04c3fSmrg 42901e04c3fSmrg default: 43001e04c3fSmrg unreachable("not reached"); 43101e04c3fSmrg } 43201e04c3fSmrg 43301e04c3fSmrg return ret; 43401e04c3fSmrg} 43501e04c3fSmrg 4367e102996Smayastatic const glsl_type * 4377e102996Smayawrap_type_in_array(const glsl_type *elem_type, const glsl_type *array_type) 4387e102996Smaya{ 4397e102996Smaya if (!array_type->is_array()) 4407e102996Smaya return elem_type; 4417e102996Smaya 4427e102996Smaya elem_type = wrap_type_in_array(elem_type, array_type->fields.array); 4437e102996Smaya 4447e102996Smaya return glsl_type::get_array_instance(elem_type, array_type->length); 4457e102996Smaya} 4467e102996Smaya 4477ec681f3Smrgstatic unsigned 4487ec681f3Smrgget_nir_how_declared(unsigned how_declared) 4497ec681f3Smrg{ 4507ec681f3Smrg if (how_declared == ir_var_hidden) 4517ec681f3Smrg return nir_var_hidden; 4527ec681f3Smrg 4537ec681f3Smrg return nir_var_declared_normally; 4547ec681f3Smrg} 4557ec681f3Smrg 45601e04c3fSmrgvoid 45701e04c3fSmrgnir_visitor::visit(ir_variable *ir) 45801e04c3fSmrg{ 45901e04c3fSmrg /* TODO: In future we should switch to using the NIR lowering pass but for 46001e04c3fSmrg * now just ignore these variables as GLSL IR should have lowered them. 46101e04c3fSmrg * Anything remaining are just dead vars that weren't cleaned up. 46201e04c3fSmrg */ 46301e04c3fSmrg if (ir->data.mode == ir_var_shader_shared) 46401e04c3fSmrg return; 46501e04c3fSmrg 4667e102996Smaya /* FINISHME: inout parameters */ 4677e102996Smaya assert(ir->data.mode != ir_var_function_inout); 4687e102996Smaya 4697e102996Smaya if (ir->data.mode == ir_var_function_out) 4707e102996Smaya return; 4717e102996Smaya 47201e04c3fSmrg nir_variable *var = rzalloc(shader, nir_variable); 47301e04c3fSmrg var->type = ir->type; 47401e04c3fSmrg var->name = ralloc_strdup(var, ir->name); 47501e04c3fSmrg 47601e04c3fSmrg var->data.always_active_io = ir->data.always_active_io; 47701e04c3fSmrg var->data.read_only = ir->data.read_only; 47801e04c3fSmrg var->data.centroid = ir->data.centroid; 47901e04c3fSmrg var->data.sample = ir->data.sample; 48001e04c3fSmrg var->data.patch = ir->data.patch; 4817ec681f3Smrg var->data.how_declared = get_nir_how_declared(ir->data.how_declared); 48201e04c3fSmrg var->data.invariant = ir->data.invariant; 48301e04c3fSmrg var->data.location = ir->data.location; 48401e04c3fSmrg var->data.stream = ir->data.stream; 4857ec681f3Smrg if (ir->data.stream & (1u << 31)) 4867ec681f3Smrg var->data.stream |= NIR_STREAM_PACKED; 4877ec681f3Smrg 4887ec681f3Smrg var->data.precision = ir->data.precision; 4897ec681f3Smrg var->data.explicit_location = ir->data.explicit_location; 4907ec681f3Smrg var->data.matrix_layout = ir->data.matrix_layout; 4917ec681f3Smrg var->data.from_named_ifc_block = ir->data.from_named_ifc_block; 49201e04c3fSmrg var->data.compact = false; 49301e04c3fSmrg 49401e04c3fSmrg switch(ir->data.mode) { 49501e04c3fSmrg case ir_var_auto: 49601e04c3fSmrg case ir_var_temporary: 49701e04c3fSmrg if (is_global) 4987e102996Smaya var->data.mode = nir_var_shader_temp; 49901e04c3fSmrg else 5007e102996Smaya var->data.mode = nir_var_function_temp; 50101e04c3fSmrg break; 50201e04c3fSmrg 50301e04c3fSmrg case ir_var_function_in: 50401e04c3fSmrg case ir_var_const_in: 5057e102996Smaya var->data.mode = nir_var_function_temp; 50601e04c3fSmrg break; 50701e04c3fSmrg 50801e04c3fSmrg case ir_var_shader_in: 5097ec681f3Smrg if (shader->info.stage == MESA_SHADER_GEOMETRY && 5107ec681f3Smrg ir->data.location == VARYING_SLOT_PRIMITIVE_ID) { 51101e04c3fSmrg /* For whatever reason, GLSL IR makes gl_PrimitiveIDIn an input */ 51201e04c3fSmrg var->data.location = SYSTEM_VALUE_PRIMITIVE_ID; 51301e04c3fSmrg var->data.mode = nir_var_system_value; 51401e04c3fSmrg } else { 51501e04c3fSmrg var->data.mode = nir_var_shader_in; 51601e04c3fSmrg 51701e04c3fSmrg if (shader->info.stage == MESA_SHADER_TESS_EVAL && 51801e04c3fSmrg (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER || 51901e04c3fSmrg ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) { 52001e04c3fSmrg var->data.compact = ir->type->without_array()->is_scalar(); 52101e04c3fSmrg } 5227e102996Smaya 5237e102996Smaya if (shader->info.stage > MESA_SHADER_VERTEX && 5247e102996Smaya ir->data.location >= VARYING_SLOT_CLIP_DIST0 && 5257e102996Smaya ir->data.location <= VARYING_SLOT_CULL_DIST1) { 5267e102996Smaya var->data.compact = ir->type->without_array()->is_scalar(); 5277e102996Smaya } 52801e04c3fSmrg } 52901e04c3fSmrg break; 53001e04c3fSmrg 53101e04c3fSmrg case ir_var_shader_out: 53201e04c3fSmrg var->data.mode = nir_var_shader_out; 53301e04c3fSmrg if (shader->info.stage == MESA_SHADER_TESS_CTRL && 53401e04c3fSmrg (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER || 53501e04c3fSmrg ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) { 53601e04c3fSmrg var->data.compact = ir->type->without_array()->is_scalar(); 53701e04c3fSmrg } 5387e102996Smaya 5397e102996Smaya if (shader->info.stage <= MESA_SHADER_GEOMETRY && 5407e102996Smaya ir->data.location >= VARYING_SLOT_CLIP_DIST0 && 5417e102996Smaya ir->data.location <= VARYING_SLOT_CULL_DIST1) { 5427e102996Smaya var->data.compact = ir->type->without_array()->is_scalar(); 5437e102996Smaya } 54401e04c3fSmrg break; 54501e04c3fSmrg 54601e04c3fSmrg case ir_var_uniform: 5477e102996Smaya if (ir->get_interface_type()) 5487e102996Smaya var->data.mode = nir_var_mem_ubo; 5497e102996Smaya else 5507e102996Smaya var->data.mode = nir_var_uniform; 55101e04c3fSmrg break; 55201e04c3fSmrg 55301e04c3fSmrg case ir_var_shader_storage: 5547e102996Smaya var->data.mode = nir_var_mem_ssbo; 55501e04c3fSmrg break; 55601e04c3fSmrg 55701e04c3fSmrg case ir_var_system_value: 55801e04c3fSmrg var->data.mode = nir_var_system_value; 55901e04c3fSmrg break; 56001e04c3fSmrg 56101e04c3fSmrg default: 56201e04c3fSmrg unreachable("not reached"); 56301e04c3fSmrg } 56401e04c3fSmrg 5657ec681f3Smrg unsigned mem_access = 0; 5667e102996Smaya if (ir->data.memory_read_only) 5677ec681f3Smrg mem_access |= ACCESS_NON_WRITEABLE; 5687e102996Smaya if (ir->data.memory_write_only) 5697ec681f3Smrg mem_access |= ACCESS_NON_READABLE; 5707e102996Smaya if (ir->data.memory_coherent) 5717ec681f3Smrg mem_access |= ACCESS_COHERENT; 5727e102996Smaya if (ir->data.memory_volatile) 5737ec681f3Smrg mem_access |= ACCESS_VOLATILE; 5747e102996Smaya if (ir->data.memory_restrict) 5757ec681f3Smrg mem_access |= ACCESS_RESTRICT; 5767ec681f3Smrg 5777ec681f3Smrg var->interface_type = ir->get_interface_type(); 5787e102996Smaya 5797e102996Smaya /* For UBO and SSBO variables, we need explicit types */ 5807e102996Smaya if (var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo)) { 5817e102996Smaya const glsl_type *explicit_ifc_type = 5827e102996Smaya ir->get_interface_type()->get_explicit_interface_type(supports_std430); 58301e04c3fSmrg 5847ec681f3Smrg var->interface_type = explicit_ifc_type; 5857ec681f3Smrg 5867e102996Smaya if (ir->type->without_array()->is_interface()) { 5877e102996Smaya /* If the type contains the interface, wrap the explicit type in the 5887e102996Smaya * right number of arrays. 5897e102996Smaya */ 5907e102996Smaya var->type = wrap_type_in_array(explicit_ifc_type, ir->type); 5917e102996Smaya } else { 5927e102996Smaya /* Otherwise, this variable is one entry in the interface */ 5937e102996Smaya UNUSED bool found = false; 5947e102996Smaya for (unsigned i = 0; i < explicit_ifc_type->length; i++) { 5957e102996Smaya const glsl_struct_field *field = 5967e102996Smaya &explicit_ifc_type->fields.structure[i]; 5977e102996Smaya if (strcmp(ir->name, field->name) != 0) 5987e102996Smaya continue; 5997e102996Smaya 6007e102996Smaya var->type = field->type; 6017e102996Smaya if (field->memory_read_only) 6027ec681f3Smrg mem_access |= ACCESS_NON_WRITEABLE; 6037e102996Smaya if (field->memory_write_only) 6047ec681f3Smrg mem_access |= ACCESS_NON_READABLE; 6057e102996Smaya if (field->memory_coherent) 6067ec681f3Smrg mem_access |= ACCESS_COHERENT; 6077e102996Smaya if (field->memory_volatile) 6087ec681f3Smrg mem_access |= ACCESS_VOLATILE; 6097e102996Smaya if (field->memory_restrict) 6107ec681f3Smrg mem_access |= ACCESS_RESTRICT; 6117e102996Smaya 6127e102996Smaya found = true; 6137e102996Smaya break; 6147e102996Smaya } 6157e102996Smaya assert(found); 6167e102996Smaya } 61701e04c3fSmrg } 61801e04c3fSmrg 6197e102996Smaya var->data.interpolation = ir->data.interpolation; 6207e102996Smaya var->data.location_frac = ir->data.location_frac; 6217e102996Smaya 62201e04c3fSmrg switch (ir->data.depth_layout) { 62301e04c3fSmrg case ir_depth_layout_none: 62401e04c3fSmrg var->data.depth_layout = nir_depth_layout_none; 62501e04c3fSmrg break; 62601e04c3fSmrg case ir_depth_layout_any: 62701e04c3fSmrg var->data.depth_layout = nir_depth_layout_any; 62801e04c3fSmrg break; 62901e04c3fSmrg case ir_depth_layout_greater: 63001e04c3fSmrg var->data.depth_layout = nir_depth_layout_greater; 63101e04c3fSmrg break; 63201e04c3fSmrg case ir_depth_layout_less: 63301e04c3fSmrg var->data.depth_layout = nir_depth_layout_less; 63401e04c3fSmrg break; 63501e04c3fSmrg case ir_depth_layout_unchanged: 63601e04c3fSmrg var->data.depth_layout = nir_depth_layout_unchanged; 63701e04c3fSmrg break; 63801e04c3fSmrg default: 63901e04c3fSmrg unreachable("not reached"); 64001e04c3fSmrg } 64101e04c3fSmrg 64201e04c3fSmrg var->data.index = ir->data.index; 64301e04c3fSmrg var->data.descriptor_set = 0; 64401e04c3fSmrg var->data.binding = ir->data.binding; 64501e04c3fSmrg var->data.explicit_binding = ir->data.explicit_binding; 64601e04c3fSmrg var->data.bindless = ir->data.bindless; 64701e04c3fSmrg var->data.offset = ir->data.offset; 6487ec681f3Smrg var->data.access = (gl_access_qualifier)mem_access; 64901e04c3fSmrg 6507ec681f3Smrg if (var->type->without_array()->is_image()) { 6517ec681f3Smrg var->data.image.format = ir->data.image_format; 6527ec681f3Smrg } else if (var->data.mode == nir_var_shader_out) { 6537ec681f3Smrg var->data.xfb.buffer = ir->data.xfb_buffer; 6547ec681f3Smrg var->data.xfb.stride = ir->data.xfb_stride; 6557ec681f3Smrg } 65601e04c3fSmrg 65701e04c3fSmrg var->data.fb_fetch_output = ir->data.fb_fetch_output; 65801e04c3fSmrg var->data.explicit_xfb_buffer = ir->data.explicit_xfb_buffer; 65901e04c3fSmrg var->data.explicit_xfb_stride = ir->data.explicit_xfb_stride; 66001e04c3fSmrg 66101e04c3fSmrg var->num_state_slots = ir->get_num_state_slots(); 66201e04c3fSmrg if (var->num_state_slots > 0) { 66301e04c3fSmrg var->state_slots = rzalloc_array(var, nir_state_slot, 66401e04c3fSmrg var->num_state_slots); 66501e04c3fSmrg 66601e04c3fSmrg ir_state_slot *state_slots = ir->get_state_slots(); 66701e04c3fSmrg for (unsigned i = 0; i < var->num_state_slots; i++) { 6687ec681f3Smrg for (unsigned j = 0; j < 4; j++) 66901e04c3fSmrg var->state_slots[i].tokens[j] = state_slots[i].tokens[j]; 67001e04c3fSmrg var->state_slots[i].swizzle = state_slots[i].swizzle; 67101e04c3fSmrg } 67201e04c3fSmrg } else { 67301e04c3fSmrg var->state_slots = NULL; 67401e04c3fSmrg } 67501e04c3fSmrg 67601e04c3fSmrg var->constant_initializer = constant_copy(ir->constant_initializer, var); 67701e04c3fSmrg 6787e102996Smaya if (var->data.mode == nir_var_function_temp) 67901e04c3fSmrg nir_function_impl_add_variable(impl, var); 68001e04c3fSmrg else 68101e04c3fSmrg nir_shader_add_variable(shader, var); 68201e04c3fSmrg 68301e04c3fSmrg _mesa_hash_table_insert(var_table, ir, var); 68401e04c3fSmrg} 68501e04c3fSmrg 68601e04c3fSmrgir_visitor_status 68701e04c3fSmrgnir_function_visitor::visit_enter(ir_function *ir) 68801e04c3fSmrg{ 68901e04c3fSmrg foreach_in_list(ir_function_signature, sig, &ir->signatures) { 69001e04c3fSmrg visitor->create_function(sig); 69101e04c3fSmrg } 69201e04c3fSmrg return visit_continue_with_parent; 69301e04c3fSmrg} 69401e04c3fSmrg 69501e04c3fSmrgvoid 69601e04c3fSmrgnir_visitor::create_function(ir_function_signature *ir) 69701e04c3fSmrg{ 69801e04c3fSmrg if (ir->is_intrinsic()) 69901e04c3fSmrg return; 70001e04c3fSmrg 70101e04c3fSmrg nir_function *func = nir_function_create(shader, ir->function_name()); 7027e102996Smaya if (strcmp(ir->function_name(), "main") == 0) 7037e102996Smaya func->is_entrypoint = true; 7047e102996Smaya 7057e102996Smaya func->num_params = ir->parameters.length() + 7067e102996Smaya (ir->return_type != glsl_type::void_type); 7077e102996Smaya func->params = ralloc_array(shader, nir_parameter, func->num_params); 7087e102996Smaya 7097e102996Smaya unsigned np = 0; 7107e102996Smaya 7117e102996Smaya if (ir->return_type != glsl_type::void_type) { 7127e102996Smaya /* The return value is a variable deref (basically an out parameter) */ 7137e102996Smaya func->params[np].num_components = 1; 7147e102996Smaya func->params[np].bit_size = 32; 7157e102996Smaya np++; 7167e102996Smaya } 71701e04c3fSmrg 7187e102996Smaya foreach_in_list(ir_variable, param, &ir->parameters) { 7197e102996Smaya /* FINISHME: pass arrays, structs, etc by reference? */ 7207e102996Smaya assert(param->type->is_vector() || param->type->is_scalar()); 7217e102996Smaya 7227e102996Smaya if (param->data.mode == ir_var_function_in) { 7237e102996Smaya func->params[np].num_components = param->type->vector_elements; 7247e102996Smaya func->params[np].bit_size = glsl_get_bit_size(param->type); 7257e102996Smaya } else { 7267e102996Smaya func->params[np].num_components = 1; 7277e102996Smaya func->params[np].bit_size = 32; 7287e102996Smaya } 7297e102996Smaya np++; 7307e102996Smaya } 7317e102996Smaya assert(np == func->num_params); 73201e04c3fSmrg 73301e04c3fSmrg _mesa_hash_table_insert(this->overload_table, ir, func); 73401e04c3fSmrg} 73501e04c3fSmrg 73601e04c3fSmrgvoid 73701e04c3fSmrgnir_visitor::visit(ir_function *ir) 73801e04c3fSmrg{ 73901e04c3fSmrg foreach_in_list(ir_function_signature, sig, &ir->signatures) 74001e04c3fSmrg sig->accept(this); 74101e04c3fSmrg} 74201e04c3fSmrg 74301e04c3fSmrgvoid 74401e04c3fSmrgnir_visitor::visit(ir_function_signature *ir) 74501e04c3fSmrg{ 74601e04c3fSmrg if (ir->is_intrinsic()) 74701e04c3fSmrg return; 74801e04c3fSmrg 7497e102996Smaya this->sig = ir; 7507e102996Smaya 75101e04c3fSmrg struct hash_entry *entry = 75201e04c3fSmrg _mesa_hash_table_search(this->overload_table, ir); 75301e04c3fSmrg 75401e04c3fSmrg assert(entry); 75501e04c3fSmrg nir_function *func = (nir_function *) entry->data; 75601e04c3fSmrg 75701e04c3fSmrg if (ir->is_defined) { 75801e04c3fSmrg nir_function_impl *impl = nir_function_impl_create(func); 75901e04c3fSmrg this->impl = impl; 76001e04c3fSmrg 76101e04c3fSmrg this->is_global = false; 76201e04c3fSmrg 76301e04c3fSmrg nir_builder_init(&b, impl); 76401e04c3fSmrg b.cursor = nir_after_cf_list(&impl->body); 7657e102996Smaya 7667e102996Smaya unsigned i = (ir->return_type != glsl_type::void_type) ? 1 : 0; 7677e102996Smaya 7687e102996Smaya foreach_in_list(ir_variable, param, &ir->parameters) { 7697e102996Smaya nir_variable *var = 7707e102996Smaya nir_local_variable_create(impl, param->type, param->name); 7717e102996Smaya 7727e102996Smaya if (param->data.mode == ir_var_function_in) { 7737e102996Smaya nir_store_var(&b, var, nir_load_param(&b, i), ~0); 7747e102996Smaya } 7757e102996Smaya 7767e102996Smaya _mesa_hash_table_insert(var_table, param, var); 7777e102996Smaya i++; 7787e102996Smaya } 7797e102996Smaya 78001e04c3fSmrg visit_exec_list(&ir->body, this); 78101e04c3fSmrg 78201e04c3fSmrg this->is_global = true; 78301e04c3fSmrg } else { 78401e04c3fSmrg func->impl = NULL; 78501e04c3fSmrg } 78601e04c3fSmrg} 78701e04c3fSmrg 78801e04c3fSmrgvoid 78901e04c3fSmrgnir_visitor::visit(ir_loop *ir) 79001e04c3fSmrg{ 79101e04c3fSmrg nir_push_loop(&b); 79201e04c3fSmrg visit_exec_list(&ir->body_instructions, this); 79301e04c3fSmrg nir_pop_loop(&b, NULL); 79401e04c3fSmrg} 79501e04c3fSmrg 79601e04c3fSmrgvoid 79701e04c3fSmrgnir_visitor::visit(ir_if *ir) 79801e04c3fSmrg{ 79901e04c3fSmrg nir_push_if(&b, evaluate_rvalue(ir->condition)); 80001e04c3fSmrg visit_exec_list(&ir->then_instructions, this); 80101e04c3fSmrg nir_push_else(&b, NULL); 80201e04c3fSmrg visit_exec_list(&ir->else_instructions, this); 80301e04c3fSmrg nir_pop_if(&b, NULL); 80401e04c3fSmrg} 80501e04c3fSmrg 80601e04c3fSmrgvoid 80701e04c3fSmrgnir_visitor::visit(ir_discard *ir) 80801e04c3fSmrg{ 80901e04c3fSmrg /* 81001e04c3fSmrg * discards aren't treated as control flow, because before we lower them 81101e04c3fSmrg * they can appear anywhere in the shader and the stuff after them may still 81201e04c3fSmrg * be executed (yay, crazy GLSL rules!). However, after lowering, all the 81301e04c3fSmrg * discards will be immediately followed by a return. 81401e04c3fSmrg */ 81501e04c3fSmrg 8167ec681f3Smrg if (ir->condition) 8177ec681f3Smrg nir_discard_if(&b, evaluate_rvalue(ir->condition)); 8187ec681f3Smrg else 8197ec681f3Smrg nir_discard(&b); 8207ec681f3Smrg} 82101e04c3fSmrg 8227ec681f3Smrgvoid 8237ec681f3Smrgnir_visitor::visit(ir_demote *ir) 8247ec681f3Smrg{ 8257ec681f3Smrg nir_demote(&b); 82601e04c3fSmrg} 82701e04c3fSmrg 82801e04c3fSmrgvoid 82901e04c3fSmrgnir_visitor::visit(ir_emit_vertex *ir) 83001e04c3fSmrg{ 8317ec681f3Smrg nir_emit_vertex(&b, (unsigned)ir->stream_id()); 83201e04c3fSmrg} 83301e04c3fSmrg 83401e04c3fSmrgvoid 83501e04c3fSmrgnir_visitor::visit(ir_end_primitive *ir) 83601e04c3fSmrg{ 8377ec681f3Smrg nir_end_primitive(&b, (unsigned)ir->stream_id()); 83801e04c3fSmrg} 83901e04c3fSmrg 84001e04c3fSmrgvoid 84101e04c3fSmrgnir_visitor::visit(ir_loop_jump *ir) 84201e04c3fSmrg{ 84301e04c3fSmrg nir_jump_type type; 84401e04c3fSmrg switch (ir->mode) { 84501e04c3fSmrg case ir_loop_jump::jump_break: 84601e04c3fSmrg type = nir_jump_break; 84701e04c3fSmrg break; 84801e04c3fSmrg case ir_loop_jump::jump_continue: 84901e04c3fSmrg type = nir_jump_continue; 85001e04c3fSmrg break; 85101e04c3fSmrg default: 85201e04c3fSmrg unreachable("not reached"); 85301e04c3fSmrg } 85401e04c3fSmrg 85501e04c3fSmrg nir_jump_instr *instr = nir_jump_instr_create(this->shader, type); 85601e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 85701e04c3fSmrg} 85801e04c3fSmrg 85901e04c3fSmrgvoid 86001e04c3fSmrgnir_visitor::visit(ir_return *ir) 86101e04c3fSmrg{ 8627e102996Smaya if (ir->value != NULL) { 8637e102996Smaya nir_deref_instr *ret_deref = 8647e102996Smaya nir_build_deref_cast(&b, nir_load_param(&b, 0), 8657e102996Smaya nir_var_function_temp, ir->value->type, 0); 8667e102996Smaya 8677e102996Smaya nir_ssa_def *val = evaluate_rvalue(ir->value); 8687e102996Smaya nir_store_deref(&b, ret_deref, val, ~0); 8697e102996Smaya } 8707e102996Smaya 87101e04c3fSmrg nir_jump_instr *instr = nir_jump_instr_create(this->shader, nir_jump_return); 87201e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 87301e04c3fSmrg} 87401e04c3fSmrg 8757e102996Smayastatic void 8767e102996Smayaintrinsic_set_std430_align(nir_intrinsic_instr *intrin, const glsl_type *type) 8777e102996Smaya{ 8787e102996Smaya unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type); 8797e102996Smaya unsigned pow2_components = util_next_power_of_two(type->vector_elements); 8807e102996Smaya nir_intrinsic_set_align(intrin, (bit_size / 8) * pow2_components, 0); 8817e102996Smaya} 8827e102996Smaya 8837ec681f3Smrg/* Accumulate any qualifiers along the deref chain to get the actual 8847ec681f3Smrg * load/store qualifier. 8857ec681f3Smrg */ 8867ec681f3Smrg 8877ec681f3Smrgstatic enum gl_access_qualifier 8887ec681f3Smrgderef_get_qualifier(nir_deref_instr *deref) 8897ec681f3Smrg{ 8907ec681f3Smrg nir_deref_path path; 8917ec681f3Smrg nir_deref_path_init(&path, deref, NULL); 8927ec681f3Smrg 8937ec681f3Smrg unsigned qualifiers = path.path[0]->var->data.access; 8947ec681f3Smrg 8957ec681f3Smrg const glsl_type *parent_type = path.path[0]->type; 8967ec681f3Smrg for (nir_deref_instr **cur_ptr = &path.path[1]; *cur_ptr; cur_ptr++) { 8977ec681f3Smrg nir_deref_instr *cur = *cur_ptr; 8987ec681f3Smrg 8997ec681f3Smrg if (parent_type->is_interface()) { 9007ec681f3Smrg const struct glsl_struct_field *field = 9017ec681f3Smrg &parent_type->fields.structure[cur->strct.index]; 9027ec681f3Smrg if (field->memory_read_only) 9037ec681f3Smrg qualifiers |= ACCESS_NON_WRITEABLE; 9047ec681f3Smrg if (field->memory_write_only) 9057ec681f3Smrg qualifiers |= ACCESS_NON_READABLE; 9067ec681f3Smrg if (field->memory_coherent) 9077ec681f3Smrg qualifiers |= ACCESS_COHERENT; 9087ec681f3Smrg if (field->memory_volatile) 9097ec681f3Smrg qualifiers |= ACCESS_VOLATILE; 9107ec681f3Smrg if (field->memory_restrict) 9117ec681f3Smrg qualifiers |= ACCESS_RESTRICT; 9127ec681f3Smrg } 9137ec681f3Smrg 9147ec681f3Smrg parent_type = cur->type; 9157ec681f3Smrg } 9167ec681f3Smrg 9177ec681f3Smrg nir_deref_path_finish(&path); 9187ec681f3Smrg 9197ec681f3Smrg return (gl_access_qualifier) qualifiers; 9207ec681f3Smrg} 9217ec681f3Smrg 92201e04c3fSmrgvoid 92301e04c3fSmrgnir_visitor::visit(ir_call *ir) 92401e04c3fSmrg{ 92501e04c3fSmrg if (ir->callee->is_intrinsic()) { 92601e04c3fSmrg nir_intrinsic_op op; 92701e04c3fSmrg 92801e04c3fSmrg switch (ir->callee->intrinsic_id) { 9297e102996Smaya case ir_intrinsic_generic_atomic_add: 9307e102996Smaya op = ir->return_deref->type->is_integer_32_64() 9317e102996Smaya ? nir_intrinsic_deref_atomic_add : nir_intrinsic_deref_atomic_fadd; 9327e102996Smaya break; 9337e102996Smaya case ir_intrinsic_generic_atomic_and: 9347e102996Smaya op = nir_intrinsic_deref_atomic_and; 9357e102996Smaya break; 9367e102996Smaya case ir_intrinsic_generic_atomic_or: 9377e102996Smaya op = nir_intrinsic_deref_atomic_or; 9387e102996Smaya break; 9397e102996Smaya case ir_intrinsic_generic_atomic_xor: 9407e102996Smaya op = nir_intrinsic_deref_atomic_xor; 9417e102996Smaya break; 9427e102996Smaya case ir_intrinsic_generic_atomic_min: 9437e102996Smaya assert(ir->return_deref); 9447ec681f3Smrg if (ir->return_deref->type == glsl_type::int_type || 9457ec681f3Smrg ir->return_deref->type == glsl_type::int64_t_type) 9467e102996Smaya op = nir_intrinsic_deref_atomic_imin; 9477ec681f3Smrg else if (ir->return_deref->type == glsl_type::uint_type || 9487ec681f3Smrg ir->return_deref->type == glsl_type::uint64_t_type) 9497e102996Smaya op = nir_intrinsic_deref_atomic_umin; 9507e102996Smaya else if (ir->return_deref->type == glsl_type::float_type) 9517e102996Smaya op = nir_intrinsic_deref_atomic_fmin; 9527e102996Smaya else 9537e102996Smaya unreachable("Invalid type"); 9547e102996Smaya break; 9557e102996Smaya case ir_intrinsic_generic_atomic_max: 9567e102996Smaya assert(ir->return_deref); 9577ec681f3Smrg if (ir->return_deref->type == glsl_type::int_type || 9587ec681f3Smrg ir->return_deref->type == glsl_type::int64_t_type) 9597e102996Smaya op = nir_intrinsic_deref_atomic_imax; 9607ec681f3Smrg else if (ir->return_deref->type == glsl_type::uint_type || 9617ec681f3Smrg ir->return_deref->type == glsl_type::uint64_t_type) 9627e102996Smaya op = nir_intrinsic_deref_atomic_umax; 9637e102996Smaya else if (ir->return_deref->type == glsl_type::float_type) 9647e102996Smaya op = nir_intrinsic_deref_atomic_fmax; 9657e102996Smaya else 9667e102996Smaya unreachable("Invalid type"); 9677e102996Smaya break; 9687e102996Smaya case ir_intrinsic_generic_atomic_exchange: 9697e102996Smaya op = nir_intrinsic_deref_atomic_exchange; 9707e102996Smaya break; 9717e102996Smaya case ir_intrinsic_generic_atomic_comp_swap: 9727e102996Smaya op = ir->return_deref->type->is_integer_32_64() 9737e102996Smaya ? nir_intrinsic_deref_atomic_comp_swap 9747e102996Smaya : nir_intrinsic_deref_atomic_fcomp_swap; 9757e102996Smaya break; 97601e04c3fSmrg case ir_intrinsic_atomic_counter_read: 97701e04c3fSmrg op = nir_intrinsic_atomic_counter_read_deref; 97801e04c3fSmrg break; 97901e04c3fSmrg case ir_intrinsic_atomic_counter_increment: 98001e04c3fSmrg op = nir_intrinsic_atomic_counter_inc_deref; 98101e04c3fSmrg break; 98201e04c3fSmrg case ir_intrinsic_atomic_counter_predecrement: 98301e04c3fSmrg op = nir_intrinsic_atomic_counter_pre_dec_deref; 98401e04c3fSmrg break; 98501e04c3fSmrg case ir_intrinsic_atomic_counter_add: 98601e04c3fSmrg op = nir_intrinsic_atomic_counter_add_deref; 98701e04c3fSmrg break; 98801e04c3fSmrg case ir_intrinsic_atomic_counter_and: 98901e04c3fSmrg op = nir_intrinsic_atomic_counter_and_deref; 99001e04c3fSmrg break; 99101e04c3fSmrg case ir_intrinsic_atomic_counter_or: 99201e04c3fSmrg op = nir_intrinsic_atomic_counter_or_deref; 99301e04c3fSmrg break; 99401e04c3fSmrg case ir_intrinsic_atomic_counter_xor: 99501e04c3fSmrg op = nir_intrinsic_atomic_counter_xor_deref; 99601e04c3fSmrg break; 99701e04c3fSmrg case ir_intrinsic_atomic_counter_min: 99801e04c3fSmrg op = nir_intrinsic_atomic_counter_min_deref; 99901e04c3fSmrg break; 100001e04c3fSmrg case ir_intrinsic_atomic_counter_max: 100101e04c3fSmrg op = nir_intrinsic_atomic_counter_max_deref; 100201e04c3fSmrg break; 100301e04c3fSmrg case ir_intrinsic_atomic_counter_exchange: 100401e04c3fSmrg op = nir_intrinsic_atomic_counter_exchange_deref; 100501e04c3fSmrg break; 100601e04c3fSmrg case ir_intrinsic_atomic_counter_comp_swap: 100701e04c3fSmrg op = nir_intrinsic_atomic_counter_comp_swap_deref; 100801e04c3fSmrg break; 100901e04c3fSmrg case ir_intrinsic_image_load: 101001e04c3fSmrg op = nir_intrinsic_image_deref_load; 101101e04c3fSmrg break; 101201e04c3fSmrg case ir_intrinsic_image_store: 101301e04c3fSmrg op = nir_intrinsic_image_deref_store; 101401e04c3fSmrg break; 101501e04c3fSmrg case ir_intrinsic_image_atomic_add: 101601e04c3fSmrg op = ir->return_deref->type->is_integer_32_64() 101701e04c3fSmrg ? nir_intrinsic_image_deref_atomic_add 101801e04c3fSmrg : nir_intrinsic_image_deref_atomic_fadd; 101901e04c3fSmrg break; 102001e04c3fSmrg case ir_intrinsic_image_atomic_min: 10217ec681f3Smrg if (ir->return_deref->type == glsl_type::int_type) 10227ec681f3Smrg op = nir_intrinsic_image_deref_atomic_imin; 10237ec681f3Smrg else if (ir->return_deref->type == glsl_type::uint_type) 10247ec681f3Smrg op = nir_intrinsic_image_deref_atomic_umin; 10257ec681f3Smrg else 10267ec681f3Smrg unreachable("Invalid type"); 102701e04c3fSmrg break; 102801e04c3fSmrg case ir_intrinsic_image_atomic_max: 10297ec681f3Smrg if (ir->return_deref->type == glsl_type::int_type) 10307ec681f3Smrg op = nir_intrinsic_image_deref_atomic_imax; 10317ec681f3Smrg else if (ir->return_deref->type == glsl_type::uint_type) 10327ec681f3Smrg op = nir_intrinsic_image_deref_atomic_umax; 10337ec681f3Smrg else 10347ec681f3Smrg unreachable("Invalid type"); 103501e04c3fSmrg break; 103601e04c3fSmrg case ir_intrinsic_image_atomic_and: 103701e04c3fSmrg op = nir_intrinsic_image_deref_atomic_and; 103801e04c3fSmrg break; 103901e04c3fSmrg case ir_intrinsic_image_atomic_or: 104001e04c3fSmrg op = nir_intrinsic_image_deref_atomic_or; 104101e04c3fSmrg break; 104201e04c3fSmrg case ir_intrinsic_image_atomic_xor: 104301e04c3fSmrg op = nir_intrinsic_image_deref_atomic_xor; 104401e04c3fSmrg break; 104501e04c3fSmrg case ir_intrinsic_image_atomic_exchange: 104601e04c3fSmrg op = nir_intrinsic_image_deref_atomic_exchange; 104701e04c3fSmrg break; 104801e04c3fSmrg case ir_intrinsic_image_atomic_comp_swap: 104901e04c3fSmrg op = nir_intrinsic_image_deref_atomic_comp_swap; 105001e04c3fSmrg break; 10517ec681f3Smrg case ir_intrinsic_image_atomic_inc_wrap: 10527ec681f3Smrg op = nir_intrinsic_image_deref_atomic_inc_wrap; 10537ec681f3Smrg break; 10547ec681f3Smrg case ir_intrinsic_image_atomic_dec_wrap: 10557ec681f3Smrg op = nir_intrinsic_image_deref_atomic_dec_wrap; 10567ec681f3Smrg break; 105701e04c3fSmrg case ir_intrinsic_memory_barrier: 105801e04c3fSmrg op = nir_intrinsic_memory_barrier; 105901e04c3fSmrg break; 106001e04c3fSmrg case ir_intrinsic_image_size: 106101e04c3fSmrg op = nir_intrinsic_image_deref_size; 106201e04c3fSmrg break; 106301e04c3fSmrg case ir_intrinsic_image_samples: 106401e04c3fSmrg op = nir_intrinsic_image_deref_samples; 106501e04c3fSmrg break; 106601e04c3fSmrg case ir_intrinsic_ssbo_store: 106701e04c3fSmrg case ir_intrinsic_ssbo_load: 106801e04c3fSmrg case ir_intrinsic_ssbo_atomic_add: 106901e04c3fSmrg case ir_intrinsic_ssbo_atomic_and: 107001e04c3fSmrg case ir_intrinsic_ssbo_atomic_or: 107101e04c3fSmrg case ir_intrinsic_ssbo_atomic_xor: 107201e04c3fSmrg case ir_intrinsic_ssbo_atomic_min: 107301e04c3fSmrg case ir_intrinsic_ssbo_atomic_max: 107401e04c3fSmrg case ir_intrinsic_ssbo_atomic_exchange: 107501e04c3fSmrg case ir_intrinsic_ssbo_atomic_comp_swap: 10767ec681f3Smrg /* SSBO store/loads should only have been lowered in GLSL IR for 10777ec681f3Smrg * non-nir drivers, NIR drivers make use of gl_nir_lower_buffers() 10787ec681f3Smrg * instead. 10797ec681f3Smrg */ 10807ec681f3Smrg unreachable("Invalid operation nir doesn't want lowered ssbo " 10817ec681f3Smrg "store/loads"); 108201e04c3fSmrg case ir_intrinsic_shader_clock: 108301e04c3fSmrg op = nir_intrinsic_shader_clock; 108401e04c3fSmrg break; 108501e04c3fSmrg case ir_intrinsic_begin_invocation_interlock: 108601e04c3fSmrg op = nir_intrinsic_begin_invocation_interlock; 108701e04c3fSmrg break; 108801e04c3fSmrg case ir_intrinsic_end_invocation_interlock: 108901e04c3fSmrg op = nir_intrinsic_end_invocation_interlock; 109001e04c3fSmrg break; 109101e04c3fSmrg case ir_intrinsic_group_memory_barrier: 109201e04c3fSmrg op = nir_intrinsic_group_memory_barrier; 109301e04c3fSmrg break; 109401e04c3fSmrg case ir_intrinsic_memory_barrier_atomic_counter: 109501e04c3fSmrg op = nir_intrinsic_memory_barrier_atomic_counter; 109601e04c3fSmrg break; 109701e04c3fSmrg case ir_intrinsic_memory_barrier_buffer: 109801e04c3fSmrg op = nir_intrinsic_memory_barrier_buffer; 109901e04c3fSmrg break; 110001e04c3fSmrg case ir_intrinsic_memory_barrier_image: 110101e04c3fSmrg op = nir_intrinsic_memory_barrier_image; 110201e04c3fSmrg break; 110301e04c3fSmrg case ir_intrinsic_memory_barrier_shared: 110401e04c3fSmrg op = nir_intrinsic_memory_barrier_shared; 110501e04c3fSmrg break; 110601e04c3fSmrg case ir_intrinsic_shared_load: 110701e04c3fSmrg op = nir_intrinsic_load_shared; 110801e04c3fSmrg break; 110901e04c3fSmrg case ir_intrinsic_shared_store: 111001e04c3fSmrg op = nir_intrinsic_store_shared; 111101e04c3fSmrg break; 111201e04c3fSmrg case ir_intrinsic_shared_atomic_add: 111301e04c3fSmrg op = ir->return_deref->type->is_integer_32_64() 111401e04c3fSmrg ? nir_intrinsic_shared_atomic_add 111501e04c3fSmrg : nir_intrinsic_shared_atomic_fadd; 111601e04c3fSmrg break; 111701e04c3fSmrg case ir_intrinsic_shared_atomic_and: 111801e04c3fSmrg op = nir_intrinsic_shared_atomic_and; 111901e04c3fSmrg break; 112001e04c3fSmrg case ir_intrinsic_shared_atomic_or: 112101e04c3fSmrg op = nir_intrinsic_shared_atomic_or; 112201e04c3fSmrg break; 112301e04c3fSmrg case ir_intrinsic_shared_atomic_xor: 112401e04c3fSmrg op = nir_intrinsic_shared_atomic_xor; 112501e04c3fSmrg break; 112601e04c3fSmrg case ir_intrinsic_shared_atomic_min: 112701e04c3fSmrg assert(ir->return_deref); 11287ec681f3Smrg if (ir->return_deref->type == glsl_type::int_type || 11297ec681f3Smrg ir->return_deref->type == glsl_type::int64_t_type) 113001e04c3fSmrg op = nir_intrinsic_shared_atomic_imin; 11317ec681f3Smrg else if (ir->return_deref->type == glsl_type::uint_type || 11327ec681f3Smrg ir->return_deref->type == glsl_type::uint64_t_type) 113301e04c3fSmrg op = nir_intrinsic_shared_atomic_umin; 113401e04c3fSmrg else if (ir->return_deref->type == glsl_type::float_type) 113501e04c3fSmrg op = nir_intrinsic_shared_atomic_fmin; 113601e04c3fSmrg else 113701e04c3fSmrg unreachable("Invalid type"); 113801e04c3fSmrg break; 113901e04c3fSmrg case ir_intrinsic_shared_atomic_max: 114001e04c3fSmrg assert(ir->return_deref); 11417ec681f3Smrg if (ir->return_deref->type == glsl_type::int_type || 11427ec681f3Smrg ir->return_deref->type == glsl_type::int64_t_type) 114301e04c3fSmrg op = nir_intrinsic_shared_atomic_imax; 11447ec681f3Smrg else if (ir->return_deref->type == glsl_type::uint_type || 11457ec681f3Smrg ir->return_deref->type == glsl_type::uint64_t_type) 114601e04c3fSmrg op = nir_intrinsic_shared_atomic_umax; 114701e04c3fSmrg else if (ir->return_deref->type == glsl_type::float_type) 114801e04c3fSmrg op = nir_intrinsic_shared_atomic_fmax; 114901e04c3fSmrg else 115001e04c3fSmrg unreachable("Invalid type"); 115101e04c3fSmrg break; 115201e04c3fSmrg case ir_intrinsic_shared_atomic_exchange: 115301e04c3fSmrg op = nir_intrinsic_shared_atomic_exchange; 115401e04c3fSmrg break; 115501e04c3fSmrg case ir_intrinsic_shared_atomic_comp_swap: 115601e04c3fSmrg op = ir->return_deref->type->is_integer_32_64() 115701e04c3fSmrg ? nir_intrinsic_shared_atomic_comp_swap 115801e04c3fSmrg : nir_intrinsic_shared_atomic_fcomp_swap; 115901e04c3fSmrg break; 116001e04c3fSmrg case ir_intrinsic_vote_any: 116101e04c3fSmrg op = nir_intrinsic_vote_any; 116201e04c3fSmrg break; 116301e04c3fSmrg case ir_intrinsic_vote_all: 116401e04c3fSmrg op = nir_intrinsic_vote_all; 116501e04c3fSmrg break; 116601e04c3fSmrg case ir_intrinsic_vote_eq: 116701e04c3fSmrg op = nir_intrinsic_vote_ieq; 116801e04c3fSmrg break; 116901e04c3fSmrg case ir_intrinsic_ballot: 117001e04c3fSmrg op = nir_intrinsic_ballot; 117101e04c3fSmrg break; 117201e04c3fSmrg case ir_intrinsic_read_invocation: 117301e04c3fSmrg op = nir_intrinsic_read_invocation; 117401e04c3fSmrg break; 117501e04c3fSmrg case ir_intrinsic_read_first_invocation: 117601e04c3fSmrg op = nir_intrinsic_read_first_invocation; 117701e04c3fSmrg break; 11787ec681f3Smrg case ir_intrinsic_helper_invocation: 11797ec681f3Smrg op = nir_intrinsic_is_helper_invocation; 11807ec681f3Smrg break; 118101e04c3fSmrg default: 118201e04c3fSmrg unreachable("not reached"); 118301e04c3fSmrg } 118401e04c3fSmrg 118501e04c3fSmrg nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op); 118601e04c3fSmrg nir_ssa_def *ret = &instr->dest.ssa; 118701e04c3fSmrg 118801e04c3fSmrg switch (op) { 11897e102996Smaya case nir_intrinsic_deref_atomic_add: 11907e102996Smaya case nir_intrinsic_deref_atomic_imin: 11917e102996Smaya case nir_intrinsic_deref_atomic_umin: 11927e102996Smaya case nir_intrinsic_deref_atomic_imax: 11937e102996Smaya case nir_intrinsic_deref_atomic_umax: 11947e102996Smaya case nir_intrinsic_deref_atomic_and: 11957e102996Smaya case nir_intrinsic_deref_atomic_or: 11967e102996Smaya case nir_intrinsic_deref_atomic_xor: 11977e102996Smaya case nir_intrinsic_deref_atomic_exchange: 11987e102996Smaya case nir_intrinsic_deref_atomic_comp_swap: 11997e102996Smaya case nir_intrinsic_deref_atomic_fadd: 12007e102996Smaya case nir_intrinsic_deref_atomic_fmin: 12017e102996Smaya case nir_intrinsic_deref_atomic_fmax: 12027e102996Smaya case nir_intrinsic_deref_atomic_fcomp_swap: { 12037e102996Smaya int param_count = ir->actual_parameters.length(); 12047e102996Smaya assert(param_count == 2 || param_count == 3); 12057e102996Smaya 12067e102996Smaya /* Deref */ 12077e102996Smaya exec_node *param = ir->actual_parameters.get_head(); 12087e102996Smaya ir_rvalue *rvalue = (ir_rvalue *) param; 12097e102996Smaya ir_dereference *deref = rvalue->as_dereference(); 12107e102996Smaya ir_swizzle *swizzle = NULL; 12117e102996Smaya if (!deref) { 12127e102996Smaya /* We may have a swizzle to pick off a single vec4 component */ 12137e102996Smaya swizzle = rvalue->as_swizzle(); 12147e102996Smaya assert(swizzle && swizzle->type->vector_elements == 1); 12157e102996Smaya deref = swizzle->val->as_dereference(); 12167e102996Smaya assert(deref); 12177e102996Smaya } 12187e102996Smaya nir_deref_instr *nir_deref = evaluate_deref(deref); 12197e102996Smaya if (swizzle) { 12207e102996Smaya nir_deref = nir_build_deref_array_imm(&b, nir_deref, 12217e102996Smaya swizzle->mask.x); 12227e102996Smaya } 12237e102996Smaya instr->src[0] = nir_src_for_ssa(&nir_deref->dest.ssa); 12247e102996Smaya 12257ec681f3Smrg nir_intrinsic_set_access(instr, deref_get_qualifier(nir_deref)); 12267ec681f3Smrg 12277e102996Smaya /* data1 parameter (this is always present) */ 12287e102996Smaya param = param->get_next(); 12297e102996Smaya ir_instruction *inst = (ir_instruction *) param; 12307e102996Smaya instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 12317e102996Smaya 12327e102996Smaya /* data2 parameter (only with atomic_comp_swap) */ 12337e102996Smaya if (param_count == 3) { 12347e102996Smaya assert(op == nir_intrinsic_deref_atomic_comp_swap || 12357e102996Smaya op == nir_intrinsic_deref_atomic_fcomp_swap); 12367e102996Smaya param = param->get_next(); 12377e102996Smaya inst = (ir_instruction *) param; 12387e102996Smaya instr->src[2] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 12397e102996Smaya } 12407e102996Smaya 12417e102996Smaya /* Atomic result */ 12427e102996Smaya assert(ir->return_deref); 12437ec681f3Smrg if (ir->return_deref->type->is_integer_64()) { 12447ec681f3Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 12457ec681f3Smrg ir->return_deref->type->vector_elements, 64, NULL); 12467ec681f3Smrg } else { 12477ec681f3Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 12487ec681f3Smrg ir->return_deref->type->vector_elements, 32, NULL); 12497ec681f3Smrg } 12507e102996Smaya nir_builder_instr_insert(&b, &instr->instr); 12517e102996Smaya break; 12527e102996Smaya } 125301e04c3fSmrg case nir_intrinsic_atomic_counter_read_deref: 125401e04c3fSmrg case nir_intrinsic_atomic_counter_inc_deref: 125501e04c3fSmrg case nir_intrinsic_atomic_counter_pre_dec_deref: 125601e04c3fSmrg case nir_intrinsic_atomic_counter_add_deref: 125701e04c3fSmrg case nir_intrinsic_atomic_counter_min_deref: 125801e04c3fSmrg case nir_intrinsic_atomic_counter_max_deref: 125901e04c3fSmrg case nir_intrinsic_atomic_counter_and_deref: 126001e04c3fSmrg case nir_intrinsic_atomic_counter_or_deref: 126101e04c3fSmrg case nir_intrinsic_atomic_counter_xor_deref: 126201e04c3fSmrg case nir_intrinsic_atomic_counter_exchange_deref: 126301e04c3fSmrg case nir_intrinsic_atomic_counter_comp_swap_deref: { 126401e04c3fSmrg /* Set the counter variable dereference. */ 126501e04c3fSmrg exec_node *param = ir->actual_parameters.get_head(); 126601e04c3fSmrg ir_dereference *counter = (ir_dereference *)param; 126701e04c3fSmrg 126801e04c3fSmrg instr->src[0] = nir_src_for_ssa(&evaluate_deref(counter)->dest.ssa); 126901e04c3fSmrg param = param->get_next(); 127001e04c3fSmrg 127101e04c3fSmrg /* Set the intrinsic destination. */ 127201e04c3fSmrg if (ir->return_deref) { 127301e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL); 127401e04c3fSmrg } 127501e04c3fSmrg 127601e04c3fSmrg /* Set the intrinsic parameters. */ 127701e04c3fSmrg if (!param->is_tail_sentinel()) { 127801e04c3fSmrg instr->src[1] = 127901e04c3fSmrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 128001e04c3fSmrg param = param->get_next(); 128101e04c3fSmrg } 128201e04c3fSmrg 128301e04c3fSmrg if (!param->is_tail_sentinel()) { 128401e04c3fSmrg instr->src[2] = 128501e04c3fSmrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 128601e04c3fSmrg param = param->get_next(); 128701e04c3fSmrg } 128801e04c3fSmrg 128901e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 129001e04c3fSmrg break; 129101e04c3fSmrg } 129201e04c3fSmrg case nir_intrinsic_image_deref_load: 129301e04c3fSmrg case nir_intrinsic_image_deref_store: 129401e04c3fSmrg case nir_intrinsic_image_deref_atomic_add: 12957ec681f3Smrg case nir_intrinsic_image_deref_atomic_imin: 12967ec681f3Smrg case nir_intrinsic_image_deref_atomic_umin: 12977ec681f3Smrg case nir_intrinsic_image_deref_atomic_imax: 12987ec681f3Smrg case nir_intrinsic_image_deref_atomic_umax: 129901e04c3fSmrg case nir_intrinsic_image_deref_atomic_and: 130001e04c3fSmrg case nir_intrinsic_image_deref_atomic_or: 130101e04c3fSmrg case nir_intrinsic_image_deref_atomic_xor: 130201e04c3fSmrg case nir_intrinsic_image_deref_atomic_exchange: 130301e04c3fSmrg case nir_intrinsic_image_deref_atomic_comp_swap: 130401e04c3fSmrg case nir_intrinsic_image_deref_atomic_fadd: 130501e04c3fSmrg case nir_intrinsic_image_deref_samples: 13067ec681f3Smrg case nir_intrinsic_image_deref_size: 13077ec681f3Smrg case nir_intrinsic_image_deref_atomic_inc_wrap: 13087ec681f3Smrg case nir_intrinsic_image_deref_atomic_dec_wrap: { 130901e04c3fSmrg /* Set the image variable dereference. */ 131001e04c3fSmrg exec_node *param = ir->actual_parameters.get_head(); 131101e04c3fSmrg ir_dereference *image = (ir_dereference *)param; 13127e102996Smaya nir_deref_instr *deref = evaluate_deref(image); 13137e102996Smaya const glsl_type *type = deref->type; 131401e04c3fSmrg 13157ec681f3Smrg nir_intrinsic_set_access(instr, deref_get_qualifier(deref)); 13167ec681f3Smrg 13177e102996Smaya instr->src[0] = nir_src_for_ssa(&deref->dest.ssa); 131801e04c3fSmrg param = param->get_next(); 13197ec681f3Smrg nir_intrinsic_set_image_dim(instr, 13207ec681f3Smrg (glsl_sampler_dim)type->sampler_dimensionality); 13217ec681f3Smrg nir_intrinsic_set_image_array(instr, type->sampler_array); 132201e04c3fSmrg 132301e04c3fSmrg /* Set the intrinsic destination. */ 132401e04c3fSmrg if (ir->return_deref) { 132501e04c3fSmrg unsigned num_components = ir->return_deref->type->vector_elements; 132601e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 132701e04c3fSmrg num_components, 32, NULL); 132801e04c3fSmrg } 132901e04c3fSmrg 133001e04c3fSmrg if (op == nir_intrinsic_image_deref_size) { 133101e04c3fSmrg instr->num_components = instr->dest.ssa.num_components; 13327ec681f3Smrg } else if (op == nir_intrinsic_image_deref_load) { 13337ec681f3Smrg instr->num_components = 4; 13347ec681f3Smrg nir_intrinsic_set_dest_type(instr, 13357ec681f3Smrg nir_get_nir_type_for_glsl_base_type(type->sampled_type)); 13367ec681f3Smrg } else if (op == nir_intrinsic_image_deref_store) { 133701e04c3fSmrg instr->num_components = 4; 13387ec681f3Smrg nir_intrinsic_set_src_type(instr, 13397ec681f3Smrg nir_get_nir_type_for_glsl_base_type(type->sampled_type)); 134001e04c3fSmrg } 134101e04c3fSmrg 134201e04c3fSmrg if (op == nir_intrinsic_image_deref_size || 134301e04c3fSmrg op == nir_intrinsic_image_deref_samples) { 13447ec681f3Smrg /* image_deref_size takes an LOD parameter which is always 0 13457ec681f3Smrg * coming from GLSL. 13467ec681f3Smrg */ 13477ec681f3Smrg if (op == nir_intrinsic_image_deref_size) 13487ec681f3Smrg instr->src[1] = nir_src_for_ssa(nir_imm_int(&b, 0)); 134901e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 135001e04c3fSmrg break; 135101e04c3fSmrg } 135201e04c3fSmrg 135301e04c3fSmrg /* Set the address argument, extending the coordinate vector to four 135401e04c3fSmrg * components. 135501e04c3fSmrg */ 135601e04c3fSmrg nir_ssa_def *src_addr = 135701e04c3fSmrg evaluate_rvalue((ir_dereference *)param); 135801e04c3fSmrg nir_ssa_def *srcs[4]; 135901e04c3fSmrg 136001e04c3fSmrg for (int i = 0; i < 4; i++) { 136101e04c3fSmrg if (i < type->coordinate_components()) 136201e04c3fSmrg srcs[i] = nir_channel(&b, src_addr, i); 136301e04c3fSmrg else 13647ec681f3Smrg srcs[i] = nir_ssa_undef(&b, 1, 32); 136501e04c3fSmrg } 136601e04c3fSmrg 136701e04c3fSmrg instr->src[1] = nir_src_for_ssa(nir_vec(&b, srcs, 4)); 136801e04c3fSmrg param = param->get_next(); 136901e04c3fSmrg 137001e04c3fSmrg /* Set the sample argument, which is undefined for single-sample 137101e04c3fSmrg * images. 137201e04c3fSmrg */ 137301e04c3fSmrg if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) { 137401e04c3fSmrg instr->src[2] = 137501e04c3fSmrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 137601e04c3fSmrg param = param->get_next(); 137701e04c3fSmrg } else { 13787ec681f3Smrg instr->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32)); 137901e04c3fSmrg } 138001e04c3fSmrg 138101e04c3fSmrg /* Set the intrinsic parameters. */ 138201e04c3fSmrg if (!param->is_tail_sentinel()) { 138301e04c3fSmrg instr->src[3] = 138401e04c3fSmrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 138501e04c3fSmrg param = param->get_next(); 13867ec681f3Smrg } else if (op == nir_intrinsic_image_deref_load) { 13877ec681f3Smrg instr->src[3] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */ 138801e04c3fSmrg } 138901e04c3fSmrg 139001e04c3fSmrg if (!param->is_tail_sentinel()) { 139101e04c3fSmrg instr->src[4] = 139201e04c3fSmrg nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); 139301e04c3fSmrg param = param->get_next(); 13947ec681f3Smrg } else if (op == nir_intrinsic_image_deref_store) { 13957ec681f3Smrg instr->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */ 139601e04c3fSmrg } 13977ec681f3Smrg 139801e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 139901e04c3fSmrg break; 140001e04c3fSmrg } 140101e04c3fSmrg case nir_intrinsic_memory_barrier: 140201e04c3fSmrg case nir_intrinsic_group_memory_barrier: 140301e04c3fSmrg case nir_intrinsic_memory_barrier_atomic_counter: 140401e04c3fSmrg case nir_intrinsic_memory_barrier_buffer: 140501e04c3fSmrg case nir_intrinsic_memory_barrier_image: 140601e04c3fSmrg case nir_intrinsic_memory_barrier_shared: 140701e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 140801e04c3fSmrg break; 140901e04c3fSmrg case nir_intrinsic_shader_clock: 141001e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 2, 32, NULL); 14117ec681f3Smrg nir_intrinsic_set_memory_scope(instr, NIR_SCOPE_SUBGROUP); 141201e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 141301e04c3fSmrg break; 141401e04c3fSmrg case nir_intrinsic_begin_invocation_interlock: 141501e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 141601e04c3fSmrg break; 141701e04c3fSmrg case nir_intrinsic_end_invocation_interlock: 141801e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 141901e04c3fSmrg break; 142001e04c3fSmrg case nir_intrinsic_store_ssbo: { 142101e04c3fSmrg exec_node *param = ir->actual_parameters.get_head(); 142201e04c3fSmrg ir_rvalue *block = ((ir_instruction *)param)->as_rvalue(); 142301e04c3fSmrg 142401e04c3fSmrg param = param->get_next(); 142501e04c3fSmrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 142601e04c3fSmrg 142701e04c3fSmrg param = param->get_next(); 142801e04c3fSmrg ir_rvalue *val = ((ir_instruction *)param)->as_rvalue(); 142901e04c3fSmrg 143001e04c3fSmrg param = param->get_next(); 143101e04c3fSmrg ir_constant *write_mask = ((ir_instruction *)param)->as_constant(); 143201e04c3fSmrg assert(write_mask); 143301e04c3fSmrg 14347e102996Smaya nir_ssa_def *nir_val = evaluate_rvalue(val); 14357e102996Smaya if (val->type->is_boolean()) 14367e102996Smaya nir_val = nir_b2i32(&b, nir_val); 14377e102996Smaya 14387e102996Smaya instr->src[0] = nir_src_for_ssa(nir_val); 143901e04c3fSmrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(block)); 144001e04c3fSmrg instr->src[2] = nir_src_for_ssa(evaluate_rvalue(offset)); 14417e102996Smaya intrinsic_set_std430_align(instr, val->type); 144201e04c3fSmrg nir_intrinsic_set_write_mask(instr, write_mask->value.u[0]); 144301e04c3fSmrg instr->num_components = val->type->vector_elements; 144401e04c3fSmrg 144501e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 144601e04c3fSmrg break; 144701e04c3fSmrg } 144801e04c3fSmrg case nir_intrinsic_load_shared: { 144901e04c3fSmrg exec_node *param = ir->actual_parameters.get_head(); 145001e04c3fSmrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 145101e04c3fSmrg 145201e04c3fSmrg nir_intrinsic_set_base(instr, 0); 145301e04c3fSmrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(offset)); 145401e04c3fSmrg 145501e04c3fSmrg const glsl_type *type = ir->return_deref->var->type; 145601e04c3fSmrg instr->num_components = type->vector_elements; 14577e102996Smaya intrinsic_set_std430_align(instr, type); 145801e04c3fSmrg 145901e04c3fSmrg /* Setup destination register */ 14607e102996Smaya unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type); 146101e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 146201e04c3fSmrg type->vector_elements, bit_size, NULL); 146301e04c3fSmrg 146401e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 14657e102996Smaya 14667e102996Smaya /* The value in shared memory is a 32-bit value */ 14677e102996Smaya if (type->is_boolean()) 14687ec681f3Smrg ret = nir_b2b1(&b, &instr->dest.ssa); 146901e04c3fSmrg break; 147001e04c3fSmrg } 147101e04c3fSmrg case nir_intrinsic_store_shared: { 147201e04c3fSmrg exec_node *param = ir->actual_parameters.get_head(); 147301e04c3fSmrg ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue(); 147401e04c3fSmrg 147501e04c3fSmrg param = param->get_next(); 147601e04c3fSmrg ir_rvalue *val = ((ir_instruction *)param)->as_rvalue(); 147701e04c3fSmrg 147801e04c3fSmrg param = param->get_next(); 147901e04c3fSmrg ir_constant *write_mask = ((ir_instruction *)param)->as_constant(); 148001e04c3fSmrg assert(write_mask); 148101e04c3fSmrg 148201e04c3fSmrg nir_intrinsic_set_base(instr, 0); 148301e04c3fSmrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset)); 148401e04c3fSmrg 148501e04c3fSmrg nir_intrinsic_set_write_mask(instr, write_mask->value.u[0]); 148601e04c3fSmrg 14877e102996Smaya nir_ssa_def *nir_val = evaluate_rvalue(val); 14887e102996Smaya /* The value in shared memory is a 32-bit value */ 14897e102996Smaya if (val->type->is_boolean()) 14907ec681f3Smrg nir_val = nir_b2b32(&b, nir_val); 14917e102996Smaya 14927e102996Smaya instr->src[0] = nir_src_for_ssa(nir_val); 149301e04c3fSmrg instr->num_components = val->type->vector_elements; 14947e102996Smaya intrinsic_set_std430_align(instr, val->type); 149501e04c3fSmrg 149601e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 149701e04c3fSmrg break; 149801e04c3fSmrg } 149901e04c3fSmrg case nir_intrinsic_shared_atomic_add: 150001e04c3fSmrg case nir_intrinsic_shared_atomic_imin: 150101e04c3fSmrg case nir_intrinsic_shared_atomic_umin: 150201e04c3fSmrg case nir_intrinsic_shared_atomic_imax: 150301e04c3fSmrg case nir_intrinsic_shared_atomic_umax: 150401e04c3fSmrg case nir_intrinsic_shared_atomic_and: 150501e04c3fSmrg case nir_intrinsic_shared_atomic_or: 150601e04c3fSmrg case nir_intrinsic_shared_atomic_xor: 150701e04c3fSmrg case nir_intrinsic_shared_atomic_exchange: 150801e04c3fSmrg case nir_intrinsic_shared_atomic_comp_swap: 150901e04c3fSmrg case nir_intrinsic_shared_atomic_fadd: 151001e04c3fSmrg case nir_intrinsic_shared_atomic_fmin: 151101e04c3fSmrg case nir_intrinsic_shared_atomic_fmax: 151201e04c3fSmrg case nir_intrinsic_shared_atomic_fcomp_swap: { 151301e04c3fSmrg int param_count = ir->actual_parameters.length(); 151401e04c3fSmrg assert(param_count == 2 || param_count == 3); 151501e04c3fSmrg 151601e04c3fSmrg /* Offset */ 151701e04c3fSmrg exec_node *param = ir->actual_parameters.get_head(); 151801e04c3fSmrg ir_instruction *inst = (ir_instruction *) param; 151901e04c3fSmrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 152001e04c3fSmrg 152101e04c3fSmrg /* data1 parameter (this is always present) */ 152201e04c3fSmrg param = param->get_next(); 152301e04c3fSmrg inst = (ir_instruction *) param; 152401e04c3fSmrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 152501e04c3fSmrg 152601e04c3fSmrg /* data2 parameter (only with atomic_comp_swap) */ 152701e04c3fSmrg if (param_count == 3) { 152801e04c3fSmrg assert(op == nir_intrinsic_shared_atomic_comp_swap || 152901e04c3fSmrg op == nir_intrinsic_shared_atomic_fcomp_swap); 153001e04c3fSmrg param = param->get_next(); 153101e04c3fSmrg inst = (ir_instruction *) param; 153201e04c3fSmrg instr->src[2] = 153301e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue())); 153401e04c3fSmrg } 153501e04c3fSmrg 153601e04c3fSmrg /* Atomic result */ 153701e04c3fSmrg assert(ir->return_deref); 153801e04c3fSmrg unsigned bit_size = glsl_get_bit_size(ir->return_deref->type); 153901e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 154001e04c3fSmrg ir->return_deref->type->vector_elements, 154101e04c3fSmrg bit_size, NULL); 154201e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 154301e04c3fSmrg break; 154401e04c3fSmrg } 15457ec681f3Smrg case nir_intrinsic_vote_ieq: 15467ec681f3Smrg instr->num_components = 1; 15477ec681f3Smrg FALLTHROUGH; 154801e04c3fSmrg case nir_intrinsic_vote_any: 15497ec681f3Smrg case nir_intrinsic_vote_all: { 15507e102996Smaya nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL); 155101e04c3fSmrg 155201e04c3fSmrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 155301e04c3fSmrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 155401e04c3fSmrg 155501e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 155601e04c3fSmrg break; 155701e04c3fSmrg } 155801e04c3fSmrg 155901e04c3fSmrg case nir_intrinsic_ballot: { 156001e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 156101e04c3fSmrg ir->return_deref->type->vector_elements, 64, NULL); 156201e04c3fSmrg instr->num_components = ir->return_deref->type->vector_elements; 156301e04c3fSmrg 156401e04c3fSmrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 156501e04c3fSmrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 156601e04c3fSmrg 156701e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 156801e04c3fSmrg break; 156901e04c3fSmrg } 157001e04c3fSmrg case nir_intrinsic_read_invocation: { 157101e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 157201e04c3fSmrg ir->return_deref->type->vector_elements, 32, NULL); 157301e04c3fSmrg instr->num_components = ir->return_deref->type->vector_elements; 157401e04c3fSmrg 157501e04c3fSmrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 157601e04c3fSmrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 157701e04c3fSmrg 157801e04c3fSmrg ir_rvalue *invocation = (ir_rvalue *) ir->actual_parameters.get_head()->next; 157901e04c3fSmrg instr->src[1] = nir_src_for_ssa(evaluate_rvalue(invocation)); 158001e04c3fSmrg 158101e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 158201e04c3fSmrg break; 158301e04c3fSmrg } 158401e04c3fSmrg case nir_intrinsic_read_first_invocation: { 158501e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest, 158601e04c3fSmrg ir->return_deref->type->vector_elements, 32, NULL); 158701e04c3fSmrg instr->num_components = ir->return_deref->type->vector_elements; 158801e04c3fSmrg 158901e04c3fSmrg ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head(); 159001e04c3fSmrg instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value)); 159101e04c3fSmrg 159201e04c3fSmrg nir_builder_instr_insert(&b, &instr->instr); 159301e04c3fSmrg break; 159401e04c3fSmrg } 15957ec681f3Smrg case nir_intrinsic_is_helper_invocation: { 15967ec681f3Smrg nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL); 15977ec681f3Smrg nir_builder_instr_insert(&b, &instr->instr); 15987ec681f3Smrg break; 15997ec681f3Smrg } 160001e04c3fSmrg default: 160101e04c3fSmrg unreachable("not reached"); 160201e04c3fSmrg } 160301e04c3fSmrg 160401e04c3fSmrg if (ir->return_deref) 160501e04c3fSmrg nir_store_deref(&b, evaluate_deref(ir->return_deref), ret, ~0); 160601e04c3fSmrg 160701e04c3fSmrg return; 160801e04c3fSmrg } 160901e04c3fSmrg 16107e102996Smaya struct hash_entry *entry = 16117e102996Smaya _mesa_hash_table_search(this->overload_table, ir->callee); 16127e102996Smaya assert(entry); 16137e102996Smaya nir_function *callee = (nir_function *) entry->data; 16147e102996Smaya 16157e102996Smaya nir_call_instr *call = nir_call_instr_create(this->shader, callee); 16167e102996Smaya 16177e102996Smaya unsigned i = 0; 16187e102996Smaya nir_deref_instr *ret_deref = NULL; 16197e102996Smaya if (ir->return_deref) { 16207e102996Smaya nir_variable *ret_tmp = 16217e102996Smaya nir_local_variable_create(this->impl, ir->return_deref->type, 16227e102996Smaya "return_tmp"); 16237e102996Smaya ret_deref = nir_build_deref_var(&b, ret_tmp); 16247e102996Smaya call->params[i++] = nir_src_for_ssa(&ret_deref->dest.ssa); 16257e102996Smaya } 16267e102996Smaya 16277e102996Smaya foreach_two_lists(formal_node, &ir->callee->parameters, 16287e102996Smaya actual_node, &ir->actual_parameters) { 16297e102996Smaya ir_rvalue *param_rvalue = (ir_rvalue *) actual_node; 16307e102996Smaya ir_variable *sig_param = (ir_variable *) formal_node; 16317e102996Smaya 16327e102996Smaya if (sig_param->data.mode == ir_var_function_out) { 16337e102996Smaya nir_deref_instr *out_deref = evaluate_deref(param_rvalue); 16347e102996Smaya call->params[i] = nir_src_for_ssa(&out_deref->dest.ssa); 16357e102996Smaya } else if (sig_param->data.mode == ir_var_function_in) { 16367e102996Smaya nir_ssa_def *val = evaluate_rvalue(param_rvalue); 16377e102996Smaya nir_src src = nir_src_for_ssa(val); 16387e102996Smaya 16397ec681f3Smrg nir_src_copy(&call->params[i], &src); 16407e102996Smaya } else if (sig_param->data.mode == ir_var_function_inout) { 16417e102996Smaya unreachable("unimplemented: inout parameters"); 16427e102996Smaya } 16437e102996Smaya 16447e102996Smaya i++; 16457e102996Smaya } 16467e102996Smaya 16477e102996Smaya nir_builder_instr_insert(&b, &call->instr); 16487e102996Smaya 16497e102996Smaya if (ir->return_deref) 16507e102996Smaya nir_store_deref(&b, evaluate_deref(ir->return_deref), nir_load_deref(&b, ret_deref), ~0); 165101e04c3fSmrg} 165201e04c3fSmrg 165301e04c3fSmrgvoid 165401e04c3fSmrgnir_visitor::visit(ir_assignment *ir) 165501e04c3fSmrg{ 165601e04c3fSmrg unsigned num_components = ir->lhs->type->vector_elements; 165701e04c3fSmrg 165801e04c3fSmrg b.exact = ir->lhs->variable_referenced()->data.invariant || 165901e04c3fSmrg ir->lhs->variable_referenced()->data.precise; 166001e04c3fSmrg 166101e04c3fSmrg if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) && 166201e04c3fSmrg (ir->write_mask == (1 << num_components) - 1 || ir->write_mask == 0)) { 16637ec681f3Smrg nir_deref_instr *lhs = evaluate_deref(ir->lhs); 16647ec681f3Smrg nir_deref_instr *rhs = evaluate_deref(ir->rhs); 16657ec681f3Smrg enum gl_access_qualifier lhs_qualifiers = deref_get_qualifier(lhs); 16667ec681f3Smrg enum gl_access_qualifier rhs_qualifiers = deref_get_qualifier(rhs); 166701e04c3fSmrg if (ir->condition) { 166801e04c3fSmrg nir_push_if(&b, evaluate_rvalue(ir->condition)); 16697ec681f3Smrg nir_copy_deref_with_access(&b, lhs, rhs, lhs_qualifiers, 16707ec681f3Smrg rhs_qualifiers); 167101e04c3fSmrg nir_pop_if(&b, NULL); 167201e04c3fSmrg } else { 16737ec681f3Smrg nir_copy_deref_with_access(&b, lhs, rhs, lhs_qualifiers, 16747ec681f3Smrg rhs_qualifiers); 167501e04c3fSmrg } 167601e04c3fSmrg return; 167701e04c3fSmrg } 167801e04c3fSmrg 167901e04c3fSmrg assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector()); 168001e04c3fSmrg 168101e04c3fSmrg ir->lhs->accept(this); 168201e04c3fSmrg nir_deref_instr *lhs_deref = this->deref; 168301e04c3fSmrg nir_ssa_def *src = evaluate_rvalue(ir->rhs); 168401e04c3fSmrg 168501e04c3fSmrg if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != 0) { 168601e04c3fSmrg /* GLSL IR will give us the input to the write-masked assignment in a 168701e04c3fSmrg * single packed vector. So, for example, if the writemask is xzw, then 168801e04c3fSmrg * we have to swizzle x -> x, y -> z, and z -> w and get the y component 168901e04c3fSmrg * from the load. 169001e04c3fSmrg */ 169101e04c3fSmrg unsigned swiz[4]; 169201e04c3fSmrg unsigned component = 0; 169301e04c3fSmrg for (unsigned i = 0; i < 4; i++) { 169401e04c3fSmrg swiz[i] = ir->write_mask & (1 << i) ? component++ : 0; 169501e04c3fSmrg } 16967ec681f3Smrg src = nir_swizzle(&b, src, swiz, num_components); 169701e04c3fSmrg } 169801e04c3fSmrg 16997ec681f3Smrg enum gl_access_qualifier qualifiers = deref_get_qualifier(lhs_deref); 170001e04c3fSmrg if (ir->condition) { 170101e04c3fSmrg nir_push_if(&b, evaluate_rvalue(ir->condition)); 17027ec681f3Smrg nir_store_deref_with_access(&b, lhs_deref, src, ir->write_mask, 17037ec681f3Smrg qualifiers); 170401e04c3fSmrg nir_pop_if(&b, NULL); 170501e04c3fSmrg } else { 17067ec681f3Smrg nir_store_deref_with_access(&b, lhs_deref, src, ir->write_mask, 17077ec681f3Smrg qualifiers); 170801e04c3fSmrg } 170901e04c3fSmrg} 171001e04c3fSmrg 171101e04c3fSmrg/* 171201e04c3fSmrg * Given an instruction, returns a pointer to its destination or NULL if there 171301e04c3fSmrg * is no destination. 171401e04c3fSmrg * 171501e04c3fSmrg * Note that this only handles instructions we generate at this level. 171601e04c3fSmrg */ 171701e04c3fSmrgstatic nir_dest * 171801e04c3fSmrgget_instr_dest(nir_instr *instr) 171901e04c3fSmrg{ 172001e04c3fSmrg nir_alu_instr *alu_instr; 172101e04c3fSmrg nir_intrinsic_instr *intrinsic_instr; 172201e04c3fSmrg nir_tex_instr *tex_instr; 172301e04c3fSmrg 172401e04c3fSmrg switch (instr->type) { 172501e04c3fSmrg case nir_instr_type_alu: 172601e04c3fSmrg alu_instr = nir_instr_as_alu(instr); 172701e04c3fSmrg return &alu_instr->dest.dest; 172801e04c3fSmrg 172901e04c3fSmrg case nir_instr_type_intrinsic: 173001e04c3fSmrg intrinsic_instr = nir_instr_as_intrinsic(instr); 173101e04c3fSmrg if (nir_intrinsic_infos[intrinsic_instr->intrinsic].has_dest) 173201e04c3fSmrg return &intrinsic_instr->dest; 173301e04c3fSmrg else 173401e04c3fSmrg return NULL; 173501e04c3fSmrg 173601e04c3fSmrg case nir_instr_type_tex: 173701e04c3fSmrg tex_instr = nir_instr_as_tex(instr); 173801e04c3fSmrg return &tex_instr->dest; 173901e04c3fSmrg 174001e04c3fSmrg default: 174101e04c3fSmrg unreachable("not reached"); 174201e04c3fSmrg } 174301e04c3fSmrg 174401e04c3fSmrg return NULL; 174501e04c3fSmrg} 174601e04c3fSmrg 174701e04c3fSmrgvoid 174801e04c3fSmrgnir_visitor::add_instr(nir_instr *instr, unsigned num_components, 174901e04c3fSmrg unsigned bit_size) 175001e04c3fSmrg{ 175101e04c3fSmrg nir_dest *dest = get_instr_dest(instr); 175201e04c3fSmrg 175301e04c3fSmrg if (dest) 175401e04c3fSmrg nir_ssa_dest_init(instr, dest, num_components, bit_size, NULL); 175501e04c3fSmrg 175601e04c3fSmrg nir_builder_instr_insert(&b, instr); 175701e04c3fSmrg 175801e04c3fSmrg if (dest) { 175901e04c3fSmrg assert(dest->is_ssa); 176001e04c3fSmrg this->result = &dest->ssa; 176101e04c3fSmrg } 176201e04c3fSmrg} 176301e04c3fSmrg 176401e04c3fSmrgnir_ssa_def * 176501e04c3fSmrgnir_visitor::evaluate_rvalue(ir_rvalue* ir) 176601e04c3fSmrg{ 176701e04c3fSmrg ir->accept(this); 176801e04c3fSmrg if (ir->as_dereference() || ir->as_constant()) { 176901e04c3fSmrg /* 177001e04c3fSmrg * A dereference is being used on the right hand side, which means we 177101e04c3fSmrg * must emit a variable load. 177201e04c3fSmrg */ 177301e04c3fSmrg 17747ec681f3Smrg enum gl_access_qualifier access = deref_get_qualifier(this->deref); 17757ec681f3Smrg this->result = nir_load_deref_with_access(&b, this->deref, access); 177601e04c3fSmrg } 177701e04c3fSmrg 177801e04c3fSmrg return this->result; 177901e04c3fSmrg} 178001e04c3fSmrg 178101e04c3fSmrgstatic bool 178201e04c3fSmrgtype_is_float(glsl_base_type type) 178301e04c3fSmrg{ 178401e04c3fSmrg return type == GLSL_TYPE_FLOAT || type == GLSL_TYPE_DOUBLE || 178501e04c3fSmrg type == GLSL_TYPE_FLOAT16; 178601e04c3fSmrg} 178701e04c3fSmrg 178801e04c3fSmrgstatic bool 178901e04c3fSmrgtype_is_signed(glsl_base_type type) 179001e04c3fSmrg{ 179101e04c3fSmrg return type == GLSL_TYPE_INT || type == GLSL_TYPE_INT64 || 179201e04c3fSmrg type == GLSL_TYPE_INT16; 179301e04c3fSmrg} 179401e04c3fSmrg 179501e04c3fSmrgvoid 179601e04c3fSmrgnir_visitor::visit(ir_expression *ir) 179701e04c3fSmrg{ 179801e04c3fSmrg /* Some special cases */ 179901e04c3fSmrg switch (ir->operation) { 180001e04c3fSmrg case ir_unop_interpolate_at_centroid: 180101e04c3fSmrg case ir_binop_interpolate_at_offset: 180201e04c3fSmrg case ir_binop_interpolate_at_sample: { 180301e04c3fSmrg ir_dereference *deref = ir->operands[0]->as_dereference(); 180401e04c3fSmrg ir_swizzle *swizzle = NULL; 180501e04c3fSmrg if (!deref) { 180601e04c3fSmrg /* the api does not allow a swizzle here, but the varying packing code 180701e04c3fSmrg * may have pushed one into here. 180801e04c3fSmrg */ 180901e04c3fSmrg swizzle = ir->operands[0]->as_swizzle(); 181001e04c3fSmrg assert(swizzle); 181101e04c3fSmrg deref = swizzle->val->as_dereference(); 181201e04c3fSmrg assert(deref); 181301e04c3fSmrg } 181401e04c3fSmrg 181501e04c3fSmrg deref->accept(this); 181601e04c3fSmrg 181701e04c3fSmrg nir_intrinsic_op op; 18187ec681f3Smrg if (nir_deref_mode_is(this->deref, nir_var_shader_in)) { 181901e04c3fSmrg switch (ir->operation) { 182001e04c3fSmrg case ir_unop_interpolate_at_centroid: 182101e04c3fSmrg op = nir_intrinsic_interp_deref_at_centroid; 182201e04c3fSmrg break; 182301e04c3fSmrg case ir_binop_interpolate_at_offset: 182401e04c3fSmrg op = nir_intrinsic_interp_deref_at_offset; 182501e04c3fSmrg break; 182601e04c3fSmrg case ir_binop_interpolate_at_sample: 182701e04c3fSmrg op = nir_intrinsic_interp_deref_at_sample; 182801e04c3fSmrg break; 182901e04c3fSmrg default: 183001e04c3fSmrg unreachable("Invalid interpolation intrinsic"); 183101e04c3fSmrg } 183201e04c3fSmrg } else { 183301e04c3fSmrg /* This case can happen if the vertex shader does not write the 183401e04c3fSmrg * given varying. In this case, the linker will lower it to a 183501e04c3fSmrg * global variable. Since interpolating a variable makes no 183601e04c3fSmrg * sense, we'll just turn it into a load which will probably 183701e04c3fSmrg * eventually end up as an SSA definition. 183801e04c3fSmrg */ 18397ec681f3Smrg assert(nir_deref_mode_is(this->deref, nir_var_shader_temp)); 184001e04c3fSmrg op = nir_intrinsic_load_deref; 184101e04c3fSmrg } 184201e04c3fSmrg 184301e04c3fSmrg nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(shader, op); 184401e04c3fSmrg intrin->num_components = deref->type->vector_elements; 184501e04c3fSmrg intrin->src[0] = nir_src_for_ssa(&this->deref->dest.ssa); 184601e04c3fSmrg 184701e04c3fSmrg if (intrin->intrinsic == nir_intrinsic_interp_deref_at_offset || 184801e04c3fSmrg intrin->intrinsic == nir_intrinsic_interp_deref_at_sample) 184901e04c3fSmrg intrin->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1])); 185001e04c3fSmrg 185101e04c3fSmrg unsigned bit_size = glsl_get_bit_size(deref->type); 185201e04c3fSmrg add_instr(&intrin->instr, deref->type->vector_elements, bit_size); 185301e04c3fSmrg 185401e04c3fSmrg if (swizzle) { 185501e04c3fSmrg unsigned swiz[4] = { 185601e04c3fSmrg swizzle->mask.x, swizzle->mask.y, swizzle->mask.z, swizzle->mask.w 185701e04c3fSmrg }; 185801e04c3fSmrg 185901e04c3fSmrg result = nir_swizzle(&b, result, swiz, 18607ec681f3Smrg swizzle->type->vector_elements); 186101e04c3fSmrg } 186201e04c3fSmrg 186301e04c3fSmrg return; 186401e04c3fSmrg } 186501e04c3fSmrg 18667e102996Smaya case ir_unop_ssbo_unsized_array_length: { 18677e102996Smaya nir_intrinsic_instr *intrin = 18687e102996Smaya nir_intrinsic_instr_create(b.shader, 18697e102996Smaya nir_intrinsic_deref_buffer_array_length); 18707e102996Smaya 18717e102996Smaya ir_dereference *deref = ir->operands[0]->as_dereference(); 18727e102996Smaya intrin->src[0] = nir_src_for_ssa(&evaluate_deref(deref)->dest.ssa); 18737e102996Smaya 18747e102996Smaya add_instr(&intrin->instr, 1, 32); 18757e102996Smaya return; 18767e102996Smaya } 18777e102996Smaya 18787ec681f3Smrg case ir_binop_ubo_load: 18797ec681f3Smrg /* UBO loads should only have been lowered in GLSL IR for non-nir drivers, 18807ec681f3Smrg * NIR drivers make use of gl_nir_lower_buffers() instead. 18817ec681f3Smrg */ 18827ec681f3Smrg unreachable("Invalid operation nir doesn't want lowered ubo loads"); 188301e04c3fSmrg default: 188401e04c3fSmrg break; 188501e04c3fSmrg } 188601e04c3fSmrg 188701e04c3fSmrg nir_ssa_def *srcs[4]; 188801e04c3fSmrg for (unsigned i = 0; i < ir->num_operands; i++) 188901e04c3fSmrg srcs[i] = evaluate_rvalue(ir->operands[i]); 189001e04c3fSmrg 189101e04c3fSmrg glsl_base_type types[4]; 189201e04c3fSmrg for (unsigned i = 0; i < ir->num_operands; i++) 18937ec681f3Smrg types[i] = ir->operands[i]->type->base_type; 189401e04c3fSmrg 18957ec681f3Smrg glsl_base_type out_type = ir->type->base_type; 189601e04c3fSmrg 189701e04c3fSmrg switch (ir->operation) { 189801e04c3fSmrg case ir_unop_bit_not: result = nir_inot(&b, srcs[0]); break; 189901e04c3fSmrg case ir_unop_logic_not: 19007e102996Smaya result = nir_inot(&b, srcs[0]); 190101e04c3fSmrg break; 190201e04c3fSmrg case ir_unop_neg: 190301e04c3fSmrg result = type_is_float(types[0]) ? nir_fneg(&b, srcs[0]) 190401e04c3fSmrg : nir_ineg(&b, srcs[0]); 190501e04c3fSmrg break; 190601e04c3fSmrg case ir_unop_abs: 190701e04c3fSmrg result = type_is_float(types[0]) ? nir_fabs(&b, srcs[0]) 190801e04c3fSmrg : nir_iabs(&b, srcs[0]); 190901e04c3fSmrg break; 19107ec681f3Smrg case ir_unop_clz: 19117ec681f3Smrg result = nir_uclz(&b, srcs[0]); 19127ec681f3Smrg break; 191301e04c3fSmrg case ir_unop_saturate: 191401e04c3fSmrg assert(type_is_float(types[0])); 191501e04c3fSmrg result = nir_fsat(&b, srcs[0]); 191601e04c3fSmrg break; 191701e04c3fSmrg case ir_unop_sign: 191801e04c3fSmrg result = type_is_float(types[0]) ? nir_fsign(&b, srcs[0]) 191901e04c3fSmrg : nir_isign(&b, srcs[0]); 192001e04c3fSmrg break; 192101e04c3fSmrg case ir_unop_rcp: result = nir_frcp(&b, srcs[0]); break; 192201e04c3fSmrg case ir_unop_rsq: result = nir_frsq(&b, srcs[0]); break; 192301e04c3fSmrg case ir_unop_sqrt: result = nir_fsqrt(&b, srcs[0]); break; 192401e04c3fSmrg case ir_unop_exp: unreachable("ir_unop_exp should have been lowered"); 192501e04c3fSmrg case ir_unop_log: unreachable("ir_unop_log should have been lowered"); 192601e04c3fSmrg case ir_unop_exp2: result = nir_fexp2(&b, srcs[0]); break; 192701e04c3fSmrg case ir_unop_log2: result = nir_flog2(&b, srcs[0]); break; 192801e04c3fSmrg case ir_unop_i2f: 192901e04c3fSmrg case ir_unop_u2f: 193001e04c3fSmrg case ir_unop_b2f: 193101e04c3fSmrg case ir_unop_f2i: 193201e04c3fSmrg case ir_unop_f2u: 193301e04c3fSmrg case ir_unop_f2b: 193401e04c3fSmrg case ir_unop_i2b: 193501e04c3fSmrg case ir_unop_b2i: 193601e04c3fSmrg case ir_unop_b2i64: 193701e04c3fSmrg case ir_unop_d2f: 193801e04c3fSmrg case ir_unop_f2d: 19397ec681f3Smrg case ir_unop_f162f: 19407ec681f3Smrg case ir_unop_f2f16: 19417ec681f3Smrg case ir_unop_f162b: 19427ec681f3Smrg case ir_unop_b2f16: 19437ec681f3Smrg case ir_unop_i2i: 19447ec681f3Smrg case ir_unop_u2u: 194501e04c3fSmrg case ir_unop_d2i: 194601e04c3fSmrg case ir_unop_d2u: 194701e04c3fSmrg case ir_unop_d2b: 194801e04c3fSmrg case ir_unop_i2d: 194901e04c3fSmrg case ir_unop_u2d: 195001e04c3fSmrg case ir_unop_i642i: 195101e04c3fSmrg case ir_unop_i642u: 195201e04c3fSmrg case ir_unop_i642f: 195301e04c3fSmrg case ir_unop_i642b: 195401e04c3fSmrg case ir_unop_i642d: 195501e04c3fSmrg case ir_unop_u642i: 195601e04c3fSmrg case ir_unop_u642u: 195701e04c3fSmrg case ir_unop_u642f: 195801e04c3fSmrg case ir_unop_u642d: 195901e04c3fSmrg case ir_unop_i2i64: 196001e04c3fSmrg case ir_unop_u2i64: 196101e04c3fSmrg case ir_unop_f2i64: 196201e04c3fSmrg case ir_unop_d2i64: 196301e04c3fSmrg case ir_unop_i2u64: 196401e04c3fSmrg case ir_unop_u2u64: 196501e04c3fSmrg case ir_unop_f2u64: 196601e04c3fSmrg case ir_unop_d2u64: 196701e04c3fSmrg case ir_unop_i2u: 196801e04c3fSmrg case ir_unop_u2i: 196901e04c3fSmrg case ir_unop_i642u64: 197001e04c3fSmrg case ir_unop_u642i64: { 197101e04c3fSmrg nir_alu_type src_type = nir_get_nir_type_for_glsl_base_type(types[0]); 197201e04c3fSmrg nir_alu_type dst_type = nir_get_nir_type_for_glsl_base_type(out_type); 197301e04c3fSmrg result = nir_build_alu(&b, nir_type_conversion_op(src_type, dst_type, 197401e04c3fSmrg nir_rounding_mode_undef), 197501e04c3fSmrg srcs[0], NULL, NULL, NULL); 197601e04c3fSmrg /* b2i and b2f don't have fixed bit-size versions so the builder will 197701e04c3fSmrg * just assume 32 and we have to fix it up here. 197801e04c3fSmrg */ 197901e04c3fSmrg result->bit_size = nir_alu_type_get_type_size(dst_type); 198001e04c3fSmrg break; 198101e04c3fSmrg } 198201e04c3fSmrg 19837ec681f3Smrg case ir_unop_f2fmp: { 19847ec681f3Smrg result = nir_build_alu(&b, nir_op_f2fmp, srcs[0], NULL, NULL, NULL); 19857ec681f3Smrg break; 19867ec681f3Smrg } 19877ec681f3Smrg 19887ec681f3Smrg case ir_unop_i2imp: { 19897ec681f3Smrg result = nir_build_alu(&b, nir_op_i2imp, srcs[0], NULL, NULL, NULL); 19907ec681f3Smrg break; 19917ec681f3Smrg } 19927ec681f3Smrg 19937ec681f3Smrg case ir_unop_u2ump: { 19947ec681f3Smrg result = nir_build_alu(&b, nir_op_i2imp, srcs[0], NULL, NULL, NULL); 19957ec681f3Smrg break; 19967ec681f3Smrg } 19977ec681f3Smrg 199801e04c3fSmrg case ir_unop_bitcast_i2f: 199901e04c3fSmrg case ir_unop_bitcast_f2i: 200001e04c3fSmrg case ir_unop_bitcast_u2f: 200101e04c3fSmrg case ir_unop_bitcast_f2u: 200201e04c3fSmrg case ir_unop_bitcast_i642d: 200301e04c3fSmrg case ir_unop_bitcast_d2i64: 200401e04c3fSmrg case ir_unop_bitcast_u642d: 200501e04c3fSmrg case ir_unop_bitcast_d2u64: 200601e04c3fSmrg case ir_unop_subroutine_to_int: 200701e04c3fSmrg /* no-op */ 20087ec681f3Smrg result = nir_mov(&b, srcs[0]); 200901e04c3fSmrg break; 201001e04c3fSmrg case ir_unop_trunc: result = nir_ftrunc(&b, srcs[0]); break; 201101e04c3fSmrg case ir_unop_ceil: result = nir_fceil(&b, srcs[0]); break; 201201e04c3fSmrg case ir_unop_floor: result = nir_ffloor(&b, srcs[0]); break; 201301e04c3fSmrg case ir_unop_fract: result = nir_ffract(&b, srcs[0]); break; 201401e04c3fSmrg case ir_unop_frexp_exp: result = nir_frexp_exp(&b, srcs[0]); break; 201501e04c3fSmrg case ir_unop_frexp_sig: result = nir_frexp_sig(&b, srcs[0]); break; 201601e04c3fSmrg case ir_unop_round_even: result = nir_fround_even(&b, srcs[0]); break; 201701e04c3fSmrg case ir_unop_sin: result = nir_fsin(&b, srcs[0]); break; 201801e04c3fSmrg case ir_unop_cos: result = nir_fcos(&b, srcs[0]); break; 201901e04c3fSmrg case ir_unop_dFdx: result = nir_fddx(&b, srcs[0]); break; 202001e04c3fSmrg case ir_unop_dFdy: result = nir_fddy(&b, srcs[0]); break; 202101e04c3fSmrg case ir_unop_dFdx_fine: result = nir_fddx_fine(&b, srcs[0]); break; 202201e04c3fSmrg case ir_unop_dFdy_fine: result = nir_fddy_fine(&b, srcs[0]); break; 202301e04c3fSmrg case ir_unop_dFdx_coarse: result = nir_fddx_coarse(&b, srcs[0]); break; 202401e04c3fSmrg case ir_unop_dFdy_coarse: result = nir_fddy_coarse(&b, srcs[0]); break; 202501e04c3fSmrg case ir_unop_pack_snorm_2x16: 202601e04c3fSmrg result = nir_pack_snorm_2x16(&b, srcs[0]); 202701e04c3fSmrg break; 202801e04c3fSmrg case ir_unop_pack_snorm_4x8: 202901e04c3fSmrg result = nir_pack_snorm_4x8(&b, srcs[0]); 203001e04c3fSmrg break; 203101e04c3fSmrg case ir_unop_pack_unorm_2x16: 203201e04c3fSmrg result = nir_pack_unorm_2x16(&b, srcs[0]); 203301e04c3fSmrg break; 203401e04c3fSmrg case ir_unop_pack_unorm_4x8: 203501e04c3fSmrg result = nir_pack_unorm_4x8(&b, srcs[0]); 203601e04c3fSmrg break; 203701e04c3fSmrg case ir_unop_pack_half_2x16: 203801e04c3fSmrg result = nir_pack_half_2x16(&b, srcs[0]); 203901e04c3fSmrg break; 204001e04c3fSmrg case ir_unop_unpack_snorm_2x16: 204101e04c3fSmrg result = nir_unpack_snorm_2x16(&b, srcs[0]); 204201e04c3fSmrg break; 204301e04c3fSmrg case ir_unop_unpack_snorm_4x8: 204401e04c3fSmrg result = nir_unpack_snorm_4x8(&b, srcs[0]); 204501e04c3fSmrg break; 204601e04c3fSmrg case ir_unop_unpack_unorm_2x16: 204701e04c3fSmrg result = nir_unpack_unorm_2x16(&b, srcs[0]); 204801e04c3fSmrg break; 204901e04c3fSmrg case ir_unop_unpack_unorm_4x8: 205001e04c3fSmrg result = nir_unpack_unorm_4x8(&b, srcs[0]); 205101e04c3fSmrg break; 205201e04c3fSmrg case ir_unop_unpack_half_2x16: 205301e04c3fSmrg result = nir_unpack_half_2x16(&b, srcs[0]); 205401e04c3fSmrg break; 205501e04c3fSmrg case ir_unop_pack_sampler_2x32: 205601e04c3fSmrg case ir_unop_pack_image_2x32: 205701e04c3fSmrg case ir_unop_pack_double_2x32: 205801e04c3fSmrg case ir_unop_pack_int_2x32: 205901e04c3fSmrg case ir_unop_pack_uint_2x32: 206001e04c3fSmrg result = nir_pack_64_2x32(&b, srcs[0]); 206101e04c3fSmrg break; 206201e04c3fSmrg case ir_unop_unpack_sampler_2x32: 206301e04c3fSmrg case ir_unop_unpack_image_2x32: 206401e04c3fSmrg case ir_unop_unpack_double_2x32: 206501e04c3fSmrg case ir_unop_unpack_int_2x32: 206601e04c3fSmrg case ir_unop_unpack_uint_2x32: 206701e04c3fSmrg result = nir_unpack_64_2x32(&b, srcs[0]); 206801e04c3fSmrg break; 206901e04c3fSmrg case ir_unop_bitfield_reverse: 207001e04c3fSmrg result = nir_bitfield_reverse(&b, srcs[0]); 207101e04c3fSmrg break; 207201e04c3fSmrg case ir_unop_bit_count: 207301e04c3fSmrg result = nir_bit_count(&b, srcs[0]); 207401e04c3fSmrg break; 207501e04c3fSmrg case ir_unop_find_msb: 207601e04c3fSmrg switch (types[0]) { 207701e04c3fSmrg case GLSL_TYPE_UINT: 207801e04c3fSmrg result = nir_ufind_msb(&b, srcs[0]); 207901e04c3fSmrg break; 208001e04c3fSmrg case GLSL_TYPE_INT: 208101e04c3fSmrg result = nir_ifind_msb(&b, srcs[0]); 208201e04c3fSmrg break; 208301e04c3fSmrg default: 208401e04c3fSmrg unreachable("Invalid type for findMSB()"); 208501e04c3fSmrg } 208601e04c3fSmrg break; 208701e04c3fSmrg case ir_unop_find_lsb: 208801e04c3fSmrg result = nir_find_lsb(&b, srcs[0]); 208901e04c3fSmrg break; 209001e04c3fSmrg 209101e04c3fSmrg case ir_unop_get_buffer_size: { 209201e04c3fSmrg nir_intrinsic_instr *load = nir_intrinsic_instr_create( 209301e04c3fSmrg this->shader, 20947ec681f3Smrg nir_intrinsic_get_ssbo_size); 209501e04c3fSmrg load->num_components = ir->type->vector_elements; 209601e04c3fSmrg load->src[0] = nir_src_for_ssa(evaluate_rvalue(ir->operands[0])); 209701e04c3fSmrg unsigned bit_size = glsl_get_bit_size(ir->type); 209801e04c3fSmrg add_instr(&load->instr, ir->type->vector_elements, bit_size); 209901e04c3fSmrg return; 210001e04c3fSmrg } 210101e04c3fSmrg 21027ec681f3Smrg case ir_unop_atan: 21037ec681f3Smrg result = nir_atan(&b, srcs[0]); 21047ec681f3Smrg break; 21057ec681f3Smrg 210601e04c3fSmrg case ir_binop_add: 210701e04c3fSmrg result = type_is_float(out_type) ? nir_fadd(&b, srcs[0], srcs[1]) 210801e04c3fSmrg : nir_iadd(&b, srcs[0], srcs[1]); 210901e04c3fSmrg break; 21107ec681f3Smrg case ir_binop_add_sat: 21117ec681f3Smrg result = type_is_signed(out_type) ? nir_iadd_sat(&b, srcs[0], srcs[1]) 21127ec681f3Smrg : nir_uadd_sat(&b, srcs[0], srcs[1]); 21137ec681f3Smrg break; 211401e04c3fSmrg case ir_binop_sub: 211501e04c3fSmrg result = type_is_float(out_type) ? nir_fsub(&b, srcs[0], srcs[1]) 211601e04c3fSmrg : nir_isub(&b, srcs[0], srcs[1]); 211701e04c3fSmrg break; 21187ec681f3Smrg case ir_binop_sub_sat: 21197ec681f3Smrg result = type_is_signed(out_type) ? nir_isub_sat(&b, srcs[0], srcs[1]) 21207ec681f3Smrg : nir_usub_sat(&b, srcs[0], srcs[1]); 21217ec681f3Smrg break; 21227ec681f3Smrg case ir_binop_abs_sub: 21237ec681f3Smrg /* out_type is always unsigned for ir_binop_abs_sub, so we have to key 21247ec681f3Smrg * on the type of the sources. 21257ec681f3Smrg */ 21267ec681f3Smrg result = type_is_signed(types[0]) ? nir_uabs_isub(&b, srcs[0], srcs[1]) 21277ec681f3Smrg : nir_uabs_usub(&b, srcs[0], srcs[1]); 21287ec681f3Smrg break; 21297ec681f3Smrg case ir_binop_avg: 21307ec681f3Smrg result = type_is_signed(out_type) ? nir_ihadd(&b, srcs[0], srcs[1]) 21317ec681f3Smrg : nir_uhadd(&b, srcs[0], srcs[1]); 21327ec681f3Smrg break; 21337ec681f3Smrg case ir_binop_avg_round: 21347ec681f3Smrg result = type_is_signed(out_type) ? nir_irhadd(&b, srcs[0], srcs[1]) 21357ec681f3Smrg : nir_urhadd(&b, srcs[0], srcs[1]); 21367ec681f3Smrg break; 21377ec681f3Smrg case ir_binop_mul_32x16: 21387ec681f3Smrg result = type_is_signed(out_type) ? nir_imul_32x16(&b, srcs[0], srcs[1]) 21397ec681f3Smrg : nir_umul_32x16(&b, srcs[0], srcs[1]); 21407ec681f3Smrg break; 214101e04c3fSmrg case ir_binop_mul: 21427e102996Smaya if (type_is_float(out_type)) 21437e102996Smaya result = nir_fmul(&b, srcs[0], srcs[1]); 21447e102996Smaya else if (out_type == GLSL_TYPE_INT64 && 21457e102996Smaya (ir->operands[0]->type->base_type == GLSL_TYPE_INT || 21467e102996Smaya ir->operands[1]->type->base_type == GLSL_TYPE_INT)) 21477e102996Smaya result = nir_imul_2x32_64(&b, srcs[0], srcs[1]); 21487e102996Smaya else if (out_type == GLSL_TYPE_UINT64 && 21497e102996Smaya (ir->operands[0]->type->base_type == GLSL_TYPE_UINT || 21507e102996Smaya ir->operands[1]->type->base_type == GLSL_TYPE_UINT)) 21517e102996Smaya result = nir_umul_2x32_64(&b, srcs[0], srcs[1]); 21527e102996Smaya else 21537e102996Smaya result = nir_imul(&b, srcs[0], srcs[1]); 215401e04c3fSmrg break; 215501e04c3fSmrg case ir_binop_div: 215601e04c3fSmrg if (type_is_float(out_type)) 215701e04c3fSmrg result = nir_fdiv(&b, srcs[0], srcs[1]); 215801e04c3fSmrg else if (type_is_signed(out_type)) 215901e04c3fSmrg result = nir_idiv(&b, srcs[0], srcs[1]); 216001e04c3fSmrg else 216101e04c3fSmrg result = nir_udiv(&b, srcs[0], srcs[1]); 216201e04c3fSmrg break; 216301e04c3fSmrg case ir_binop_mod: 216401e04c3fSmrg result = type_is_float(out_type) ? nir_fmod(&b, srcs[0], srcs[1]) 216501e04c3fSmrg : nir_umod(&b, srcs[0], srcs[1]); 216601e04c3fSmrg break; 216701e04c3fSmrg case ir_binop_min: 216801e04c3fSmrg if (type_is_float(out_type)) 216901e04c3fSmrg result = nir_fmin(&b, srcs[0], srcs[1]); 217001e04c3fSmrg else if (type_is_signed(out_type)) 217101e04c3fSmrg result = nir_imin(&b, srcs[0], srcs[1]); 217201e04c3fSmrg else 217301e04c3fSmrg result = nir_umin(&b, srcs[0], srcs[1]); 217401e04c3fSmrg break; 217501e04c3fSmrg case ir_binop_max: 217601e04c3fSmrg if (type_is_float(out_type)) 217701e04c3fSmrg result = nir_fmax(&b, srcs[0], srcs[1]); 217801e04c3fSmrg else if (type_is_signed(out_type)) 217901e04c3fSmrg result = nir_imax(&b, srcs[0], srcs[1]); 218001e04c3fSmrg else 218101e04c3fSmrg result = nir_umax(&b, srcs[0], srcs[1]); 218201e04c3fSmrg break; 218301e04c3fSmrg case ir_binop_pow: result = nir_fpow(&b, srcs[0], srcs[1]); break; 218401e04c3fSmrg case ir_binop_bit_and: result = nir_iand(&b, srcs[0], srcs[1]); break; 218501e04c3fSmrg case ir_binop_bit_or: result = nir_ior(&b, srcs[0], srcs[1]); break; 218601e04c3fSmrg case ir_binop_bit_xor: result = nir_ixor(&b, srcs[0], srcs[1]); break; 218701e04c3fSmrg case ir_binop_logic_and: 21887e102996Smaya result = nir_iand(&b, srcs[0], srcs[1]); 218901e04c3fSmrg break; 219001e04c3fSmrg case ir_binop_logic_or: 21917e102996Smaya result = nir_ior(&b, srcs[0], srcs[1]); 219201e04c3fSmrg break; 219301e04c3fSmrg case ir_binop_logic_xor: 21947e102996Smaya result = nir_ixor(&b, srcs[0], srcs[1]); 219501e04c3fSmrg break; 21967ec681f3Smrg case ir_binop_lshift: result = nir_ishl(&b, srcs[0], nir_u2u32(&b, srcs[1])); break; 219701e04c3fSmrg case ir_binop_rshift: 21987ec681f3Smrg result = (type_is_signed(out_type)) ? nir_ishr(&b, srcs[0], nir_u2u32(&b, srcs[1])) 21997ec681f3Smrg : nir_ushr(&b, srcs[0], nir_u2u32(&b, srcs[1])); 220001e04c3fSmrg break; 220101e04c3fSmrg case ir_binop_imul_high: 220201e04c3fSmrg result = (out_type == GLSL_TYPE_INT) ? nir_imul_high(&b, srcs[0], srcs[1]) 220301e04c3fSmrg : nir_umul_high(&b, srcs[0], srcs[1]); 220401e04c3fSmrg break; 220501e04c3fSmrg case ir_binop_carry: result = nir_uadd_carry(&b, srcs[0], srcs[1]); break; 220601e04c3fSmrg case ir_binop_borrow: result = nir_usub_borrow(&b, srcs[0], srcs[1]); break; 220701e04c3fSmrg case ir_binop_less: 22087e102996Smaya if (type_is_float(types[0])) 22097e102996Smaya result = nir_flt(&b, srcs[0], srcs[1]); 22107e102996Smaya else if (type_is_signed(types[0])) 22117e102996Smaya result = nir_ilt(&b, srcs[0], srcs[1]); 22127e102996Smaya else 22137e102996Smaya result = nir_ult(&b, srcs[0], srcs[1]); 221401e04c3fSmrg break; 221501e04c3fSmrg case ir_binop_gequal: 22167e102996Smaya if (type_is_float(types[0])) 22177e102996Smaya result = nir_fge(&b, srcs[0], srcs[1]); 22187e102996Smaya else if (type_is_signed(types[0])) 22197e102996Smaya result = nir_ige(&b, srcs[0], srcs[1]); 22207e102996Smaya else 22217e102996Smaya result = nir_uge(&b, srcs[0], srcs[1]); 222201e04c3fSmrg break; 222301e04c3fSmrg case ir_binop_equal: 22247e102996Smaya if (type_is_float(types[0])) 22257e102996Smaya result = nir_feq(&b, srcs[0], srcs[1]); 22267e102996Smaya else 22277e102996Smaya result = nir_ieq(&b, srcs[0], srcs[1]); 222801e04c3fSmrg break; 222901e04c3fSmrg case ir_binop_nequal: 22307e102996Smaya if (type_is_float(types[0])) 22317ec681f3Smrg result = nir_fneu(&b, srcs[0], srcs[1]); 22327e102996Smaya else 22337e102996Smaya result = nir_ine(&b, srcs[0], srcs[1]); 223401e04c3fSmrg break; 223501e04c3fSmrg case ir_binop_all_equal: 22367e102996Smaya if (type_is_float(types[0])) { 22377e102996Smaya switch (ir->operands[0]->type->vector_elements) { 22387e102996Smaya case 1: result = nir_feq(&b, srcs[0], srcs[1]); break; 22397e102996Smaya case 2: result = nir_ball_fequal2(&b, srcs[0], srcs[1]); break; 22407e102996Smaya case 3: result = nir_ball_fequal3(&b, srcs[0], srcs[1]); break; 22417e102996Smaya case 4: result = nir_ball_fequal4(&b, srcs[0], srcs[1]); break; 22427e102996Smaya default: 22437e102996Smaya unreachable("not reached"); 224401e04c3fSmrg } 224501e04c3fSmrg } else { 224601e04c3fSmrg switch (ir->operands[0]->type->vector_elements) { 22477e102996Smaya case 1: result = nir_ieq(&b, srcs[0], srcs[1]); break; 22487e102996Smaya case 2: result = nir_ball_iequal2(&b, srcs[0], srcs[1]); break; 22497e102996Smaya case 3: result = nir_ball_iequal3(&b, srcs[0], srcs[1]); break; 22507e102996Smaya case 4: result = nir_ball_iequal4(&b, srcs[0], srcs[1]); break; 225101e04c3fSmrg default: 225201e04c3fSmrg unreachable("not reached"); 225301e04c3fSmrg } 225401e04c3fSmrg } 225501e04c3fSmrg break; 225601e04c3fSmrg case ir_binop_any_nequal: 22577e102996Smaya if (type_is_float(types[0])) { 22587e102996Smaya switch (ir->operands[0]->type->vector_elements) { 22597ec681f3Smrg case 1: result = nir_fneu(&b, srcs[0], srcs[1]); break; 22607e102996Smaya case 2: result = nir_bany_fnequal2(&b, srcs[0], srcs[1]); break; 22617e102996Smaya case 3: result = nir_bany_fnequal3(&b, srcs[0], srcs[1]); break; 22627e102996Smaya case 4: result = nir_bany_fnequal4(&b, srcs[0], srcs[1]); break; 22637e102996Smaya default: 22647e102996Smaya unreachable("not reached"); 226501e04c3fSmrg } 226601e04c3fSmrg } else { 226701e04c3fSmrg switch (ir->operands[0]->type->vector_elements) { 22687e102996Smaya case 1: result = nir_ine(&b, srcs[0], srcs[1]); break; 22697e102996Smaya case 2: result = nir_bany_inequal2(&b, srcs[0], srcs[1]); break; 22707e102996Smaya case 3: result = nir_bany_inequal3(&b, srcs[0], srcs[1]); break; 22717e102996Smaya case 4: result = nir_bany_inequal4(&b, srcs[0], srcs[1]); break; 227201e04c3fSmrg default: 227301e04c3fSmrg unreachable("not reached"); 227401e04c3fSmrg } 227501e04c3fSmrg } 227601e04c3fSmrg break; 227701e04c3fSmrg case ir_binop_dot: 22787ec681f3Smrg result = nir_fdot(&b, srcs[0], srcs[1]); 227901e04c3fSmrg break; 228001e04c3fSmrg case ir_binop_vector_extract: { 228101e04c3fSmrg result = nir_channel(&b, srcs[0], 0); 228201e04c3fSmrg for (unsigned i = 1; i < ir->operands[0]->type->vector_elements; i++) { 228301e04c3fSmrg nir_ssa_def *swizzled = nir_channel(&b, srcs[0], i); 22847ec681f3Smrg result = nir_bcsel(&b, nir_ieq_imm(&b, srcs[1], i), 228501e04c3fSmrg swizzled, result); 228601e04c3fSmrg } 228701e04c3fSmrg break; 228801e04c3fSmrg } 228901e04c3fSmrg 22907ec681f3Smrg case ir_binop_atan2: 22917ec681f3Smrg result = nir_atan2(&b, srcs[0], srcs[1]); 22927ec681f3Smrg break; 22937ec681f3Smrg 229401e04c3fSmrg case ir_binop_ldexp: result = nir_ldexp(&b, srcs[0], srcs[1]); break; 229501e04c3fSmrg case ir_triop_fma: 229601e04c3fSmrg result = nir_ffma(&b, srcs[0], srcs[1], srcs[2]); 229701e04c3fSmrg break; 229801e04c3fSmrg case ir_triop_lrp: 229901e04c3fSmrg result = nir_flrp(&b, srcs[0], srcs[1], srcs[2]); 230001e04c3fSmrg break; 230101e04c3fSmrg case ir_triop_csel: 23027e102996Smaya result = nir_bcsel(&b, srcs[0], srcs[1], srcs[2]); 230301e04c3fSmrg break; 230401e04c3fSmrg case ir_triop_bitfield_extract: 23057ec681f3Smrg result = ir->type->is_int_16_32() ? 23067ec681f3Smrg nir_ibitfield_extract(&b, nir_i2i32(&b, srcs[0]), nir_i2i32(&b, srcs[1]), nir_i2i32(&b, srcs[2])) : 23077ec681f3Smrg nir_ubitfield_extract(&b, nir_u2u32(&b, srcs[0]), nir_i2i32(&b, srcs[1]), nir_i2i32(&b, srcs[2])); 230801e04c3fSmrg break; 230901e04c3fSmrg case ir_quadop_bitfield_insert: 23107ec681f3Smrg result = nir_bitfield_insert(&b, 23117ec681f3Smrg nir_u2u32(&b, srcs[0]), nir_u2u32(&b, srcs[1]), 23127ec681f3Smrg nir_i2i32(&b, srcs[2]), nir_i2i32(&b, srcs[3])); 231301e04c3fSmrg break; 231401e04c3fSmrg case ir_quadop_vector: 231501e04c3fSmrg result = nir_vec(&b, srcs, ir->type->vector_elements); 231601e04c3fSmrg break; 231701e04c3fSmrg 231801e04c3fSmrg default: 231901e04c3fSmrg unreachable("not reached"); 232001e04c3fSmrg } 232101e04c3fSmrg} 232201e04c3fSmrg 232301e04c3fSmrgvoid 232401e04c3fSmrgnir_visitor::visit(ir_swizzle *ir) 232501e04c3fSmrg{ 232601e04c3fSmrg unsigned swizzle[4] = { ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w }; 232701e04c3fSmrg result = nir_swizzle(&b, evaluate_rvalue(ir->val), swizzle, 23287ec681f3Smrg ir->type->vector_elements); 232901e04c3fSmrg} 233001e04c3fSmrg 233101e04c3fSmrgvoid 233201e04c3fSmrgnir_visitor::visit(ir_texture *ir) 233301e04c3fSmrg{ 233401e04c3fSmrg unsigned num_srcs; 233501e04c3fSmrg nir_texop op; 233601e04c3fSmrg switch (ir->op) { 233701e04c3fSmrg case ir_tex: 233801e04c3fSmrg op = nir_texop_tex; 233901e04c3fSmrg num_srcs = 1; /* coordinate */ 234001e04c3fSmrg break; 234101e04c3fSmrg 234201e04c3fSmrg case ir_txb: 234301e04c3fSmrg case ir_txl: 234401e04c3fSmrg op = (ir->op == ir_txb) ? nir_texop_txb : nir_texop_txl; 234501e04c3fSmrg num_srcs = 2; /* coordinate, bias/lod */ 234601e04c3fSmrg break; 234701e04c3fSmrg 234801e04c3fSmrg case ir_txd: 234901e04c3fSmrg op = nir_texop_txd; /* coordinate, dPdx, dPdy */ 235001e04c3fSmrg num_srcs = 3; 235101e04c3fSmrg break; 235201e04c3fSmrg 235301e04c3fSmrg case ir_txf: 235401e04c3fSmrg op = nir_texop_txf; 235501e04c3fSmrg if (ir->lod_info.lod != NULL) 235601e04c3fSmrg num_srcs = 2; /* coordinate, lod */ 235701e04c3fSmrg else 235801e04c3fSmrg num_srcs = 1; /* coordinate */ 235901e04c3fSmrg break; 236001e04c3fSmrg 236101e04c3fSmrg case ir_txf_ms: 236201e04c3fSmrg op = nir_texop_txf_ms; 236301e04c3fSmrg num_srcs = 2; /* coordinate, sample_index */ 236401e04c3fSmrg break; 236501e04c3fSmrg 236601e04c3fSmrg case ir_txs: 236701e04c3fSmrg op = nir_texop_txs; 236801e04c3fSmrg if (ir->lod_info.lod != NULL) 236901e04c3fSmrg num_srcs = 1; /* lod */ 237001e04c3fSmrg else 237101e04c3fSmrg num_srcs = 0; 237201e04c3fSmrg break; 237301e04c3fSmrg 237401e04c3fSmrg case ir_lod: 237501e04c3fSmrg op = nir_texop_lod; 237601e04c3fSmrg num_srcs = 1; /* coordinate */ 237701e04c3fSmrg break; 237801e04c3fSmrg 237901e04c3fSmrg case ir_tg4: 238001e04c3fSmrg op = nir_texop_tg4; 238101e04c3fSmrg num_srcs = 1; /* coordinate */ 238201e04c3fSmrg break; 238301e04c3fSmrg 238401e04c3fSmrg case ir_query_levels: 238501e04c3fSmrg op = nir_texop_query_levels; 238601e04c3fSmrg num_srcs = 0; 238701e04c3fSmrg break; 238801e04c3fSmrg 238901e04c3fSmrg case ir_texture_samples: 239001e04c3fSmrg op = nir_texop_texture_samples; 239101e04c3fSmrg num_srcs = 0; 239201e04c3fSmrg break; 239301e04c3fSmrg 239401e04c3fSmrg case ir_samples_identical: 239501e04c3fSmrg op = nir_texop_samples_identical; 239601e04c3fSmrg num_srcs = 1; /* coordinate */ 239701e04c3fSmrg break; 239801e04c3fSmrg 239901e04c3fSmrg default: 240001e04c3fSmrg unreachable("not reached"); 240101e04c3fSmrg } 240201e04c3fSmrg 240301e04c3fSmrg if (ir->projector != NULL) 240401e04c3fSmrg num_srcs++; 240501e04c3fSmrg if (ir->shadow_comparator != NULL) 240601e04c3fSmrg num_srcs++; 24077e102996Smaya /* offsets are constants we store inside nir_tex_intrs.offsets */ 24087e102996Smaya if (ir->offset != NULL && !ir->offset->type->is_array()) 240901e04c3fSmrg num_srcs++; 241001e04c3fSmrg 241101e04c3fSmrg /* Add one for the texture deref */ 241201e04c3fSmrg num_srcs += 2; 241301e04c3fSmrg 241401e04c3fSmrg nir_tex_instr *instr = nir_tex_instr_create(this->shader, num_srcs); 241501e04c3fSmrg 241601e04c3fSmrg instr->op = op; 241701e04c3fSmrg instr->sampler_dim = 241801e04c3fSmrg (glsl_sampler_dim) ir->sampler->type->sampler_dimensionality; 241901e04c3fSmrg instr->is_array = ir->sampler->type->sampler_array; 242001e04c3fSmrg instr->is_shadow = ir->sampler->type->sampler_shadow; 242101e04c3fSmrg if (instr->is_shadow) 242201e04c3fSmrg instr->is_new_style_shadow = (ir->type->vector_elements == 1); 24237ec681f3Smrg instr->dest_type = nir_get_nir_type_for_glsl_type(ir->type); 242401e04c3fSmrg 242501e04c3fSmrg nir_deref_instr *sampler_deref = evaluate_deref(ir->sampler); 24267e102996Smaya 24277e102996Smaya /* check for bindless handles */ 24287ec681f3Smrg if (!nir_deref_mode_is(sampler_deref, nir_var_uniform) || 24297e102996Smaya nir_deref_instr_get_variable(sampler_deref)->data.bindless) { 24307e102996Smaya nir_ssa_def *load = nir_load_deref(&b, sampler_deref); 24317e102996Smaya instr->src[0].src = nir_src_for_ssa(load); 24327e102996Smaya instr->src[0].src_type = nir_tex_src_texture_handle; 24337e102996Smaya instr->src[1].src = nir_src_for_ssa(load); 24347e102996Smaya instr->src[1].src_type = nir_tex_src_sampler_handle; 24357e102996Smaya } else { 24367e102996Smaya instr->src[0].src = nir_src_for_ssa(&sampler_deref->dest.ssa); 24377e102996Smaya instr->src[0].src_type = nir_tex_src_texture_deref; 24387e102996Smaya instr->src[1].src = nir_src_for_ssa(&sampler_deref->dest.ssa); 24397e102996Smaya instr->src[1].src_type = nir_tex_src_sampler_deref; 24407e102996Smaya } 244101e04c3fSmrg 244201e04c3fSmrg unsigned src_number = 2; 244301e04c3fSmrg 244401e04c3fSmrg if (ir->coordinate != NULL) { 244501e04c3fSmrg instr->coord_components = ir->coordinate->type->vector_elements; 244601e04c3fSmrg instr->src[src_number].src = 244701e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->coordinate)); 244801e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_coord; 244901e04c3fSmrg src_number++; 245001e04c3fSmrg } 245101e04c3fSmrg 245201e04c3fSmrg if (ir->projector != NULL) { 245301e04c3fSmrg instr->src[src_number].src = 245401e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->projector)); 245501e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_projector; 245601e04c3fSmrg src_number++; 245701e04c3fSmrg } 245801e04c3fSmrg 245901e04c3fSmrg if (ir->shadow_comparator != NULL) { 246001e04c3fSmrg instr->src[src_number].src = 246101e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->shadow_comparator)); 246201e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_comparator; 246301e04c3fSmrg src_number++; 246401e04c3fSmrg } 246501e04c3fSmrg 246601e04c3fSmrg if (ir->offset != NULL) { 24677e102996Smaya if (ir->offset->type->is_array()) { 24687e102996Smaya for (int i = 0; i < ir->offset->type->array_size(); i++) { 24697e102996Smaya const ir_constant *c = 24707e102996Smaya ir->offset->as_constant()->get_array_element(i); 24717e102996Smaya 24727e102996Smaya for (unsigned j = 0; j < 2; ++j) { 24737e102996Smaya int val = c->get_int_component(j); 24747e102996Smaya assert(val <= 31 && val >= -32); 24757e102996Smaya instr->tg4_offsets[i][j] = val; 24767e102996Smaya } 24777e102996Smaya } 24787e102996Smaya } else { 24797e102996Smaya assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar()); 248001e04c3fSmrg 24817e102996Smaya instr->src[src_number].src = 24827e102996Smaya nir_src_for_ssa(evaluate_rvalue(ir->offset)); 24837e102996Smaya instr->src[src_number].src_type = nir_tex_src_offset; 24847e102996Smaya src_number++; 24857e102996Smaya } 248601e04c3fSmrg } 248701e04c3fSmrg 248801e04c3fSmrg switch (ir->op) { 248901e04c3fSmrg case ir_txb: 249001e04c3fSmrg instr->src[src_number].src = 249101e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.bias)); 249201e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_bias; 249301e04c3fSmrg src_number++; 249401e04c3fSmrg break; 249501e04c3fSmrg 249601e04c3fSmrg case ir_txl: 249701e04c3fSmrg case ir_txf: 249801e04c3fSmrg case ir_txs: 249901e04c3fSmrg if (ir->lod_info.lod != NULL) { 250001e04c3fSmrg instr->src[src_number].src = 250101e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.lod)); 250201e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_lod; 250301e04c3fSmrg src_number++; 250401e04c3fSmrg } 250501e04c3fSmrg break; 250601e04c3fSmrg 250701e04c3fSmrg case ir_txd: 250801e04c3fSmrg instr->src[src_number].src = 250901e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.grad.dPdx)); 251001e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_ddx; 251101e04c3fSmrg src_number++; 251201e04c3fSmrg instr->src[src_number].src = 251301e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.grad.dPdy)); 251401e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_ddy; 251501e04c3fSmrg src_number++; 251601e04c3fSmrg break; 251701e04c3fSmrg 251801e04c3fSmrg case ir_txf_ms: 251901e04c3fSmrg instr->src[src_number].src = 252001e04c3fSmrg nir_src_for_ssa(evaluate_rvalue(ir->lod_info.sample_index)); 252101e04c3fSmrg instr->src[src_number].src_type = nir_tex_src_ms_index; 252201e04c3fSmrg src_number++; 252301e04c3fSmrg break; 252401e04c3fSmrg 252501e04c3fSmrg case ir_tg4: 252601e04c3fSmrg instr->component = ir->lod_info.component->as_constant()->value.u[0]; 252701e04c3fSmrg break; 252801e04c3fSmrg 252901e04c3fSmrg default: 253001e04c3fSmrg break; 253101e04c3fSmrg } 253201e04c3fSmrg 253301e04c3fSmrg assert(src_number == num_srcs); 253401e04c3fSmrg 253501e04c3fSmrg unsigned bit_size = glsl_get_bit_size(ir->type); 253601e04c3fSmrg add_instr(&instr->instr, nir_tex_instr_dest_size(instr), bit_size); 253701e04c3fSmrg} 253801e04c3fSmrg 253901e04c3fSmrgvoid 254001e04c3fSmrgnir_visitor::visit(ir_constant *ir) 254101e04c3fSmrg{ 254201e04c3fSmrg /* 254301e04c3fSmrg * We don't know if this variable is an array or struct that gets 254401e04c3fSmrg * dereferenced, so do the safe thing an make it a variable with a 254501e04c3fSmrg * constant initializer and return a dereference. 254601e04c3fSmrg */ 254701e04c3fSmrg 254801e04c3fSmrg nir_variable *var = 254901e04c3fSmrg nir_local_variable_create(this->impl, ir->type, "const_temp"); 255001e04c3fSmrg var->data.read_only = true; 255101e04c3fSmrg var->constant_initializer = constant_copy(ir, var); 255201e04c3fSmrg 255301e04c3fSmrg this->deref = nir_build_deref_var(&b, var); 255401e04c3fSmrg} 255501e04c3fSmrg 255601e04c3fSmrgvoid 255701e04c3fSmrgnir_visitor::visit(ir_dereference_variable *ir) 255801e04c3fSmrg{ 25597e102996Smaya if (ir->variable_referenced()->data.mode == ir_var_function_out) { 25607e102996Smaya unsigned i = (sig->return_type != glsl_type::void_type) ? 1 : 0; 25617e102996Smaya 25627e102996Smaya foreach_in_list(ir_variable, param, &sig->parameters) { 25637e102996Smaya if (param == ir->variable_referenced()) { 25647e102996Smaya break; 25657e102996Smaya } 25667e102996Smaya i++; 25677e102996Smaya } 25687e102996Smaya 25697e102996Smaya this->deref = nir_build_deref_cast(&b, nir_load_param(&b, i), 25707e102996Smaya nir_var_function_temp, ir->type, 0); 25717e102996Smaya return; 25727e102996Smaya } 25737e102996Smaya 25747e102996Smaya assert(ir->variable_referenced()->data.mode != ir_var_function_inout); 25757e102996Smaya 257601e04c3fSmrg struct hash_entry *entry = 257701e04c3fSmrg _mesa_hash_table_search(this->var_table, ir->var); 257801e04c3fSmrg assert(entry); 257901e04c3fSmrg nir_variable *var = (nir_variable *) entry->data; 258001e04c3fSmrg 258101e04c3fSmrg this->deref = nir_build_deref_var(&b, var); 258201e04c3fSmrg} 258301e04c3fSmrg 258401e04c3fSmrgvoid 258501e04c3fSmrgnir_visitor::visit(ir_dereference_record *ir) 258601e04c3fSmrg{ 258701e04c3fSmrg ir->record->accept(this); 258801e04c3fSmrg 258901e04c3fSmrg int field_index = ir->field_idx; 259001e04c3fSmrg assert(field_index >= 0); 259101e04c3fSmrg 259201e04c3fSmrg this->deref = nir_build_deref_struct(&b, this->deref, field_index); 259301e04c3fSmrg} 259401e04c3fSmrg 259501e04c3fSmrgvoid 259601e04c3fSmrgnir_visitor::visit(ir_dereference_array *ir) 259701e04c3fSmrg{ 259801e04c3fSmrg nir_ssa_def *index = evaluate_rvalue(ir->array_index); 259901e04c3fSmrg 260001e04c3fSmrg ir->array->accept(this); 260101e04c3fSmrg 260201e04c3fSmrg this->deref = nir_build_deref_array(&b, this->deref, index); 260301e04c3fSmrg} 260401e04c3fSmrg 260501e04c3fSmrgvoid 260601e04c3fSmrgnir_visitor::visit(ir_barrier *) 260701e04c3fSmrg{ 26087ec681f3Smrg if (shader->info.stage == MESA_SHADER_COMPUTE) 26097ec681f3Smrg nir_memory_barrier_shared(&b); 26107ec681f3Smrg else if (shader->info.stage == MESA_SHADER_TESS_CTRL) 26117ec681f3Smrg nir_memory_barrier_tcs_patch(&b); 26127ec681f3Smrg 26137ec681f3Smrg nir_control_barrier(&b); 261401e04c3fSmrg} 26157e102996Smaya 26167e102996Smayanir_shader * 26177e102996Smayaglsl_float64_funcs_to_nir(struct gl_context *ctx, 26187e102996Smaya const nir_shader_compiler_options *options) 26197e102996Smaya{ 26207ec681f3Smrg /* It's not possible to use float64 on GLSL ES, so don't bother trying to 26217ec681f3Smrg * build the support code. The support code depends on higher versions of 26227ec681f3Smrg * desktop GLSL, so it will fail to compile (below) anyway. 26237ec681f3Smrg */ 26247ec681f3Smrg if (!_mesa_is_desktop_gl(ctx) || ctx->Const.GLSLVersion < 400) 26257ec681f3Smrg return NULL; 26267ec681f3Smrg 26277e102996Smaya /* We pretend it's a vertex shader. Ultimately, the stage shouldn't 26287e102996Smaya * matter because we're not optimizing anything here. 26297e102996Smaya */ 26307e102996Smaya struct gl_shader *sh = _mesa_new_shader(-1, MESA_SHADER_VERTEX); 26317e102996Smaya sh->Source = float64_source; 26327e102996Smaya sh->CompileStatus = COMPILE_FAILURE; 26337e102996Smaya _mesa_glsl_compile_shader(ctx, sh, false, false, true); 26347e102996Smaya 26357e102996Smaya if (!sh->CompileStatus) { 26367e102996Smaya if (sh->InfoLog) { 26377e102996Smaya _mesa_problem(ctx, 26387e102996Smaya "fp64 software impl compile failed:\n%s\nsource:\n%s\n", 26397e102996Smaya sh->InfoLog, float64_source); 26407e102996Smaya } 26417e102996Smaya return NULL; 26427e102996Smaya } 26437e102996Smaya 26447e102996Smaya nir_shader *nir = nir_shader_create(NULL, MESA_SHADER_VERTEX, options, NULL); 26457e102996Smaya 26467e102996Smaya nir_visitor v1(ctx, nir); 26477e102996Smaya nir_function_visitor v2(&v1); 26487e102996Smaya v2.run(sh->ir); 26497e102996Smaya visit_exec_list(sh->ir, &v1); 26507e102996Smaya 26517e102996Smaya /* _mesa_delete_shader will try to free sh->Source but it's static const */ 26527e102996Smaya sh->Source = NULL; 26537e102996Smaya _mesa_delete_shader(ctx, sh); 26547e102996Smaya 26557e102996Smaya nir_validate_shader(nir, "float64_funcs_to_nir"); 26567e102996Smaya 26577ec681f3Smrg NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp); 26587e102996Smaya NIR_PASS_V(nir, nir_lower_returns); 26597e102996Smaya NIR_PASS_V(nir, nir_inline_functions); 26607e102996Smaya NIR_PASS_V(nir, nir_opt_deref); 26617e102996Smaya 26627ec681f3Smrg /* Do some optimizations to clean up the shader now. By optimizing the 26637ec681f3Smrg * functions in the library, we avoid having to re-do that work every 26647ec681f3Smrg * time we inline a copy of a function. Reducing basic blocks also helps 26657ec681f3Smrg * with compile times. 26667ec681f3Smrg */ 26677ec681f3Smrg NIR_PASS_V(nir, nir_lower_vars_to_ssa); 26687ec681f3Smrg NIR_PASS_V(nir, nir_copy_prop); 26697ec681f3Smrg NIR_PASS_V(nir, nir_opt_dce); 26707ec681f3Smrg NIR_PASS_V(nir, nir_opt_cse); 26717ec681f3Smrg NIR_PASS_V(nir, nir_opt_gcm, true); 26727ec681f3Smrg NIR_PASS_V(nir, nir_opt_peephole_select, 1, false, false); 26737ec681f3Smrg NIR_PASS_V(nir, nir_opt_dce); 26747ec681f3Smrg 26757e102996Smaya return nir; 26767e102996Smaya} 2677