nir: add support for gather offsets
Values inside the offsets parameter of textureGatherOffsets are required to be constants in the range of [GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET]. As this range is never outside [-32, 31] for all existing drivers inside mesa, we can simply store the offsets as a int8_t[4][2] array inside nir_tex_instr. Right now only Nvidia hardware supports this in hardware, so we can turn this on inside Nouveau for the NIR path as it is already enabled with the TGSI one. v2: use memcpy instead of for loops add missing bits to nir_instr_set don't show offsets if they are all 0 v3: default offsets aren't all 0 v4: rename offsets -> tg4_offsets rename nir_tex_instr_has_explicit_offsets -> nir_tex_instr_has_explicit_tg4_offsets Signed-off-by: Karol Herbst <kherbst@redhat.com>
This commit is contained in:

committed by
Karol Herbst

parent
b95b33a5c7
commit
71c66c254b
@@ -2378,7 +2378,8 @@ nir_visitor::visit(ir_texture *ir)
|
||||
num_srcs++;
|
||||
if (ir->shadow_comparator != NULL)
|
||||
num_srcs++;
|
||||
if (ir->offset != NULL)
|
||||
/* offsets are constants we store inside nir_tex_intrs.offsets */
|
||||
if (ir->offset != NULL && !ir->offset->type->is_array())
|
||||
num_srcs++;
|
||||
|
||||
/* Add one for the texture deref */
|
||||
@@ -2439,7 +2440,18 @@ nir_visitor::visit(ir_texture *ir)
|
||||
}
|
||||
|
||||
if (ir->offset != NULL) {
|
||||
/* we don't support multiple offsets yet */
|
||||
if (ir->offset->type->is_array()) {
|
||||
for (int i = 0; i < ir->offset->type->array_size(); i++) {
|
||||
const ir_constant *c =
|
||||
ir->offset->as_constant()->get_array_element(i);
|
||||
|
||||
for (unsigned j = 0; j < 2; ++j) {
|
||||
int val = c->get_int_component(j);
|
||||
assert(val <= 31 && val >= -32);
|
||||
instr->tg4_offsets[i][j] = val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar());
|
||||
|
||||
instr->src[src_number].src =
|
||||
@@ -2447,6 +2459,7 @@ nir_visitor::visit(ir_texture *ir)
|
||||
instr->src[src_number].src_type = nir_tex_src_offset;
|
||||
src_number++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ir->op) {
|
||||
case ir_txb:
|
||||
|
@@ -531,6 +531,14 @@ nir_call_instr_create(nir_shader *shader, nir_function *callee)
|
||||
return instr;
|
||||
}
|
||||
|
||||
static int8_t default_tg4_offsets[4][2] =
|
||||
{
|
||||
{ 0, 1 },
|
||||
{ 1, 1 },
|
||||
{ 1, 0 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
nir_tex_instr *
|
||||
nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
|
||||
{
|
||||
@@ -547,6 +555,7 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
|
||||
instr->texture_index = 0;
|
||||
instr->texture_array_size = 0;
|
||||
instr->sampler_index = 0;
|
||||
memcpy(instr->tg4_offsets, default_tg4_offsets, sizeof(instr->tg4_offsets));
|
||||
|
||||
return instr;
|
||||
}
|
||||
@@ -589,6 +598,15 @@ nir_tex_instr_remove_src(nir_tex_instr *tex, unsigned src_idx)
|
||||
tex->num_srcs--;
|
||||
}
|
||||
|
||||
bool
|
||||
nir_tex_instr_has_explicit_tg4_offsets(nir_tex_instr *tex)
|
||||
{
|
||||
if (tex->op != nir_texop_tg4)
|
||||
return false;
|
||||
return memcmp(tex->tg4_offsets, default_tg4_offsets,
|
||||
sizeof(tex->tg4_offsets)) != 0;
|
||||
}
|
||||
|
||||
nir_phi_instr *
|
||||
nir_phi_instr_create(nir_shader *shader)
|
||||
{
|
||||
|
@@ -1482,6 +1482,9 @@ typedef struct {
|
||||
/* gather component selector */
|
||||
unsigned component : 2;
|
||||
|
||||
/* gather offsets */
|
||||
int8_t tg4_offsets[4][2];
|
||||
|
||||
/** The texture index
|
||||
*
|
||||
* If this texture instruction has a nir_tex_src_texture_offset source,
|
||||
@@ -1699,6 +1702,8 @@ void nir_tex_instr_add_src(nir_tex_instr *tex,
|
||||
|
||||
void nir_tex_instr_remove_src(nir_tex_instr *tex, unsigned src_idx);
|
||||
|
||||
bool nir_tex_instr_has_explicit_tg4_offsets(nir_tex_instr *tex);
|
||||
|
||||
typedef struct {
|
||||
nir_instr instr;
|
||||
|
||||
|
@@ -394,6 +394,7 @@ clone_tex(clone_state *state, const nir_tex_instr *tex)
|
||||
ntex->is_shadow = tex->is_shadow;
|
||||
ntex->is_new_style_shadow = tex->is_new_style_shadow;
|
||||
ntex->component = tex->component;
|
||||
memcpy(ntex->tg4_offsets, tex->tg4_offsets, sizeof(tex->tg4_offsets));
|
||||
|
||||
ntex->texture_index = tex->texture_index;
|
||||
ntex->texture_array_size = tex->texture_array_size;
|
||||
|
@@ -200,6 +200,9 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr)
|
||||
hash = HASH(hash, instr->is_new_style_shadow);
|
||||
unsigned component = instr->component;
|
||||
hash = HASH(hash, component);
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
for (unsigned j = 0; j < 2; ++j)
|
||||
hash = HASH(hash, instr->tg4_offsets[i][j]);
|
||||
hash = HASH(hash, instr->texture_index);
|
||||
hash = HASH(hash, instr->texture_array_size);
|
||||
hash = HASH(hash, instr->sampler_index);
|
||||
@@ -403,6 +406,10 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(tex1->tg4_offsets, tex2->tg4_offsets,
|
||||
sizeof(tex1->tg4_offsets)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
case nir_instr_type_load_const: {
|
||||
|
@@ -984,6 +984,14 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
|
||||
fprintf(fp, "%u (gather_component), ", instr->component);
|
||||
}
|
||||
|
||||
if (nir_tex_instr_has_explicit_tg4_offsets(instr)) {
|
||||
fprintf(fp, "{ (%i, %i)", instr->tg4_offsets[0][0], instr->tg4_offsets[0][1]);
|
||||
for (unsigned i = 1; i < 4; ++i)
|
||||
fprintf(fp, ", (%i, %i)", instr->tg4_offsets[i][0],
|
||||
instr->tg4_offsets[i][1]);
|
||||
fprintf(fp, " } (offsets), ");
|
||||
}
|
||||
|
||||
if (!has_texture_deref) {
|
||||
fprintf(fp, "%u (texture), ", instr->texture_index);
|
||||
}
|
||||
|
@@ -617,6 +617,7 @@ write_tex(write_ctx *ctx, const nir_tex_instr *tex)
|
||||
blob_write_uint32(ctx->blob, tex->texture_index);
|
||||
blob_write_uint32(ctx->blob, tex->texture_array_size);
|
||||
blob_write_uint32(ctx->blob, tex->sampler_index);
|
||||
blob_write_bytes(ctx->blob, tex->tg4_offsets, sizeof(tex->tg4_offsets));
|
||||
|
||||
STATIC_ASSERT(sizeof(union packed_tex_data) == sizeof(uint32_t));
|
||||
union packed_tex_data packed = {
|
||||
@@ -647,6 +648,7 @@ read_tex(read_ctx *ctx)
|
||||
tex->texture_index = blob_read_uint32(ctx->blob);
|
||||
tex->texture_array_size = blob_read_uint32(ctx->blob);
|
||||
tex->sampler_index = blob_read_uint32(ctx->blob);
|
||||
blob_copy_bytes(ctx->blob, tex->tg4_offsets, sizeof(tex->tg4_offsets));
|
||||
|
||||
union packed_tex_data packed;
|
||||
packed.u32 = blob_read_uint32(ctx->blob);
|
||||
|
@@ -598,6 +598,11 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
|
||||
0, nir_tex_instr_src_size(instr, i));
|
||||
}
|
||||
|
||||
if (nir_tex_instr_has_explicit_tg4_offsets(instr)) {
|
||||
validate_assert(state, instr->op == nir_texop_tg4);
|
||||
validate_assert(state, !src_type_seen[nir_tex_src_offset]);
|
||||
}
|
||||
|
||||
validate_dest(&instr->dest, state, 0, nir_tex_instr_dest_size(instr));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user