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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user