--- src/compiler/glsl/shader_cache.cpp | 5 ++++- src/compiler/glsl/tests/cache_test.c | 29 ++++++++++++++++++++----- src/gallium/drivers/radeonsi/si_state_shaders.c | 9 ++++++-- src/mesa/state_tracker/st_shader_cache.c | 5 ++++- src/util/disk_cache.c | 27 +++++++++++++---------- src/util/disk_cache.h | 7 ++---- 6 files changed, 55 insertions(+), 27 deletions(-)
diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp index 6e2c527..1865e96 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -1269,21 +1269,24 @@ shader_cache_write_program_metadata(struct gl_context *ctx, char sha1_buf[41]; for (unsigned i = 0; i < prog->NumShaders; i++) { disk_cache_put_key(cache, prog->Shaders[i]->sha1); if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { fprintf(stderr, "marking shader: %s\n", _mesa_sha1_format(sha1_buf, prog->Shaders[i]->sha1)); } } - disk_cache_put(cache, prog->data->sha1, metadata->data, metadata->size); + struct disk_cache_put_job *dc_job = + disk_cache_create_put_job(cache, prog->data->sha1, metadata->data, + metadata->size, metadata); + disk_cache_put(dc_job, 0); free(metadata); if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { fprintf(stderr, "putting program metadata in cache: %s\n", _mesa_sha1_format(sha1_buf, prog->data->sha1)); } } bool diff --git a/src/compiler/glsl/tests/cache_test.c b/src/compiler/glsl/tests/cache_test.c index 7a1ff0a..a2b33f7 100644 --- a/src/compiler/glsl/tests/cache_test.c +++ b/src/compiler/glsl/tests/cache_test.c @@ -251,31 +251,37 @@ test_put_and_get(void) cache = disk_cache_create("test", "make_check"); _mesa_sha1_compute(blob, sizeof(blob), blob_key); /* Ensure that disk_cache_get returns nothing before anything is added. */ result = disk_cache_get(cache, blob_key, &size); expect_null(result, "disk_cache_get with non-existent item (pointer)"); expect_equal(size, 0, "disk_cache_get with non-existent item (size)"); /* Simple test of put and get. */ - disk_cache_put(cache, blob_key, blob, sizeof(blob)); + struct disk_cache_put_job *dc_job = + disk_cache_create_put_job(cache, blob_key, blob, sizeof(blob), NULL); + disk_cache_put(dc_job, 0); + free(dc_job); result = disk_cache_get(cache, blob_key, &size); expect_equal_str(blob, result, "disk_cache_get of existing item (pointer)"); expect_equal(size, sizeof(blob), "disk_cache_get of existing item (size)"); free(result); /* Test put and get of a second item. */ _mesa_sha1_compute(string, sizeof(string), string_key); - disk_cache_put(cache, string_key, string, sizeof(string)); + dc_job = disk_cache_create_put_job(cache, string_key, string, + sizeof(string), NULL); + disk_cache_put(dc_job, 0); + free(dc_job); result = disk_cache_get(cache, string_key, &size); expect_equal_str(result, string, "2nd disk_cache_get of existing item (pointer)"); expect_equal(size, sizeof(string), "2nd disk_cache_get of existing item (size)"); free(result); /* Set the cache size to 1KB and add a 1KB item to force an eviction. */ disk_cache_destroy(cache); @@ -297,21 +303,23 @@ test_put_and_get(void) * That's actually expected given how the eviction code is * implemented, (which expects to only evict once things are more * interestingly full than that). * * For this test, we force this signature to land in the same * directory as the original blob first written to the cache. */ _mesa_sha1_compute(one_KB, 1024, one_KB_key); one_KB_key[0] = blob_key_byte_zero; - disk_cache_put(cache, one_KB_key, one_KB, 1024); + dc_job = disk_cache_create_put_job(cache, one_KB_key, one_KB, 1024, NULL); + disk_cache_put(dc_job, 0); + free(dc_job); free(one_KB); result = disk_cache_get(cache, one_KB_key, &size); expect_non_null(result, "3rd disk_cache_get of existing item (pointer)"); expect_equal(size, 1024, "3rd disk_cache_get of existing item (size)"); free(result); /* Ensure eviction happened by checking that only one of the two @@ -327,42 +335,51 @@ test_put_and_get(void) expect_equal(count, 1, "disk_cache_put eviction with MAX_SIZE=1K"); /* Now increase the size to 1M, add back both items, and ensure all * three that have been added are available via disk_cache_get. */ disk_cache_destroy(cache); setenv("MESA_GLSL_CACHE_MAX_SIZE", "1M", 1); cache = disk_cache_create("test", "make_check"); - disk_cache_put(cache, blob_key, blob, sizeof(blob)); - disk_cache_put(cache, string_key, string, sizeof(string)); + dc_job = disk_cache_create_put_job(cache, blob_key, blob, sizeof(blob), + NULL); + disk_cache_put(dc_job, 0); + free(dc_job); + dc_job = disk_cache_create_put_job(cache, string_key, string, + sizeof(string), NULL); + disk_cache_put(dc_job, 0); + free(dc_job); count = 0; if (does_cache_contain(cache, blob_key)) count++; if (does_cache_contain(cache, string_key)) count++; if (does_cache_contain(cache, one_KB_key)) count++; expect_equal(count, 3, "no eviction before overflow with MAX_SIZE=1M"); /* Finally, check eviction again after adding an object of size 1M. */ one_MB = calloc(1024, 1024); _mesa_sha1_compute(one_MB, 1024 * 1024, one_MB_key); one_MB_key[0] = blob_key_byte_zero;; - disk_cache_put(cache, one_MB_key, one_MB, 1024 * 1024); + dc_job = disk_cache_create_put_job(cache, one_MB_key, one_MB, 1024 * 1024, + NULL); + disk_cache_put(dc_job, 0); + free(dc_job); free(one_MB); count = 0; if (does_cache_contain(cache, blob_key)) count++; if (does_cache_contain(cache, string_key)) count++; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 9cde0aa..343cb83 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -201,22 +201,27 @@ static bool si_shader_cache_insert_shader(struct si_screen *sscreen, return false; if (_mesa_hash_table_insert(sscreen->shader_cache, tgsi_binary, hw_binary) == NULL) { FREE(hw_binary); 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)); + + struct disk_cache_put_job *dc_job = + disk_cache_create_put_job(sscreen->b.disk_shader_cache, + key, hw_binary, + *((uint32_t *) hw_binary), + NULL); + disk_cache_put(dc_job, 0); } return true; } static bool si_shader_cache_load_shader(struct si_screen *sscreen, void *tgsi_binary, struct si_shader *shader) { struct hash_entry *entry = diff --git a/src/mesa/state_tracker/st_shader_cache.c b/src/mesa/state_tracker/st_shader_cache.c index 4383194..040fbc1 100644 --- a/src/mesa/state_tracker/st_shader_cache.c +++ b/src/mesa/state_tracker/st_shader_cache.c @@ -40,21 +40,24 @@ write_stream_out_to_cache(struct blob *blob, static void write_tgsi_to_cache(struct blob *blob, struct pipe_shader_state *tgsi, struct st_context *st, unsigned char *sha1, unsigned num_tokens) { blob_write_uint32(blob, num_tokens); blob_write_bytes(blob, tgsi->tokens, num_tokens * sizeof(struct tgsi_token)); - disk_cache_put(st->ctx->Cache, sha1, blob->data, blob->size); + struct disk_cache_put_job *dc_job = + disk_cache_create_put_job(st->ctx->Cache, sha1, blob->data, blob->size, + blob); + disk_cache_put(dc_job, 0); } /** * Store tgsi and any other required state in on-disk shader cache. */ void st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog, struct pipe_shader_state *out_state, unsigned num_tokens) { diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c index 37b3576..e0b540c 100644 --- a/src/util/disk_cache.c +++ b/src/util/disk_cache.c @@ -761,48 +761,50 @@ disk_cache_destroy_put_job(void *job, int thread_index) free(dc_job); } } struct cache_entry_file_data { uint32_t crc32; uint32_t uncompressed_size; }; void -disk_cache_put(struct disk_cache *cache, - const cache_key key, - const void *data, - size_t size) +disk_cache_put(void *job, int thread_index) { + if (!job) + return; + + struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *) job; + int fd = -1, fd_final = -1, err, ret; size_t len; char *filename = NULL, *filename_tmp = NULL; - filename = get_cache_file(cache, key); + filename = get_cache_file(dc_job->cache, dc_job->key); if (filename == NULL) goto done; /* Write to a temporary file to allow for an atomic rename to the * final destination filename, (to prevent any readers from seeing * a partially written file). */ if (asprintf(&filename_tmp, "%s.tmp", filename) == -1) goto done; fd = open(filename_tmp, O_WRONLY | O_CLOEXEC | O_CREAT, 0644); /* Make the two-character subdirectory within the cache as needed. */ if (fd == -1) { if (errno != ENOENT) goto done; - make_cache_file_directory(cache, key); + make_cache_file_directory(dc_job->cache, dc_job->key); fd = open(filename_tmp, O_WRONLY | O_CLOEXEC | O_CREAT, 0644); if (fd == -1) goto done; } /* With the temporary file open, we take an exclusive flock on * it. If the flock fails, then another process still has the file * open with the flock held. So just let that file be responsible * for writing the file. @@ -821,52 +823,53 @@ disk_cache_put(struct disk_cache *cache, if (fd_final != -1) goto done; /* OK, we're now on the hook to write out a file that we know is * not in the cache, and is also not being written out to the cache * by some other process. * * Before we do that, if the cache is too large, evict something * else first. */ - if (*cache->size + size > cache->max_size) - evict_random_item(cache); + if (*dc_job->cache->size + dc_job->size > dc_job->cache->max_size) + evict_random_item(dc_job->cache); /* Create CRC of the data and store at the start of the file. We will * read this when restoring the cache and use it to check for corruption. */ struct cache_entry_file_data cf_data; - cf_data.crc32 = util_hash_crc32(data, size); - cf_data.uncompressed_size = size; + cf_data.crc32 = util_hash_crc32(dc_job->data, dc_job->size); + cf_data.uncompressed_size = dc_job->size; size_t cf_data_size = sizeof(cf_data); for (len = 0; len < cf_data_size; len += ret) { ret = write(fd, ((uint8_t *) &cf_data) + len, cf_data_size - len); if (ret == -1) { unlink(filename_tmp); goto done; } } /* Now, finally, write out the contents to the temporary file, then * rename them atomically to the destination filename, and also * perform an atomic increment of the total cache size. */ - size_t file_size = deflate_and_write_to_disk(data, size, fd, filename_tmp); + size_t file_size = deflate_and_write_to_disk(dc_job->data, dc_job->size, + fd, filename_tmp); if (file_size == 0) { unlink(filename_tmp); goto done; } rename(filename_tmp, filename); file_size += cf_data_size; - p_atomic_add(cache->size, file_size); + p_atomic_add(dc_job->cache->size, file_size); done: if (fd_final != -1) close(fd_final); /* This close finally releases the flock, (now that the final dile * has been renamed into place and the size has been added). */ if (fd != -1) close(fd); if (filename_tmp) diff --git a/src/util/disk_cache.h b/src/util/disk_cache.h index 136140e..19eb1a9 100644 --- a/src/util/disk_cache.h +++ b/src/util/disk_cache.h @@ -156,22 +156,21 @@ disk_cache_destroy_put_job(void *job, int thread_index); /** * Store an item in the cache under the name \key. * * The item can be retrieved later with disk_cache_get(), (unless the item has * been evicted in the interim). * * Any call to disk_cache_put() may cause an existing, random item to be * evicted from the cache. */ void -disk_cache_put(struct disk_cache *cache, const cache_key key, - const void *data, size_t size); +disk_cache_put(void *job, int thread_index); /** * Retrieve an item previously stored in the cache with the name <key>. * * The item must have been previously stored with a call to disk_cache_put(). * * If \size is non-NULL, then, on successful return, it will be set to the * size of the object. * * \return A pointer to the stored object if found. NULL if the object @@ -225,23 +224,21 @@ disk_cache_create_put_job(struct disk_cache *cache, const cache_key key, const void *data, size_t size, void *mem) { return NULL; } static inline void disk_cache_destroy_put_job(void *job, int thread_index) { return; } -static inline void -disk_cache_put(struct disk_cache *cache, const cache_key key, - const void *data, size_t size) +disk_cache_put(void *job, int thread_index) { return; } static inline void disk_cache_remove(struct disk_cache *cache, const cache_key key) { return; } -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev