"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/nouveau/nouveau_compiler.c" (16 Sep 2020, 6419 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nouveau_compiler.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright 2014 Ilia Mirkin
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice shall be included in
   12  * all copies or substantial portions of the Software.
   13  *
   14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   20  * OTHER DEALINGS IN THE SOFTWARE.
   21  */
   22 
   23 #include <errno.h>
   24 
   25 #include "tgsi/tgsi_text.h"
   26 #include "util/u_debug.h"
   27 
   28 #include "codegen/nv50_ir_driver.h"
   29 #include "nv50/nv50_context.h"
   30 
   31 /* these headers weren't really meant to be included together */
   32 #undef SB_DATA
   33 
   34 #include "nv30/nv30_state.h"
   35 #include "nv30/nvfx_shader.h"
   36 
   37 static int
   38 nv30_fp(int chipset, struct tgsi_token tokens[],
   39         unsigned *size, unsigned **code) {
   40    struct nv30_fragprog fp;
   41    memset(&fp, 0, sizeof(fp));
   42    fp.pipe.tokens = tokens;
   43    tgsi_scan_shader(fp.pipe.tokens, &fp.info);
   44    _nvfx_fragprog_translate(chipset >= 0x40 ? 0x4097 : 0x3097, &fp);
   45    *size = fp.insn_len * 4;
   46    *code = fp.insn;
   47    return !fp.translated;
   48 }
   49 
   50 static int
   51 nv30_vp(int chipset, struct tgsi_token tokens[],
   52         unsigned *size, unsigned **code) {
   53    struct nv30_vertprog vp;
   54    memset(&vp, 0, sizeof(vp));
   55 
   56    vp.pipe.tokens = tokens;
   57    tgsi_scan_shader(vp.pipe.tokens, &vp.info);
   58    _nvfx_vertprog_translate(chipset >= 0x40 ? 0x4097 : 0x3097, &vp);
   59    *size = vp.nr_insns * 16;
   60    *code = (unsigned *)vp.insns;
   61    return !vp.translated;
   62 }
   63 
   64 static int
   65 nv30_codegen(int chipset, int type, struct tgsi_token tokens[],
   66              unsigned *size, unsigned **code) {
   67    switch (type) {
   68       case PIPE_SHADER_FRAGMENT:
   69          return nv30_fp(chipset, tokens, size, code);
   70       case PIPE_SHADER_VERTEX:
   71          return nv30_vp(chipset, tokens, size, code);
   72    }
   73    _debug_printf("Unexpected shader type: %d\n", type);
   74    return 1;
   75 }
   76 
   77 static int
   78 dummy_assign_slots(struct nv50_ir_prog_info *info)
   79 {
   80    unsigned i, n, c;
   81 
   82    n = 0;
   83    for (i = 0; i < info->numInputs; ++i) {
   84       for (c = 0; c < 4; ++c)
   85          if (info->in[i].mask & (1 << c))
   86             info->in[i].slot[c] = n++;
   87    }
   88 
   89    /* VertexID before InstanceID */
   90    if (info->io.vertexId < info->numSysVals)
   91       info->sv[info->io.vertexId].slot[0] = n++;
   92    if (info->io.instanceId < info->numSysVals)
   93       info->sv[info->io.instanceId].slot[0] = n++;
   94 
   95    n = 0;
   96    for (i = 0; i < info->numOutputs; ++i) {
   97       for (c = 0; c < 4; ++c)
   98          if (info->out[i].mask & (1 << c))
   99             info->out[i].slot[c] = n++;
  100    }
  101    return 0;
  102 }
  103 
  104 static int
  105 nouveau_codegen(int chipset, int type, struct tgsi_token tokens[],
  106                 unsigned *size, unsigned **code) {
  107    struct nv50_ir_prog_info info = {0};
  108    int ret;
  109 
  110    info.type = type;
  111    info.target = chipset;
  112    info.bin.sourceRep = PIPE_SHADER_IR_TGSI;
  113    info.bin.source = tokens;
  114 
  115    info.io.auxCBSlot = 15;
  116    info.io.ucpBase = NV50_CB_AUX_UCP_OFFSET;
  117    info.io.suInfoBase = NV50_CB_AUX_TEX_MS_OFFSET;
  118    info.io.msInfoCBSlot = 15;
  119    info.io.msInfoBase = NV50_CB_AUX_MS_OFFSET;
  120 
  121    info.assignSlots = dummy_assign_slots;
  122 
  123    info.optLevel = debug_get_num_option("NV50_PROG_OPTIMIZE", 3);
  124    info.dbgFlags = debug_get_num_option("NV50_PROG_DEBUG", 0);
  125    info.omitLineNum = debug_get_num_option("NV50_PROG_DEBUG_OMIT_LINENUM", 0);
  126 
  127    ret = nv50_ir_generate_code(&info);
  128    if (ret) {
  129       _debug_printf("Error compiling program: %d\n", ret);
  130       return ret;
  131    }
  132 
  133    *size = info.bin.codeSize;
  134    *code = info.bin.code;
  135    return 0;
  136 }
  137 
  138 int
  139 main(int argc, char *argv[])
  140 {
  141    struct tgsi_token tokens[4096];
  142    int i, chipset = 0, type = -1;
  143    const char *filename = NULL;
  144    FILE *f;
  145    char text[65536] = {0};
  146    unsigned size = 0, *code = NULL;
  147 
  148    for (i = 1; i < argc; i++) {
  149       if (!strcmp(argv[i], "-a"))
  150          chipset = strtol(argv[++i], NULL, 16);
  151       else
  152          filename = argv[i];
  153    }
  154 
  155    if (!chipset) {
  156       _debug_printf("Must specify a chipset (-a)\n");
  157       return 1;
  158    }
  159 
  160    if (!filename) {
  161       _debug_printf("Must specify a filename\n");
  162       return 1;
  163    }
  164 
  165    if (!strcmp(filename, "-"))
  166       f = stdin;
  167    else
  168       f = fopen(filename, "r");
  169 
  170    if (!f) {
  171       _debug_printf("Error opening file '%s': %s\n", filename, strerror(errno));
  172       return 1;
  173    }
  174 
  175    if (!fread(text, 1, sizeof(text), f) || ferror(f)) {
  176       _debug_printf("Error reading file '%s'\n", filename);
  177       fclose(f);
  178       return 1;
  179    }
  180    fclose(f);
  181 
  182    _debug_printf("Compiling for NV%X\n", chipset);
  183 
  184    if (!strncmp(text, "FRAG", 4))
  185       type = PIPE_SHADER_FRAGMENT;
  186    else if (!strncmp(text, "VERT", 4))
  187       type = PIPE_SHADER_VERTEX;
  188    else if (!strncmp(text, "GEOM", 4))
  189       type = PIPE_SHADER_GEOMETRY;
  190    else if (!strncmp(text, "COMP", 4))
  191       type = PIPE_SHADER_COMPUTE;
  192    else if (!strncmp(text, "TESS_CTRL", 9))
  193       type = PIPE_SHADER_TESS_CTRL;
  194    else if (!strncmp(text, "TESS_EVAL", 9))
  195       type = PIPE_SHADER_TESS_EVAL;
  196    else {
  197       _debug_printf("Unrecognized TGSI header\n");
  198       return 1;
  199    }
  200 
  201    if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
  202       _debug_printf("Failed to parse TGSI shader\n");
  203       return 1;
  204    }
  205 
  206    if (chipset >= 0x50) {
  207       i = nouveau_codegen(chipset, type, tokens, &size, &code);
  208    } else if (chipset >= 0x30) {
  209       i = nv30_codegen(chipset, type, tokens, &size, &code);
  210    } else {
  211       _debug_printf("chipset NV%02X not supported\n", chipset);
  212       i = 1;
  213    }
  214    if (i)
  215       return i;
  216 
  217    _debug_printf("program binary (%d bytes)\n", size);
  218    for (i = 0; i < size; i += 4) {
  219       printf("%08x ", code[i / 4]);
  220       if (i % (8 * 4) == (7 * 4))
  221          printf("\n");
  222    }
  223    if (i % (8 * 4) != 0)
  224       printf("\n");
  225 
  226    return 0;
  227 }