Home | History | Annotate | Download | only in nouveau
      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 = NV50_PROGRAM_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 
    126    ret = nv50_ir_generate_code(&info);
    127    if (ret) {
    128       _debug_printf("Error compiling program: %d\n", ret);
    129       return ret;
    130    }
    131 
    132    *size = info.bin.codeSize;
    133    *code = info.bin.code;
    134    return 0;
    135 }
    136 
    137 int
    138 main(int argc, char *argv[])
    139 {
    140    struct tgsi_token tokens[4096];
    141    int i, chipset = 0, type = -1;
    142    const char *filename = NULL;
    143    FILE *f;
    144    char text[65536] = {0};
    145    unsigned size = 0, *code = NULL;
    146 
    147    for (i = 1; i < argc; i++) {
    148       if (!strcmp(argv[i], "-a"))
    149          chipset = strtol(argv[++i], NULL, 16);
    150       else
    151          filename = argv[i];
    152    }
    153 
    154    if (!chipset) {
    155       _debug_printf("Must specify a chipset (-a)\n");
    156       return 1;
    157    }
    158 
    159    if (!filename) {
    160       _debug_printf("Must specify a filename\n");
    161       return 1;
    162    }
    163 
    164    if (!strcmp(filename, "-"))
    165       f = stdin;
    166    else
    167       f = fopen(filename, "r");
    168 
    169    if (!f) {
    170       _debug_printf("Error opening file '%s': %s\n", filename, strerror(errno));
    171       return 1;
    172    }
    173 
    174    if (!fread(text, 1, sizeof(text), f) || ferror(f)) {
    175       _debug_printf("Error reading file '%s'\n", filename);
    176       fclose(f);
    177       return 1;
    178    }
    179    fclose(f);
    180 
    181    _debug_printf("Compiling for NV%X\n", chipset);
    182 
    183    if (!strncmp(text, "FRAG", 4))
    184       type = PIPE_SHADER_FRAGMENT;
    185    else if (!strncmp(text, "VERT", 4))
    186       type = PIPE_SHADER_VERTEX;
    187    else if (!strncmp(text, "GEOM", 4))
    188       type = PIPE_SHADER_GEOMETRY;
    189    else if (!strncmp(text, "COMP", 4))
    190       type = PIPE_SHADER_COMPUTE;
    191    else if (!strncmp(text, "TESS_CTRL", 9))
    192       type = PIPE_SHADER_TESS_CTRL;
    193    else if (!strncmp(text, "TESS_EVAL", 9))
    194       type = PIPE_SHADER_TESS_EVAL;
    195    else {
    196       _debug_printf("Unrecognized TGSI header\n");
    197       return 1;
    198    }
    199 
    200    if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
    201       _debug_printf("Failed to parse TGSI shader\n");
    202       return 1;
    203    }
    204 
    205    if (chipset >= 0x50) {
    206       i = nouveau_codegen(chipset, type, tokens, &size, &code);
    207    } else if (chipset >= 0x30) {
    208       i = nv30_codegen(chipset, type, tokens, &size, &code);
    209    } else {
    210       _debug_printf("chipset NV%02X not supported\n", chipset);
    211       i = 1;
    212    }
    213    if (i)
    214       return i;
    215 
    216    _debug_printf("program binary (%d bytes)\n", size);
    217    for (i = 0; i < size; i += 4) {
    218       printf("%08x ", code[i / 4]);
    219       if (i % (8 * 4) == (7 * 4))
    220          printf("\n");
    221    }
    222    if (i % (8 * 4) != 0)
    223       printf("\n");
    224 
    225    return 0;
    226 }
    227