[Mesa-dev] [PATCH 3/4] glsl: pass shader source keys to the disk cache
Timothy Arceri
tarceri at itsqueeze.com
Mon Aug 14 23:26:50 UTC 2017
We don't actually write them to disk here. That will happen in the
following commit.
---
src/compiler/glsl/shader_cache.cpp | 20 +++++++++++++++++---
src/compiler/glsl/tests/cache_test.c | 12 ++++++------
src/gallium/drivers/radeonsi/si_state_shaders.c | 2 +-
src/mesa/state_tracker/st_shader_cache.c | 2 +-
src/util/disk_cache.c | 8 +++++---
src/util/disk_cache.h | 6 ++++--
6 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index cc4d24482d..7a97fb7cb8 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -1302,37 +1302,51 @@ shader_cache_write_program_metadata(struct gl_context *ctx,
write_uniform_remap_tables(metadata, prog);
write_atomic_buffers(metadata, prog);
write_buffer_blocks(metadata, prog);
write_subroutines(metadata, prog);
write_program_resource_list(metadata, prog);
+ struct cache_item_metadata cache_item_metadata;
+ cache_item_metadata.type = CACHE_ITEM_TYPE_GLSL;
+ cache_item_metadata.keys =
+ (cache_key *) malloc(prog->NumShaders * sizeof(cache_key));
+ cache_item_metadata.num_keys = prog->NumShaders;
+
+ if (!cache_item_metadata.keys)
+ goto fail;
+
char sha1_buf[41];
for (unsigned i = 0; i < prog->NumShaders; i++) {
disk_cache_put_key(cache, prog->Shaders[i]->sha1);
+ memcpy(cache_item_metadata.keys[i], prog->Shaders[i]->sha1,
+ sizeof(cache_key));
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
_mesa_sha1_format(sha1_buf, prog->Shaders[i]->sha1);
fprintf(stderr, "marking shader: %s\n", sha1_buf);
}
}
- disk_cache_put(cache, prog->data->sha1, metadata->data, metadata->size);
-
- blob_destroy(metadata);
+ disk_cache_put(cache, prog->data->sha1, metadata->data, metadata->size,
+ &cache_item_metadata);
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
_mesa_sha1_format(sha1_buf, prog->data->sha1);
fprintf(stderr, "putting program metadata in cache: %s\n", sha1_buf);
}
+
+fail:
+ free(cache_item_metadata.keys);
+ blob_destroy(metadata);
}
bool
shader_cache_read_program_metadata(struct gl_context *ctx,
struct gl_shader_program *prog)
{
/* Fixed function programs generated by Mesa are not cached. So don't
* try to read metadata for them from the cache.
*/
if (prog->Name == 0)
diff --git a/src/compiler/glsl/tests/cache_test.c b/src/compiler/glsl/tests/cache_test.c
index aa779e3985..c6f306d069 100644
--- a/src/compiler/glsl/tests/cache_test.c
+++ b/src/compiler/glsl/tests/cache_test.c
@@ -261,36 +261,36 @@ test_put_and_get(void)
cache = disk_cache_create("test", "make_check", 0);
disk_cache_compute_key(cache, 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));
+ disk_cache_put(cache, blob_key, blob, sizeof(blob), NULL);
/* disk_cache_put() hands things off to a thread give it some time to
* finish.
*/
wait_until_file_written(cache, blob_key);
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. */
disk_cache_compute_key(cache, string, sizeof(string), string_key);
- disk_cache_put(cache, string_key, string, sizeof(string));
+ disk_cache_put(cache, string_key, string, sizeof(string), NULL);
/* disk_cache_put() hands things off to a thread give it some time to
* finish.
*/
wait_until_file_written(cache, string_key);
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)");
@@ -317,21 +317,21 @@ 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.
*/
disk_cache_compute_key(cache, one_KB, 1024, one_KB_key);
one_KB_key[0] = blob_key[0];
- disk_cache_put(cache, one_KB_key, one_KB, 1024);
+ disk_cache_put(cache, one_KB_key, one_KB, 1024, NULL);
free(one_KB);
/* disk_cache_put() hands things off to a thread give it some time to
* finish.
*/
wait_until_file_written(cache, one_KB_key);
result = disk_cache_get(cache, one_KB_key, &size);
expect_non_null(result, "3rd disk_cache_get of existing item (pointer)");
@@ -360,22 +360,22 @@ 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", 0);
- disk_cache_put(cache, blob_key, blob, sizeof(blob));
- disk_cache_put(cache, string_key, string, sizeof(string));
+ disk_cache_put(cache, blob_key, blob, sizeof(blob), NULL);
+ disk_cache_put(cache, string_key, string, sizeof(string), NULL);
/* disk_cache_put() hands things off to a thread give it some time to
* finish.
*/
wait_until_file_written(cache, blob_key);
wait_until_file_written(cache, string_key);
count = 0;
if (does_cache_contain(cache, blob_key))
count++;
@@ -387,21 +387,21 @@ test_put_and_get(void)
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);
disk_cache_compute_key(cache, one_MB, 1024 * 1024, one_MB_key);
one_MB_key[0] = blob_key[0];
- disk_cache_put(cache, one_MB_key, one_MB, 1024 * 1024);
+ disk_cache_put(cache, one_MB_key, one_MB, 1024 * 1024, NULL);
free(one_MB);
/* disk_cache_put() hands things off to a thread give it some time to
* finish.
*/
wait_until_file_written(cache, one_MB_key);
bool contains_1MB_file = false;
count = 0;
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index de5260ccd8..7970203c72 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -206,21 +206,21 @@ static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
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) {
disk_cache_compute_key(sscreen->b.disk_shader_cache, tgsi_binary,
*((uint32_t *)tgsi_binary), key);
disk_cache_put(sscreen->b.disk_shader_cache, key, hw_binary,
- *((uint32_t *) hw_binary));
+ *((uint32_t *) hw_binary), NULL);
}
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 ba964eb5f0..2c38f27ffd 100644
--- a/src/mesa/state_tracker/st_shader_cache.c
+++ b/src/mesa/state_tracker/st_shader_cache.c
@@ -40,21 +40,21 @@ 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);
+ disk_cache_put(st->ctx->Cache, sha1, blob->data, blob->size, NULL);
}
/**
* 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 283856b15c..c5a7d1f98a 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -752,21 +752,22 @@ deflate_and_write_to_disk(const void *in_data, size_t in_data_size, int dest,
/* stream should be complete */
assert(ret == Z_STREAM_END);
/* clean up and return */
(void)deflateEnd(&strm);
return compressed_size;
}
static struct disk_cache_put_job *
create_put_job(struct disk_cache *cache, const cache_key key,
- const void *data, size_t size)
+ const void *data, size_t size,
+ struct cache_item_metadata *cache_item_metadata)
{
struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *)
malloc(sizeof(struct disk_cache_put_job) + size);
if (dc_job) {
dc_job->cache = cache;
memcpy(dc_job->key, key, sizeof(cache_key));
dc_job->data = dc_job + 1;
memcpy(dc_job->data, data, size);
dc_job->size = size;
@@ -915,24 +916,25 @@ cache_put(void *job, int thread_index)
if (fd != -1)
close(fd);
if (filename_tmp)
free(filename_tmp);
if (filename)
free(filename);
}
void
disk_cache_put(struct disk_cache *cache, const cache_key key,
- const void *data, size_t size)
+ const void *data, size_t size,
+ struct cache_item_metadata *cache_item_metadata)
{
struct disk_cache_put_job *dc_job =
- create_put_job(cache, key, data, size);
+ create_put_job(cache, key, data, size, cache_item_metadata);
if (dc_job) {
util_queue_fence_init(&dc_job->fence);
util_queue_add_job(&cache->cache_queue, dc_job, &dc_job->fence,
cache_put, destroy_put_job);
}
}
/**
* Decompresses cache entry, returns true if successful.
diff --git a/src/util/disk_cache.h b/src/util/disk_cache.h
index d6d7609ffb..8f57061433 100644
--- a/src/util/disk_cache.h
+++ b/src/util/disk_cache.h
@@ -134,21 +134,22 @@ disk_cache_remove(struct disk_cache *cache, const cache_key key);
* 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);
+ const void *data, size_t size,
+ struct cache_item_metadata *cache_item_metadata);
/**
* 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
@@ -200,21 +201,22 @@ disk_cache_create(const char *gpu_name, const char *timestamp,
return NULL;
}
static inline void
disk_cache_destroy(struct disk_cache *cache) {
return;
}
static inline void
disk_cache_put(struct disk_cache *cache, const cache_key key,
- const void *data, size_t size)
+ const void *data, size_t size,
+ struct cache_item_metadata *cache_item_metadata)
{
return;
}
static inline void
disk_cache_remove(struct disk_cache *cache, const cache_key key)
{
return;
}
--
2.13.4
More information about the mesa-dev
mailing list