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 */
}
if (ir->offset != NULL) {
- /* we don't support multiple offsets yet */
- assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar());
+ 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 =
- nir_src_for_ssa(evaluate_rvalue(ir->offset));
- instr->src[src_number].src_type = nir_tex_src_offset;
- src_number++;
+ instr->src[src_number].src =
+ nir_src_for_ssa(evaluate_rvalue(ir->offset));
+ instr->src[src_number].src_type = nir_tex_src_offset;
+ src_number++;
+ }
}
switch (ir->op) {
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)
{
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;
}
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)
{
/* 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,
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;
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;
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);
return false;
}
+ if (memcmp(tex1->tg4_offsets, tex2->tg4_offsets,
+ sizeof(tex1->tg4_offsets)))
+ return false;
+
return true;
}
case nir_instr_type_load_const: {
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);
}
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 = {
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);
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));
}