zink: use descriptor indices in compiler

should be no functional changes, just adding indirection

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16645>
This commit is contained in:
Mike Blumenkrantz 2022-05-16 16:56:11 -04:00 committed by Marge Bot
parent f7eb871efa
commit fe2ba184d8

View file

@ -1695,30 +1695,35 @@ analyze_io(struct zink_shader *zs, nir_shader *shader)
return ret; return ret;
} }
struct zink_bindless_info {
nir_variable *bindless[4];
unsigned bindless_set;
};
/* this is a "default" bindless texture used if the shader has no texture variables */ /* this is a "default" bindless texture used if the shader has no texture variables */
static nir_variable * static nir_variable *
create_bindless_texture(nir_shader *nir, nir_tex_instr *tex) create_bindless_texture(nir_shader *nir, nir_tex_instr *tex, unsigned descriptor_set)
{ {
unsigned binding = tex->sampler_dim == GLSL_SAMPLER_DIM_BUF ? 1 : 0; unsigned binding = tex->sampler_dim == GLSL_SAMPLER_DIM_BUF ? 1 : 0;
nir_variable *var; nir_variable *var;
const struct glsl_type *sampler_type = glsl_sampler_type(tex->sampler_dim, tex->is_shadow, tex->is_array, GLSL_TYPE_FLOAT); const struct glsl_type *sampler_type = glsl_sampler_type(tex->sampler_dim, tex->is_shadow, tex->is_array, GLSL_TYPE_FLOAT);
var = nir_variable_create(nir, nir_var_uniform, glsl_array_type(sampler_type, ZINK_MAX_BINDLESS_HANDLES, 0), "bindless_texture"); var = nir_variable_create(nir, nir_var_uniform, glsl_array_type(sampler_type, ZINK_MAX_BINDLESS_HANDLES, 0), "bindless_texture");
var->data.descriptor_set = ZINK_DESCRIPTOR_BINDLESS; var->data.descriptor_set = descriptor_set;
var->data.driver_location = var->data.binding = binding; var->data.driver_location = var->data.binding = binding;
return var; return var;
} }
/* this is a "default" bindless image used if the shader has no image variables */ /* this is a "default" bindless image used if the shader has no image variables */
static nir_variable * static nir_variable *
create_bindless_image(nir_shader *nir, enum glsl_sampler_dim dim) create_bindless_image(nir_shader *nir, enum glsl_sampler_dim dim, unsigned descriptor_set)
{ {
unsigned binding = dim == GLSL_SAMPLER_DIM_BUF ? 3 : 2; unsigned binding = dim == GLSL_SAMPLER_DIM_BUF ? 3 : 2;
nir_variable *var; nir_variable *var;
const struct glsl_type *image_type = glsl_image_type(dim, false, GLSL_TYPE_FLOAT); const struct glsl_type *image_type = glsl_image_type(dim, false, GLSL_TYPE_FLOAT);
var = nir_variable_create(nir, nir_var_image, glsl_array_type(image_type, ZINK_MAX_BINDLESS_HANDLES, 0), "bindless_image"); var = nir_variable_create(nir, nir_var_image, glsl_array_type(image_type, ZINK_MAX_BINDLESS_HANDLES, 0), "bindless_image");
var->data.descriptor_set = ZINK_DESCRIPTOR_BINDLESS; var->data.descriptor_set = descriptor_set;
var->data.driver_location = var->data.binding = binding; var->data.driver_location = var->data.binding = binding;
var->data.image.format = PIPE_FORMAT_R8G8B8A8_UNORM; var->data.image.format = PIPE_FORMAT_R8G8B8A8_UNORM;
return var; return var;
@ -1728,7 +1733,7 @@ create_bindless_image(nir_shader *nir, enum glsl_sampler_dim dim)
static bool static bool
lower_bindless_instr(nir_builder *b, nir_instr *in, void *data) lower_bindless_instr(nir_builder *b, nir_instr *in, void *data)
{ {
nir_variable **bindless = data; struct zink_bindless_info *bindless = data;
if (in->type == nir_instr_type_tex) { if (in->type == nir_instr_type_tex) {
nir_tex_instr *tex = nir_instr_as_tex(in); nir_tex_instr *tex = nir_instr_as_tex(in);
@ -1736,9 +1741,9 @@ lower_bindless_instr(nir_builder *b, nir_instr *in, void *data)
if (idx == -1) if (idx == -1)
return false; return false;
nir_variable *var = tex->sampler_dim == GLSL_SAMPLER_DIM_BUF ? bindless[1] : bindless[0]; nir_variable *var = tex->sampler_dim == GLSL_SAMPLER_DIM_BUF ? bindless->bindless[1] : bindless->bindless[0];
if (!var) if (!var)
var = create_bindless_texture(b->shader, tex); var = create_bindless_texture(b->shader, tex, bindless->bindless_set);
b->cursor = nir_before_instr(in); b->cursor = nir_before_instr(in);
nir_deref_instr *deref = nir_build_deref_var(b, var); nir_deref_instr *deref = nir_build_deref_var(b, var);
if (glsl_type_is_array(var->type)) if (glsl_type_is_array(var->type))
@ -1802,9 +1807,9 @@ lower_bindless_instr(nir_builder *b, nir_instr *in, void *data)
} }
enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr); enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
nir_variable *var = dim == GLSL_SAMPLER_DIM_BUF ? bindless[3] : bindless[2]; nir_variable *var = dim == GLSL_SAMPLER_DIM_BUF ? bindless->bindless[3] : bindless->bindless[2];
if (!var) if (!var)
var = create_bindless_image(b->shader, dim); var = create_bindless_image(b->shader, dim, bindless->bindless_set);
instr->intrinsic = op; instr->intrinsic = op;
b->cursor = nir_before_instr(in); b->cursor = nir_before_instr(in);
nir_deref_instr *deref = nir_build_deref_var(b, var); nir_deref_instr *deref = nir_build_deref_var(b, var);
@ -1815,7 +1820,7 @@ lower_bindless_instr(nir_builder *b, nir_instr *in, void *data)
} }
static bool static bool
lower_bindless(nir_shader *shader, nir_variable **bindless) lower_bindless(nir_shader *shader, struct zink_bindless_info *bindless)
{ {
if (!nir_shader_instructions_pass(shader, lower_bindless_instr, nir_metadata_dominance, bindless)) if (!nir_shader_instructions_pass(shader, lower_bindless_instr, nir_metadata_dominance, bindless))
return false; return false;
@ -1868,7 +1873,7 @@ lower_bindless_io(nir_shader *shader)
} }
static uint32_t static uint32_t
zink_binding(gl_shader_stage stage, VkDescriptorType type, int index) zink_binding(gl_shader_stage stage, VkDescriptorType type, int index, bool compact_descriptors)
{ {
if (stage == MESA_SHADER_NONE) { if (stage == MESA_SHADER_NONE) {
unreachable("not supported"); unreachable("not supported");
@ -1884,12 +1889,12 @@ zink_binding(gl_shader_stage stage, VkDescriptorType type, int index)
return (stage * PIPE_MAX_SAMPLERS) + index; return (stage * PIPE_MAX_SAMPLERS) + index;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
return stage; return stage + (compact_descriptors * (ZINK_SHADER_COUNT * 2));
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
assert(index < ZINK_MAX_SHADER_IMAGES); assert(index < ZINK_MAX_SHADER_IMAGES);
return (stage * ZINK_MAX_SHADER_IMAGES) + index; return (stage * ZINK_MAX_SHADER_IMAGES) + index + (compact_descriptors * (ZINK_SHADER_COUNT * PIPE_MAX_SAMPLERS));
default: default:
unreachable("unexpected type"); unreachable("unexpected type");
@ -1898,7 +1903,7 @@ zink_binding(gl_shader_stage stage, VkDescriptorType type, int index)
} }
static void static void
handle_bindless_var(nir_shader *nir, nir_variable *var, const struct glsl_type *type, nir_variable **bindless) handle_bindless_var(nir_shader *nir, nir_variable *var, const struct glsl_type *type, struct zink_bindless_info *bindless)
{ {
if (glsl_type_is_struct(type)) { if (glsl_type_is_struct(type)) {
for (unsigned i = 0; i < glsl_get_length(type); i++) for (unsigned i = 0; i < glsl_get_length(type); i++)
@ -1928,17 +1933,17 @@ handle_bindless_var(nir_shader *nir, nir_variable *var, const struct glsl_type *
default: default:
unreachable("unknown"); unreachable("unknown");
} }
if (!bindless[binding]) { if (!bindless->bindless[binding]) {
bindless[binding] = nir_variable_clone(var, nir); bindless->bindless[binding] = nir_variable_clone(var, nir);
bindless[binding]->data.bindless = 0; bindless->bindless[binding]->data.bindless = 0;
bindless[binding]->data.descriptor_set = ZINK_DESCRIPTOR_BINDLESS; bindless->bindless[binding]->data.descriptor_set = bindless->bindless_set;
bindless[binding]->type = glsl_array_type(type, ZINK_MAX_BINDLESS_HANDLES, 0); bindless->bindless[binding]->type = glsl_array_type(type, ZINK_MAX_BINDLESS_HANDLES, 0);
bindless[binding]->data.driver_location = bindless[binding]->data.binding = binding; bindless->bindless[binding]->data.driver_location = bindless->bindless[binding]->data.binding = binding;
if (!bindless[binding]->data.image.format) if (!bindless->bindless[binding]->data.image.format)
bindless[binding]->data.image.format = PIPE_FORMAT_R8G8B8A8_UNORM; bindless->bindless[binding]->data.image.format = PIPE_FORMAT_R8G8B8A8_UNORM;
nir_shader_add_variable(nir, bindless[binding]); nir_shader_add_variable(nir, bindless->bindless[binding]);
} else { } else {
assert(glsl_get_sampler_dim(glsl_without_array(bindless[binding]->type)) == glsl_get_sampler_dim(glsl_without_array(var->type))); assert(glsl_get_sampler_dim(glsl_without_array(bindless->bindless[binding]->type)) == glsl_get_sampler_dim(glsl_without_array(var->type)));
} }
var->data.mode = nir_var_shader_temp; var->data.mode = nir_var_shader_temp;
} }
@ -2222,7 +2227,8 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
fprintf(stderr, "---8<---\n"); fprintf(stderr, "---8<---\n");
} }
nir_variable *bindless[4] = {0}; struct zink_bindless_info bindless = {0};
bindless.bindless_set = screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS];
bool has_bindless_io = false; bool has_bindless_io = false;
nir_foreach_variable_with_modes(var, nir, nir_var_shader_in | nir_var_shader_out) { nir_foreach_variable_with_modes(var, nir, nir_var_shader_in | nir_var_shader_out) {
if (glsl_type_is_image(var->type) || glsl_type_is_sampler(var->type)) { if (glsl_type_is_image(var->type) || glsl_type_is_sampler(var->type)) {
@ -2252,7 +2258,8 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
var->data.binding = !var->data.driver_location ? nir->info.stage : var->data.binding = !var->data.driver_location ? nir->info.stage :
zink_binding(nir->info.stage, zink_binding(nir->info.stage,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
var->data.driver_location); var->data.driver_location,
screen->compact_descriptors);
assert(var->data.driver_location || var->data.binding < 10); assert(var->data.driver_location || var->data.binding < 10);
VkDescriptorType vktype = !var->data.driver_location ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; VkDescriptorType vktype = !var->data.driver_location ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
int binding = var->data.binding; int binding = var->data.binding;
@ -2265,10 +2272,11 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
ret->num_bindings[ztype]++; ret->num_bindings[ztype]++;
} else if (var->data.mode == nir_var_mem_ssbo) { } else if (var->data.mode == nir_var_mem_ssbo) {
ztype = ZINK_DESCRIPTOR_TYPE_SSBO; ztype = ZINK_DESCRIPTOR_TYPE_SSBO;
var->data.descriptor_set = ztype + 1; var->data.descriptor_set = screen->desc_set_id[ztype];
var->data.binding = zink_binding(nir->info.stage, var->data.binding = zink_binding(nir->info.stage,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
var->data.driver_location); var->data.driver_location,
screen->compact_descriptors);
ret->bindings[ztype][ret->num_bindings[ztype]].index = var->data.driver_location; ret->bindings[ztype][ret->num_bindings[ztype]].index = var->data.driver_location;
ret->bindings[ztype][ret->num_bindings[ztype]].binding = var->data.binding; ret->bindings[ztype][ret->num_bindings[ztype]].binding = var->data.binding;
ret->bindings[ztype][ret->num_bindings[ztype]].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; ret->bindings[ztype][ret->num_bindings[ztype]].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
@ -2280,15 +2288,15 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
var->data.mode == nir_var_image); var->data.mode == nir_var_image);
if (var->data.bindless) { if (var->data.bindless) {
ret->bindless = true; ret->bindless = true;
handle_bindless_var(nir, var, type, bindless); handle_bindless_var(nir, var, type, &bindless);
} else if (glsl_type_is_sampler(type) || glsl_type_is_image(type)) { } else if (glsl_type_is_sampler(type) || glsl_type_is_image(type)) {
VkDescriptorType vktype = glsl_type_is_image(type) ? zink_image_type(type) : zink_sampler_type(type); VkDescriptorType vktype = glsl_type_is_image(type) ? zink_image_type(type) : zink_sampler_type(type);
ztype = zink_desc_type_from_vktype(vktype); ztype = zink_desc_type_from_vktype(vktype);
if (vktype == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) if (vktype == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
ret->num_texel_buffers++; ret->num_texel_buffers++;
var->data.driver_location = var->data.binding; var->data.driver_location = var->data.binding;
var->data.descriptor_set = ztype + 1; var->data.descriptor_set = screen->desc_set_id[ztype];
var->data.binding = zink_binding(nir->info.stage, vktype, var->data.driver_location); var->data.binding = zink_binding(nir->info.stage, vktype, var->data.driver_location, screen->compact_descriptors);
ret->bindings[ztype][ret->num_bindings[ztype]].index = var->data.driver_location; ret->bindings[ztype][ret->num_bindings[ztype]].index = var->data.driver_location;
ret->bindings[ztype][ret->num_bindings[ztype]].binding = var->data.binding; ret->bindings[ztype][ret->num_bindings[ztype]].binding = var->data.binding;
ret->bindings[ztype][ret->num_bindings[ztype]].type = vktype; ret->bindings[ztype][ret->num_bindings[ztype]].type = vktype;
@ -2302,7 +2310,7 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
} }
} }
bool bindless_lowered = false; bool bindless_lowered = false;
NIR_PASS(bindless_lowered, nir, lower_bindless, bindless); NIR_PASS(bindless_lowered, nir, lower_bindless, &bindless);
ret->bindless |= bindless_lowered; ret->bindless |= bindless_lowered;
ret->nir = nir; ret->nir = nir;