From: Rhys Perry Date: Wed, 6 Jun 2018 19:55:05 +0000 (+0100) Subject: glsl_to_tgsi: allow bound samplers and images to be used as l-values X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=42d4acb39dbdc11645a3a7e4f9d6f1ca080bcf04;p=mesa.git glsl_to_tgsi: allow bound samplers and images to be used as l-values Signed-off-by: Rhys Perry Signed-off-by: Marek Olšák --- diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 00799b4a872..73a8dc49a63 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -317,6 +317,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); @@ -2440,10 +2441,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: @@ -2672,6 +2678,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. @@ -2771,6 +2780,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); @@ -4115,6 +4127,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) @@ -5909,6 +5960,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 { @@ -5947,6 +5999,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 c482828eddb..fccb7041cfb 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;