#define CONST(x) CONST_VAL(ETNA_UNIFORM_CONSTANT, x)
#define UNIFORM(x) CONST_VAL(ETNA_UNIFORM_UNIFORM, x)
#define TEXSCALE(x, i) CONST_VAL(ETNA_UNIFORM_TEXRECT_SCALE_X + (i), x)
+#define TEXSIZE(x, i) CONST_VAL(ETNA_UNIFORM_TEXTURE_WIDTH + (i), x)
static int
const_add(uint64_t *c, uint64_t value)
return src_swizzle(const_src(c, values, 2), SWIZZLE(X,Y,X,X));
}
+ case nir_intrinsic_load_texture_size_etna: {
+ int sampler = nir_src_as_int(intr->src[0]);
+ nir_const_value values[] = {
+ TEXSIZE(sampler, 0),
+ TEXSIZE(sampler, 1),
+ TEXSIZE(sampler, 2),
+ };
+
+ return src_swizzle(const_src(c, values, 3), SWIZZLE(X,Y,Z,X));
+ }
default:
compile_error(c, "Unhandled NIR intrinsic type: %s\n",
nir_intrinsic_infos[intr->intrinsic].name);
case nir_intrinsic_load_input:
case nir_intrinsic_load_instance_id:
case nir_intrinsic_load_texture_scale:
+ case nir_intrinsic_load_texture_size_etna:
break;
default:
compile_error(c, "Unhandled NIR intrinsic type: %s\n",
return fui(1.0f / dim);
}
+static inline bool
+is_array_texture(enum pipe_texture_target target)
+{
+ switch (target) {
+ case PIPE_TEXTURE_1D_ARRAY:
+ case PIPE_TEXTURE_2D_ARRAY:
+ case PIPE_TEXTURE_CUBE_ARRAY:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint32_t
+get_texture_size(const struct etna_context *ctx, bool frag,
+ enum etna_uniform_contents contents, uint32_t data)
+{
+ unsigned index = get_const_idx(ctx, frag, data);
+ struct pipe_sampler_view *texture = ctx->sampler_view[index];
+
+ switch (contents) {
+ case ETNA_UNIFORM_TEXTURE_WIDTH:
+ if (texture->target == PIPE_BUFFER) {
+ return texture->u.buf.size / util_format_get_blocksize(texture->format);
+ } else {
+ return u_minify(texture->texture->width0, texture->u.tex.first_level);
+ }
+ case ETNA_UNIFORM_TEXTURE_HEIGHT:
+ return u_minify(texture->texture->height0, texture->u.tex.first_level);
+ case ETNA_UNIFORM_TEXTURE_DEPTH:
+ assert(texture->target != PIPE_BUFFER);
+
+ if (is_array_texture(texture->target)) {
+ if (texture->target != PIPE_TEXTURE_CUBE_ARRAY) {
+ return texture->texture->array_size;
+ } else {
+ assert(texture->texture->array_size % 6 == 0);
+ return texture->texture->array_size / 6;
+ }
+ }
+
+ return u_minify(texture->texture->depth0, texture->u.tex.first_level);
+ default:
+ unreachable("Bad texture size field");
+ }
+}
+
void
etna_uniforms_write(const struct etna_context *ctx,
const struct etna_shader_variant *sobj,
get_texrect_scale(ctx, frag, uinfo->contents[i], val));
break;
+ case ETNA_UNIFORM_TEXTURE_WIDTH:
+ case ETNA_UNIFORM_TEXTURE_HEIGHT:
+ case ETNA_UNIFORM_TEXTURE_DEPTH:
+ etna_cmd_stream_emit(stream,
+ get_texture_size(ctx, frag, uinfo->contents[i], val));
+ break;
+
case ETNA_UNIFORM_UBO0_ADDR ... ETNA_UNIFORM_UBOMAX_ADDR:
idx = uinfo->contents[i] - ETNA_UNIFORM_UBO0_ADDR;
etna_cmd_stream_reloc(stream, &(struct etna_reloc) {