#include "compiler/nir/nir_control_flow.h"
#include "compiler/nir/nir_builder.h"
#include "main/imports.h"
+#include "main/mtypes.h"
/*
* pass to lower GLSL IR to NIR
} /* end of anonymous namespace */
+static void
+nir_remap_attributes(nir_shader *shader,
+ const nir_shader_compiler_options *options)
+{
+ if (options->vs_inputs_dual_locations) {
+ nir_foreach_variable(var, &shader->inputs) {
+ var->data.location +=
+ _mesa_bitcount_64(shader->info.vs.double_inputs &
+ BITFIELD64_MASK(var->data.location));
+ }
+ }
+
+ /* Once the remap is done, reset double_inputs_read, so later it will have
+ * which location/slots are doubles */
+ shader->info.vs.double_inputs = 0;
+}
+
nir_shader *
glsl_to_nir(const struct gl_shader_program *shader_prog,
gl_shader_stage stage,
nir_lower_constant_initializers(shader, (nir_variable_mode)~0);
- shader->info->name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name);
+ /* Remap the locations to slots so those requiring two slots will occupy
+ * two locations. For instance, if we have in the IR code a dvec3 attr0 in
+ * location 0 and vec4 attr1 in location 1, in NIR attr0 will use
+ * locations/slots 0 and 1, and attr1 will use location/slot 2 */
+ if (shader->info.stage == MESA_SHADER_VERTEX)
+ nir_remap_attributes(shader, options);
+
+ shader->info.name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name);
if (shader_prog->Label)
- shader->info->label = ralloc_strdup(shader, shader_prog->Label);
- shader->info->num_textures = util_last_bit(sh->Program->SamplersUsed);
- shader->info->clip_distance_array_size = sh->Program->ClipDistanceArraySize;
- shader->info->cull_distance_array_size = sh->Program->CullDistanceArraySize;
- shader->info->has_transform_feedback_varyings =
+ shader->info.label = ralloc_strdup(shader, shader_prog->Label);
+
+ /* Check for transform feedback varyings specified via the API */
+ shader->info.has_transform_feedback_varyings =
shader_prog->TransformFeedback.NumVarying > 0;
+ /* Check for transform feedback varyings specified in the Shader */
+ if (shader_prog->last_vert_prog)
+ shader->info.has_transform_feedback_varyings |=
+ shader_prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying > 0;
+
return shader;
}
if (ir == NULL)
return NULL;
- nir_constant *ret = ralloc(mem_ctx, nir_constant);
+ nir_constant *ret = rzalloc(mem_ctx, nir_constant);
const unsigned rows = ir->type->vector_elements;
const unsigned cols = ir->type->matrix_columns;
}
break;
- case GLSL_TYPE_BOOL:
+ case GLSL_TYPE_UINT64:
/* Only float base types can be matrices. */
assert(cols == 1);
for (unsigned r = 0; r < rows; r++)
- ret->values[0].u32[r] = ir->value.b[r] ? NIR_TRUE : NIR_FALSE;
+ ret->values[0].u64[r] = ir->value.u64[r];
+ break;
+ case GLSL_TYPE_INT64:
+ /* Only float base types can be matrices. */
+ assert(cols == 1);
+
+ for (unsigned r = 0; r < rows; r++)
+ ret->values[0].i64[r] = ir->value.i64[r];
break;
- case GLSL_TYPE_STRUCT:
- ret->elements = ralloc_array(mem_ctx, nir_constant *,
- ir->type->length);
- ret->num_elements = ir->type->length;
+ case GLSL_TYPE_BOOL:
+ /* Only float base types can be matrices. */
+ assert(cols == 1);
+
+ for (unsigned r = 0; r < rows; r++)
+ ret->values[0].u32[r] = ir->value.b[r] ? NIR_TRUE : NIR_FALSE;
- i = 0;
- foreach_in_list(ir_constant, field, &ir->components) {
- ret->elements[i] = constant_copy(field, mem_ctx);
- i++;
- }
break;
+ case GLSL_TYPE_STRUCT:
case GLSL_TYPE_ARRAY:
ret->elements = ralloc_array(mem_ctx, nir_constant *,
ir->type->length);
ret->num_elements = ir->type->length;
for (i = 0; i < ir->type->length; i++)
- ret->elements[i] = constant_copy(ir->array_elements[i], mem_ctx);
+ ret->elements[i] = constant_copy(ir->const_elements[i], mem_ctx);
break;
default:
void
nir_visitor::visit(ir_variable *ir)
{
- nir_variable *var = ralloc(shader, nir_variable);
+ /* TODO: In future we should switch to using the NIR lowering pass but for
+ * now just ignore these variables as GLSL IR should have lowered them.
+ * Anything remaining are just dead vars that weren't cleaned up.
+ */
+ if (ir->data.mode == ir_var_shader_shared)
+ return;
+
+ nir_variable *var = rzalloc(shader, nir_variable);
var->type = ir->type;
var->name = ralloc_strdup(var, ir->name);
+ var->data.always_active_io = ir->data.always_active_io;
var->data.read_only = ir->data.read_only;
var->data.centroid = ir->data.centroid;
var->data.sample = ir->data.sample;
var->data.patch = ir->data.patch;
var->data.invariant = ir->data.invariant;
var->data.location = ir->data.location;
+ var->data.stream = ir->data.stream;
+ var->data.compact = false;
switch(ir->data.mode) {
case ir_var_auto:
break;
case ir_var_shader_in:
- if (shader->stage == MESA_SHADER_FRAGMENT &&
+ if (shader->info.stage == MESA_SHADER_FRAGMENT &&
ir->data.location == VARYING_SLOT_FACE) {
/* For whatever reason, GLSL IR makes gl_FrontFacing an input */
var->data.location = SYSTEM_VALUE_FRONT_FACE;
var->data.mode = nir_var_system_value;
- } else if (shader->stage == MESA_SHADER_GEOMETRY &&
+ } else if (shader->info.stage == MESA_SHADER_GEOMETRY &&
ir->data.location == VARYING_SLOT_PRIMITIVE_ID) {
/* For whatever reason, GLSL IR makes gl_PrimitiveIDIn an input */
var->data.location = SYSTEM_VALUE_PRIMITIVE_ID;
var->data.mode = nir_var_system_value;
} else {
var->data.mode = nir_var_shader_in;
+
+ if (shader->info.stage == MESA_SHADER_TESS_EVAL &&
+ (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
+ ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) {
+ var->data.compact = ir->type->without_array()->is_scalar();
+ }
+ }
+
+ /* Mark all the locations that require two slots */
+ if (shader->info.stage == MESA_SHADER_VERTEX &&
+ glsl_type_is_dual_slot(glsl_without_array(var->type))) {
+ for (unsigned i = 0; i < glsl_count_attribute_slots(var->type, true); i++) {
+ uint64_t bitfield = BITFIELD64_BIT(var->data.location + i);
+ shader->info.vs.double_inputs |= bitfield;
+ }
}
break;
case ir_var_shader_out:
var->data.mode = nir_var_shader_out;
+ if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
+ (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
+ ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) {
+ var->data.compact = ir->type->without_array()->is_scalar();
+ }
break;
case ir_var_uniform:
var->data.interpolation = ir->data.interpolation;
var->data.origin_upper_left = ir->data.origin_upper_left;
var->data.pixel_center_integer = ir->data.pixel_center_integer;
- var->data.compact = false;
var->data.location_frac = ir->data.location_frac;
+ if (var->data.pixel_center_integer) {
+ assert(shader->info.stage == MESA_SHADER_FRAGMENT);
+ shader->info.fs.pixel_center_integer = true;
+ }
+
switch (ir->data.depth_layout) {
case ir_depth_layout_none:
var->data.depth_layout = nir_depth_layout_none;
}
var->data.index = ir->data.index;
+ var->data.descriptor_set = 0;
var->data.binding = ir->data.binding;
+ var->data.bindless = ir->data.bindless;
var->data.offset = ir->data.offset;
- var->data.image.read_only = ir->data.image_read_only;
- var->data.image.write_only = ir->data.image_write_only;
- var->data.image.coherent = ir->data.image_coherent;
- var->data.image._volatile = ir->data.image_volatile;
- var->data.image.restrict_flag = ir->data.image_restrict;
+ var->data.image.read_only = ir->data.memory_read_only;
+ var->data.image.write_only = ir->data.memory_write_only;
+ var->data.image.coherent = ir->data.memory_coherent;
+ var->data.image._volatile = ir->data.memory_volatile;
+ var->data.image.restrict_flag = ir->data.memory_restrict;
var->data.image.format = ir->data.image_format;
var->data.fb_fetch_output = ir->data.fb_fetch_output;
var->num_state_slots = ir->get_num_state_slots();
if (var->num_state_slots > 0) {
- var->state_slots = ralloc_array(var, nir_state_slot,
- var->num_state_slots);
+ var->state_slots = rzalloc_array(var, nir_state_slot,
+ var->num_state_slots);
ir_state_slot *state_slots = ir->get_state_slots();
for (unsigned i = 0; i < var->num_state_slots; i++) {
void
nir_visitor::visit(ir_loop *ir)
{
- nir_loop *loop = nir_loop_create(this->shader);
- nir_builder_cf_insert(&b, &loop->cf_node);
-
- b.cursor = nir_after_cf_list(&loop->body);
+ nir_push_loop(&b);
visit_exec_list(&ir->body_instructions, this);
- b.cursor = nir_after_cf_node(&loop->cf_node);
+ nir_pop_loop(&b, NULL);
}
void
nir_visitor::visit(ir_if *ir)
{
- nir_src condition =
- nir_src_for_ssa(evaluate_rvalue(ir->condition));
-
- nir_if *if_stmt = nir_if_create(this->shader);
- if_stmt->condition = condition;
- nir_builder_cf_insert(&b, &if_stmt->cf_node);
-
- b.cursor = nir_after_cf_list(&if_stmt->then_list);
+ nir_push_if(&b, evaluate_rvalue(ir->condition));
visit_exec_list(&ir->then_instructions, this);
-
- b.cursor = nir_after_cf_list(&if_stmt->else_list);
+ nir_push_else(&b, NULL);
visit_exec_list(&ir->else_instructions, this);
-
- b.cursor = nir_after_cf_node(&if_stmt->cf_node);
+ nir_pop_if(&b, NULL);
}
void
op = nir_intrinsic_atomic_counter_comp_swap_var;
break;
case ir_intrinsic_image_load:
- op = nir_intrinsic_image_load;
+ op = nir_intrinsic_image_var_load;
break;
case ir_intrinsic_image_store:
- op = nir_intrinsic_image_store;
+ op = nir_intrinsic_image_var_store;
break;
case ir_intrinsic_image_atomic_add:
- op = nir_intrinsic_image_atomic_add;
+ op = nir_intrinsic_image_var_atomic_add;
break;
case ir_intrinsic_image_atomic_min:
- op = nir_intrinsic_image_atomic_min;
+ op = nir_intrinsic_image_var_atomic_min;
break;
case ir_intrinsic_image_atomic_max:
- op = nir_intrinsic_image_atomic_max;
+ op = nir_intrinsic_image_var_atomic_max;
break;
case ir_intrinsic_image_atomic_and:
- op = nir_intrinsic_image_atomic_and;
+ op = nir_intrinsic_image_var_atomic_and;
break;
case ir_intrinsic_image_atomic_or:
- op = nir_intrinsic_image_atomic_or;
+ op = nir_intrinsic_image_var_atomic_or;
break;
case ir_intrinsic_image_atomic_xor:
- op = nir_intrinsic_image_atomic_xor;
+ op = nir_intrinsic_image_var_atomic_xor;
break;
case ir_intrinsic_image_atomic_exchange:
- op = nir_intrinsic_image_atomic_exchange;
+ op = nir_intrinsic_image_var_atomic_exchange;
break;
case ir_intrinsic_image_atomic_comp_swap:
- op = nir_intrinsic_image_atomic_comp_swap;
+ op = nir_intrinsic_image_var_atomic_comp_swap;
break;
case ir_intrinsic_memory_barrier:
op = nir_intrinsic_memory_barrier;
break;
case ir_intrinsic_image_size:
- op = nir_intrinsic_image_size;
+ op = nir_intrinsic_image_var_size;
break;
case ir_intrinsic_image_samples:
- op = nir_intrinsic_image_samples;
+ op = nir_intrinsic_image_var_samples;
break;
case ir_intrinsic_ssbo_store:
op = nir_intrinsic_store_ssbo;
case ir_intrinsic_shared_atomic_comp_swap:
op = nir_intrinsic_shared_atomic_comp_swap;
break;
+ case ir_intrinsic_vote_any:
+ op = nir_intrinsic_vote_any;
+ break;
+ case ir_intrinsic_vote_all:
+ op = nir_intrinsic_vote_all;
+ break;
+ case ir_intrinsic_vote_eq:
+ op = nir_intrinsic_vote_ieq;
+ break;
+ case ir_intrinsic_ballot:
+ op = nir_intrinsic_ballot;
+ break;
+ case ir_intrinsic_read_invocation:
+ op = nir_intrinsic_read_invocation;
+ break;
+ case ir_intrinsic_read_first_invocation:
+ op = nir_intrinsic_read_first_invocation;
+ break;
default:
unreachable("not reached");
}
nir_builder_instr_insert(&b, &instr->instr);
break;
}
- case nir_intrinsic_image_load:
- case nir_intrinsic_image_store:
- case nir_intrinsic_image_atomic_add:
- case nir_intrinsic_image_atomic_min:
- case nir_intrinsic_image_atomic_max:
- case nir_intrinsic_image_atomic_and:
- case nir_intrinsic_image_atomic_or:
- case nir_intrinsic_image_atomic_xor:
- case nir_intrinsic_image_atomic_exchange:
- case nir_intrinsic_image_atomic_comp_swap:
- case nir_intrinsic_image_samples:
- case nir_intrinsic_image_size: {
+ case nir_intrinsic_image_var_load:
+ case nir_intrinsic_image_var_store:
+ case nir_intrinsic_image_var_atomic_add:
+ case nir_intrinsic_image_var_atomic_min:
+ case nir_intrinsic_image_var_atomic_max:
+ case nir_intrinsic_image_var_atomic_and:
+ case nir_intrinsic_image_var_atomic_or:
+ case nir_intrinsic_image_var_atomic_xor:
+ case nir_intrinsic_image_var_atomic_exchange:
+ case nir_intrinsic_image_var_atomic_comp_swap:
+ case nir_intrinsic_image_var_samples:
+ case nir_intrinsic_image_var_size: {
nir_ssa_undef_instr *instr_undef =
nir_ssa_undef_instr_create(shader, 1, 32);
nir_builder_instr_insert(&b, &instr_undef->instr);
/* Set the intrinsic destination. */
if (ir->return_deref) {
- const nir_intrinsic_info *info =
- &nir_intrinsic_infos[instr->intrinsic];
+ unsigned num_components = ir->return_deref->type->vector_elements;
+ if (instr->intrinsic == nir_intrinsic_image_var_size)
+ instr->num_components = num_components;
nir_ssa_dest_init(&instr->instr, &instr->dest,
- info->dest_components, 32, NULL);
+ num_components, 32, NULL);
}
- if (op == nir_intrinsic_image_size ||
- op == nir_intrinsic_image_samples) {
+ if (op == nir_intrinsic_image_var_size ||
+ op == nir_intrinsic_image_var_samples) {
nir_builder_instr_insert(&b, &instr->instr);
break;
}
nir_builder_instr_insert(&b, &instr->instr);
break;
case nir_intrinsic_shader_clock:
- nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+ nir_ssa_dest_init(&instr->instr, &instr->dest, 2, 32, NULL);
+ instr->num_components = 2;
nir_builder_instr_insert(&b, &instr->instr);
break;
case nir_intrinsic_store_ssbo: {
* consider a true boolean to be ~0. Fix this up with a != 0
* comparison.
*/
- if (type->base_type == GLSL_TYPE_BOOL) {
+ if (type->is_boolean()) {
nir_alu_instr *load_ssbo_compare =
nir_alu_instr_create(shader, nir_op_ine);
load_ssbo_compare->src[0].src.is_ssa = true;
nir_builder_instr_insert(&b, &instr->instr);
break;
}
+ case nir_intrinsic_vote_any:
+ case nir_intrinsic_vote_all:
+ case nir_intrinsic_vote_ieq: {
+ nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+ instr->num_components = 1;
+
+ ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
+
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
+
+ case nir_intrinsic_ballot: {
+ nir_ssa_dest_init(&instr->instr, &instr->dest,
+ ir->return_deref->type->vector_elements, 64, NULL);
+ instr->num_components = ir->return_deref->type->vector_elements;
+
+ ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
+
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
+ case nir_intrinsic_read_invocation: {
+ nir_ssa_dest_init(&instr->instr, &instr->dest,
+ ir->return_deref->type->vector_elements, 32, NULL);
+ instr->num_components = ir->return_deref->type->vector_elements;
+
+ ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
+
+ ir_rvalue *invocation = (ir_rvalue *) ir->actual_parameters.get_head()->next;
+ instr->src[1] = nir_src_for_ssa(evaluate_rvalue(invocation));
+
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
+ case nir_intrinsic_read_first_invocation: {
+ nir_ssa_dest_init(&instr->instr, &instr->dest,
+ ir->return_deref->type->vector_elements, 32, NULL);
+ instr->num_components = ir->return_deref->type->vector_elements;
+
+ ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
+ instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
+
+ nir_builder_instr_insert(&b, &instr->instr);
+ break;
+ }
default:
unreachable("not reached");
}
copy->variables[1] = evaluate_deref(©->instr, ir->rhs);
if (ir->condition) {
- nir_if *if_stmt = nir_if_create(this->shader);
- if_stmt->condition = nir_src_for_ssa(evaluate_rvalue(ir->condition));
- nir_builder_cf_insert(&b, &if_stmt->cf_node);
- nir_instr_insert_after_cf_list(&if_stmt->then_list, ©->instr);
- b.cursor = nir_after_cf_node(&if_stmt->cf_node);
+ nir_push_if(&b, evaluate_rvalue(ir->condition));
+ nir_builder_instr_insert(&b, ©->instr);
+ nir_pop_if(&b, NULL);
} else {
nir_builder_instr_insert(&b, ©->instr);
}
store->src[0] = nir_src_for_ssa(src);
if (ir->condition) {
- nir_if *if_stmt = nir_if_create(this->shader);
- if_stmt->condition = nir_src_for_ssa(evaluate_rvalue(ir->condition));
- nir_builder_cf_insert(&b, &if_stmt->cf_node);
- nir_instr_insert_after_cf_list(&if_stmt->then_list, &store->instr);
- b.cursor = nir_after_cf_node(&if_stmt->cf_node);
+ nir_push_if(&b, evaluate_rvalue(ir->condition));
+ nir_builder_instr_insert(&b, &store->instr);
+ nir_pop_if(&b, NULL);
} else {
nir_builder_instr_insert(&b, &store->instr);
}
static bool
type_is_float(glsl_base_type type)
{
- return type == GLSL_TYPE_FLOAT || type == GLSL_TYPE_DOUBLE;
+ return type == GLSL_TYPE_FLOAT || type == GLSL_TYPE_DOUBLE ||
+ type == GLSL_TYPE_FLOAT16;
+}
+
+static bool
+type_is_signed(glsl_base_type type)
+{
+ return type == GLSL_TYPE_INT || type == GLSL_TYPE_INT64 ||
+ type == GLSL_TYPE_INT16;
}
void
* a true boolean to be ~0. Fix this up with a != 0 comparison.
*/
- if (ir->type->base_type == GLSL_TYPE_BOOL)
+ if (ir->type->is_boolean())
this->result = nir_ine(&b, &load->dest.ssa, nir_imm_int(&b, 0));
return;
}
nir_ssa_def *srcs[4];
- for (unsigned i = 0; i < ir->get_num_operands(); i++)
+ for (unsigned i = 0; i < ir->num_operands; i++)
srcs[i] = evaluate_rvalue(ir->operands[i]);
glsl_base_type types[4];
- for (unsigned i = 0; i < ir->get_num_operands(); i++)
+ for (unsigned i = 0; i < ir->num_operands; i++)
if (supports_ints)
types[i] = ir->operands[i]->type->base_type;
else
case ir_unop_exp2: result = nir_fexp2(&b, srcs[0]); break;
case ir_unop_log2: result = nir_flog2(&b, srcs[0]); break;
case ir_unop_i2f:
- result = supports_ints ? nir_i2f(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
+ result = supports_ints ? nir_i2f32(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
break;
case ir_unop_u2f:
- result = supports_ints ? nir_u2f(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
+ result = supports_ints ? nir_u2f32(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
break;
case ir_unop_b2f:
result = supports_ints ? nir_b2f(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
break;
- case ir_unop_f2i: result = nir_f2i(&b, srcs[0]); break;
- case ir_unop_f2u: result = nir_f2u(&b, srcs[0]); break;
- case ir_unop_f2b: result = nir_f2b(&b, srcs[0]); break;
- case ir_unop_i2b: result = nir_i2b(&b, srcs[0]); break;
- case ir_unop_b2i: result = nir_b2i(&b, srcs[0]); break;
- case ir_unop_d2f: result = nir_d2f(&b, srcs[0]); break;
- case ir_unop_f2d: result = nir_f2d(&b, srcs[0]); break;
- case ir_unop_d2i: result = nir_d2i(&b, srcs[0]); break;
- case ir_unop_d2u: result = nir_d2u(&b, srcs[0]); break;
- case ir_unop_d2b: result = nir_d2b(&b, srcs[0]); break;
+ case ir_unop_f2i:
+ case ir_unop_f2u:
+ case ir_unop_f2b:
+ case ir_unop_i2b:
+ case ir_unop_b2i:
+ case ir_unop_b2i64:
+ case ir_unop_d2f:
+ case ir_unop_f2d:
+ case ir_unop_d2i:
+ case ir_unop_d2u:
+ case ir_unop_d2b:
case ir_unop_i2d:
- assert(supports_ints);
- result = nir_i2d(&b, srcs[0]);
- break;
case ir_unop_u2d:
- assert(supports_ints);
- result = nir_u2d(&b, srcs[0]);
- break;
+ case ir_unop_i642i:
+ case ir_unop_i642u:
+ case ir_unop_i642f:
+ case ir_unop_i642b:
+ case ir_unop_i642d:
+ case ir_unop_u642i:
+ case ir_unop_u642u:
+ case ir_unop_u642f:
+ case ir_unop_u642d:
+ case ir_unop_i2i64:
+ case ir_unop_u2i64:
+ case ir_unop_f2i64:
+ case ir_unop_d2i64:
+ case ir_unop_i2u64:
+ case ir_unop_u2u64:
+ case ir_unop_f2u64:
+ case ir_unop_d2u64:
case ir_unop_i2u:
case ir_unop_u2i:
+ case ir_unop_i642u64:
+ case ir_unop_u642i64: {
+ nir_alu_type src_type = nir_get_nir_type_for_glsl_base_type(types[0]);
+ nir_alu_type dst_type = nir_get_nir_type_for_glsl_base_type(out_type);
+ result = nir_build_alu(&b, nir_type_conversion_op(src_type, dst_type,
+ nir_rounding_mode_undef),
+ srcs[0], NULL, NULL, NULL);
+ /* b2i and b2f don't have fixed bit-size versions so the builder will
+ * just assume 32 and we have to fix it up here.
+ */
+ result->bit_size = nir_alu_type_get_type_size(dst_type);
+ break;
+ }
+
case ir_unop_bitcast_i2f:
case ir_unop_bitcast_f2i:
case ir_unop_bitcast_u2f:
case ir_unop_bitcast_f2u:
+ case ir_unop_bitcast_i642d:
+ case ir_unop_bitcast_d2i64:
+ case ir_unop_bitcast_u642d:
+ case ir_unop_bitcast_d2u64:
case ir_unop_subroutine_to_int:
/* no-op */
result = nir_imov(&b, srcs[0]);
case ir_unop_ceil: result = nir_fceil(&b, srcs[0]); break;
case ir_unop_floor: result = nir_ffloor(&b, srcs[0]); break;
case ir_unop_fract: result = nir_ffract(&b, srcs[0]); break;
+ case ir_unop_frexp_exp: result = nir_frexp_exp(&b, srcs[0]); break;
+ case ir_unop_frexp_sig: result = nir_frexp_sig(&b, srcs[0]); break;
case ir_unop_round_even: result = nir_fround_even(&b, srcs[0]); break;
case ir_unop_sin: result = nir_fsin(&b, srcs[0]); break;
case ir_unop_cos: result = nir_fcos(&b, srcs[0]); break;
case ir_unop_unpack_half_2x16:
result = nir_unpack_half_2x16(&b, srcs[0]);
break;
+ case ir_unop_pack_sampler_2x32:
+ case ir_unop_pack_image_2x32:
case ir_unop_pack_double_2x32:
- result = nir_pack_double_2x32(&b, srcs[0]);
+ case ir_unop_pack_int_2x32:
+ case ir_unop_pack_uint_2x32:
+ result = nir_pack_64_2x32(&b, srcs[0]);
break;
+ case ir_unop_unpack_sampler_2x32:
+ case ir_unop_unpack_image_2x32:
case ir_unop_unpack_double_2x32:
- result = nir_unpack_double_2x32(&b, srcs[0]);
+ case ir_unop_unpack_int_2x32:
+ case ir_unop_unpack_uint_2x32:
+ result = nir_unpack_64_2x32(&b, srcs[0]);
break;
case ir_unop_bitfield_reverse:
result = nir_bitfield_reverse(&b, srcs[0]);
case ir_binop_div:
if (type_is_float(out_type))
result = nir_fdiv(&b, srcs[0], srcs[1]);
- else if (out_type == GLSL_TYPE_INT)
+ else if (type_is_signed(out_type))
result = nir_idiv(&b, srcs[0], srcs[1]);
else
result = nir_udiv(&b, srcs[0], srcs[1]);
case ir_binop_min:
if (type_is_float(out_type))
result = nir_fmin(&b, srcs[0], srcs[1]);
- else if (out_type == GLSL_TYPE_INT)
+ else if (type_is_signed(out_type))
result = nir_imin(&b, srcs[0], srcs[1]);
else
result = nir_umin(&b, srcs[0], srcs[1]);
case ir_binop_max:
if (type_is_float(out_type))
result = nir_fmax(&b, srcs[0], srcs[1]);
- else if (out_type == GLSL_TYPE_INT)
+ else if (type_is_signed(out_type))
result = nir_imax(&b, srcs[0], srcs[1]);
else
result = nir_umax(&b, srcs[0], srcs[1]);
break;
case ir_binop_lshift: result = nir_ishl(&b, srcs[0], srcs[1]); break;
case ir_binop_rshift:
- result = (out_type == GLSL_TYPE_INT) ? nir_ishr(&b, srcs[0], srcs[1])
- : nir_ushr(&b, srcs[0], srcs[1]);
+ result = (type_is_signed(out_type)) ? nir_ishr(&b, srcs[0], srcs[1])
+ : nir_ushr(&b, srcs[0], srcs[1]);
break;
case ir_binop_imul_high:
result = (out_type == GLSL_TYPE_INT) ? nir_imul_high(&b, srcs[0], srcs[1])
if (supports_ints) {
if (type_is_float(types[0]))
result = nir_flt(&b, srcs[0], srcs[1]);
- else if (types[0] == GLSL_TYPE_INT)
+ else if (type_is_signed(types[0]))
result = nir_ilt(&b, srcs[0], srcs[1]);
else
result = nir_ult(&b, srcs[0], srcs[1]);
result = nir_slt(&b, srcs[0], srcs[1]);
}
break;
- case ir_binop_greater:
- if (supports_ints) {
- if (type_is_float(types[0]))
- result = nir_flt(&b, srcs[1], srcs[0]);
- else if (types[0] == GLSL_TYPE_INT)
- result = nir_ilt(&b, srcs[1], srcs[0]);
- else
- result = nir_ult(&b, srcs[1], srcs[0]);
- } else {
- result = nir_slt(&b, srcs[1], srcs[0]);
- }
- break;
- case ir_binop_lequal:
- if (supports_ints) {
- if (type_is_float(types[0]))
- result = nir_fge(&b, srcs[1], srcs[0]);
- else if (types[0] == GLSL_TYPE_INT)
- result = nir_ige(&b, srcs[1], srcs[0]);
- else
- result = nir_uge(&b, srcs[1], srcs[0]);
- } else {
- result = nir_slt(&b, srcs[1], srcs[0]);
- }
- break;
case ir_binop_gequal:
if (supports_ints) {
if (type_is_float(types[0]))
result = nir_fge(&b, srcs[0], srcs[1]);
- else if (types[0] == GLSL_TYPE_INT)
+ else if (type_is_signed(types[0]))
result = nir_ige(&b, srcs[0], srcs[1]);
else
result = nir_uge(&b, srcs[0], srcs[1]);
{
ir->record->accept(this);
- int field_index = this->deref_tail->type->field_index(ir->field);
+ int field_index = ir->field_idx;
assert(field_index >= 0);
nir_deref_struct *deref = nir_deref_struct_create(this->deref_tail, field_index);