[Mesa-dev] [PATCH 3/6] glsl_to_tgsi: allow bound samplers and images to be used as l-values

Rhys Perry pendingchaos02 at gmail.com
Wed Jun 6 19:55:05 UTC 2018


Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp       | 55 +++++++++++++++++++++++-
 src/mesa/state_tracker/st_glsl_to_tgsi_private.h |  1 +
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b321112cf8..7938753453 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -316,6 +316,7 @@ public:
                           st_src_reg *indirect,
                           unsigned *location);
    st_src_reg canonicalize_gather_offset(st_src_reg offset);
+   bool handle_bound_deref(ir_dereference *ir);
 
    bool try_emit_mad(ir_expression *ir,
               int mul_operand);
@@ -2439,10 +2440,15 @@ st_translate_interp_loc(ir_variable *var)
 void
 glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
 {
-   variable_storage *entry = find_variable_storage(ir->var);
+   variable_storage *entry;
    ir_variable *var = ir->var;
    bool remove_array;
 
+   if (handle_bound_deref(ir->as_dereference()))
+      return;
+
+   entry = find_variable_storage(ir->var);
+
    if (!entry) {
       switch (var->data.mode) {
       case ir_var_uniform:
@@ -2669,6 +2675,9 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
    bool is_2D = false;
    ir_variable *var = ir->variable_referenced();
 
+   if (handle_bound_deref(ir->as_dereference()))
+      return;
+
    /* We only need the logic provided by st_glsl_storage_type_size()
     * for arrays of structs. Indirect sampler and image indexing is handled
     * elsewhere.
@@ -2768,6 +2777,9 @@ glsl_to_tgsi_visitor::visit(ir_dereference_record *ir)
    ir_variable *var = ir->record->variable_referenced();
    int offset = 0;
 
+   if (handle_bound_deref(ir->as_dereference()))
+      return;
+
    ir->record->accept(this);
 
    assert(ir->field_idx >= 0);
@@ -4110,6 +4122,45 @@ glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
 
    return offset;
 }
+ 
+bool
+glsl_to_tgsi_visitor::handle_bound_deref(ir_dereference *ir)
+{
+   ir_variable *var = ir->variable_referenced();
+
+   if (!var || var->data.mode != ir_var_uniform || var->data.bindless ||
+       !(ir->type->is_image() || ir->type->is_sampler()))
+      return false;
+
+   //Convert from bound sampler/image to bindless handle
+   bool is_image = ir->type->is_image();
+   st_src_reg resource(is_image ? PROGRAM_IMAGE : PROGRAM_SAMPLER, 0, GLSL_TYPE_UINT);
+   uint16_t index = 0;
+   unsigned array_size = 1, base = 0;
+   st_src_reg reladdr;
+   get_deref_offsets(ir, &array_size, &base, &index, &reladdr, true);
+
+   resource.index = index;
+   if (reladdr.file != PROGRAM_UNDEFINED) {
+      resource.reladdr = ralloc(mem_ctx, st_src_reg);
+      *resource.reladdr = reladdr;
+      emit_arl(ir, sampler_reladdr, reladdr);
+   }
+
+   this->result = get_temp(glsl_type::uvec2_type);
+   st_dst_reg dst(this->result);
+   dst.writemask = WRITEMASK_XY;
+
+   glsl_to_tgsi_instruction *inst = emit_asm(
+      ir, is_image ? TGSI_OPCODE_IMG2HND : TGSI_OPCODE_SAMP2HND, dst);
+
+   inst->tex_target = ir->type->sampler_index();
+   inst->resource = resource;
+   inst->sampler_array_size = array_size;
+   inst->sampler_base = base;
+
+   return true;
+}
 
 void
 glsl_to_tgsi_visitor::visit(ir_texture *ir)
@@ -5904,6 +5955,7 @@ compile_tgsi_instruction(struct st_translate *t,
    case TGSI_OPCODE_TXL2:
    case TGSI_OPCODE_TG4:
    case TGSI_OPCODE_LODQ:
+   case TGSI_OPCODE_SAMP2HND:
       if (inst->resource.file == PROGRAM_SAMPLER) {
          src[num_src] = t->samplers[inst->resource.index];
       } else {
@@ -5942,6 +5994,7 @@ compile_tgsi_instruction(struct st_translate *t,
    case TGSI_OPCODE_ATOMUMAX:
    case TGSI_OPCODE_ATOMIMIN:
    case TGSI_OPCODE_ATOMIMAX:
+   case TGSI_OPCODE_IMG2HND:
       for (i = num_src - 1; i >= 0; i--)
          src[i + 1] = src[i];
       num_src++;
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi_private.h b/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
index c482828edd..fccb7041cf 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
@@ -179,6 +179,7 @@ is_resource_instruction(unsigned opcode)
    case TGSI_OPCODE_ATOMUMAX:
    case TGSI_OPCODE_ATOMIMIN:
    case TGSI_OPCODE_ATOMIMAX:
+   case TGSI_OPCODE_IMG2HND:
       return true;
    default:
       return false;
-- 
2.14.4



More information about the mesa-dev mailing list