summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/d3d12/d3d12_compiler.cpp44
-rw-r--r--src/gallium/drivers/d3d12/d3d12_compiler.h15
-rw-r--r--src/gallium/drivers/d3d12/d3d12_gs_variant.cpp113
-rw-r--r--src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp46
4 files changed, 126 insertions, 92 deletions
diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp
index 345a1a3b739..53fc94ca9cb 100644
--- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp
@@ -512,26 +512,36 @@ needs_vertex_reordering(struct d3d12_selection_context *sel_ctx, const struct pi
static nir_variable *
create_varying_from_info(nir_shader *nir, struct d3d12_varying_info *info,
- unsigned slot, nir_variable_mode mode, bool patch)
+ unsigned slot, unsigned slot_frac, nir_variable_mode mode, bool patch)
{
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);
+ info->slots[slot].vars[slot_frac].driver_location);
+ var = nir_variable_create(nir, mode, info->slots[slot].types[slot_frac], tmp);
var->data.location = slot;
- var->data.driver_location = info->vars[slot].driver_location;
- var->data.interpolation = info->vars[slot].interpolation;
- var->data.patch = info->vars[slot].patch;
- var->data.compact = info->vars[slot].compact;
+ var->data.location_frac = slot_frac;
+ var->data.driver_location = info->slots[slot].vars[slot_frac].driver_location;
+ var->data.interpolation = info->slots[slot].vars[slot_frac].interpolation;
+ var->data.patch = info->slots[slot].patch;
+ var->data.compact = info->slots[slot].vars[slot_frac].compact;
if (patch)
var->data.location += VARYING_SLOT_PATCH0;
return var;
}
+void
+create_varyings_from_info(nir_shader *nir, struct d3d12_varying_info *info,
+ unsigned slot, nir_variable_mode mode, bool patch)
+{
+ unsigned mask = info->slots[slot].location_frac_mask;
+ while (mask)
+ create_varying_from_info(nir, info, slot, u_bit_scan(&mask), mode, patch);
+}
+
static void
fill_varyings(struct d3d12_varying_info *info, nir_shader *s,
nir_variable_mode modes, uint64_t mask, bool patch)
@@ -547,12 +557,14 @@ fill_varyings(struct d3d12_varying_info *info, nir_shader *s,
if (!(mask & slot_bit))
continue;
- info->vars[slot].driver_location = var->data.driver_location;
- info->vars[slot].type = var->type;
- info->vars[slot].interpolation = var->data.interpolation;
- info->vars[slot].patch = var->data.patch;
- info->vars[slot].compact = var->data.compact;
+ info->slots[slot].types[var->data.location_frac] = var->type;
+ info->slots[slot].patch = var->data.patch;
+ auto& var_slot = info->slots[slot].vars[var->data.location_frac];
+ var_slot.driver_location = var->data.driver_location;
+ var_slot.interpolation = var->data.interpolation;
+ var_slot.compact = var->data.compact;
info->mask |= slot_bit;
+ info->slots[slot].location_frac_mask |= (1 << var->data.location_frac);
}
}
@@ -1066,14 +1078,14 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele
uint64_t mask = key.required_varying_inputs.mask & ~new_nir_variant->info.inputs_read;
while (mask) {
int slot = u_bit_scan64(&mask);
- create_varying_from_info(new_nir_variant, &key.required_varying_inputs, slot, nir_var_shader_in, false);
+ create_varyings_from_info(new_nir_variant, &key.required_varying_inputs, slot, nir_var_shader_in, false);
}
if (sel->stage == PIPE_SHADER_TESS_EVAL) {
uint32_t patch_mask = (uint32_t)key.ds.required_patch_inputs.mask & ~new_nir_variant->info.patch_inputs_read;
while (patch_mask) {
int slot = u_bit_scan(&patch_mask);
- create_varying_from_info(new_nir_variant, &key.ds.required_patch_inputs, slot, nir_var_shader_in, true);
+ create_varyings_from_info(new_nir_variant, &key.ds.required_patch_inputs, slot, nir_var_shader_in, true);
}
}
dxil_reassign_driver_locations(new_nir_variant, nir_var_shader_in,
@@ -1085,14 +1097,14 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele
uint64_t mask = key.required_varying_outputs.mask & ~new_nir_variant->info.outputs_written;
while (mask) {
int slot = u_bit_scan64(&mask);
- create_varying_from_info(new_nir_variant, &key.required_varying_outputs, slot, nir_var_shader_out, false);
+ create_varyings_from_info(new_nir_variant, &key.required_varying_outputs, slot, nir_var_shader_out, false);
}
if (sel->stage == PIPE_SHADER_TESS_CTRL) {
uint32_t patch_mask = (uint32_t)key.hs.required_patch_outputs.mask & ~new_nir_variant->info.patch_outputs_written;
while (patch_mask) {
int slot = u_bit_scan(&patch_mask);
- create_varying_from_info(new_nir_variant, &key.ds.required_patch_inputs, slot, nir_var_shader_out, true);
+ create_varyings_from_info(new_nir_variant, &key.ds.required_patch_inputs, slot, nir_var_shader_out, true);
}
}
dxil_reassign_driver_locations(new_nir_variant, nir_var_shader_out,
diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.h b/src/gallium/drivers/d3d12/d3d12_compiler.h
index 6d670b9682c..fc5bfad8d6c 100644
--- a/src/gallium/drivers/d3d12/d3d12_compiler.h
+++ b/src/gallium/drivers/d3d12/d3d12_compiler.h
@@ -70,12 +70,15 @@ d3d12_get_compiler_options(struct pipe_screen *screen,
struct d3d12_varying_info {
struct {
- const struct glsl_type *type;
- unsigned interpolation:3; // INTERP_MODE_COUNT = 5
- unsigned driver_location:6; // VARYING_SLOT_MAX = 64
- unsigned patch:1;
- unsigned compact:1;
- } vars[VARYING_SLOT_MAX];
+ const struct glsl_type *types[4];
+ uint8_t location_frac_mask:2;
+ uint8_t patch:1;
+ struct {
+ unsigned interpolation:3; // INTERP_MODE_COUNT = 5
+ unsigned driver_location:6; // VARYING_SLOT_MAX = 64
+ unsigned compact:1;
+ } vars[4];
+ } slots[VARYING_SLOT_MAX];
uint64_t mask;
};
diff --git a/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp b/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp
index f3bb2f93edc..500a06b8b7c 100644
--- a/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp
@@ -77,31 +77,40 @@ d3d12_make_passthrough_gs(struct d3d12_context *ctx, struct d3d12_gs_variant_key
/* Copy inputs to outputs. */
while (varyings) {
- nir_variable *in, *out;
char tmp[100];
const int i = u_bit_scan64(&varyings);
- snprintf(tmp, ARRAY_SIZE(tmp), "in_%d", key->varyings.vars[i].driver_location);
- in = nir_variable_create(nir,
- nir_var_shader_in,
- glsl_array_type(key->varyings.vars[i].type, 1, false),
- tmp);
- in->data.location = i;
- in->data.driver_location = key->varyings.vars[i].driver_location;
- in->data.interpolation = key->varyings.vars[i].interpolation;
-
- snprintf(tmp, ARRAY_SIZE(tmp), "out_%d", key->varyings.vars[i].driver_location);
- out = nir_variable_create(nir,
- nir_var_shader_out,
- key->varyings.vars[i].type,
- tmp);
- out->data.location = i;
- out->data.driver_location = key->varyings.vars[i].driver_location;
- out->data.interpolation = key->varyings.vars[i].interpolation;
-
- nir_deref_instr *in_value = nir_build_deref_array(&b, nir_build_deref_var(&b, in),
- nir_imm_int(&b, 0));
- nir_copy_deref(&b, nir_build_deref_var(&b, out), in_value);
+ unsigned frac_slots = key->varyings.slots[i].location_frac_mask;
+ while (frac_slots) {
+ nir_variable *in, *out;
+ int j = u_bit_scan(&frac_slots);
+
+ snprintf(tmp, ARRAY_SIZE(tmp), "in_%d", key->varyings.slots[i].vars[j].driver_location);
+ in = nir_variable_create(nir,
+ nir_var_shader_in,
+ glsl_array_type(key->varyings.slots[i].types[j], 1, false),
+ tmp);
+ in->data.location = i;
+ in->data.location_frac = j;
+ in->data.driver_location = key->varyings.slots[i].vars[j].driver_location;
+ in->data.interpolation = key->varyings.slots[i].vars[j].interpolation;
+ in->data.compact = key->varyings.slots[i].vars[j].compact;
+
+ snprintf(tmp, ARRAY_SIZE(tmp), "out_%d", key->varyings.slots[i].vars[j].driver_location);
+ out = nir_variable_create(nir,
+ nir_var_shader_out,
+ key->varyings.slots[i].types[j],
+ tmp);
+ out->data.location = i;
+ out->data.location_frac = j;
+ out->data.driver_location = key->varyings.slots[i].vars[j].driver_location;
+ out->data.interpolation = key->varyings.slots[i].vars[j].interpolation;
+ out->data.compact = key->varyings.slots[i].vars[j].compact;
+
+ nir_deref_instr *in_value = nir_build_deref_array(&b, nir_build_deref_var(&b, in),
+ nir_imm_int(&b, 0));
+ nir_copy_deref(&b, nir_build_deref_var(&b, out), in_value);
+ }
}
nir_emit_vertex(&b, 0);
@@ -168,33 +177,41 @@ d3d12_begin_emit_primitives_gs(struct emit_primitives_context *emit_ctx,
char tmp[100];
const int i = u_bit_scan64(&varyings);
- snprintf(tmp, ARRAY_SIZE(tmp), "in_%d", emit_ctx->num_vars);
- emit_ctx->in[emit_ctx->num_vars] = nir_variable_create(nir,
- nir_var_shader_in,
- glsl_array_type(key->varyings.vars[i].type, 3, 0),
- tmp);
- emit_ctx->in[emit_ctx->num_vars]->data.location = i;
- emit_ctx->in[emit_ctx->num_vars]->data.driver_location = key->varyings.vars[i].driver_location;
- emit_ctx->in[emit_ctx->num_vars]->data.interpolation = key->varyings.vars[i].interpolation;
-
- /* Don't create an output for the edge flag variable */
- if (i == VARYING_SLOT_EDGE) {
- edgeflag_var = emit_ctx->in[emit_ctx->num_vars];
- continue;
- } else if (i == VARYING_SLOT_POS) {
- pos_var = emit_ctx->in[emit_ctx->num_vars];
+ unsigned frac_slots = key->varyings.slots[i].location_frac_mask;
+ while (frac_slots) {
+ int j = u_bit_scan(&frac_slots);
+ snprintf(tmp, ARRAY_SIZE(tmp), "in_%d", emit_ctx->num_vars);
+ emit_ctx->in[emit_ctx->num_vars] = nir_variable_create(nir,
+ nir_var_shader_in,
+ glsl_array_type(key->varyings.slots[i].types[j], 3, 0),
+ tmp);
+ emit_ctx->in[emit_ctx->num_vars]->data.location = i;
+ emit_ctx->in[emit_ctx->num_vars]->data.location_frac = j;
+ emit_ctx->in[emit_ctx->num_vars]->data.driver_location = key->varyings.slots[i].vars[j].driver_location;
+ emit_ctx->in[emit_ctx->num_vars]->data.interpolation = key->varyings.slots[i].vars[j].interpolation;
+ emit_ctx->in[emit_ctx->num_vars]->data.compact = key->varyings.slots[i].vars[j].compact;
+
+ /* Don't create an output for the edge flag variable */
+ if (i == VARYING_SLOT_EDGE) {
+ edgeflag_var = emit_ctx->in[emit_ctx->num_vars];
+ continue;
+ } else if (i == VARYING_SLOT_POS) {
+ pos_var = emit_ctx->in[emit_ctx->num_vars];
+ }
+
+ snprintf(tmp, ARRAY_SIZE(tmp), "out_%d", emit_ctx->num_vars);
+ emit_ctx->out[emit_ctx->num_vars] = nir_variable_create(nir,
+ nir_var_shader_out,
+ key->varyings.slots[i].types[j],
+ tmp);
+ emit_ctx->out[emit_ctx->num_vars]->data.location = i;
+ emit_ctx->out[emit_ctx->num_vars]->data.location_frac = j;
+ emit_ctx->out[emit_ctx->num_vars]->data.driver_location = key->varyings.slots[i].vars[j].driver_location;
+ emit_ctx->out[emit_ctx->num_vars]->data.interpolation = key->varyings.slots[i].vars[j].interpolation;
+ emit_ctx->out[emit_ctx->num_vars]->data.compact = key->varyings.slots[i].vars[j].compact;
+
+ emit_ctx->num_vars++;
}
-
- snprintf(tmp, ARRAY_SIZE(tmp), "out_%d", emit_ctx->num_vars);
- emit_ctx->out[emit_ctx->num_vars] = nir_variable_create(nir,
- nir_var_shader_out,
- key->varyings.vars[i].type,
- tmp);
- emit_ctx->out[emit_ctx->num_vars]->data.location = i;
- emit_ctx->out[emit_ctx->num_vars]->data.driver_location = key->varyings.vars[i].driver_location;
- emit_ctx->out[emit_ctx->num_vars]->data.interpolation = key->varyings.vars[i].interpolation;
-
- emit_ctx->num_vars++;
}
if (key->has_front_face) {
diff --git a/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp b/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp
index 2f2bd903b66..1773ef488ff 100644
--- a/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp
@@ -69,28 +69,30 @@ create_tess_ctrl_shader_variant(struct d3d12_context *ctx, struct d3d12_tcs_vari
while(varying_mask) {
int var_idx = u_bit_scan64(&varying_mask);
- auto var = &key->varyings.vars[var_idx];
- const struct glsl_type *type = var->type;
- const struct glsl_type *in_type = var->type;
- const struct glsl_type *out_type = var->type;
- in_type = glsl_array_type(type, key->vertices_out, 0);
- out_type = glsl_array_type(type, key->vertices_out, 0);
-
- char buf[1024];
- snprintf(buf, sizeof(buf), "in_%d", var->driver_location);
- nir_variable *in = nir_variable_create(nir, nir_var_shader_in, in_type, buf);
- snprintf(buf, sizeof(buf), "out_%d", var->driver_location);
- nir_variable *out = nir_variable_create(nir, nir_var_shader_out, out_type, buf);
- out->data.location = in->data.location = var_idx;
- out->data.driver_location = in->data.driver_location = var->driver_location;
-
- for (unsigned i = 0; i < key->vertices_out; i++) {
- nir_if *start_block = nir_push_if(&b, nir_ieq(&b, invocation_id, nir_imm_int(&b, i)));
- nir_deref_instr *in_array_var = nir_build_deref_array(&b, nir_build_deref_var(&b, in), invocation_id);
- nir_ssa_def *load = nir_load_deref(&b, in_array_var);
- nir_deref_instr *out_array_var = nir_build_deref_array_imm(&b, nir_build_deref_var(&b, out), i);
- nir_store_deref(&b, out_array_var, load, 0xff);
- nir_pop_if(&b, start_block);
+ auto slot = &key->varyings.slots[var_idx];
+ unsigned frac_mask = slot->location_frac_mask;
+ while (frac_mask) {
+ int frac = u_bit_scan(&frac_mask);
+ auto var = &slot->vars[frac];
+ const struct glsl_type *type = glsl_array_type(slot->types[frac], key->vertices_out, 0);
+
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "in_%d", var->driver_location);
+ nir_variable *in = nir_variable_create(nir, nir_var_shader_in, type, buf);
+ snprintf(buf, sizeof(buf), "out_%d", var->driver_location);
+ nir_variable *out = nir_variable_create(nir, nir_var_shader_out, type, buf);
+ out->data.location = in->data.location = var_idx;
+ out->data.location_frac = in->data.location_frac = frac;
+ out->data.driver_location = in->data.driver_location = var->driver_location;
+
+ for (unsigned i = 0; i < key->vertices_out; i++) {
+ nir_if *start_block = nir_push_if(&b, nir_ieq(&b, invocation_id, nir_imm_int(&b, i)));
+ nir_deref_instr *in_array_var = nir_build_deref_array(&b, nir_build_deref_var(&b, in), invocation_id);
+ nir_ssa_def *load = nir_load_deref(&b, in_array_var);
+ nir_deref_instr *out_array_var = nir_build_deref_array_imm(&b, nir_build_deref_var(&b, out), i);
+ nir_store_deref(&b, out_array_var, load, 0xff);
+ nir_pop_if(&b, start_block);
+ }
}
}
nir_variable *gl_TessLevelInner = nir_variable_create(nir, nir_var_shader_out, glsl_array_type(glsl_float_type(), 2, 0), "gl_TessLevelInner");