return ret;
}
-static void
-emit_image(struct ntv_context *ctx, struct nir_variable *var)
+static SpvId
+get_bare_image_type(struct ntv_context *ctx, struct nir_variable *var, bool is_sampler)
{
const struct glsl_type *type = glsl_without_array(var->type);
bool is_ms;
- bool is_sampler = glsl_type_is_sampler(type);
if (var->data.fb_fetch_output) {
spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInputAttachment);
spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageCubeArray);
SpvId result_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
- SpvId image_type = spirv_builder_type_image(&ctx->builder, result_type,
+ return spirv_builder_type_image(&ctx->builder, result_type,
dimension, false,
arrayed,
is_ms, is_sampler ? 1 : 2,
get_image_format(ctx, var->data.image.format));
+}
+
+static SpvId
+get_image_type(struct ntv_context *ctx, struct nir_variable *var, bool is_sampler)
+{
+ SpvId image_type = get_bare_image_type(ctx, var, is_sampler);
+ return is_sampler ? spirv_builder_type_sampled_image(&ctx->builder, image_type) : image_type;
+}
+
+static SpvId
+emit_image(struct ntv_context *ctx, struct nir_variable *var, bool bindless)
+{
+ if (var->data.bindless)
+ return 0;
+ const struct glsl_type *type = glsl_without_array(var->type);
+ bool is_sampler = glsl_type_is_sampler(type);
+ SpvId image_type = get_bare_image_type(ctx, var, is_sampler);
SpvId var_type = is_sampler ? spirv_builder_type_sampled_image(&ctx->builder, image_type) : image_type;
int index = var->data.driver_location;
assert(!is_sampler || !ctx->sampler_types[index]);
assert(is_sampler || !ctx->image_types[index]);
- if (glsl_type_is_array(var->type)) {
+ if (!bindless && glsl_type_is_array(var->type)) {
var_type = spirv_builder_type_array(&ctx->builder, var_type,
emit_uint_const(ctx, 32, glsl_get_aoa_size(var->type)));
spirv_builder_emit_array_stride(&ctx->builder, var_type, sizeof(void*));
if (var->data.fb_fetch_output)
spirv_builder_emit_input_attachment_index(&ctx->builder, var_id, var->data.index);
+ if (bindless)
+ return var_id;
+
+ _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
if (is_sampler) {
ctx->sampler_types[index] = image_type;
ctx->samplers[index] = var_id;
} else {
ctx->image_types[index] = image_type;
ctx->images[index] = var_id;
- _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
*key = var_id;
_mesa_hash_table_insert(ctx->image_vars, key, var);
spirv_builder_emit_descriptor_set(&ctx->builder, var_id, var->data.descriptor_set);
spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+ return var_id;
}
static SpvId
assert(var->data.mode == nir_var_uniform);
const struct glsl_type *type = glsl_without_array(var->type);
if (glsl_type_is_sampler(type) || glsl_type_is_image(type))
- emit_image(ctx, var);
+ emit_image(ctx, var, false);
}
}
{
SpvId ptr = get_src(ctx, intr->src);
+ nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+ SpvId type;
+ if (glsl_type_is_image(deref->type)) {
+ nir_variable *var = nir_deref_instr_get_variable(deref);
+ type = get_image_type(ctx, var, glsl_type_is_sampler(glsl_without_array(var->type)));
+ } else {
+ type = get_glsl_type(ctx, deref->type);
+ }
SpvId result = spirv_builder_emit_load(&ctx->builder,
- get_glsl_type(ctx, nir_src_as_deref(intr->src[0])->type),
+ type,
ptr);
unsigned num_components = nir_dest_num_components(intr->dest);
unsigned bit_size = nir_dest_bit_size(intr->dest);
emit_image_deref_store(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
SpvId img_var = get_src(ctx, &intr->src[0]);
- nir_variable *var = get_var_from_image(ctx, img_var);
- SpvId img_type = ctx->image_types[var->data.driver_location];
+ nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+ nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
+ SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
const struct glsl_type *type = glsl_without_array(var->type);
SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
emit_image_deref_load(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
SpvId img_var = get_src(ctx, &intr->src[0]);
- nir_variable *var = get_var_from_image(ctx, img_var);
- SpvId img_type = ctx->image_types[var->data.driver_location];
+ nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+ nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
+ SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
const struct glsl_type *type = glsl_without_array(var->type);
SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
emit_image_deref_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
SpvId img_var = get_src(ctx, &intr->src[0]);
- nir_variable *var = get_var_from_image(ctx, img_var);
- SpvId img_type = ctx->image_types[var->data.driver_location];
+ nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+ nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
+ SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
const struct glsl_type *type = glsl_without_array(var->type);
SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
SpvId result = spirv_builder_emit_image_query_size(&ctx->builder, get_uvec_type(ctx, 32, glsl_get_sampler_coordinate_components(type)), img, 0);
emit_image_deref_samples(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
SpvId img_var = get_src(ctx, &intr->src[0]);
- nir_variable *var = get_var_from_image(ctx, img_var);
- SpvId img_type = ctx->image_types[var->data.driver_location];
+ nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+ nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
+ SpvId img_type = var->data.bindless ? get_bare_image_type(ctx, var, false) : ctx->image_types[var->data.driver_location];
SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples, get_dest_type(ctx, &intr->dest, nir_type_uint), img);
store_dest(ctx, &intr->dest, result, nir_type_uint);
static void
emit_image_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
{
- SpvId img_var = get_src(ctx, &intr->src[0]);
SpvId param = get_src(ctx, &intr->src[3]);
- nir_variable *var = get_var_from_image(ctx, img_var);
+ SpvId img_var = get_src(ctx, &intr->src[0]);
+ nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
+ nir_variable *var = deref->deref_type == nir_deref_type_var ? deref->var : get_var_from_image(ctx, img_var);
const struct glsl_type *type = glsl_without_array(var->type);
bool is_ms;
type_to_dim(glsl_get_sampler_dim(type), &is_ms);
assert(tex->texture_index == tex->sampler_index);
SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0,
- const_offset = 0, offset = 0, sample = 0, tex_offset = 0;
+ const_offset = 0, offset = 0, sample = 0, tex_offset = 0, bindless = 0;
unsigned coord_components = 0;
+ nir_variable *bindless_var = NULL;
for (unsigned i = 0; i < tex->num_srcs; i++) {
nir_const_value *cv;
switch (tex->src[i].src_type) {
break;
case nir_tex_src_sampler_offset:
+ case nir_tex_src_sampler_handle:
/* don't care */
break;
+ case nir_tex_src_texture_handle:
+ bindless = get_src(ctx, &tex->src[i].src);
+ bindless_var = nir_deref_instr_get_variable(nir_src_as_deref(tex->src[i].src));
+ break;
+
default:
fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
unreachable("unknown texture source");
}
}
}
- SpvId image_type = ctx->sampler_types[texture_index];
+ SpvId image_type = bindless ? get_bare_image_type(ctx, bindless_var, true) : ctx->sampler_types[texture_index];
assert(image_type);
SpvId sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
image_type);
assert(sampled_type);
- assert(ctx->samplers_used & (1u << texture_index));
- SpvId sampler_id = ctx->samplers[texture_index];
+ assert(bindless || ctx->samplers_used & (1u << texture_index));
+ SpvId sampler_id = bindless ? bindless : ctx->samplers[texture_index];
if (tex_offset) {
SpvId ptr = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassUniformConstant, sampled_type);
sampler_id = spirv_builder_emit_access_chain(&ctx->builder, ptr, sampler_id, &tex_offset, 1);
break;
case nir_var_uniform: {
- assert(glsl_type_is_image(glsl_without_array(var->type)));
struct hash_entry *he = _mesa_hash_table_search(ctx->vars, var);
assert(he);
base = (SpvId)(intptr_t)he->data;
- type = ctx->image_types[var->data.driver_location];
+ type = get_image_type(ctx, var, glsl_type_is_sampler(glsl_without_array(var->type)));
break;
}