nir: Implement __intrinsic_store_ssbo
v2 (Connor): - Make the STORE() macro take arguments for the extra sources (and their size) and any extra indices required. Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
This commit is contained in:
parent
f17c6b9066
commit
9bb7d9ecf8
|
@ -649,6 +649,8 @@ nir_visitor::visit(ir_call *ir)
|
|||
op = nir_intrinsic_image_size;
|
||||
} else if (strcmp(ir->callee_name(), "__intrinsic_image_samples") == 0) {
|
||||
op = nir_intrinsic_image_samples;
|
||||
} else if (strcmp(ir->callee_name(), "__intrinsic_store_ssbo") == 0) {
|
||||
op = nir_intrinsic_store_ssbo;
|
||||
} else {
|
||||
unreachable("not reached");
|
||||
}
|
||||
|
@ -747,6 +749,40 @@ nir_visitor::visit(ir_call *ir)
|
|||
}
|
||||
case nir_intrinsic_memory_barrier:
|
||||
break;
|
||||
case nir_intrinsic_store_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();
|
||||
|
||||
param = param->get_next();
|
||||
ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
|
||||
|
||||
param = param->get_next();
|
||||
ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
|
||||
assert(write_mask);
|
||||
|
||||
/* Check if we need the indirect version */
|
||||
ir_constant *const_offset = offset->as_constant();
|
||||
if (!const_offset) {
|
||||
op = nir_intrinsic_store_ssbo_indirect;
|
||||
ralloc_free(instr);
|
||||
instr = nir_intrinsic_instr_create(shader, op);
|
||||
instr->src[2] = evaluate_rvalue(offset);
|
||||
instr->const_index[0] = 0;
|
||||
} else {
|
||||
instr->const_index[0] = const_offset->value.u[0];
|
||||
}
|
||||
|
||||
instr->const_index[1] = write_mask->value.u[0];
|
||||
|
||||
instr->src[0] = evaluate_rvalue(val);
|
||||
instr->num_components = val->type->vector_elements;
|
||||
|
||||
instr->src[1] = evaluate_rvalue(block);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
unreachable("not reached");
|
||||
}
|
||||
|
|
|
@ -205,15 +205,19 @@ LOAD(input, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
|
|||
/*
|
||||
* Stores work the same way as loads, except now the first register input is
|
||||
* the value or array to store and the optional second input is the indirect
|
||||
* offset.
|
||||
* offset. SSBO stores are similar, but they accept an extra source for the
|
||||
* block index and an extra index with the writemask to use.
|
||||
*/
|
||||
|
||||
#define STORE(name, num_indices, flags) \
|
||||
INTRINSIC(store_##name, 1, ARR(0), false, 0, 0, num_indices, flags) \
|
||||
INTRINSIC(store_##name##_indirect, 2, ARR(0, 1), false, 0, 0, \
|
||||
num_indices, flags) \
|
||||
#define STORE(name, extra_srcs, extra_srcs_size, extra_indices, flags) \
|
||||
INTRINSIC(store_##name, 1 + extra_srcs, \
|
||||
ARR(0, extra_srcs_size, extra_srcs_size, extra_srcs_size), \
|
||||
false, 0, 0, 1 + extra_indices, flags) \
|
||||
INTRINSIC(store_##name##_indirect, 2 + extra_srcs, \
|
||||
ARR(0, 1, extra_srcs_size, extra_srcs_size), \
|
||||
false, 0, 0, 1 + extra_indices, flags)
|
||||
|
||||
STORE(output, 1, 0)
|
||||
/* STORE(ssbo, 2, 0) */
|
||||
STORE(output, 0, 0, 0, 0)
|
||||
STORE(ssbo, 1, 1, 1, 0)
|
||||
|
||||
LAST_INTRINSIC(store_output_indirect)
|
||||
LAST_INTRINSIC(store_ssbo_indirect)
|
||||
|
|
Loading…
Reference in New Issue