glsl: Add helperInvocationEXT() builtin
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Fri, 20 Sep 2019 17:50:37 +0000 (10:50 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 30 Sep 2019 19:44:30 +0000 (12:44 -0700)
From EXT_demote_to_helper_invocation, implemented with the existing
nir_intrinsic_is_helper_invocation.

Such builtin is necessary when using `demote` because we can't
redefine the value of gl_HelperInvocation (since it is an input
variable).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/compiler/glsl/builtin_functions.cpp
src/compiler/glsl/glsl_to_nir.cpp
src/compiler/glsl/ir.h
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index eef5737128d8f485990a52b8e2dc7a4ec049de8e..67ed936478ff14d48ccd04a789d9e7e6a07c0ee1 100644 (file)
@@ -819,6 +819,13 @@ shader_atomic_float_minmax(const _mesa_glsl_parse_state *state)
 {
    return state->INTEL_shader_atomic_float_minmax_enable;
 }
+
+static bool
+demote_to_helper_invocation(const _mesa_glsl_parse_state *state)
+{
+   return state->EXT_demote_to_helper_invocation_enable;
+}
+
 /** @} */
 
 /******************************************************************************/
@@ -1182,6 +1189,9 @@ private:
    ir_function_signature *_vote(const char *intrinsic_name,
                                 builtin_available_predicate avail);
 
+   ir_function_signature *_helper_invocation_intrinsic();
+   ir_function_signature *_helper_invocation();
+
 #undef B0
 #undef B1
 #undef B2
@@ -1491,6 +1501,8 @@ builtin_builder::create_intrinsics()
                 _read_first_invocation_intrinsic(glsl_type::uvec4_type),
                 NULL);
 
+   add_function("__intrinsic_helper_invocation",
+                _helper_invocation_intrinsic(), NULL);
 }
 
 /**
@@ -4230,6 +4242,8 @@ builtin_builder::create_builtins()
                 _vote("__intrinsic_vote_eq", v460_desktop),
                 NULL);
 
+   add_function("helperInvocationEXT", _helper_invocation(), NULL);
+
    add_function("__builtin_idiv64",
                 generate_ir::idiv64(mem_ctx, integer_functions_supported),
                 NULL);
@@ -7274,6 +7288,28 @@ builtin_builder::_vote(const char *intrinsic_name,
    return sig;
 }
 
+ir_function_signature *
+builtin_builder::_helper_invocation_intrinsic()
+{
+   MAKE_INTRINSIC(glsl_type::bool_type, ir_intrinsic_helper_invocation,
+                  demote_to_helper_invocation, 0);
+   return sig;
+}
+
+ir_function_signature *
+builtin_builder::_helper_invocation()
+{
+   MAKE_SIG(glsl_type::bool_type, demote_to_helper_invocation, 0);
+
+   ir_variable *retval = body.make_temp(glsl_type::bool_type, "retval");
+
+   body.emit(call(shader->symbols->get_function("__intrinsic_helper_invocation"),
+                  retval, sig->parameters));
+   body.emit(ret(retval));
+
+   return sig;
+}
+
 /** @} */
 
 /******************************************************************************/
index 883cfb57601300f79e311302ba097d21c86c7fb5..2238bf68044a5fdffa0654aa538790a31a772288 100644 (file)
@@ -1166,6 +1166,9 @@ nir_visitor::visit(ir_call *ir)
       case ir_intrinsic_read_first_invocation:
          op = nir_intrinsic_read_first_invocation;
          break;
+      case ir_intrinsic_helper_invocation:
+         op = nir_intrinsic_is_helper_invocation;
+         break;
       default:
          unreachable("not reached");
       }
@@ -1641,6 +1644,12 @@ nir_visitor::visit(ir_call *ir)
          nir_builder_instr_insert(&b, &instr->instr);
          break;
       }
+      case nir_intrinsic_is_helper_invocation: {
+         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL);
+         instr->num_components = 1;
+         nir_builder_instr_insert(&b, &instr->instr);
+         break;
+      }
       default:
          unreachable("not reached");
       }
index e3c28bbb2b8b277c1d7e3d66182ca073f40d74d2..ecf4b691472b06fb3364e355ebf296906d8a88c4 100644 (file)
@@ -1138,6 +1138,8 @@ enum ir_intrinsic_id {
    ir_intrinsic_read_invocation,
    ir_intrinsic_read_first_invocation,
 
+   ir_intrinsic_helper_invocation,
+
    ir_intrinsic_shared_load,
    ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
    ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared),
index b0afe2d23850dbf4174b5253bba1b4864a51ad6b..799c161cfaf62433cd5e7488d12473429bc3afca 100644 (file)
@@ -4120,6 +4120,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
    case ir_intrinsic_generic_atomic_comp_swap:
    case ir_intrinsic_begin_invocation_interlock:
    case ir_intrinsic_end_invocation_interlock:
+   case ir_intrinsic_helper_invocation:
       unreachable("Invalid intrinsic");
    }
 }