diff options
-rw-r--r-- | src/gallium/drivers/d3d12/d3d12_compiler.cpp | 44 | ||||
-rw-r--r-- | src/gallium/drivers/d3d12/d3d12_compiler.h | 15 | ||||
-rw-r--r-- | src/gallium/drivers/d3d12/d3d12_gs_variant.cpp | 113 | ||||
-rw-r--r-- | src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp | 46 |
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"); |