X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Fir3%2Fir3_cmdline.c;h=b2aa9f063a7dedfbe6582d0625b09668434231bd;hb=59fb59ad54d368683d5cc3b149f021452bddc05f;hp=ad9d2719d59a0a9f9497f567e989c3774362ab69;hpb=c8fb5f8a011e1db78af3ceaf91c5cb3b1acaee14;p=mesa.git diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index ad9d2719d59..b2aa9f063a7 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -40,132 +40,131 @@ #include "freedreno_util.h" #include "ir3_compiler.h" +#include "ir3_nir.h" #include "instr-a3xx.h" #include "ir3.h" -static void dump_reg(const char *name, uint32_t r) -{ - if (r != regid(63,0)) - debug_printf("; %s: r%d.%c\n", name, r >> 2, "xyzw"[r & 0x3]); -} - -static void dump_semantic(struct ir3_shader_variant *so, - unsigned sem, const char *name) -{ - uint32_t regid; - regid = ir3_find_output_regid(so, ir3_semantic_name(sem, 0)); - dump_reg(name, regid); -} +#include "compiler/glsl/standalone.h" +#include "compiler/glsl/glsl_to_nir.h" +#include "compiler/nir_types.h" static void dump_info(struct ir3_shader_variant *so, const char *str) { uint32_t *bin; - const char *type = (so->type == SHADER_VERTEX) ? "VERT" : "FRAG"; - - // for debug, dump some before/after info: - // TODO make gpu_id configurable on cmdline - bin = ir3_shader_assemble(so, 320); - if (fd_mesa_debug & FD_DBG_DISASM) { - struct ir3 *ir = so->ir; - struct ir3_register *reg; - uint8_t regid; - unsigned i; - - debug_printf("; %s: %s\n", type, str); - - for (i = 0; i < ir->ninputs; i++) { - if (!ir->inputs[i]) { - debug_printf("; in%d unused\n", i); - continue; - } - reg = ir->inputs[i]->regs[0]; - regid = reg->num; - debug_printf("@in(%sr%d.%c)\tin%d\n", - (reg->flags & IR3_REG_HALF) ? "h" : "", - (regid >> 2), "xyzw"[regid & 0x3], i); - } - - for (i = 0; i < ir->noutputs; i++) { - if (!ir->outputs[i]) { - debug_printf("; out%d unused\n", i); - continue; - } - /* kill shows up as a virtual output.. skip it! */ - if (is_kill(ir->outputs[i])) - continue; - reg = ir->outputs[i]->regs[0]; - regid = reg->num; - debug_printf("@out(%sr%d.%c)\tout%d\n", - (reg->flags & IR3_REG_HALF) ? "h" : "", - (regid >> 2), "xyzw"[regid & 0x3], i); - } + const char *type = ir3_shader_stage(so->shader); + bin = ir3_shader_assemble(so, so->shader->compiler->gpu_id); + debug_printf("; %s: %s\n", type, str); + ir3_shader_disasm(so, bin); + free(bin); +} - for (i = 0; i < so->immediates_count; i++) { - debug_printf("@const(c%d.x)\t", so->first_immediate + i); - debug_printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - so->immediates[i].val[0], - so->immediates[i].val[1], - so->immediates[i].val[2], - so->immediates[i].val[3]); +static void +insert_sorted(struct exec_list *var_list, nir_variable *new_var) +{ + nir_foreach_variable(var, var_list) { + if (var->data.location > new_var->data.location) { + exec_node_insert_node_before(&var->node, &new_var->node); + return; } + } + exec_list_push_tail(var_list, &new_var->node); +} - disasm_a3xx(bin, so->info.sizedwords, 0, so->type); +static void +sort_varyings(struct exec_list *var_list) +{ + struct exec_list new_list; + exec_list_make_empty(&new_list); + nir_foreach_variable_safe(var, var_list) { + exec_node_remove(&var->node); + insert_sorted(&new_list, var); + } + exec_list_move_nodes_to(&new_list, var_list); +} - debug_printf("; %s: outputs:", type); - for (i = 0; i < so->outputs_count; i++) { - uint8_t regid = so->outputs[i].regid; - ir3_semantic sem = so->outputs[i].semantic; - debug_printf(" r%d.%c (%u:%u)", - (regid >> 2), "xyzw"[regid & 0x3], - sem2name(sem), sem2idx(sem)); - } - debug_printf("\n"); - debug_printf("; %s: inputs:", type); - for (i = 0; i < so->inputs_count; i++) { - uint8_t regid = so->inputs[i].regid; - ir3_semantic sem = so->inputs[i].semantic; - debug_printf(" r%d.%c (%u:%u,cm=%x,il=%u,b=%u)", - (regid >> 2), "xyzw"[regid & 0x3], - sem2name(sem), sem2idx(sem), - so->inputs[i].compmask, - so->inputs[i].inloc, - so->inputs[i].bary); +static void +fixup_varying_slots(struct exec_list *var_list) +{ + nir_foreach_variable(var, var_list) { + if (var->data.location >= VARYING_SLOT_VAR0) { + var->data.location += 9; + } else if ((var->data.location >= VARYING_SLOT_TEX0) && + (var->data.location <= VARYING_SLOT_TEX7)) { + var->data.location += VARYING_SLOT_VAR0 - VARYING_SLOT_TEX0; } - debug_printf("\n"); } +} - /* print generic shader info: */ - debug_printf("; %s: %u instructions, %d half, %d full\n", type, - so->info.instrs_count, - so->info.max_half_reg + 1, - so->info.max_reg + 1); - - /* print shader type specific info: */ - switch (so->type) { - case SHADER_VERTEX: - dump_semantic(so, TGSI_SEMANTIC_POSITION, "pos"); - dump_semantic(so, TGSI_SEMANTIC_PSIZE, "psize"); - break; - case SHADER_FRAGMENT: - dump_reg("pos (bary)", so->pos_regid); - dump_semantic(so, TGSI_SEMANTIC_POSITION, "posz"); - dump_semantic(so, TGSI_SEMANTIC_COLOR, "color"); - /* these two are hard-coded since we don't know how to - * program them to anything but all 0's... - */ - if (so->frag_coord) - debug_printf("; fragcoord: r0.x\n"); - if (so->frag_face) - debug_printf("; fragface: hr0.x\n"); +static struct ir3_compiler *compiler; + +static nir_shader * +load_glsl(unsigned num_files, char* const* files, gl_shader_stage stage) +{ + static const struct standalone_options options = { + .glsl_version = 140, + .do_link = true, + }; + struct gl_shader_program *prog; + + prog = standalone_compile_shader(&options, num_files, files); + if (!prog) + errx(1, "couldn't parse `%s'", files[0]); + + nir_shader *nir = glsl_to_nir(prog, stage, ir3_get_compiler_options(compiler)); + + /* required NIR passes: */ + /* TODO cmdline args for some of the conditional lowering passes? */ + + NIR_PASS_V(nir, nir_lower_io_to_temporaries, + nir_shader_get_entrypoint(nir), + true, true); + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS_V(nir, nir_lower_io_types); + + switch (stage) { + case MESA_SHADER_VERTEX: + nir_assign_var_locations(&nir->inputs, + &nir->num_inputs, + ir3_glsl_type_size); + + /* Re-lower global vars, to deal with any dead VS inputs. */ + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + + sort_varyings(&nir->outputs); + nir_assign_var_locations(&nir->outputs, + &nir->num_outputs, + ir3_glsl_type_size); + fixup_varying_slots(&nir->outputs); break; - case SHADER_COMPUTE: + case MESA_SHADER_FRAGMENT: + sort_varyings(&nir->inputs); + nir_assign_var_locations(&nir->inputs, + &nir->num_inputs, + ir3_glsl_type_size); + fixup_varying_slots(&nir->inputs); + nir_assign_var_locations(&nir->outputs, + &nir->num_outputs, + ir3_glsl_type_size); break; + default: + errx(1, "unhandled shader stage: %d", stage); } - free(bin); - debug_printf("\n"); -} + nir_assign_var_locations(&nir->uniforms, + &nir->num_uniforms, + ir3_glsl_type_size); + NIR_PASS_V(nir, nir_lower_system_values); + NIR_PASS_V(nir, nir_lower_io, nir_var_all, ir3_glsl_type_size, 0); + NIR_PASS_V(nir, nir_lower_samplers, prog); + + return nir; +} static int read_file(const char *filename, void **ptr, size_t *size) @@ -197,7 +196,7 @@ read_file(const char *filename, void **ptr, size_t *size) static void print_usage(void) { - printf("Usage: ir3_compiler [OPTIONS]... FILE\n"); + printf("Usage: ir3_compiler [OPTIONS]... \n"); printf(" --verbose - verbose compiler/debug messages\n"); printf(" --binning-pass - generate binning pass shader (VERT)\n"); printf(" --color-two-side - emulate two-sided color (FRAG)\n"); @@ -205,25 +204,30 @@ static void print_usage(void) printf(" --saturate-s MASK - bitmask of samplers to saturate S coord\n"); printf(" --saturate-t MASK - bitmask of samplers to saturate T coord\n"); printf(" --saturate-r MASK - bitmask of samplers to saturate R coord\n"); - printf(" --nocp - disable copy propagation\n"); - printf(" --nir - use NIR compiler\n"); + printf(" --astc-srgb MASK - bitmask of samplers to enable astc-srgb workaround\n"); + printf(" --stream-out - enable stream-out (aka transform feedback)\n"); + printf(" --ucp MASK - bitmask of enabled user-clip-planes\n"); + printf(" --gpu GPU_ID - specify gpu-id (default 320)\n"); printf(" --help - show this message\n"); } int main(int argc, char **argv) { int ret = 0, n = 1; - const char *filename; - struct tgsi_token toks[65536]; - struct tgsi_parse_context parse; - struct ir3_compiler *compiler; + char *filenames[2]; + int num_files = 0; + unsigned stage = 0; struct ir3_shader_variant v; + struct ir3_shader s; struct ir3_shader_key key = {}; + /* TODO cmdline option to target different gpus: */ + unsigned gpu_id = 320; const char *info; void *ptr; size_t size; - fd_mesa_debug |= FD_DBG_DISASM; + memset(&s, 0, sizeof(s)); + memset(&v, 0, sizeof(v)); /* cmdline args which impact shader variant get spit out in a * comment on the first line.. a quick/dirty way to preserve @@ -234,7 +238,7 @@ int main(int argc, char **argv) while (n < argc) { if (!strcmp(argv[n], "--verbose")) { - fd_mesa_debug |= FD_DBG_MSGS | FD_DBG_OPTMSGS; + fd_mesa_debug |= FD_DBG_MSGS | FD_DBG_OPTMSGS | FD_DBG_DISASM; n++; continue; } @@ -281,6 +285,45 @@ int main(int argc, char **argv) continue; } + if (!strcmp(argv[n], "--astc-srgb")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.vastc_srgb = key.fastc_srgb = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--stream-out")) { + struct pipe_stream_output_info *so = &s.stream_output; + debug_printf(" %s", argv[n]); + /* TODO more dynamic config based on number of outputs, etc + * rather than just hard-code for first output: + */ + so->num_outputs = 1; + so->stride[0] = 4; + so->output[0].register_index = 0; + so->output[0].start_component = 0; + so->output[0].num_components = 4; + so->output[0].output_buffer = 0; + so->output[0].dst_offset = 2; + so->output[0].stream = 0; + n++; + continue; + } + + if (!strcmp(argv[n], "--ucp")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.ucp_enables = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--gpu")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + gpu_id = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + if (!strcmp(argv[n], "--help")) { print_usage(); return 0; @@ -290,41 +333,88 @@ int main(int argc, char **argv) } debug_printf("\n"); - filename = argv[n]; + while (n < argc) { + char *filename = argv[n]; + char *ext = rindex(filename, '.'); + + if (strcmp(ext, ".tgsi") == 0) { + if (num_files != 0) + errx(1, "in TGSI mode, only a single file may be specified"); + s.from_tgsi = true; + } else if (strcmp(ext, ".frag") == 0) { + if (s.from_tgsi) + errx(1, "cannot mix GLSL and TGSI"); + if (num_files >= ARRAY_SIZE(filenames)) + errx(1, "too many GLSL files"); + stage = MESA_SHADER_FRAGMENT; + } else if (strcmp(ext, ".vert") == 0) { + if (s.from_tgsi) + errx(1, "cannot mix GLSL and TGSI"); + if (num_files >= ARRAY_SIZE(filenames)) + errx(1, "too many GLSL files"); + stage = MESA_SHADER_VERTEX; + } else { + print_usage(); + return -1; + } - memset(&v, 0, sizeof(v)); - v.key = key; + filenames[num_files++] = filename; - ret = read_file(filename, &ptr, &size); - if (ret) { + n++; + } + + nir_shader *nir; + + compiler = ir3_compiler_create(NULL, gpu_id); + + if (s.from_tgsi) { + struct tgsi_token toks[65536]; + + ret = read_file(filenames[0], &ptr, &size); + if (ret) { + print_usage(); + return ret; + } + + if (fd_mesa_debug & FD_DBG_OPTMSGS) + debug_printf("%s\n", (char *)ptr); + + if (!tgsi_text_translate(ptr, toks, ARRAY_SIZE(toks))) + errx(1, "could not parse `%s'", filenames[0]); + + if (fd_mesa_debug & FD_DBG_OPTMSGS) + tgsi_dump(toks, 0); + + nir = ir3_tgsi_to_nir(toks); + } else if (num_files > 0) { + nir = load_glsl(num_files, filenames, stage); + } else { print_usage(); - return ret; + return -1; } - if (fd_mesa_debug & FD_DBG_OPTMSGS) - debug_printf("%s\n", (char *)ptr); + s.compiler = compiler; + s.nir = ir3_optimize_nir(&s, nir, NULL); - if (!tgsi_text_translate(ptr, toks, Elements(toks))) - errx(1, "could not parse `%s'", filename); + v.key = key; + v.shader = &s; - tgsi_parse_init(&parse, toks); - switch (parse.FullHeader.Processor.Processor) { - case TGSI_PROCESSOR_FRAGMENT: - v.type = SHADER_FRAGMENT; + switch (nir->info.stage) { + case MESA_SHADER_FRAGMENT: + s.type = v.type = SHADER_FRAGMENT; break; - case TGSI_PROCESSOR_VERTEX: - v.type = SHADER_VERTEX; + case MESA_SHADER_VERTEX: + s.type = v.type = SHADER_VERTEX; break; - case TGSI_PROCESSOR_COMPUTE: - v.type = SHADER_COMPUTE; + case MESA_SHADER_COMPUTE: + s.type = v.type = SHADER_COMPUTE; break; + default: + errx(1, "unhandled shader stage: %d", nir->info.stage); } - /* TODO cmdline option to target different gpus: */ - compiler = ir3_compiler_create(320); - info = "NIR compiler"; - ret = ir3_compile_shader_nir(compiler, &v, toks, key); + ret = ir3_compile_shader_nir(s.compiler, &v); if (ret) { fprintf(stderr, "compiler failed!\n"); return ret;