mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 08:08:06 +02:00
d3d12: Lower uniforms to UBO by nir options
Ubo0 is tricky. It exists if there were any uniforms when lower_uniforms_to_ubo was run. If we try to run that ourselves, it might be too late and DCE/remove_dead_variables might've been run, which removed the uniforms and their accesses, without decrementing num_uniforms. So we have no good way of knowing whether to declare ubos from [0, N] or [1, N]. In practice this probably doesn't make much of a difference but the logic is there so ¯\_(ツ)_/¯ If we use the nir option, then dead code isn't run, and num_uniforms is a true indicator of whether ubo0 exists or not. Note that this means we are no longer running this pass for internal shaders that don't come from the GLSL compiler, so various places are updated to query the nir info bit that's set by running this pass. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28535>
This commit is contained in:
parent
e80cda0512
commit
33735585a9
8 changed files with 29 additions and 38 deletions
|
|
@ -125,12 +125,6 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
|
|||
if (key->stage == PIPE_SHADER_VERTEX && key->vs.needs_format_emulation)
|
||||
dxil_nir_lower_vs_vertex_conversion(nir, key->vs.format_conversion);
|
||||
|
||||
uint32_t num_ubos_before_lower_to_ubo = nir->info.num_ubos;
|
||||
uint32_t num_uniforms_before_lower_to_ubo = nir->num_uniforms;
|
||||
NIR_PASS_V(nir, nir_lower_uniforms_to_ubo, false, false);
|
||||
shader->has_default_ubo0 = num_uniforms_before_lower_to_ubo > 0 &&
|
||||
nir->info.num_ubos > num_ubos_before_lower_to_ubo;
|
||||
|
||||
if (key->last_vertex_processing_stage) {
|
||||
if (key->invert_depth)
|
||||
NIR_PASS_V(nir, d3d12_nir_invert_depth, key->invert_depth, key->halfz);
|
||||
|
|
@ -150,7 +144,6 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
|
|||
struct nir_to_dxil_options opts = {};
|
||||
opts.interpolate_at_vertex = screen->have_load_at_vertex;
|
||||
opts.lower_int16 = !screen->opts4.Native16BitShaderOpsSupported;
|
||||
opts.no_ubo0 = !shader->has_default_ubo0;
|
||||
opts.last_ubo_is_not_arrayed = shader->num_state_vars > 0;
|
||||
if (key->stage == PIPE_SHADER_FRAGMENT)
|
||||
opts.provoking_vertex = key->fs.provoking_vertex;
|
||||
|
|
@ -191,11 +184,9 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
|
|||
|
||||
// Ubo variables
|
||||
if(nir->info.num_ubos) {
|
||||
shader->begin_ubo_binding = shader->nir->num_uniforms > 0 || !shader->nir->info.first_ubo_is_default_ubo ? 0 : 1;
|
||||
// Ignore state_vars ubo as it is bound as root constants
|
||||
unsigned num_ubo_bindings = nir->info.num_ubos - (shader->state_vars_used ? 1 : 0);
|
||||
for(unsigned i = shader->has_default_ubo0 ? 0 : 1; i < num_ubo_bindings; ++i) {
|
||||
shader->cb_bindings[shader->num_cb_bindings++].binding = i;
|
||||
}
|
||||
shader->end_ubo_binding = nir->info.num_ubos - (shader->state_vars_used ? 1 : 0);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
|
|
@ -208,10 +208,9 @@ struct d3d12_shader {
|
|||
struct d3d12_varying_info *tess_eval_output_vars;
|
||||
struct d3d12_varying_info *tess_ctrl_input_vars;
|
||||
|
||||
struct {
|
||||
unsigned binding;
|
||||
} cb_bindings[PIPE_MAX_CONSTANT_BUFFERS];
|
||||
size_t num_cb_bindings;
|
||||
/* UBOs can be sparse, if there's no uniforms then ubo0 is unused, and state vars are an internal ubo */
|
||||
uint32_t begin_ubo_binding;
|
||||
uint32_t end_ubo_binding;
|
||||
|
||||
struct {
|
||||
enum d3d12_state_var var;
|
||||
|
|
@ -221,17 +220,18 @@ struct d3d12_shader {
|
|||
size_t state_vars_size;
|
||||
bool state_vars_used;
|
||||
|
||||
/* Samplers/textures can be sparse for some internal shaders */
|
||||
struct {
|
||||
uint32_t dimension;
|
||||
} srv_bindings[PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
size_t begin_srv_binding;
|
||||
size_t end_srv_binding;
|
||||
uint32_t begin_srv_binding;
|
||||
uint32_t end_srv_binding;
|
||||
|
||||
/* Images and SSBOs are never sparse */
|
||||
struct {
|
||||
uint32_t dimension;
|
||||
} uav_bindings[PIPE_MAX_SHADER_IMAGES];
|
||||
|
||||
bool has_default_ubo0;
|
||||
unsigned pstipple_binding;
|
||||
|
||||
struct d3d12_shader_key key;
|
||||
|
|
|
|||
|
|
@ -60,9 +60,8 @@ fill_cbv_descriptors(struct d3d12_context *ctx,
|
|||
struct d3d12_descriptor_handle table_start;
|
||||
d2d12_descriptor_heap_get_next_handle(batch->view_heap, &table_start);
|
||||
|
||||
for (unsigned i = 0; i < shader->num_cb_bindings; i++) {
|
||||
unsigned binding = shader->cb_bindings[i].binding;
|
||||
struct pipe_constant_buffer *buffer = &ctx->cbufs[stage][binding];
|
||||
for (unsigned i = shader->begin_ubo_binding; i < shader->end_ubo_binding; i++) {
|
||||
struct pipe_constant_buffer *buffer = &ctx->cbufs[stage][i];
|
||||
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc = {};
|
||||
if (buffer && buffer->buffer) {
|
||||
|
|
@ -474,7 +473,7 @@ check_descriptors_left(struct d3d12_context *ctx, bool compute)
|
|||
if (!shader)
|
||||
continue;
|
||||
|
||||
needed_descs += shader->current->num_cb_bindings;
|
||||
needed_descs += shader->current->end_ubo_binding;
|
||||
needed_descs += shader->current->end_srv_binding - shader->current->begin_srv_binding;
|
||||
needed_descs += shader->current->nir->info.num_ssbos;
|
||||
needed_descs += shader->current->nir->info.num_images;
|
||||
|
|
@ -514,7 +513,7 @@ update_shader_stage_root_parameters(struct d3d12_context *ctx,
|
|||
uint64_t dirty = ctx->shader_dirty[stage];
|
||||
assert(shader);
|
||||
|
||||
if (shader->num_cb_bindings > 0) {
|
||||
if (shader->end_ubo_binding - shader->begin_ubo_binding > 0) {
|
||||
if (dirty & D3D12_SHADER_DIRTY_CONSTBUF) {
|
||||
assert(num_root_descriptors < MAX_DESCRIPTOR_TABLES);
|
||||
root_desc_tables[num_root_descriptors] = fill_cbv_descriptors(ctx, shader, stage);
|
||||
|
|
|
|||
|
|
@ -510,7 +510,7 @@ d3d12_lower_state_vars(nir_shader *nir, struct d3d12_shader *shader)
|
|||
* exists it will be replaced by using the same binding.
|
||||
* In the event there are no other UBO's, use binding slot 1 to
|
||||
* be consistent with other non-default UBO's */
|
||||
unsigned binding = MAX2(nir->info.num_ubos, 1);
|
||||
unsigned binding = MAX2(nir->info.num_ubos, nir->info.first_ubo_is_default_ubo ? 1 : 0);
|
||||
|
||||
nir_foreach_variable_with_modes_safe(var, nir, nir_var_uniform) {
|
||||
if (var->num_state_slots == 1 &&
|
||||
|
|
|
|||
|
|
@ -125,13 +125,13 @@ create_root_signature(struct d3d12_context *ctx, struct d3d12_root_signature_key
|
|||
unsigned stage = key->compute ? PIPE_SHADER_COMPUTE : i;
|
||||
D3D12_SHADER_VISIBILITY visibility = get_shader_visibility((enum pipe_shader_type)stage);
|
||||
|
||||
if (key->stages[i].num_cb_bindings > 0) {
|
||||
if (key->stages[i].end_cb_bindings - key->stages[i].begin_cb_bindings > 0) {
|
||||
init_range_root_param(&root_params[num_params++],
|
||||
&desc_ranges[num_ranges++],
|
||||
D3D12_DESCRIPTOR_RANGE_TYPE_CBV,
|
||||
key->stages[i].num_cb_bindings,
|
||||
key->stages[i].end_cb_bindings - key->stages[i].begin_cb_bindings,
|
||||
visibility,
|
||||
key->stages[i].has_default_ubo0 ? 0 : 1,
|
||||
key->stages[i].begin_cb_bindings,
|
||||
0);
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ create_root_signature(struct d3d12_context *ctx, struct d3d12_root_signature_key
|
|||
|
||||
if (key->stages[i].state_vars_size > 0) {
|
||||
init_constant_root_param(&root_params[num_params++],
|
||||
key->stages[i].num_cb_bindings + (key->stages[i].has_default_ubo0 ? 0 : 1),
|
||||
key->stages[i].end_cb_bindings,
|
||||
key->stages[i].state_vars_size,
|
||||
visibility);
|
||||
}
|
||||
|
|
@ -253,11 +253,11 @@ fill_key(struct d3d12_context *ctx, struct d3d12_root_signature_key *key, bool c
|
|||
ctx->gfx_pipeline_state.stages[i];
|
||||
|
||||
if (shader) {
|
||||
key->stages[i].num_cb_bindings = shader->num_cb_bindings;
|
||||
key->stages[i].begin_cb_bindings = shader->begin_ubo_binding;
|
||||
key->stages[i].end_cb_bindings = shader->end_ubo_binding;
|
||||
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;
|
||||
key->stages[i].num_ssbos = shader->nir->info.num_ssbos;
|
||||
key->stages[i].num_images = shader->nir->info.num_images;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ struct d3d12_root_signature_key {
|
|||
bool compute;
|
||||
bool has_stream_output;
|
||||
struct {
|
||||
unsigned num_cb_bindings;
|
||||
unsigned begin_cb_bindings;
|
||||
unsigned end_cb_bindings;
|
||||
unsigned end_srv_binding;
|
||||
unsigned begin_srv_binding;
|
||||
unsigned state_vars_size;
|
||||
unsigned num_ssbos;
|
||||
unsigned num_images;
|
||||
bool has_default_ubo0;
|
||||
} stages[D3D12_GFX_SHADER_STAGES];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ nir_options = {
|
|||
nir_lower_dfloor |
|
||||
nir_lower_dceil |
|
||||
nir_lower_dround_even,
|
||||
.lower_uniforms_to_ubo = true,
|
||||
.max_unroll_iterations = 32, /* arbitrary */
|
||||
.force_indirect_unrolling = (nir_var_shader_in | nir_var_shader_out),
|
||||
.lower_device_index_to_zero = true,
|
||||
|
|
@ -3365,7 +3366,7 @@ get_resource_handle(struct ntd_context *ctx, nir_src *src, enum dxil_resource_cl
|
|||
* load_vulkan_descriptor handle creation.
|
||||
*/
|
||||
unsigned base_binding = 0;
|
||||
if (ctx->opts->environment == DXIL_ENVIRONMENT_GL &&
|
||||
if (ctx->shader->info.first_ubo_is_default_ubo &&
|
||||
class == DXIL_RESOURCE_CLASS_CBV)
|
||||
base_binding = 1;
|
||||
|
||||
|
|
@ -5877,16 +5878,17 @@ emit_cbvs(struct ntd_context *ctx)
|
|||
} else {
|
||||
if (ctx->shader->info.num_ubos) {
|
||||
const unsigned ubo_size = 16384 /*4096 vec4's*/;
|
||||
bool has_ubo0 = !ctx->opts->no_ubo0;
|
||||
uint array_base = ctx->shader->info.first_ubo_is_default_ubo ? 1 : 0;
|
||||
bool has_ubo0 = ctx->shader->num_uniforms > 0 && ctx->shader->info.first_ubo_is_default_ubo;
|
||||
bool has_state_vars = ctx->opts->last_ubo_is_not_arrayed;
|
||||
unsigned ubo1_array_size = ctx->shader->info.num_ubos -
|
||||
(has_state_vars ? 2 : 1);
|
||||
unsigned ubo1_array_size = ctx->shader->info.num_ubos - array_base -
|
||||
(has_state_vars ? 1 : 0);
|
||||
|
||||
if (has_ubo0 &&
|
||||
!emit_cbv(ctx, 0, 0, ubo_size, 1, "__ubo_uniforms"))
|
||||
return false;
|
||||
if (ubo1_array_size &&
|
||||
!emit_cbv(ctx, 1, 0, ubo_size, ubo1_array_size, "__ubos"))
|
||||
!emit_cbv(ctx, array_base, 0, ubo_size, ubo1_array_size, "__ubos"))
|
||||
return false;
|
||||
if (has_state_vars &&
|
||||
!emit_cbv(ctx, ctx->shader->info.num_ubos - 1, 0, ubo_size, 1, "__ubo_state_vars"))
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ struct nir_to_dxil_options {
|
|||
bool interpolate_at_vertex;
|
||||
bool lower_int16;
|
||||
bool disable_math_refactoring;
|
||||
bool no_ubo0;
|
||||
bool last_ubo_is_not_arrayed;
|
||||
unsigned provoking_vertex;
|
||||
unsigned num_kernel_globals;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue