summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorRhys Perry <[email protected]>2018-06-06 20:55:05 +0100
committerMarek Olšák <[email protected]>2018-08-01 00:10:00 -0400
commit42d4acb39dbdc11645a3a7e4f9d6f1ca080bcf04 (patch)
tree79ac1147adfc26c50467457c10de0b576e097722 /src/mesa
parent00589be6c42501779e609b6c1e89a14d8536df08 (diff)
glsl_to_tgsi: allow bound samplers and images to be used as l-values
Signed-off-by: Rhys Perry <[email protected]> Signed-off-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp55
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi_private.h1
2 files changed, 55 insertions, 1 deletions
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;