Path: blob/21.2-virgl/src/asahi/compiler/cmdline.c
4564 views
/*1* Copyright (C) 2019 Ryan Houdek <[email protected]>2* Copyright (C) 2014 Rob Clark <[email protected]>3* Copyright © 2015 Red Hat4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice (including the next13* paragraph) shall be included in all copies or substantial portions of the14* Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE22* SOFTWARE.23*/2425#include "main/mtypes.h"26#include "compiler/glsl/standalone.h"27#include "compiler/glsl/glsl_to_nir.h"28#include "compiler/glsl/gl_nir.h"29#include "compiler/nir_types.h"30#include "util/u_dynarray.h"31#include "agx_compile.h"32#include "agx_minifloat.h"3334static int35st_packed_uniforms_type_size(const struct glsl_type *type, bool bindless)36{37return glsl_count_dword_slots(type, bindless);38}3940static int41glsl_type_size(const struct glsl_type *type, bool bindless)42{43return glsl_count_attribute_slots(type, false);44}4546static void47insert_sorted(struct exec_list *var_list, nir_variable *new_var)48{49nir_foreach_variable_in_list (var, var_list) {50if (var->data.location > new_var->data.location) {51exec_node_insert_node_before(&var->node, &new_var->node);52return;53}54}55exec_list_push_tail(var_list, &new_var->node);56}5758static void59sort_varyings(nir_shader *nir, nir_variable_mode mode)60{61struct exec_list new_list;62exec_list_make_empty(&new_list);63nir_foreach_variable_with_modes_safe (var, nir, mode) {64exec_node_remove(&var->node);65insert_sorted(&new_list, var);66}67exec_list_append(&nir->variables, &new_list);68}6970static void71fixup_varying_slots(nir_shader *nir, nir_variable_mode mode)72{73nir_foreach_variable_with_modes (var, nir, mode) {74if (var->data.location >= VARYING_SLOT_VAR0) {75var->data.location += 9;76} else if ((var->data.location >= VARYING_SLOT_TEX0) &&77(var->data.location <= VARYING_SLOT_TEX7)) {78var->data.location += VARYING_SLOT_VAR0 - VARYING_SLOT_TEX0;79}80}81}8283static void84compile_shader(char **argv)85{86struct gl_shader_program *prog;87nir_shader *nir[2];88unsigned shader_types[2] = {89MESA_SHADER_VERTEX,90MESA_SHADER_FRAGMENT,91};9293struct standalone_options options = {94.glsl_version = 300, /* ES - needed for precision */95.do_link = true,96.lower_precision = true97};9899static struct gl_context local_ctx;100101prog = standalone_compile_shader(&options, 2, argv, &local_ctx);102prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->info.stage = MESA_SHADER_FRAGMENT;103104struct util_dynarray binary;105106util_dynarray_init(&binary, NULL);107108for (unsigned i = 0; i < 2; ++i) {109nir[i] = glsl_to_nir(&local_ctx, prog, shader_types[i], &agx_nir_options);110111if (i == 0) {112nir_assign_var_locations(nir[i], nir_var_shader_in, &nir[i]->num_inputs,113glsl_type_size);114sort_varyings(nir[i], nir_var_shader_out);115nir_assign_var_locations(nir[i], nir_var_shader_out, &nir[i]->num_outputs,116glsl_type_size);117fixup_varying_slots(nir[i], nir_var_shader_out);118} else {119sort_varyings(nir[i], nir_var_shader_in);120nir_assign_var_locations(nir[i], nir_var_shader_in, &nir[i]->num_inputs,121glsl_type_size);122fixup_varying_slots(nir[i], nir_var_shader_in);123nir_assign_var_locations(nir[i], nir_var_shader_out, &nir[i]->num_outputs,124glsl_type_size);125}126127nir_assign_var_locations(nir[i], nir_var_uniform, &nir[i]->num_uniforms,128glsl_type_size);129130NIR_PASS_V(nir[i], nir_lower_global_vars_to_local);131NIR_PASS_V(nir[i], nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir[i]), true, i == 0);132NIR_PASS_V(nir[i], nir_lower_system_values);133NIR_PASS_V(nir[i], gl_nir_lower_samplers, prog);134NIR_PASS_V(nir[i], nir_split_var_copies);135NIR_PASS_V(nir[i], nir_lower_var_copies);136137NIR_PASS_V(nir[i], nir_lower_io, nir_var_uniform,138st_packed_uniforms_type_size,139(nir_lower_io_options)0);140NIR_PASS_V(nir[i], nir_lower_uniforms_to_ubo, true, false);141142/* before buffers and vars_to_ssa */143NIR_PASS_V(nir[i], gl_nir_lower_images, true);144145NIR_PASS_V(nir[i], gl_nir_lower_buffers, prog);146NIR_PASS_V(nir[i], nir_opt_constant_folding);147148struct agx_shader_info out = { 0 };149struct agx_shader_key keys[2] = {150{151.vs = {152.num_vbufs = 1,153.vbuf_strides = { 16 },154.attributes = {155{156.buf = 0,157.src_offset = 0,158.format = AGX_FORMAT_I32,159.nr_comps_minus_1 = 4 - 1160}161},162}163},164{165.fs = {166.tib_formats = { AGX_FORMAT_U8NORM }167}168}169};170171agx_compile_shader_nir(nir[i], &keys[i], &binary, &out);172173char *fn = NULL;174asprintf(&fn, "shader_%u.bin", i);175assert(fn != NULL);176FILE *fp = fopen(fn, "wb");177fwrite(binary.data, 1, binary.size, fp);178fclose(fp);179free(fn);180181util_dynarray_clear(&binary);182}183184util_dynarray_fini(&binary);185}186187static void188disassemble(const char *filename, bool verbose)189{190FILE *fp = fopen(filename, "rb");191assert(fp);192193fseek(fp, 0, SEEK_END);194unsigned filesize = ftell(fp);195rewind(fp);196197uint32_t *code = malloc(filesize);198unsigned res = fread(code, 1, filesize, fp);199if (res != filesize) {200printf("Couldn't read full file\n");201}202fclose(fp);203204/* TODO: stub */205206free(code);207}208209static void210tests()211{212#ifndef NDEBUG213agx_minifloat_tests();214printf("Pass.\n");215#else216fprintf(stderr, "tests not compiled in NDEBUG mode");217#endif218}219220int221main(int argc, char **argv)222{223if (argc < 2) {224printf("Pass a command\n");225exit(1);226}227228if (strcmp(argv[1], "compile") == 0)229compile_shader(&argv[2]);230else if (strcmp(argv[1], "disasm") == 0)231disassemble(argv[2], false);232else if (strcmp(argv[1], "disasm-verbose") == 0)233disassemble(argv[2], true);234else if (strcmp(argv[1], "test") == 0)235tests();236else237unreachable("Unknown command. Valid: compile/disasm/disasm-verbose");238239return 0;240}241242243