d3d12, microsoft/compiler: Use SRV/sampler variable binding data

For GL, we've previously mostly ignored the binding property for sampler variables
during the shader compilation step. For CL, our image bindings were always 0-based as well.

Now, for Vulkan, we are going to be getting explicit bindings and need to emit DXIL that
respects those bindings. Since Vulkan can also have both split and combined images and samplers,
we now need to be smarter about recognizing when NIR is trying to use a "sampler" as *both* an
image and sampler (in deref mode, the same variable will be deref'd as both image and sampler).

That "being smarter" bit comes next, but first, let's prep GL for building correct root
signatures and binding the resources correctly.

Reviewed-By: Bill Kristiansen <billkris@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10298>
This commit is contained in:
Jesse Natalie
2021-04-16 11:40:35 -07:00
committed by Marge Bot
parent f64c7cb246
commit ec9fa0ed13
6 changed files with 41 additions and 42 deletions
+5 -4
View File
@@ -175,16 +175,17 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
}
// Non-ubo variables
shader->begin_srv_binding = (UINT_MAX);
nir_foreach_variable_with_modes(var, nir, nir_var_uniform) {
auto type = glsl_without_array(var->type);
if (glsl_type_is_sampler(type) && glsl_get_sampler_result_type(type) != GLSL_TYPE_VOID) {
unsigned count = glsl_type_is_array(var->type) ? glsl_get_aoa_size(var->type) : 1;
for (unsigned i = 0; i < count; ++i) {
shader->srv_bindings[shader->num_srv_bindings].index = var->data.binding + i;
shader->srv_bindings[shader->num_srv_bindings].binding = var->data.binding;
shader->srv_bindings[shader->num_srv_bindings].dimension = resource_dimension(glsl_get_sampler_dim(type));
shader->num_srv_bindings++;
shader->srv_bindings[var->data.binding + i].binding = var->data.binding;
shader->srv_bindings[var->data.binding + i].dimension = resource_dimension(glsl_get_sampler_dim(type));
}
shader->begin_srv_binding = MIN2(var->data.binding, shader->begin_srv_binding);
shader->end_srv_binding = MAX2(var->data.binding + count, shader->end_srv_binding);
}
}
+2 -2
View File
@@ -136,11 +136,11 @@ struct d3d12_shader {
bool state_vars_used;
struct {
int index;
int binding;
uint32_t dimension;
} srv_bindings[PIPE_MAX_SHADER_SAMPLER_VIEWS];
size_t num_srv_bindings;
size_t begin_srv_binding;
size_t end_srv_binding;
bool has_default_ubo0;
unsigned pstipple_binding;
+18 -18
View File
@@ -90,19 +90,19 @@ fill_srv_descriptors(struct d3d12_context *ctx,
d2d12_descriptor_heap_get_next_handle(batch->view_heap, &table_start);
for (unsigned i = 0; i < shader->num_srv_bindings; i++)
for (unsigned i = shader->begin_srv_binding; i < shader->end_srv_binding; i++)
{
struct d3d12_sampler_view *view;
if ((unsigned)shader->srv_bindings[i].binding == shader->pstipple_binding) {
if (i == shader->pstipple_binding) {
view = (struct d3d12_sampler_view*)ctx->pstipple.sampler_view;
} else {
int index = shader->srv_bindings[i].index;
view = (struct d3d12_sampler_view*)ctx->sampler_views[stage][index];
view = (struct d3d12_sampler_view*)ctx->sampler_views[stage][i];
}
unsigned desc_idx = i - shader->begin_srv_binding;
if (view != NULL) {
descs[i] = view->handle.cpu_handle ;
descs[desc_idx] = view->handle.cpu_handle;
d3d12_batch_reference_sampler_view(batch, view);
D3D12_RESOURCE_STATES state = (stage == PIPE_SHADER_FRAGMENT) ?
@@ -120,11 +120,11 @@ fill_srv_descriptors(struct d3d12_context *ctx,
state);
}
} else {
descs[i] = screen->null_srvs[shader->srv_bindings[i].dimension].cpu_handle;
descs[desc_idx] = screen->null_srvs[shader->srv_bindings[i].dimension].cpu_handle;
}
}
d3d12_descriptor_heap_append_handles(batch->view_heap, descs, shader->num_srv_bindings);
d3d12_descriptor_heap_append_handles(batch->view_heap, descs, shader->end_srv_binding - shader->begin_srv_binding);
return table_start.gpu_handle;
}
@@ -141,27 +141,27 @@ fill_sampler_descriptors(struct d3d12_context *ctx,
d2d12_descriptor_heap_get_next_handle(batch->sampler_heap, &table_start);
for (unsigned i = 0; i < shader->num_srv_bindings; i++)
for (unsigned i = shader->begin_srv_binding; i < shader->end_srv_binding; i++)
{
struct d3d12_sampler_state *sampler;
if ((unsigned)shader->srv_bindings[i].binding == shader->pstipple_binding) {
if (i == shader->pstipple_binding) {
sampler = ctx->pstipple.sampler_cso;
} else {
int index = shader->srv_bindings[i].index;
sampler = ctx->samplers[stage][index];
sampler = ctx->samplers[stage][i];
}
unsigned desc_idx = i - shader->begin_srv_binding;
if (sampler != NULL) {
if (sampler->is_shadow_sampler && shader_sel->compare_with_lod_bias_grad)
descs[i] = sampler->handle_without_shadow.cpu_handle;
descs[desc_idx] = sampler->handle_without_shadow.cpu_handle;
else
descs[i] = sampler->handle.cpu_handle;
descs[desc_idx] = sampler->handle.cpu_handle;
} else
descs[i] = ctx->null_sampler.cpu_handle;
descs[desc_idx] = ctx->null_sampler.cpu_handle;
}
d3d12_descriptor_heap_append_handles(batch->sampler_heap, descs, shader->num_srv_bindings);
d3d12_descriptor_heap_append_handles(batch->sampler_heap, descs, shader->end_srv_binding - shader->begin_srv_binding);
return table_start.gpu_handle;
}
@@ -219,7 +219,7 @@ check_descriptors_left(struct d3d12_context *ctx)
continue;
needed_descs += shader->current->num_cb_bindings;
needed_descs += shader->current->num_srv_bindings;
needed_descs += shader->current->end_srv_binding - shader->current->begin_srv_binding;
}
if (d3d12_descriptor_heap_get_remaining_handles(batch->view_heap) < needed_descs)
@@ -232,7 +232,7 @@ check_descriptors_left(struct d3d12_context *ctx)
if (!shader)
continue;
needed_descs += shader->current->num_srv_bindings;
needed_descs += shader->current->end_srv_binding - shader->current->begin_srv_binding;
}
if (d3d12_descriptor_heap_get_remaining_handles(batch->sampler_heap) < needed_descs)
@@ -262,7 +262,7 @@ set_graphics_root_parameters(struct d3d12_context *ctx,
ctx->cmdlist->SetGraphicsRootDescriptorTable(num_params, fill_cbv_descriptors(ctx, shader, i));
num_params++;
}
if (shader->num_srv_bindings > 0) {
if (shader->end_srv_binding > 0) {
if (dirty & D3D12_SHADER_DIRTY_SAMPLER_VIEWS)
ctx->cmdlist->SetGraphicsRootDescriptorTable(num_params, fill_srv_descriptors(ctx, shader, i));
num_params++;
@@ -115,23 +115,23 @@ create_root_signature(struct d3d12_context *ctx, struct d3d12_root_signature_key
num_params++;
}
if (key->stages[i].num_srv_bindings > 0) {
if (key->stages[i].end_srv_binding > 0) {
init_range_root_param(&root_params[num_params],
&desc_ranges[num_params],
D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
key->stages[i].num_srv_bindings,
key->stages[i].end_srv_binding - key->stages[i].begin_srv_binding,
visibility,
0);
key->stages[i].begin_srv_binding);
num_params++;
}
if (key->stages[i].num_srv_bindings > 0) {
if (key->stages[i].end_srv_binding > 0) {
init_range_root_param(&root_params[num_params],
&desc_ranges[num_params],
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
key->stages[i].num_srv_bindings,
key->stages[i].end_srv_binding - key->stages[i].begin_srv_binding,
visibility,
0);
key->stages[i].begin_srv_binding);
num_params++;
}
@@ -186,7 +186,8 @@ fill_key(struct d3d12_context *ctx, struct d3d12_root_signature_key *key)
if (shader) {
key->stages[i].num_cb_bindings = shader->num_cb_bindings;
key->stages[i].num_srv_bindings = shader->num_srv_bindings;
key->stages[i].end_srv_binding = shader->end_srv_binding;
key->stages[i].begin_srv_binding = shader->begin_srv_binding;
key->stages[i].state_vars_size = shader->state_vars_size;
key->stages[i].has_default_ubo0 = shader->has_default_ubo0;
@@ -30,7 +30,8 @@ struct d3d12_root_signature_key {
bool has_stream_output;
struct {
unsigned num_cb_bindings;
unsigned num_srv_bindings;
unsigned end_srv_binding;
unsigned begin_srv_binding;
unsigned state_vars_size;
bool has_default_ubo0;
} stages[D3D12_GFX_SHADER_STAGES];
+6 -10
View File
@@ -793,9 +793,10 @@ get_resource_id(struct ntd_context *ctx, enum dxil_resource_class class,
}
static bool
emit_srv(struct ntd_context *ctx, nir_variable *var, unsigned binding, unsigned count)
emit_srv(struct ntd_context *ctx, nir_variable *var, unsigned count)
{
unsigned id = util_dynarray_num_elements(&ctx->srv_metadata_nodes, const struct dxil_mdnode *);
unsigned binding = var->data.binding;
resource_array_layout layout = {id, binding, count};
enum dxil_component_type comp_type;
@@ -1099,9 +1100,10 @@ emit_ubo_var(struct ntd_context *ctx, nir_variable *var)
}
static bool
emit_sampler(struct ntd_context *ctx, nir_variable *var, unsigned binding, unsigned count)
emit_sampler(struct ntd_context *ctx, nir_variable *var, unsigned count)
{
unsigned id = util_dynarray_num_elements(&ctx->sampler_metadata_nodes, const struct dxil_mdnode *);
unsigned binding = var->data.binding;
resource_array_layout layout = {id, binding, count};
const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
const struct dxil_type *sampler_type = dxil_module_get_struct_type(&ctx->mod, "struct.SamplerState", &int32_type, 1);
@@ -4287,8 +4289,6 @@ shader_has_shared_ops(struct nir_shader *s)
static bool
emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts)
{
unsigned binding;
/* The validator forces us to emit resources in a specific order:
* CBVs, Samplers, SRVs, UAVs. While we are at it also remove
* stale struct uniforms, they are lowered but might not have been removed */
@@ -4299,26 +4299,22 @@ emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts)
return false;
/* Samplers */
binding = 0;
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_uniform) {
unsigned count = glsl_type_get_sampler_count(var->type);
if (var->data.mode == nir_var_uniform && count &&
glsl_get_sampler_result_type(glsl_without_array(var->type)) == GLSL_TYPE_VOID) {
if (!emit_sampler(ctx, var, binding, count))
if (!emit_sampler(ctx, var, count))
return false;
binding += count;
}
}
/* SRVs */
binding = 0;
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_uniform) {
unsigned count = glsl_type_get_sampler_count(var->type);
if (var->data.mode == nir_var_uniform && count &&
glsl_get_sampler_result_type(glsl_without_array(var->type)) != GLSL_TYPE_VOID) {
if (!emit_srv(ctx, var, binding, count))
if (!emit_srv(ctx, var, count))
return false;
binding += count;
}
}