glsl_to_tgsi: allow bound samplers and images to be used as l-values
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Signed-off-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
@@ -317,6 +317,7 @@ public:
|
|||||||
st_src_reg *indirect,
|
st_src_reg *indirect,
|
||||||
unsigned *location);
|
unsigned *location);
|
||||||
st_src_reg canonicalize_gather_offset(st_src_reg offset);
|
st_src_reg canonicalize_gather_offset(st_src_reg offset);
|
||||||
|
bool handle_bound_deref(ir_dereference *ir);
|
||||||
|
|
||||||
bool try_emit_mad(ir_expression *ir,
|
bool try_emit_mad(ir_expression *ir,
|
||||||
int mul_operand);
|
int mul_operand);
|
||||||
@@ -2440,10 +2441,15 @@ st_translate_interp_loc(ir_variable *var)
|
|||||||
void
|
void
|
||||||
glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
|
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;
|
ir_variable *var = ir->var;
|
||||||
bool remove_array;
|
bool remove_array;
|
||||||
|
|
||||||
|
if (handle_bound_deref(ir->as_dereference()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry = find_variable_storage(ir->var);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
switch (var->data.mode) {
|
switch (var->data.mode) {
|
||||||
case ir_var_uniform:
|
case ir_var_uniform:
|
||||||
@@ -2672,6 +2678,9 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
|
|||||||
bool is_2D = false;
|
bool is_2D = false;
|
||||||
ir_variable *var = ir->variable_referenced();
|
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()
|
/* We only need the logic provided by st_glsl_storage_type_size()
|
||||||
* for arrays of structs. Indirect sampler and image indexing is handled
|
* for arrays of structs. Indirect sampler and image indexing is handled
|
||||||
* elsewhere.
|
* elsewhere.
|
||||||
@@ -2771,6 +2780,9 @@ glsl_to_tgsi_visitor::visit(ir_dereference_record *ir)
|
|||||||
ir_variable *var = ir->record->variable_referenced();
|
ir_variable *var = ir->record->variable_referenced();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
|
if (handle_bound_deref(ir->as_dereference()))
|
||||||
|
return;
|
||||||
|
|
||||||
ir->record->accept(this);
|
ir->record->accept(this);
|
||||||
|
|
||||||
assert(ir->field_idx >= 0);
|
assert(ir->field_idx >= 0);
|
||||||
@@ -4116,6 +4128,45 @@ glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
|
|||||||
return 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
|
void
|
||||||
glsl_to_tgsi_visitor::visit(ir_texture *ir)
|
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_TXL2:
|
||||||
case TGSI_OPCODE_TG4:
|
case TGSI_OPCODE_TG4:
|
||||||
case TGSI_OPCODE_LODQ:
|
case TGSI_OPCODE_LODQ:
|
||||||
|
case TGSI_OPCODE_SAMP2HND:
|
||||||
if (inst->resource.file == PROGRAM_SAMPLER) {
|
if (inst->resource.file == PROGRAM_SAMPLER) {
|
||||||
src[num_src] = t->samplers[inst->resource.index];
|
src[num_src] = t->samplers[inst->resource.index];
|
||||||
} else {
|
} else {
|
||||||
@@ -5947,6 +5999,7 @@ compile_tgsi_instruction(struct st_translate *t,
|
|||||||
case TGSI_OPCODE_ATOMUMAX:
|
case TGSI_OPCODE_ATOMUMAX:
|
||||||
case TGSI_OPCODE_ATOMIMIN:
|
case TGSI_OPCODE_ATOMIMIN:
|
||||||
case TGSI_OPCODE_ATOMIMAX:
|
case TGSI_OPCODE_ATOMIMAX:
|
||||||
|
case TGSI_OPCODE_IMG2HND:
|
||||||
for (i = num_src - 1; i >= 0; i--)
|
for (i = num_src - 1; i >= 0; i--)
|
||||||
src[i + 1] = src[i];
|
src[i + 1] = src[i];
|
||||||
num_src++;
|
num_src++;
|
||||||
|
@@ -179,6 +179,7 @@ is_resource_instruction(unsigned opcode)
|
|||||||
case TGSI_OPCODE_ATOMUMAX:
|
case TGSI_OPCODE_ATOMUMAX:
|
||||||
case TGSI_OPCODE_ATOMIMIN:
|
case TGSI_OPCODE_ATOMIMIN:
|
||||||
case TGSI_OPCODE_ATOMIMAX:
|
case TGSI_OPCODE_ATOMIMAX:
|
||||||
|
case TGSI_OPCODE_IMG2HND:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
Reference in New Issue
Block a user