gallium/util: replace pipe_mutex_lock() with mtx_lock()
[mesa.git] / src / gallium / drivers / radeonsi / si_state_shaders.c
index d6d4560404f336578f4890fb3b202fc3a93e0a92..c7a8d1f2afb9135f89daf82787d8fb3be48f628e 100644 (file)
@@ -36,6 +36,9 @@
 #include "util/u_memory.h"
 #include "util/u_prim.h"
 
+#include "util/disk_cache.h"
+#include "util/mesa-sha1.h"
+
 /* SHADER_CACHE */
 
 /**
@@ -182,10 +185,12 @@ static bool si_load_shader_binary(struct si_shader *shader, void *binary)
  */
 static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
                                          void *tgsi_binary,
-                                         struct si_shader *shader)
+                                         struct si_shader *shader,
+                                         bool insert_into_disk_cache)
 {
        void *hw_binary;
        struct hash_entry *entry;
+       uint8_t key[CACHE_KEY_SIZE];
 
        entry = _mesa_hash_table_search(sscreen->shader_cache, tgsi_binary);
        if (entry)
@@ -201,6 +206,12 @@ static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
                return false;
        }
 
+       if (sscreen->b.disk_shader_cache && insert_into_disk_cache) {
+               _mesa_sha1_compute(tgsi_binary, *((uint32_t *)tgsi_binary), key);
+               disk_cache_put(sscreen->b.disk_shader_cache, key, hw_binary,
+                              *((uint32_t *) hw_binary));
+       }
+
        return true;
 }
 
@@ -210,12 +221,54 @@ static bool si_shader_cache_load_shader(struct si_screen *sscreen,
 {
        struct hash_entry *entry =
                _mesa_hash_table_search(sscreen->shader_cache, tgsi_binary);
-       if (!entry)
-               return false;
+       if (!entry) {
+               if (sscreen->b.disk_shader_cache) {
+                       unsigned char sha1[CACHE_KEY_SIZE];
+                       size_t tg_size = *((uint32_t *) tgsi_binary);
+
+                       _mesa_sha1_compute(tgsi_binary, tg_size, sha1);
+
+                       size_t binary_size;
+                       uint8_t *buffer =
+                               disk_cache_get(sscreen->b.disk_shader_cache,
+                                              sha1, &binary_size);
+                       if (!buffer)
+                               return false;
 
-       if (!si_load_shader_binary(shader, entry->data))
-               return false;
+                       if (binary_size < sizeof(uint32_t) ||
+                           *((uint32_t*)buffer) != binary_size) {
+                                /* Something has gone wrong discard the item
+                                 * from the cache and rebuild/link from
+                                 * source.
+                                 */
+                               assert(!"Invalid radeonsi shader disk cache "
+                                      "item!");
+
+                               disk_cache_remove(sscreen->b.disk_shader_cache,
+                                                 sha1);
+                               free(buffer);
+
+                               return false;
+                       }
+
+                       if (!si_load_shader_binary(shader, buffer)) {
+                               free(buffer);
+                               return false;
+                       }
+                       free(buffer);
 
+                       if (!si_shader_cache_insert_shader(sscreen, tgsi_binary,
+                                                          shader, false))
+                               FREE(tgsi_binary);
+               } else {
+                       return false;
+               }
+       } else {
+               if (si_load_shader_binary(shader, entry->data))
+                       FREE(tgsi_binary);
+               else
+                       return false;
+       }
        p_atomic_inc(&sscreen->b.num_shader_cache_hits);
        return true;
 }
@@ -246,11 +299,12 @@ static void si_destroy_shader_cache_entry(struct hash_entry *entry)
 
 bool si_init_shader_cache(struct si_screen *sscreen)
 {
-       pipe_mutex_init(sscreen->shader_cache_mutex);
+       (void) mtx_init(&sscreen->shader_cache_mutex, mtx_plain);
        sscreen->shader_cache =
                _mesa_hash_table_create(NULL,
                                        si_shader_cache_key_hash,
                                        si_shader_cache_key_equals);
+
        return sscreen->shader_cache != NULL;
 }
 
@@ -259,7 +313,7 @@ void si_destroy_shader_cache(struct si_screen *sscreen)
        if (sscreen->shader_cache)
                _mesa_hash_table_destroy(sscreen->shader_cache,
                                         si_destroy_shader_cache_entry);
-       pipe_mutex_destroy(sscreen->shader_cache_mutex);
+       mtx_destroy(&sscreen->shader_cache_mutex);
 }
 
 /* SHADER STATES */
@@ -992,6 +1046,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
        case PIPE_SHADER_TESS_CTRL:
                key->part.tcs.epilog.prim_mode =
                        sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
