nir: Implement __intrinsic_load_ssbo
v2: - Fix ssbo loads with boolean variables. v3: - Simplify the changes (Kristian) Reviewed-by: Connor Abbott <connor.w.abbott@intel.com> Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
This commit is contained in:
parent
3e70c968de
commit
e59ae238b6
|
@ -651,6 +651,8 @@ nir_visitor::visit(ir_call *ir)
|
|||
op = nir_intrinsic_image_samples;
|
||||
} else if (strcmp(ir->callee_name(), "__intrinsic_store_ssbo") == 0) {
|
||||
op = nir_intrinsic_store_ssbo;
|
||||
} else if (strcmp(ir->callee_name(), "__intrinsic_load_ssbo") == 0) {
|
||||
op = nir_intrinsic_load_ssbo;
|
||||
} else {
|
||||
unreachable("not reached");
|
||||
}
|
||||
|
@ -791,6 +793,71 @@ nir_visitor::visit(ir_call *ir)
|
|||
nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_ssbo: {
|
||||
exec_node *param = ir->actual_parameters.get_head();
|
||||
ir_rvalue *block = ((ir_instruction *)param)->as_rvalue();
|
||||
|
||||
param = param->get_next();
|
||||
ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
|
||||
|
||||
/* Check if we need the indirect version */
|
||||
ir_constant *const_offset = offset->as_constant();
|
||||
if (!const_offset) {
|
||||
op = nir_intrinsic_load_ssbo_indirect;
|
||||
ralloc_free(instr);
|
||||
instr = nir_intrinsic_instr_create(shader, op);
|
||||
instr->src[1] = evaluate_rvalue(offset);
|
||||
instr->const_index[0] = 0;
|
||||
dest = &instr->dest;
|
||||
} else {
|
||||
instr->const_index[0] = const_offset->value.u[0];
|
||||
}
|
||||
|
||||
instr->src[0] = evaluate_rvalue(block);
|
||||
|
||||
const glsl_type *type = ir->return_deref->var->type;
|
||||
instr->num_components = type->vector_elements;
|
||||
|
||||
/* Setup destination register */
|
||||
nir_ssa_dest_init(&instr->instr, &instr->dest,
|
||||
type->vector_elements, NULL);
|
||||
|
||||
/* Insert the created nir instruction now since in the case of boolean
|
||||
* result we will need to emit another instruction after it
|
||||
*/
|
||||
nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
|
||||
|
||||
/*
|
||||
* In SSBO/UBO's, a true boolean value is any non-zero value, but we
|
||||
* consider a true boolean to be ~0. Fix this up with a != 0
|
||||
* comparison.
|
||||
*/
|
||||
if (type->base_type == GLSL_TYPE_BOOL) {
|
||||
nir_load_const_instr *const_zero =
|
||||
nir_load_const_instr_create(shader, 1);
|
||||
const_zero->value.u[0] = 0;
|
||||
nir_instr_insert_after_cf_list(this->cf_node_list,
|
||||
&const_zero->instr);
|
||||
|
||||
nir_alu_instr *load_ssbo_compare =
|
||||
nir_alu_instr_create(shader, nir_op_ine);
|
||||
load_ssbo_compare->src[0].src.is_ssa = true;
|
||||
load_ssbo_compare->src[0].src.ssa = &instr->dest.ssa;
|
||||
load_ssbo_compare->src[1].src.is_ssa = true;
|
||||
load_ssbo_compare->src[1].src.ssa = &const_zero->def;
|
||||
for (unsigned i = 0; i < type->vector_elements; i++)
|
||||
load_ssbo_compare->src[1].swizzle[i] = 0;
|
||||
nir_ssa_dest_init(&load_ssbo_compare->instr,
|
||||
&load_ssbo_compare->dest.dest,
|
||||
type->vector_elements, NULL);
|
||||
load_ssbo_compare->dest.write_mask = (1 << type->vector_elements) - 1;
|
||||
nir_instr_insert_after_cf_list(this->cf_node_list,
|
||||
&load_ssbo_compare->instr);
|
||||
dest = &load_ssbo_compare->dest.dest;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
unreachable("not reached");
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ SYSTEM_VALUE(user_clip_plane, 4, 1) /* const_index[0] is user_clip_plane[idx] */
|
|||
LOAD(uniform, 0, 2, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
|
||||
LOAD(ubo, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
|
||||
LOAD(input, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
|
||||
/* LOAD(ssbo, 1, 0) */
|
||||
LOAD(ssbo, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
|
||||
|
||||
/*
|
||||
* Stores work the same way as loads, except now the first register input is
|
||||
|
|
|
@ -94,6 +94,8 @@ is_phi_src_scalarizable(nir_phi_src *src,
|
|||
case nir_intrinsic_load_uniform_indirect:
|
||||
case nir_intrinsic_load_ubo:
|
||||
case nir_intrinsic_load_ubo_indirect:
|
||||
case nir_intrinsic_load_ssbo:
|
||||
case nir_intrinsic_load_ssbo_indirect:
|
||||
case nir_intrinsic_load_input:
|
||||
case nir_intrinsic_load_input_indirect:
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue