microsoft/compiler: Support compact arrays for clip/cull in nir_to_dxil

Reviewed-by: Bill Kristiansen <billkris@microsoft.com>
Acked-by: Michael Tang <tangm@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9846>
This commit is contained in:
Jesse Natalie 2021-03-25 18:21:10 -07:00 committed by Marge Bot
parent 4941decc58
commit baeb363df0
2 changed files with 97 additions and 17 deletions

View file

@ -97,7 +97,7 @@ in_sysvalue_name(nir_variable *var)
* to the semantic name string. Then these strings are dumped into the stream.
*/
static unsigned
get_additional_semantic_info(nir_variable *var, struct semantic_info *info,
get_additional_semantic_info(nir_shader *s, nir_variable *var, struct semantic_info *info,
unsigned next_row, bool is_gs_shader)
{
const struct glsl_type *type = var->type;
@ -113,6 +113,24 @@ get_additional_semantic_info(nir_variable *var, struct semantic_info *info,
info->start_row = info->index;
} else if (is_depth || (info->kind == DXIL_SEM_PRIMITIVE_ID && is_gs_shader)) {
info->start_row = -1;
} else if (var->data.compact) {
if (var->data.location_frac) {
info->start_row = next_row - 1;
} else {
info->start_row = next_row;
next_row++;
}
assert(glsl_type_is_array(type) && info->kind == DXIL_SEM_CLIP_DISTANCE);
unsigned num_floats = glsl_get_aoa_size(type);
unsigned start_offset = (var->data.location - VARYING_SLOT_CLIP_DIST0) * 4 +
var->data.location_frac;
if (start_offset >= s->info.clip_distance_array_size) {
info->kind = DXIL_SEM_CULL_DISTANCE;
snprintf(info->name, 64, "SV_CullDistance");
}
info->cols = num_floats;
} else {
info->start_row = next_row;
if (glsl_type_is_array(type) && is_gs_shader)
@ -126,9 +144,11 @@ get_additional_semantic_info(nir_variable *var, struct semantic_info *info,
next_row += info->rows;
}
info->start_col = (uint8_t)var->data.location_frac;
if (glsl_type_is_array(type))
type = glsl_get_array_element(type);
info->cols = (uint8_t)glsl_get_components(type);
if (!info->cols) {
if (glsl_type_is_array(type))
type = glsl_get_array_element(type);
info->cols = (uint8_t)glsl_get_components(type);
}
return next_row;
}
@ -446,7 +466,7 @@ get_input_signature_group(struct dxil_module *mod, const struct dxil_mdnode **in
struct semantic_info semantic = {0};
get_semantics(var, &semantic);
mod->inputs[num_inputs].sysvalue = semantic.sysvalue_name;
*row_iter = get_additional_semantic_info(var, &semantic, *row_iter, is_gs_shader);
*row_iter = get_additional_semantic_info(s, var, &semantic, *row_iter, is_gs_shader);
mod->inputs[num_inputs].name = ralloc_strdup(mod->ralloc_ctx,
semantic.name);
@ -531,7 +551,7 @@ get_output_signature(struct dxil_module *mod, nir_shader *s)
get_semantic_name(var, &semantic, var->type);
mod->outputs[num_outputs].sysvalue = out_sysvalue_name(var);
}
next_row = get_additional_semantic_info(var, &semantic, next_row, false);
next_row = get_additional_semantic_info(s, var, &semantic, next_row, false);
mod->info.has_out_position |= semantic.kind== DXIL_SEM_POSITION;
mod->info.has_out_depth |= semantic.kind == DXIL_SEM_DEPTH;

View file

@ -2448,6 +2448,8 @@ emit_store_output(struct ntd_context *ctx, nir_intrinsic_instr *intr,
nir_variable *output)
{
nir_alu_type out_type = nir_get_nir_type_for_glsl_base_type(glsl_get_base_type(output->type));
if (output->data.compact)
out_type = nir_type_float;
enum overload_type overload = get_overload(out_type, 32);
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.storeOutput", overload);
@ -2459,15 +2461,26 @@ emit_store_output(struct ntd_context *ctx, nir_intrinsic_instr *intr,
const struct dxil_value *row = dxil_module_get_int32_const(&ctx->mod, 0);
bool success = true;
uint32_t writemask = nir_intrinsic_write_mask(intr);
for (unsigned i = 0; i < nir_src_num_components(intr->src[1]) && success; ++i) {
if (writemask & (1 << i)) {
const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, i);
const struct dxil_value *value = get_src(ctx, &intr->src[1], i, out_type);
const struct dxil_value *args[] = {
opcode, output_id, row, col, value
};
success &= dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
if (output->data.compact) {
nir_deref_instr *array_deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
unsigned array_index = nir_src_as_uint(array_deref->arr.index);
const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, array_index);
const struct dxil_value *value = get_src(ctx, &intr->src[1], 0, out_type);
const struct dxil_value *args[] = {
opcode, output_id, row, col, value
};
success = dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
} else {
uint32_t writemask = nir_intrinsic_write_mask(intr);
for (unsigned i = 0; i < nir_src_num_components(intr->src[1]) && success; ++i) {
if (writemask & (1 << i)) {
const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, i);
const struct dxil_value *value = get_src(ctx, &intr->src[1], i, out_type);
const struct dxil_value *args[] = {
opcode, output_id, row, col, value
};
success &= dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
}
}
}
return success;
@ -2529,6 +2542,49 @@ emit_load_input_array(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_va
return true;
}
static bool
emit_load_compact_input_array(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable *var, nir_deref_instr *deref)
{
assert(var);
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_LOAD_INPUT);
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, var->data.driver_location);
const struct dxil_value *row = dxil_module_get_int32_const(&ctx->mod, 0);
const struct dxil_value *vertex_id;
nir_src *col = &deref->arr.index;
nir_src_is_const(*col);
if (ctx->mod.shader_kind == DXIL_GEOMETRY_SHADER) {
nir_deref_instr *deref_parent = nir_deref_instr_parent(deref);
assert(deref_parent->deref_type == nir_deref_type_array);
vertex_id = get_src(ctx, &deref_parent->arr.index, 0, nir_type_int);
} else {
const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
vertex_id = dxil_module_get_undef(&ctx->mod, int32_type);
}
nir_alu_type out_type = nir_type_float;
enum overload_type overload = get_overload(out_type, 32);
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.loadInput", overload);
if (!func)
return false;
const struct dxil_value *comp = dxil_module_get_int8_const(&ctx->mod, nir_src_as_int(*col));
const struct dxil_value *args[] = {
opcode, input_id, row, comp, vertex_id
};
const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
if (!retval)
return false;
store_dest(ctx, &intr->dest, 0, retval, out_type);
return true;
}
static bool
emit_load_input_interpolated(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable *var)
{
@ -2706,8 +2762,12 @@ emit_load_deref(struct ntd_context *ctx, nir_intrinsic_instr *intr)
switch (var->data.mode) {
case nir_var_shader_in:
if (glsl_type_is_array(var->type))
return emit_load_input_array(ctx, intr, var, &deref->arr.index);
if (glsl_type_is_array(var->type)) {
if (var->data.compact)
return emit_load_compact_input_array(ctx, intr, var, deref);
else
return emit_load_input_array(ctx, intr, var, &deref->arr.index);
}
return emit_load_input(ctx, intr, var);
default: