Home | History | Annotate | Download | only in shader
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2012-2013 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #include "toy_compiler.h"
     29 #include "toy_helpers.h"
     30 #include "toy_legalize.h"
     31 #include "toy_optimize.h"
     32 #include "ilo_shader_internal.h"
     33 
     34 struct cs_compile_context {
     35    struct ilo_shader *shader;
     36    const struct ilo_shader_variant *variant;
     37 
     38    struct toy_compiler tc;
     39 
     40    int first_free_grf;
     41    int last_free_grf;
     42 
     43    int num_grf_per_vrf;
     44 
     45    int first_free_mrf;
     46    int last_free_mrf;
     47 };
     48 
     49 /**
     50  * Compile the shader.
     51  */
     52 static bool
     53 cs_compile(struct cs_compile_context *ccc)
     54 {
     55    struct toy_compiler *tc = &ccc->tc;
     56    struct ilo_shader *sh = ccc->shader;
     57 
     58    toy_compiler_legalize_for_ra(tc);
     59    toy_compiler_optimize(tc);
     60    toy_compiler_allocate_registers(tc,
     61          ccc->first_free_grf,
     62          ccc->last_free_grf,
     63          ccc->num_grf_per_vrf);
     64    toy_compiler_legalize_for_asm(tc);
     65 
     66    if (tc->fail) {
     67       ilo_err("failed to legalize FS instructions: %s\n", tc->reason);
     68       return false;
     69    }
     70 
     71    if (ilo_debug & ILO_DEBUG_CS) {
     72       ilo_printf("legalized instructions:\n");
     73       toy_compiler_dump(tc);
     74       ilo_printf("\n");
     75    }
     76 
     77    if (true) {
     78       sh->kernel = toy_compiler_assemble(tc, &sh->kernel_size);
     79    } else {
     80       static const uint32_t microcode[] = {
     81          /* fill in the microcode here */
     82          0x0, 0x0, 0x0, 0x0,
     83       };
     84       const bool swap = true;
     85 
     86       sh->kernel_size = sizeof(microcode);
     87       sh->kernel = MALLOC(sh->kernel_size);
     88 
     89       if (sh->kernel) {
     90          const int num_dwords = sizeof(microcode) / 4;
     91          const uint32_t *src = microcode;
     92          uint32_t *dst = (uint32_t *) sh->kernel;
     93          int i;
     94 
     95          for (i = 0; i < num_dwords; i += 4) {
     96             if (swap) {
     97                dst[i + 0] = src[i + 3];
     98                dst[i + 1] = src[i + 2];
     99                dst[i + 2] = src[i + 1];
    100                dst[i + 3] = src[i + 0];
    101             }
    102             else {
    103                memcpy(dst, src, 16);
    104             }
    105          }
    106       }
    107    }
    108 
    109    if (!sh->kernel) {
    110       ilo_err("failed to compile CS: %s\n", tc->reason);
    111       return false;
    112    }
    113 
    114    if (ilo_debug & ILO_DEBUG_CS) {
    115       ilo_printf("disassembly:\n");
    116       toy_compiler_disassemble(tc->dev, sh->kernel, sh->kernel_size, false);
    117       ilo_printf("\n");
    118    }
    119 
    120    return true;
    121 }
    122 
    123 static void
    124 cs_dummy(struct cs_compile_context *ccc)
    125 {
    126    struct toy_compiler *tc = &ccc->tc;
    127    struct toy_dst header;
    128    struct toy_src r0, desc;
    129    struct toy_inst *inst;
    130 
    131    header = tdst_ud(tdst(TOY_FILE_MRF, ccc->first_free_mrf, 0));
    132    r0 = tsrc_ud(tsrc(TOY_FILE_GRF, 0, 0));
    133 
    134    inst = tc_MOV(tc, header, r0);
    135    inst->exec_size = GEN6_EXECSIZE_8;
    136    inst->mask_ctrl = GEN6_MASKCTRL_NOMASK;
    137 
    138    desc = tsrc_imm_mdesc(tc, true, 1, 0, true,
    139          GEN6_MSG_TS_RESOURCE_SELECT_NO_DEREF |
    140          GEN6_MSG_TS_REQUESTER_TYPE_ROOT |
    141          GEN6_MSG_TS_OPCODE_DEREF);
    142 
    143    tc_SEND(tc, tdst_null(), tsrc_from(header), desc, GEN6_SFID_SPAWNER);
    144 }
    145 
    146 static bool
    147 cs_setup(struct cs_compile_context *ccc,
    148          const struct ilo_shader_state *state,
    149          const struct ilo_shader_variant *variant)
    150 {
    151    memset(ccc, 0, sizeof(*ccc));
    152 
    153    ccc->shader = CALLOC_STRUCT(ilo_shader);
    154    if (!ccc->shader)
    155       return false;
    156 
    157    ccc->variant = variant;
    158 
    159    toy_compiler_init(&ccc->tc, state->info.dev);
    160 
    161    ccc->tc.templ.access_mode = GEN6_ALIGN_1;
    162    ccc->tc.templ.qtr_ctrl = GEN6_QTRCTRL_1H;
    163    ccc->tc.templ.exec_size = GEN6_EXECSIZE_16;
    164    ccc->tc.rect_linear_width = 8;
    165 
    166    ccc->first_free_grf = 1;
    167    ccc->last_free_grf = 127;
    168 
    169    /* m0 is reserved for system routines */
    170    ccc->first_free_mrf = 1;
    171    ccc->last_free_mrf = 15;
    172 
    173    /* instructions are compressed with GEN6_EXECSIZE_16 */
    174    ccc->num_grf_per_vrf = 2;
    175 
    176    if (ilo_dev_gen(ccc->tc.dev) >= ILO_GEN(7)) {
    177       ccc->last_free_grf -= 15;
    178       ccc->first_free_mrf = ccc->last_free_grf + 1;
    179       ccc->last_free_mrf = ccc->first_free_mrf + 14;
    180    }
    181 
    182    ccc->shader->in.start_grf = 1;
    183    ccc->shader->dispatch_16 = true;
    184 
    185    /* INPUT */
    186    ccc->shader->bt.const_base = 0;
    187    ccc->shader->bt.const_count = 1;
    188 
    189    /* a GLOBAL */
    190    ccc->shader->bt.global_base = 1;
    191    ccc->shader->bt.global_count = 1;
    192 
    193    ccc->shader->bt.total_count = 2;
    194 
    195    return true;
    196 }
    197 
    198 /**
    199  * Compile the compute shader.
    200  */
    201 struct ilo_shader *
    202 ilo_shader_compile_cs(const struct ilo_shader_state *state,
    203                       const struct ilo_shader_variant *variant)
    204 {
    205    struct cs_compile_context ccc;
    206 
    207    ILO_DEV_ASSERT(state->info.dev, 7, 7.5);
    208 
    209    if (!cs_setup(&ccc, state, variant))
    210       return NULL;
    211 
    212    cs_dummy(&ccc);
    213 
    214    if (!cs_compile(&ccc)) {
    215       FREE(ccc.shader);
    216       ccc.shader = NULL;
    217    }
    218 
    219    toy_compiler_cleanup(&ccc.tc);
    220 
    221    return ccc.shader;
    222 }
    223