Commit 47f87bb3 authored by Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Committed by Erik Faye-Lund
Browse files

d3d12: Add required varyings type/interpolation into shader key

parent ee125c59
......@@ -419,6 +419,24 @@ needs_vertex_reordering(struct d3d12_selection_context *sel_ctx)
((flat || xfb) && sel_ctx->alternate_tri));
}
static nir_variable *
create_varying_from_info(nir_shader *nir, struct d3d12_varying_info *info,
unsigned slot, nir_variable_mode mode)
{
nir_variable *var;
char tmp[100];
snprintf(tmp, ARRAY_SIZE(tmp),
mode == nir_var_shader_in ? "in_%d" : "out_%d",
info->vars[slot].driver_location);
var = nir_variable_create(nir, mode, info->vars[slot].type, tmp);
var->data.location = slot;
var->data.driver_location = info->vars[slot].driver_location;
var->data.interpolation = info->vars[slot].interpolation;
return var;
}
static void
fill_varyings(struct d3d12_varying_info *info, struct exec_list *vars, uint64_t mask)
{
......@@ -498,8 +516,10 @@ d3d12_compare_shader_keys(const d3d12_shader_key *expect, const d3d12_shader_key
/* Because we only add varyings we check that a shader has at least the expected in-
* and outputs. */
if ((expect->required_varying_inputs & ~have->required_varying_inputs) ||
(expect->required_varying_outputs & ~have->required_varying_outputs) ||
if (memcmp(&expect->required_varying_inputs, &have->required_varying_inputs,
sizeof(struct d3d12_varying_info)) ||
memcmp(&expect->required_varying_outputs, &have->required_varying_outputs,
sizeof(struct d3d12_varying_info)) ||
(expect->next_varying_inputs != have->next_varying_inputs) ||
(expect->prev_varying_outputs != have->prev_varying_outputs))
return false;
......@@ -591,7 +611,8 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
system_out_values |= VARYING_BIT_POS;
if (stage == PIPE_SHADER_FRAGMENT)
system_out_values |= VARYING_BIT_PSIZ;
key->required_varying_inputs = prev->current->nir->info.outputs_written & ~system_out_values;
uint64_t mask = prev->current->nir->info.outputs_written & ~system_out_values;
fill_varyings(&key->required_varying_inputs, &prev->current->nir->outputs, mask);
key->prev_varying_outputs = prev->current->nir->info.outputs_written;
/* Set the provoking vertex based on the previous shader output. Only set the
......@@ -608,7 +629,8 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
if (!next->is_gs_variant) {
if (stage == PIPE_SHADER_VERTEX)
system_generated_in_values |= VARYING_BIT_POS;
key->required_varying_outputs = next->current->nir->info.inputs_read & ~system_generated_in_values;
uint64_t mask = next->current->nir->info.inputs_read & ~system_generated_in_values;
fill_varyings(&key->required_varying_outputs, &next->current->nir->inputs, mask);
}
key->next_varying_inputs = next->current->nir->info.inputs_read;
}
......@@ -747,35 +769,22 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele
key.sampler_compare_funcs, key.swizzle_state);
/* Add the needed in and outputs, and re-sort */
uint64_t mask = key.required_varying_inputs & ~new_nir_variant->info.inputs_read;
uint64_t mask = key.required_varying_inputs.mask & ~new_nir_variant->info.inputs_read;
if (prev) {
if (mask) {
nir_foreach_variable(var, &prev->current->nir->outputs) {
if (mask & (1ull << var->data.location)) {
nir_variable *new_var = nir_variable_clone(var, new_nir_variant);
new_var->data.mode = nir_var_shader_in;
new_var->data.driver_location = exec_list_length(&new_nir_variant->inputs);
exec_list_push_tail(&new_nir_variant->inputs, &new_var->node);
}
}
while (mask) {
int slot = u_bit_scan64(&mask);
create_varying_from_info(new_nir_variant, &key.required_varying_inputs, slot, nir_var_shader_in);
}
d3d12_reassign_driver_locations(&new_nir_variant->inputs,
prev->current->nir->info.outputs_written);
d3d12_reassign_driver_locations(&new_nir_variant->inputs, key.prev_varying_outputs);
}
mask = key.required_varying_outputs & ~new_nir_variant->info.outputs_written;
mask = key.required_varying_outputs.mask & ~new_nir_variant->info.outputs_written;
if (next) {
if (mask && !next->is_gs_variant) {
nir_foreach_variable(var, &next->current->nir->inputs) {
if (mask & (1ull << var->data.location)) {
nir_variable *new_var = nir_variable_clone(var, new_nir_variant);
new_var->data.mode = nir_var_shader_out;
new_var->data.driver_location = exec_list_length(&new_nir_variant->outputs);
exec_list_push_tail(&new_nir_variant->outputs, &new_var->node);
}
}
while (mask) {
int slot = u_bit_scan64(&mask);
create_varying_from_info(new_nir_variant, &key.required_varying_outputs, slot, nir_var_shader_out);
}
d3d12_reassign_driver_locations(&new_nir_variant->outputs, key.next_varying_inputs);
}
......
......@@ -61,8 +61,8 @@ struct d3d12_varying_info {
struct d3d12_shader_key {
enum pipe_shader_type stage;
uint64_t required_varying_inputs;
uint64_t required_varying_outputs;
struct d3d12_varying_info required_varying_inputs;
struct d3d12_varying_info required_varying_outputs;
uint64_t next_varying_inputs;
uint64_t prev_varying_outputs;
unsigned last_vertex_processing_stage : 1;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment