Home | History | Annotate | Download | only in i965
      1 /*
      2  * Copyright  2014 Intel Corporation
      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 (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * 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 NONINFRINGEMENT.  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 DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #include "compiler/blob.h"
     25 #include "compiler/glsl/ir_uniform.h"
     26 #include "compiler/glsl/shader_cache.h"
     27 #include "main/mtypes.h"
     28 #include "util/build_id.h"
     29 #include "util/debug.h"
     30 #include "util/disk_cache.h"
     31 #include "util/macros.h"
     32 #include "util/mesa-sha1.h"
     33 
     34 #include "brw_context.h"
     35 #include "brw_program.h"
     36 #include "brw_cs.h"
     37 #include "brw_gs.h"
     38 #include "brw_state.h"
     39 #include "brw_vs.h"
     40 #include "brw_wm.h"
     41 
     42 static void
     43 gen_shader_sha1(struct brw_context *brw, struct gl_program *prog,
     44                 gl_shader_stage stage, void *key, unsigned char *out_sha1)
     45 {
     46    char sha1_buf[41];
     47    unsigned char sha1[20];
     48    char manifest[256];
     49    int offset = 0;
     50 
     51    _mesa_sha1_format(sha1_buf, prog->sh.data->sha1);
     52    offset += snprintf(manifest, sizeof(manifest), "program: %s\n", sha1_buf);
     53 
     54    _mesa_sha1_compute(key, brw_prog_key_size(stage), sha1);
     55    _mesa_sha1_format(sha1_buf, sha1);
     56    offset += snprintf(manifest + offset, sizeof(manifest) - offset,
     57                       "%s_key: %s\n", _mesa_shader_stage_to_abbrev(stage),
     58                       sha1_buf);
     59 
     60    _mesa_sha1_compute(manifest, strlen(manifest), out_sha1);
     61 }
     62 
     63 static void
     64 write_blob_program_data(struct blob *binary, gl_shader_stage stage,
     65                         const void *program,
     66                         struct brw_stage_prog_data *prog_data)
     67 {
     68    /* Write prog_data to blob. */
     69    blob_write_bytes(binary, prog_data, brw_prog_data_size(stage));
     70 
     71    /* Write program to blob. */
     72    blob_write_bytes(binary, program, prog_data->program_size);
     73 
     74    /* Write push params */
     75    blob_write_bytes(binary, prog_data->param,
     76                     sizeof(uint32_t) * prog_data->nr_params);
     77 
     78    /* Write pull params */
     79    blob_write_bytes(binary, prog_data->pull_param,
     80                     sizeof(uint32_t) * prog_data->nr_pull_params);
     81 }
     82 
     83 static bool
     84 read_blob_program_data(struct blob_reader *binary, struct gl_program *prog,
     85                        gl_shader_stage stage, const uint8_t **program,
     86                        struct brw_stage_prog_data *prog_data)
     87 {
     88    /* Read shader prog_data from blob. */
     89    blob_copy_bytes(binary, prog_data, brw_prog_data_size(stage));
     90    if (binary->overrun)
     91       return false;
     92 
     93    /* Read shader program from blob. */
     94    *program = blob_read_bytes(binary, prog_data->program_size);
     95 
     96    /* Read push params */
     97    prog_data->param = rzalloc_array(NULL, uint32_t, prog_data->nr_params);
     98    blob_copy_bytes(binary, prog_data->param,
     99                    sizeof(uint32_t) * prog_data->nr_params);
    100 
    101    /* Read pull params */
    102    prog_data->pull_param = rzalloc_array(NULL, uint32_t,
    103                                          prog_data->nr_pull_params);
    104    blob_copy_bytes(binary, prog_data->pull_param,
    105                    sizeof(uint32_t) * prog_data->nr_pull_params);
    106 
    107    return (binary->current == binary->end && !binary->overrun);
    108 }
    109 
    110 static bool
    111 read_and_upload(struct brw_context *brw, struct disk_cache *cache,
    112                 struct gl_program *prog, gl_shader_stage stage)
    113 {
    114    unsigned char binary_sha1[20];
    115 
    116    union brw_any_prog_key prog_key;
    117 
    118    switch (stage) {
    119    case MESA_SHADER_VERTEX:
    120       brw_vs_populate_key(brw, &prog_key.vs);
    121       /* We don't care what instance of the program it is for the disk cache
    122        * hash lookup, so set the id to 0 for the sha1 hashing.
    123        * program_string_id will be set below.
    124        */
    125       prog_key.vs.program_string_id = 0;
    126       break;
    127    case MESA_SHADER_TESS_CTRL:
    128       brw_tcs_populate_key(brw, &prog_key.tcs);
    129       prog_key.tcs.program_string_id = 0;
    130       break;
    131    case MESA_SHADER_TESS_EVAL:
    132       brw_tes_populate_key(brw, &prog_key.tes);
    133       prog_key.tes.program_string_id = 0;
    134       break;
    135    case MESA_SHADER_GEOMETRY:
    136       brw_gs_populate_key(brw, &prog_key.gs);
    137       prog_key.gs.program_string_id = 0;
    138       break;
    139    case MESA_SHADER_FRAGMENT:
    140       brw_wm_populate_key(brw, &prog_key.wm);
    141       prog_key.wm.program_string_id = 0;
    142       break;
    143    case MESA_SHADER_COMPUTE:
    144       brw_cs_populate_key(brw, &prog_key.cs);
    145       prog_key.cs.program_string_id = 0;
    146       break;
    147    default:
    148       unreachable("Unsupported stage!");
    149    }
    150 
    151    gen_shader_sha1(brw, prog, stage, &prog_key, binary_sha1);
    152 
    153    size_t buffer_size;
    154    uint8_t *buffer = disk_cache_get(cache, binary_sha1, &buffer_size);
    155    if (buffer == NULL) {
    156       if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
    157          char sha1_buf[41];
    158          _mesa_sha1_format(sha1_buf, binary_sha1);
    159          fprintf(stderr, "No cached %s binary found for: %s\n",
    160                  _mesa_shader_stage_to_abbrev(stage), sha1_buf);
    161       }
    162       return false;
    163    }
    164 
    165    if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
    166       char sha1_buf[41];
    167       _mesa_sha1_format(sha1_buf, binary_sha1);
    168       fprintf(stderr, "attempting to populate bo cache with binary: %s\n",
    169               sha1_buf);
    170    }
    171 
    172    struct blob_reader binary;
    173    blob_reader_init(&binary, buffer, buffer_size);
    174 
    175    const uint8_t *program;
    176    struct brw_stage_prog_data *prog_data =
    177       ralloc_size(NULL, sizeof(union brw_any_prog_data));
    178    if (!read_blob_program_data(&binary, prog, stage, &program, prog_data)) {
    179       /* Something very bad has gone wrong discard the item from the cache and
    180        * rebuild from source.
    181        */
    182       if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
    183          fprintf(stderr, "Error reading program from cache (invalid i965 "
    184                  "cache item)\n");
    185       }
    186 
    187       disk_cache_remove(cache, binary_sha1);
    188       ralloc_free(prog_data);
    189       free(buffer);
    190       return false;
    191    }
    192 
    193    enum brw_cache_id cache_id;
    194    struct brw_stage_state *stage_state;
    195 
    196    switch (stage) {
    197    case MESA_SHADER_VERTEX:
    198       prog_key.vs.program_string_id = brw_program(prog)->id;
    199       cache_id = BRW_CACHE_VS_PROG;
    200       stage_state = &brw->vs.base;
    201       break;
    202    case MESA_SHADER_TESS_CTRL:
    203       prog_key.tcs.program_string_id = brw_program(prog)->id;
    204       cache_id = BRW_CACHE_TCS_PROG;
    205       stage_state = &brw->tcs.base;
    206       break;
    207    case MESA_SHADER_TESS_EVAL:
    208       prog_key.tes.program_string_id = brw_program(prog)->id;
    209       cache_id = BRW_CACHE_TES_PROG;
    210       stage_state = &brw->tes.base;
    211       break;
    212    case MESA_SHADER_GEOMETRY:
    213       prog_key.gs.program_string_id = brw_program(prog)->id;
    214       cache_id = BRW_CACHE_GS_PROG;
    215       stage_state = &brw->gs.base;
    216       break;
    217    case MESA_SHADER_FRAGMENT:
    218       prog_key.wm.program_string_id = brw_program(prog)->id;
    219       cache_id = BRW_CACHE_FS_PROG;
    220       stage_state = &brw->wm.base;
    221       break;
    222    case MESA_SHADER_COMPUTE:
    223       prog_key.cs.program_string_id = brw_program(prog)->id;
    224       cache_id = BRW_CACHE_CS_PROG;
    225       stage_state = &brw->cs.base;
    226       break;
    227    default:
    228       unreachable("Unsupported stage!");
    229    }
    230 
    231    brw_alloc_stage_scratch(brw, stage_state, prog_data->total_scratch);
    232 
    233    brw_upload_cache(&brw->cache, cache_id, &prog_key, brw_prog_key_size(stage),
    234                     program, prog_data->program_size, prog_data,
    235                     brw_prog_data_size(stage), &stage_state->prog_offset,
    236                     &stage_state->prog_data);
    237 
    238    prog->program_written_to_cache = true;
    239 
    240    ralloc_free(prog_data);
    241    free(buffer);
    242 
    243    return true;
    244 }
    245 
    246 bool
    247 brw_disk_cache_upload_program(struct brw_context *brw, gl_shader_stage stage)
    248 {
    249    struct disk_cache *cache = brw->ctx.Cache;
    250    if (cache == NULL)
    251       return false;
    252 
    253    struct gl_program *prog = brw->ctx._Shader->CurrentProgram[stage];
    254    if (prog == NULL)
    255       return false;
    256 
    257    /* FIXME: For now we don't read from the cache if transform feedback is
    258     * enabled via the API. However the shader cache does support transform
    259     * feedback when enabled via in shader xfb qualifiers.
    260     */
    261    if (prog->sh.LinkedTransformFeedback &&
    262        prog->sh.LinkedTransformFeedback->api_enabled)
    263       return false;
    264 
    265    if (brw->ctx._Shader->Flags & GLSL_CACHE_FALLBACK)
    266       goto fail;
    267 
    268    if (prog->sh.data->LinkStatus != linking_skipped)
    269       goto fail;
    270 
    271    if (!read_and_upload(brw, cache, prog, stage))
    272       goto fail;
    273 
    274    if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
    275       fprintf(stderr, "read gen program from cache\n");
    276    }
    277 
    278    return true;
    279 
    280 fail:
    281    prog->program_written_to_cache = false;
    282    if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
    283       fprintf(stderr, "falling back to nir %s.\n",
    284               _mesa_shader_stage_to_abbrev(prog->info.stage));
    285    }
    286 
    287    brw_program_deserialize_nir(&brw->ctx, prog, stage);
    288 
    289    return false;
    290 }
    291 
    292 static void
    293 write_program_data(struct brw_context *brw, struct gl_program *prog,
    294                    void *key, struct brw_stage_prog_data *prog_data,
    295                    uint32_t prog_offset, struct disk_cache *cache,
    296                    gl_shader_stage stage)
    297 {
    298    struct blob binary;
    299    blob_init(&binary);
    300 
    301    const void *program_map = brw->cache.map + prog_offset;
    302    /* TODO: Improve perf for non-LLC. It would be best to save it at program
    303     * generation time when the program is in normal memory accessible with
    304     * cache to the CPU. Another easier change would be to use
    305     * _mesa_streaming_load_memcpy to read from the program mapped memory. */
    306    write_blob_program_data(&binary, stage, program_map, prog_data);
    307 
    308    unsigned char sha1[20];
    309    char buf[41];
    310    gen_shader_sha1(brw, prog, stage, key, sha1);
    311    _mesa_sha1_format(buf, sha1);
    312    if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
    313       fprintf(stderr, "putting binary in cache: %s\n", buf);
    314    }
    315 
    316    disk_cache_put(cache, sha1, binary.data, binary.size, NULL);
    317 
    318    prog->program_written_to_cache = true;
    319    blob_finish(&binary);
    320 }
    321 
    322 void
    323 brw_disk_cache_write_render_programs(struct brw_context *brw)
    324 {
    325    struct disk_cache *cache = brw->ctx.Cache;
    326    if (cache == NULL)
    327       return;
    328 
    329    struct gl_program *prog =
    330       brw->ctx._Shader->CurrentProgram[MESA_SHADER_VERTEX];
    331    if (prog && !prog->program_written_to_cache) {
    332       struct brw_vs_prog_key vs_key;
    333       brw_vs_populate_key(brw, &vs_key);
    334       vs_key.program_string_id = 0;
    335 
    336       write_program_data(brw, prog, &vs_key, brw->vs.base.prog_data,
    337                          brw->vs.base.prog_offset, cache,
    338                          MESA_SHADER_VERTEX);
    339    }
    340 
    341    prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
    342    if (prog && !prog->program_written_to_cache) {
    343       struct brw_tcs_prog_key tcs_key;
    344       brw_tcs_populate_key(brw, &tcs_key);
    345       tcs_key.program_string_id = 0;
    346 
    347       write_program_data(brw, prog, &tcs_key, brw->tcs.base.prog_data,
    348                          brw->tcs.base.prog_offset, cache,
    349                          MESA_SHADER_TESS_CTRL);
    350    }
    351 
    352    prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
    353    if (prog && !prog->program_written_to_cache) {
    354       struct brw_tes_prog_key tes_key;
    355       brw_tes_populate_key(brw, &tes_key);
    356       tes_key.program_string_id = 0;
    357 
    358       write_program_data(brw, prog, &tes_key, brw->tes.base.prog_data,
    359                          brw->tes.base.prog_offset, cache,
    360                          MESA_SHADER_TESS_EVAL);
    361    }
    362 
    363    prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
    364    if (prog && !prog->program_written_to_cache) {
    365       struct brw_gs_prog_key gs_key;
    366       brw_gs_populate_key(brw, &gs_key);
    367       gs_key.program_string_id = 0;
    368 
    369       write_program_data(brw, prog, &gs_key, brw->gs.base.prog_data,
    370                          brw->gs.base.prog_offset, cache,
    371                          MESA_SHADER_GEOMETRY);
    372    }
    373 
    374    prog = brw->ctx._Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
    375    if (prog && !prog->program_written_to_cache) {
    376       struct brw_wm_prog_key wm_key;
    377       brw_wm_populate_key(brw, &wm_key);
    378       wm_key.program_string_id = 0;
    379 
    380       write_program_data(brw, prog, &wm_key, brw->wm.base.prog_data,
    381                          brw->wm.base.prog_offset, cache,
    382                          MESA_SHADER_FRAGMENT);
    383    }
    384 }
    385 
    386 void
    387 brw_disk_cache_write_compute_program(struct brw_context *brw)
    388 {
    389    struct disk_cache *cache = brw->ctx.Cache;
    390    if (cache == NULL)
    391       return;
    392 
    393    struct gl_program *prog =
    394       brw->ctx._Shader->CurrentProgram[MESA_SHADER_COMPUTE];
    395    if (prog && !prog->program_written_to_cache) {
    396       struct brw_cs_prog_key cs_key;
    397       brw_cs_populate_key(brw, &cs_key);
    398       cs_key.program_string_id = 0;
    399 
    400       write_program_data(brw, prog, &cs_key, brw->cs.base.prog_data,
    401                          brw->cs.base.prog_offset, cache,
    402                          MESA_SHADER_COMPUTE);
    403    }
    404 }
    405 
    406 void
    407 brw_disk_cache_init(struct brw_context *brw)
    408 {
    409 #ifdef ENABLE_SHADER_CACHE
    410    if (env_var_as_boolean("MESA_GLSL_CACHE_DISABLE", true))
    411       return;
    412 
    413    char renderer[10];
    414    MAYBE_UNUSED int len = snprintf(renderer, sizeof(renderer), "i965_%04x",
    415                                    brw->screen->deviceID);
    416    assert(len == sizeof(renderer) - 1);
    417 
    418    const struct build_id_note *note =
    419       build_id_find_nhdr_for_addr(brw_disk_cache_init);
    420    assert(note && build_id_length(note) == 20 /* sha1 */);
    421 
    422    const uint8_t *id_sha1 = build_id_data(note);
    423    assert(id_sha1);
    424 
    425    char timestamp[41];
    426    _mesa_sha1_format(timestamp, id_sha1);
    427 
    428    brw->ctx.Cache = disk_cache_create(renderer, timestamp, 0);
    429 #endif
    430 }
    431