+               key->part.tcs.epilog.tes_reads_tess_factors =
+                       sctx->tes_shader.cso->info.reads_tess_factors;
 
                if (sel == sctx->fixed_func_tcs_shader.cso)
                        key->mono.tcs.inputs_to_copy = sctx->vs_shader.cso->outputs_written;
@@ -1198,9 +1254,9 @@ again:
         * in a compiler thread.
         */
        if (thread_index < 0)
-               util_queue_job_wait(&sel->ready);
+               util_queue_fence_wait(&sel->ready);
 
-       pipe_mutex_lock(sel->mutex);
+       mtx_lock(&sel->mutex);
 
        /* Find the shader variant. */
        for (iter = sel->first_variant; iter; iter = iter->next_variant) {
@@ -1243,6 +1299,7 @@ again:
         * if the initial guess was wrong. */
        struct si_shader **mainp = si_get_main_shader_part(sel, key);
        bool is_pure_monolithic =
+               sscreen->use_monolithic_shaders ||
                memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0;
 
        if (!*mainp && !is_pure_monolithic) {
@@ -1276,7 +1333,7 @@ again:
                memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
 
        shader->is_optimized =
-               !sscreen->use_monolithic_shaders &&
+               !is_pure_monolithic &&
                memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
        if (shader->is_optimized)
                util_queue_fence_init(&shader->optimized_ready);
@@ -1400,11 +1457,10 @@ void si_init_shader_selector_async(void *job, int thread_index)
                tgsi_binary = si_get_tgsi_binary(sel);
 
                /* Try to load the shader from the shader cache. */
-               pipe_mutex_lock(sscreen->shader_cache_mutex);
+               mtx_lock(&sscreen->shader_cache_mutex);
 
                if (tgsi_binary &&
                    si_shader_cache_load_shader(sscreen, tgsi_binary, shader)) {
-                       FREE(tgsi_binary);
                        pipe_mutex_unlock(sscreen->shader_cache_mutex);
                } else {
                        pipe_mutex_unlock(sscreen->shader_cache_mutex);
@@ -1419,8 +1475,8 @@ void si_init_shader_selector_async(void *job, int thread_index)
                        }
 
                        if (tgsi_binary) {
-                               pipe_mutex_lock(sscreen->shader_cache_mutex);
-                               if (!si_shader_cache_insert_shader(sscreen, tgsi_binary, shader))
+                               mtx_lock(&sscreen->shader_cache_mutex);
+                               if (!si_shader_cache_insert_shader(sscreen, tgsi_binary, shader, true))
                                        FREE(tgsi_binary);
                                pipe_mutex_unlock(sscreen->shader_cache_mutex);
                        }
@@ -1708,7 +1764,7 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
                sel->db_shader_control |= S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
        }
 
-       pipe_mutex_init(sel->mutex);
+       (void) mtx_init(&sel->mutex, mtx_plain);
        util_queue_fence_init(&sel->ready);
 
        if ((sctx->b.debug.debug_message && !sctx->b.debug.async) ||
@@ -1829,7 +1885,7 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
 static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
 {
        if (shader->is_optimized) {
-               util_queue_job_wait(&shader->optimized_ready);
+               util_queue_fence_wait(&shader->optimized_ready);
                util_queue_fence_destroy(&shader->optimized_ready);
        }
 
@@ -1881,7 +1937,7 @@ static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
                [PIPE_SHADER_FRAGMENT] = &sctx->ps_shader,
        };
 
-       util_queue_job_wait(&sel->ready);
+       util_queue_fence_wait(&sel->ready);
 
        if (current_shader[sel->type]->cso == sel) {
                current_shader[sel->type]->cso = NULL;
@@ -1904,7 +1960,7 @@ static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
                si_delete_shader(sctx, sel->gs_copy_shader);
 
        util_queue_fence_destroy(&sel->ready);
-       pipe_mutex_destroy(sel->mutex);
+       mtx_destroy(&sel->mutex);
        free(sel->tokens);
        free(sel);
 }
@@ -2309,7 +2365,9 @@ static bool si_update_spi_tmpring_size(struct si_context *sctx)
 
 static void si_init_tess_factor_ring(struct si_context *sctx)
 {
-       bool double_offchip_buffers = sctx->b.chip_class >= CIK;
+       bool double_offchip_buffers = sctx->b.chip_class >= CIK &&
+                                     sctx->b.family != CHIP_CARRIZO &&
+                                     sctx->b.family != CHIP_STONEY;
        unsigned max_offchip_buffers_per_se = double_offchip_buffers ? 128 : 64;
        unsigned max_offchip_buffers = max_offchip_buffers_per_se *
                                       sctx->screen->b.info.max_se;