[Mesa-dev] [PATCH 4/5] nir: Translate image load, store and atomic intrinsics from GLSL IR.
Francisco Jerez
currojerez at riseup.net
Fri May 8 07:30:46 PDT 2015
Connor Abbott <cwabbott0 at gmail.com> writes:
> On Tue, May 5, 2015 at 4:29 PM, Francisco Jerez <currojerez at riseup.net> wrote:
>> ---
>> src/glsl/nir/glsl_to_nir.cpp | 125 +++++++++++++++++++++++++++++++++++++++----
>> 1 file changed, 114 insertions(+), 11 deletions(-)
>>
>> diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp
>> index f6b8331..a01ab3b 100644
>> --- a/src/glsl/nir/glsl_to_nir.cpp
>> +++ b/src/glsl/nir/glsl_to_nir.cpp
>> @@ -614,27 +614,130 @@ nir_visitor::visit(ir_call *ir)
>> op = nir_intrinsic_atomic_counter_inc_var;
>> } else if (strcmp(ir->callee_name(), "__intrinsic_atomic_predecrement") == 0) {
>> op = nir_intrinsic_atomic_counter_dec_var;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_load") == 0) {
>> + op = nir_intrinsic_image_load;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_store") == 0) {
>> + op = nir_intrinsic_image_store;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_add") == 0) {
>> + op = nir_intrinsic_image_atomic_add;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_min") == 0) {
>> + op = nir_intrinsic_image_atomic_min;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_max") == 0) {
>> + op = nir_intrinsic_image_atomic_max;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_and") == 0) {
>> + op = nir_intrinsic_image_atomic_and;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_or") == 0) {
>> + op = nir_intrinsic_image_atomic_or;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_xor") == 0) {
>> + op = nir_intrinsic_image_atomic_xor;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_exchange") == 0) {
>> + op = nir_intrinsic_image_atomic_exchange;
>> + } else if (strcmp(ir->callee_name(), "__intrinsic_image_atomic_comp_swap") == 0) {
>> + op = nir_intrinsic_image_atomic_comp_swap;
>> } else {
>> unreachable("not reached");
>> }
>>
>> nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op);
>> - ir_dereference *param =
>> - (ir_dereference *) ir->actual_parameters.get_head();
>> - instr->variables[0] = evaluate_deref(&instr->instr, param);
>> - nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
>> +
>> + switch (op) {
>> + case nir_intrinsic_atomic_counter_read_var:
>> + case nir_intrinsic_atomic_counter_inc_var:
>> + case nir_intrinsic_atomic_counter_dec_var: {
>> + ir_dereference *param =
>> + (ir_dereference *) ir->actual_parameters.get_head();
>> + instr->variables[0] = evaluate_deref(&instr->instr, param);
>> + nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
>> + 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: {
>> + nir_load_const_instr *instr_zero = nir_load_const_instr_create(shader, 1);
>> + instr_zero->value.u[0] = 0;
>> + nir_instr_insert_after_cf_list(this->cf_node_list, &instr_zero->instr);
>> +
>> + /* Set the image variable dereference. */
>> + exec_node *param = ir->actual_parameters.get_head();
>> + ir_dereference *image = (ir_dereference *)param;
>> + const glsl_type *type =
>> + image->variable_referenced()->type->without_array();
>> +
>> + instr->variables[0] = evaluate_deref(&instr->instr, image);
>> + param = param->get_next();
>> +
>> + /* Set the address argument, extending the coordinate vector to four
>> + * components.
>> + */
>> + const nir_src src_addr = evaluate_rvalue((ir_dereference *)param);
>> + nir_alu_instr *instr_addr = nir_alu_instr_create(shader, nir_op_vec4);
>> + nir_ssa_dest_init(&instr_addr->instr, &instr_addr->dest.dest, 4, NULL);
>> +
>> + for (int i = 0; i < 4; i++) {
>> + if (i < type->coordinate_components()) {
>> + instr_addr->src[i].src = src_addr;
>> + instr_addr->src[i].swizzle[0] = i;
>> + } else {
>> + instr_addr->src[i].src = nir_src_for_ssa(&instr_zero->def);
>
> I think it would better convey the intent to create an ssa_undef_instr
> and use that here instead of zero. Unless something else relies on the
> extra coordinates being zeroed?
>
Yeah, that would work too. Zero makes some sense because an
n-dimensional image is largely equivalent to an n+1-dimensional image
with the last dimension equal to one. Some implementation
*cough*i965*cough* actually requires you to send a whole vec4 of
coordinates (in SIMD4x2 mode) no matter what dimensionality the surface
has, and the last component must be zero. That said, it doesn't really
matter for the back-end what we do here because the implementation
doesn't actually make use of this guarantee, and setting it to undefined
might be slightly beneficial for other reasons, so I don't personally
care.
If you want it to be undefined I'll also go update the intrinsic
documentation in PATCH 1.
>> + }
>> + }
>> +
>> + nir_instr_insert_after_cf_list(cf_node_list, &instr_addr->instr);
>> + instr->src[0] = nir_src_for_ssa(&instr_addr->dest.dest.ssa);
>> + param = param->get_next();
>> +
>> + /* Set the sample argument, which should be zero for single-sample
>> + * images.
>> + */
>> + if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) {
>> + instr->src[1] = evaluate_rvalue((ir_dereference *)param);
>> + param = param->get_next();
>> + } else {
>> + instr->src[1] = nir_src_for_ssa(&instr_zero->def);
>> + }
>> +
>> + /* Set the intrinsic parameters. */
>> + if (!param->is_tail_sentinel()) {
>> + instr->src[2] = evaluate_rvalue((ir_dereference *)param);
>> + param = param->get_next();
>> + }
>> +
>> + if (!param->is_tail_sentinel()) {
>> + instr->src[3] = evaluate_rvalue((ir_dereference *)param);
>> + param = param->get_next();
>> + }
>> +
>> + /* Set the intrinsic destination. */
>> + if (ir->return_deref)
>> + nir_ssa_dest_init(&instr->instr, &instr->dest,
>> + ir->return_deref->type->vector_elements, NULL);
>> + break;
>> + }
>> + default:
>> + unreachable("not reached");
>> + }
>>
>> nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
>>
>> - nir_intrinsic_instr *store_instr =
>> - nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
>> - store_instr->num_components = 1;
>> + if (ir->return_deref) {
>> + nir_intrinsic_instr *store_instr =
>> + nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
>> + store_instr->num_components = ir->return_deref->type->vector_elements;
>>
>> - store_instr->variables[0] = evaluate_deref(&store_instr->instr, ir->return_deref);
>> - store_instr->src[0].is_ssa = true;
>> - store_instr->src[0].ssa = &instr->dest.ssa;
>> + store_instr->variables[0] =
>> + evaluate_deref(&store_instr->instr, ir->return_deref);
>> + store_instr->src[0] = nir_src_for_ssa(&instr->dest.ssa);
>>
>> - nir_instr_insert_after_cf_list(this->cf_node_list, &store_instr->instr);
>> + nir_instr_insert_after_cf_list(this->cf_node_list,
>> + &store_instr->instr);
>> + }
>>
>> return;
>> }
>> --
>> 2.3.5
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 212 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150508/1a1a1355/attachment-0001.sig>
More information about the mesa-dev
mailing list