diff --git a/src/gallium/drivers/asahi/agx_disk_cache.c b/src/gallium/drivers/asahi/agx_disk_cache.c index 5dbd7df6d32..0d1c740ddfa 100644 --- a/src/gallium/drivers/asahi/agx_disk_cache.c +++ b/src/gallium/drivers/asahi/agx_disk_cache.c @@ -56,6 +56,66 @@ agx_disk_cache_compute_key(struct disk_cache *cache, disk_cache_compute_key(cache, data, hash_size + key_size, cache_key); } +static void +write_shader(struct blob *blob, const struct agx_compiled_shader *binary, + bool is_root_gs) +{ + uint32_t shader_size = binary->bo->size; + blob_write_uint32(blob, shader_size); + blob_write_bytes(blob, binary->bo->ptr.cpu, shader_size); + blob_write_bytes(blob, &binary->info, sizeof(binary->info)); + blob_write_uint32(blob, binary->push_range_count); + blob_write_bytes(blob, binary->push, + sizeof(binary->push[0]) * binary->push_range_count); + + if (is_root_gs) { + blob_write_uint32(blob, binary->gs_count_words); + blob_write_uint32(blob, binary->gs_output_mode); + write_shader(blob, binary->pre_gs, false); + + blob_write_uint8(blob, binary->gs_copy != NULL); + if (binary->gs_copy) + write_shader(blob, binary->gs_copy, false); + + blob_write_uint8(blob, binary->gs_count != NULL); + if (binary->gs_count) + write_shader(blob, binary->gs_count, false); + } +} + +static struct agx_compiled_shader * +read_shader(struct agx_screen *screen, struct blob_reader *blob, + const struct agx_uncompiled_shader *uncompiled, bool is_root) +{ + struct agx_compiled_shader *binary = CALLOC_STRUCT(agx_compiled_shader); + binary->stage = uncompiled->type; + binary->so = uncompiled; + + uint32_t binary_size = blob_read_uint32(blob); + binary->bo = agx_bo_create(&screen->dev, binary_size, + AGX_BO_EXEC | AGX_BO_LOW_VA, "Executable"); + blob_copy_bytes(blob, binary->bo->ptr.cpu, binary_size); + + blob_copy_bytes(blob, &binary->info, sizeof(binary->info)); + binary->push_range_count = blob_read_uint32(blob); + blob_copy_bytes(blob, binary->push, + sizeof(binary->push[0]) * binary->push_range_count); + + if (is_root && uncompiled->type == PIPE_SHADER_GEOMETRY) { + binary->gs_count_words = blob_read_uint32(blob); + binary->gs_output_mode = blob_read_uint32(blob); + binary->pre_gs = read_shader(screen, blob, uncompiled, false); + + if (blob_read_uint8(blob)) + binary->gs_copy = read_shader(screen, blob, uncompiled, false); + + if (blob_read_uint8(blob)) + binary->gs_count = read_shader(screen, blob, uncompiled, false); + } + + return binary; +} + /** * Store the given compiled shader in the disk cache. * @@ -72,10 +132,6 @@ agx_disk_cache_store(struct disk_cache *cache, if (!cache) return; - /* TODO: Support caching GS */ - if (uncompiled->type == PIPE_SHADER_GEOMETRY) - return; - assert(binary->bo->ptr.cpu != NULL && "shaders must be CPU mapped"); cache_key cache_key; @@ -84,13 +140,7 @@ agx_disk_cache_store(struct disk_cache *cache, struct blob blob; blob_init(&blob); - uint32_t shader_size = binary->bo->size; - blob_write_uint32(&blob, shader_size); - blob_write_bytes(&blob, binary->bo->ptr.cpu, shader_size); - blob_write_bytes(&blob, &binary->info, sizeof(binary->info)); - blob_write_uint32(&blob, binary->push_range_count); - blob_write_bytes(&blob, binary->push, - sizeof(binary->push[0]) * binary->push_range_count); + write_shader(&blob, binary, uncompiled->type == PIPE_SHADER_GEOMETRY); disk_cache_put(cache, cache_key, blob.data, blob.size, NULL); blob_finish(&blob); @@ -110,10 +160,6 @@ agx_disk_cache_retrieve(struct agx_screen *screen, if (!cache) return NULL; - /* TODO: Support caching GS */ - if (uncompiled->type == PIPE_SHADER_GEOMETRY) - return NULL; - cache_key cache_key; agx_disk_cache_compute_key(cache, uncompiled, key, cache_key); @@ -122,22 +168,11 @@ agx_disk_cache_retrieve(struct agx_screen *screen, if (!buffer) return NULL; - struct agx_compiled_shader *binary = CALLOC_STRUCT(agx_compiled_shader); - binary->stage = uncompiled->type; - binary->so = uncompiled; - struct blob_reader blob; blob_reader_init(&blob, buffer, size); - uint32_t binary_size = blob_read_uint32(&blob); - binary->bo = agx_bo_create(&screen->dev, binary_size, - AGX_BO_EXEC | AGX_BO_LOW_VA, "Executable"); - blob_copy_bytes(&blob, binary->bo->ptr.cpu, binary_size); - - blob_copy_bytes(&blob, &binary->info, sizeof(binary->info)); - binary->push_range_count = blob_read_uint32(&blob); - blob_copy_bytes(&blob, binary->push, - sizeof(binary->push[0]) * binary->push_range_count); + struct agx_compiled_shader *binary = + read_shader(screen, &blob, uncompiled, true); free(buffer); return binary; diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 5d8debd005b..46d8edbb683 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -502,6 +502,10 @@ struct asahi_tcs_shader_key { }; struct asahi_gs_shader_key { + /* Rasterizer shader key */ + uint64_t outputs_flat_shaded; + uint64_t outputs_linear_shaded; + /* Input assembly key */ enum mesa_prim mode; bool flatshade_first; @@ -509,8 +513,6 @@ struct asahi_gs_shader_key { /* Rasterizer shader key */ bool clip_halfz; bool fixed_point_size; - uint64_t outputs_flat_shaded; - uint64_t outputs_linear_shaded; /* If true, this GS is run only for its side effects (including XFB) */ bool rasterizer_discard;