Home | History | Annotate | Download | only in etnaviv
      1 /*
      2  * Copyright (c) 2012-2015 Etnaviv Project
      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, sub license,
      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 (including the
     12  * next paragraph) shall be included in all copies or substantial portions
     13  * of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *    Wladimir J. van der Laan <laanwj (at) gmail.com>
     25  */
     26 
     27 #include "etnaviv_shader.h"
     28 
     29 #include "etnaviv_compiler.h"
     30 #include "etnaviv_context.h"
     31 #include "etnaviv_debug.h"
     32 #include "etnaviv_screen.h"
     33 #include "etnaviv_util.h"
     34 
     35 #include "tgsi/tgsi_parse.h"
     36 #include "util/u_math.h"
     37 #include "util/u_memory.h"
     38 
     39 /* Upload shader code to bo, if not already done */
     40 static bool etna_icache_upload_shader(struct etna_context *ctx, struct etna_shader_variant *v)
     41 {
     42    if (v->bo)
     43       return true;
     44    v->bo = etna_bo_new(ctx->screen->dev, v->code_size*4, DRM_ETNA_GEM_CACHE_UNCACHED);
     45    if (!v->bo)
     46       return false;
     47 
     48    void *buf = etna_bo_map(v->bo);
     49    etna_bo_cpu_prep(v->bo, DRM_ETNA_PREP_WRITE);
     50    memcpy(buf, v->code, v->code_size*4);
     51    etna_bo_cpu_fini(v->bo);
     52    DBG("Uploaded %s of %u words to bo %p", v->processor == PIPE_SHADER_FRAGMENT ? "fs":"vs", v->code_size, v->bo);
     53    return true;
     54 }
     55 
     56 /* Link vs and fs together: fill in shader_state from vs and fs
     57  * as this function is called every time a new fs or vs is bound, the goal is to
     58  * do little processing as possible here, and to precompute as much as possible in
     59  * the vs/fs shader_object.
     60  *
     61  * XXX we could cache the link result for a certain set of VS/PS; usually a pair
     62  * of VS and PS will be used together anyway.
     63  */
     64 static bool
     65 etna_link_shaders(struct etna_context *ctx, struct compiled_shader_state *cs,
     66                   struct etna_shader_variant *vs, struct etna_shader_variant *fs)
     67 {
     68    struct etna_shader_link_info link = { };
     69 
     70    assert(vs->processor == PIPE_SHADER_VERTEX);
     71    assert(fs->processor == PIPE_SHADER_FRAGMENT);
     72 
     73 #ifdef DEBUG
     74    if (DBG_ENABLED(ETNA_DBG_DUMP_SHADERS)) {
     75       etna_dump_shader(vs);
     76       etna_dump_shader(fs);
     77    }
     78 #endif
     79 
     80    if (etna_link_shader(&link, vs, fs)) {
     81       /* linking failed: some fs inputs do not have corresponding
     82        * vs outputs */
     83       assert(0);
     84 
     85       return false;
     86    }
     87 
     88    if (DBG_ENABLED(ETNA_DBG_LINKER_MSGS)) {
     89       debug_printf("link result:\n");
     90       debug_printf("  vs  -> fs  comps use     pa_attr\n");
     91 
     92       for (int idx = 0; idx < link.num_varyings; ++idx)
     93          debug_printf("  t%-2u -> t%-2u %-5.*s %u,%u,%u,%u 0x%08x\n",
     94                       link.varyings[idx].reg, idx + 1,
     95                       link.varyings[idx].num_components, "xyzw",
     96                       link.varyings[idx].use[0], link.varyings[idx].use[1],
     97                       link.varyings[idx].use[2], link.varyings[idx].use[3],
     98                       link.varyings[idx].pa_attributes);
     99    }
    100 
    101    /* set last_varying_2x flag if the last varying has 1 or 2 components */
    102    bool last_varying_2x = false;
    103    if (link.num_varyings > 0 && link.varyings[link.num_varyings - 1].num_components <= 2)
    104       last_varying_2x = true;
    105 
    106    cs->RA_CONTROL = VIVS_RA_CONTROL_UNK0 |
    107                     COND(last_varying_2x, VIVS_RA_CONTROL_LAST_VARYING_2X);
    108 
    109    cs->PA_ATTRIBUTE_ELEMENT_COUNT = VIVS_PA_ATTRIBUTE_ELEMENT_COUNT_COUNT(link.num_varyings);
    110    for (int idx = 0; idx < link.num_varyings; ++idx)
    111       cs->PA_SHADER_ATTRIBUTES[idx] = link.varyings[idx].pa_attributes;
    112 
    113    cs->VS_END_PC = vs->code_size / 4;
    114    cs->VS_OUTPUT_COUNT = 1 + link.num_varyings; /* position + varyings */
    115 
    116    /* vs outputs (varyings) */
    117    DEFINE_ETNA_BITARRAY(vs_output, 16, 8) = {0};
    118    int varid = 0;
    119    etna_bitarray_set(vs_output, 8, varid++, vs->vs_pos_out_reg);
    120    for (int idx = 0; idx < link.num_varyings; ++idx)
    121       etna_bitarray_set(vs_output, 8, varid++, link.varyings[idx].reg);
    122    if (vs->vs_pointsize_out_reg >= 0)
    123       etna_bitarray_set(vs_output, 8, varid++, vs->vs_pointsize_out_reg); /* pointsize is last */
    124 
    125    for (int idx = 0; idx < ARRAY_SIZE(cs->VS_OUTPUT); ++idx)
    126       cs->VS_OUTPUT[idx] = vs_output[idx];
    127 
    128    if (vs->vs_pointsize_out_reg != -1) {
    129       /* vertex shader outputs point coordinate, provide extra output and make
    130        * sure PA config is
    131        * not masked */
    132       cs->PA_CONFIG = ~0;
    133       cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT + 1;
    134    } else {
    135       /* vertex shader does not output point coordinate, make sure thate
    136        * POINT_SIZE_ENABLE is masked
    137        * and no extra output is given */
    138       cs->PA_CONFIG = ~VIVS_PA_CONFIG_POINT_SIZE_ENABLE;
    139       cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT;
    140    }
    141 
    142    cs->VS_LOAD_BALANCING = vs->vs_load_balancing;
    143    cs->VS_START_PC = 0;
    144 
    145    cs->PS_END_PC = fs->code_size / 4;
    146    cs->PS_OUTPUT_REG = fs->ps_color_out_reg;
    147    cs->PS_INPUT_COUNT =
    148       VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 1) | /* Number of inputs plus position */
    149       VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8);
    150    cs->PS_TEMP_REGISTER_CONTROL =
    151       VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 1));
    152    cs->PS_CONTROL = VIVS_PS_CONTROL_UNK1; /* XXX when can we set BYPASS? */
    153    cs->PS_START_PC = 0;
    154 
    155    /* Precompute PS_INPUT_COUNT and TEMP_REGISTER_CONTROL in the case of MSAA
    156     * mode, avoids some fumbling in sync_context. */
    157    cs->PS_INPUT_COUNT_MSAA =
    158       VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 2) | /* MSAA adds another input */
    159       VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8);
    160    cs->PS_TEMP_REGISTER_CONTROL_MSAA =
    161       VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 2));
    162 
    163    uint32_t total_components = 0;
    164    DEFINE_ETNA_BITARRAY(num_components, ETNA_NUM_VARYINGS, 4) = {0};
    165    DEFINE_ETNA_BITARRAY(component_use, 4 * ETNA_NUM_VARYINGS, 2) = {0};
    166    for (int idx = 0; idx < link.num_varyings; ++idx) {
    167       const struct etna_varying *varying = &link.varyings[idx];
    168 
    169       etna_bitarray_set(num_components, 4, idx, varying->num_components);
    170       for (int comp = 0; comp < varying->num_components; ++comp) {
    171          etna_bitarray_set(component_use, 2, total_components, varying->use[comp]);
    172          total_components += 1;
    173       }
    174    }
    175 
    176    cs->GL_VARYING_TOTAL_COMPONENTS =
    177       VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(align(total_components, 2));
    178    cs->GL_VARYING_NUM_COMPONENTS = num_components[0];
    179    cs->GL_VARYING_COMPONENT_USE[0] = component_use[0];
    180    cs->GL_VARYING_COMPONENT_USE[1] = component_use[1];
    181 
    182    cs->GL_HALTI5_SH_SPECIALS =
    183       0x7f7f0000 | /* unknown bits, probably other PS inputs */
    184       /* pointsize is last (see above) */
    185       VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT((vs->vs_pointsize_out_reg != -1) ?
    186                                               cs->VS_OUTPUT_COUNT * 4 : 0x00) |
    187       VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN((link.pcoord_varying_comp_ofs != -1) ?
    188                                               link.pcoord_varying_comp_ofs : 0x7f);
    189 
    190    /* reference instruction memory */
    191    cs->vs_inst_mem_size = vs->code_size;
    192    cs->VS_INST_MEM = vs->code;
    193 
    194    cs->ps_inst_mem_size = fs->code_size;
    195    cs->PS_INST_MEM = fs->code;
    196 
    197    if (vs->needs_icache | fs->needs_icache) {
    198       /* If either of the shaders needs ICACHE, we use it for both. It is
    199        * either switched on or off for the entire shader processor.
    200        */
    201       if (!etna_icache_upload_shader(ctx, vs) ||
    202           !etna_icache_upload_shader(ctx, fs)) {
    203          assert(0);
    204          return false;
    205       }
    206 
    207       cs->VS_INST_ADDR.bo = vs->bo;
    208       cs->VS_INST_ADDR.offset = 0;
    209       cs->VS_INST_ADDR.flags = ETNA_RELOC_READ;
    210       cs->PS_INST_ADDR.bo = fs->bo;
    211       cs->PS_INST_ADDR.offset = 0;
    212       cs->PS_INST_ADDR.flags = ETNA_RELOC_READ;
    213    } else {
    214       /* clear relocs */
    215       memset(&cs->VS_INST_ADDR, 0, sizeof(cs->VS_INST_ADDR));
    216       memset(&cs->PS_INST_ADDR, 0, sizeof(cs->PS_INST_ADDR));
    217    }
    218 
    219    return true;
    220 }
    221 
    222 bool
    223 etna_shader_link(struct etna_context *ctx)
    224 {
    225    if (!ctx->shader.vs || !ctx->shader.fs)
    226       return false;
    227 
    228    /* re-link vs and fs if needed */
    229    return etna_link_shaders(ctx, &ctx->shader_state, ctx->shader.vs, ctx->shader.fs);
    230 }
    231 
    232 static bool
    233 etna_shader_update_vs_inputs(struct etna_context *ctx,
    234                              struct compiled_shader_state *cs,
    235                              const struct etna_shader_variant *vs,
    236                              const struct compiled_vertex_elements_state *ves)
    237 {
    238    unsigned num_temps, cur_temp, num_vs_inputs;
    239 
    240    if (!vs)
    241       return false;
    242 
    243    /* Number of vertex elements determines number of VS inputs. Otherwise,
    244     * the GPU crashes. Allocate any unused vertex elements to VS temporary
    245     * registers. */
    246    num_vs_inputs = MAX2(ves->num_elements, vs->infile.num_reg);
    247    if (num_vs_inputs != ves->num_elements) {
    248       BUG("Number of elements %u does not match the number of VS inputs %zu",
    249           ctx->vertex_elements->num_elements, ctx->shader.vs->infile.num_reg);
    250       return false;
    251    }
    252 
    253    cur_temp = vs->num_temps;
    254    num_temps = num_vs_inputs - vs->infile.num_reg + cur_temp;
    255 
    256    cs->VS_INPUT_COUNT = VIVS_VS_INPUT_COUNT_COUNT(num_vs_inputs) |
    257                         VIVS_VS_INPUT_COUNT_UNK8(vs->input_count_unk8);
    258    cs->VS_TEMP_REGISTER_CONTROL =
    259       VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS(num_temps);
    260 
    261    /* vs inputs (attributes) */
    262    DEFINE_ETNA_BITARRAY(vs_input, 16, 8) = {0};
    263    for (int idx = 0; idx < num_vs_inputs; ++idx) {
    264       if (idx < vs->infile.num_reg)
    265          etna_bitarray_set(vs_input, 8, idx, vs->infile.reg[idx].reg);
    266       else
    267          etna_bitarray_set(vs_input, 8, idx, cur_temp++);
    268    }
    269 
    270    for (int idx = 0; idx < ARRAY_SIZE(cs->VS_INPUT); ++idx)
    271       cs->VS_INPUT[idx] = vs_input[idx];
    272 
    273    return true;
    274 }
    275 
    276 static inline const char *
    277 etna_shader_stage(struct etna_shader_variant *shader)
    278 {
    279    switch (shader->processor) {
    280    case PIPE_SHADER_VERTEX:     return "VERT";
    281    case PIPE_SHADER_FRAGMENT:   return "FRAG";
    282    case PIPE_SHADER_COMPUTE:    return "CL";
    283    default:
    284       unreachable("invalid type");
    285       return NULL;
    286    }
    287 }
    288 
    289 static void
    290 dump_shader_info(struct etna_shader_variant *v, struct pipe_debug_callback *debug)
    291 {
    292    if (!unlikely(etna_mesa_debug & ETNA_DBG_SHADERDB))
    293       return;
    294 
    295    pipe_debug_message(debug, SHADER_INFO, "\n"
    296          "SHADER-DB: %s prog %d/%d: %u instructions %u temps\n"
    297          "SHADER-DB: %s prog %d/%d: %u immediates %u consts\n"
    298          "SHADER-DB: %s prog %d/%d: %u loops\n",
    299          etna_shader_stage(v),
    300          v->shader->id, v->id,
    301          v->code_size,
    302          v->num_temps,
    303          etna_shader_stage(v),
    304          v->shader->id, v->id,
    305          v->uniforms.imm_count,
    306          v->uniforms.const_count,
    307          etna_shader_stage(v),
    308          v->shader->id, v->id,
    309          v->num_loops);
    310 }
    311 
    312 bool
    313 etna_shader_update_vertex(struct etna_context *ctx)
    314 {
    315    return etna_shader_update_vs_inputs(ctx, &ctx->shader_state, ctx->shader.vs,
    316                                        ctx->vertex_elements);
    317 }
    318 
    319 static struct etna_shader_variant *
    320 create_variant(struct etna_shader *shader, struct etna_shader_key key)
    321 {
    322    struct etna_shader_variant *v = CALLOC_STRUCT(etna_shader_variant);
    323    int ret;
    324 
    325    if (!v)
    326       return NULL;
    327 
    328    v->shader = shader;
    329    v->key = key;
    330 
    331    ret = etna_compile_shader(v);
    332    if (!ret) {
    333       debug_error("compile failed!");
    334       goto fail;
    335    }
    336 
    337    v->id = ++shader->variant_count;
    338 
    339    return v;
    340 
    341 fail:
    342    FREE(v);
    343    return NULL;
    344 }
    345 
    346 struct etna_shader_variant *
    347 etna_shader_variant(struct etna_shader *shader, struct etna_shader_key key,
    348                    struct pipe_debug_callback *debug)
    349 {
    350    struct etna_shader_variant *v;
    351 
    352    for (v = shader->variants; v; v = v->next)
    353       if (etna_shader_key_equal(&key, &v->key))
    354          return v;
    355 
    356    /* compile new variant if it doesn't exist already */
    357    v = create_variant(shader, key);
    358    if (v) {
    359       v->next = shader->variants;
    360       shader->variants = v;
    361       dump_shader_info(v, debug);
    362    }
    363 
    364    return v;
    365 }
    366 
    367 static void *
    368 etna_create_shader_state(struct pipe_context *pctx,
    369                          const struct pipe_shader_state *pss)
    370 {
    371    struct etna_context *ctx = etna_context(pctx);
    372    struct etna_shader *shader = CALLOC_STRUCT(etna_shader);
    373 
    374    if (!shader)
    375       return NULL;
    376 
    377    static uint32_t id;
    378    shader->id = id++;
    379    shader->specs = &ctx->specs;
    380    shader->tokens = tgsi_dup_tokens(pss->tokens);
    381 
    382    if (etna_mesa_debug & ETNA_DBG_SHADERDB) {
    383       /* if shader-db run, create a standard variant immediately
    384        * (as otherwise nothing will trigger the shader to be
    385        * actually compiled).
    386        */
    387       struct etna_shader_key key = {};
    388       etna_shader_variant(shader, key, &ctx->debug);
    389    }
    390 
    391    return shader;
    392 }
    393 
    394 static void
    395 etna_delete_shader_state(struct pipe_context *pctx, void *ss)
    396 {
    397    struct etna_shader *shader = ss;
    398    struct etna_shader_variant *v, *t;
    399 
    400    v = shader->variants;
    401    while (v) {
    402       t = v;
    403       v = v->next;
    404       if (t->bo)
    405          etna_bo_del(t->bo);
    406       etna_destroy_shader(t);
    407    }
    408 
    409    FREE(shader->tokens);
    410    FREE(shader);
    411 }
    412 
    413 static void
    414 etna_bind_fs_state(struct pipe_context *pctx, void *hwcso)
    415 {
    416    struct etna_context *ctx = etna_context(pctx);
    417 
    418    ctx->shader.bind_fs = hwcso;
    419    ctx->dirty |= ETNA_DIRTY_SHADER;
    420 }
    421 
    422 static void
    423 etna_bind_vs_state(struct pipe_context *pctx, void *hwcso)
    424 {
    425    struct etna_context *ctx = etna_context(pctx);
    426 
    427    ctx->shader.bind_vs = hwcso;
    428    ctx->dirty |= ETNA_DIRTY_SHADER;
    429 }
    430 
    431 void
    432 etna_shader_init(struct pipe_context *pctx)
    433 {
    434    pctx->create_fs_state = etna_create_shader_state;
    435    pctx->bind_fs_state = etna_bind_fs_state;
    436    pctx->delete_fs_state = etna_delete_shader_state;
    437    pctx->create_vs_state = etna_create_shader_state;
    438    pctx->bind_vs_state = etna_bind_vs_state;
    439    pctx->delete_vs_state = etna_delete_shader_state;
    440 }
    441