From 3c2c232059b778ef38fe198d21971bafa7e7aafc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 19 Jul 2019 16:07:47 +1000 Subject: [PATCH] llvmpipe: move the fragment shader variant key to dynamic length. This mirrors the vs/gs keys, and will be needed when adding images support. The const changes also mirror how the draw code work (as is needed when we add images) Reviewed-by: Roland Scheidegger --- src/gallium/drivers/llvmpipe/lp_state_fs.c | 49 ++++++++++++++++++------------ src/gallium/drivers/llvmpipe/lp_state_fs.h | 19 ++++++++++-- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index bf2c031..dc5a0ae 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -2424,7 +2424,7 @@ generate_fragment(struct llvmpipe_context *lp, unsigned partial_mask) { struct gallivm_state *gallivm = variant->gallivm; - const struct lp_fragment_shader_variant_key *key = &variant->key; + struct lp_fragment_shader_variant_key *key = &variant->key; struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; char func_name[64]; struct lp_type fs_type; @@ -2595,7 +2595,7 @@ generate_fragment(struct llvmpipe_context *lp, } /* code generated texture sampling */ - sampler = lp_llvm_sampler_soa_create(key->state); + sampler = lp_llvm_sampler_soa_create(key->samplers); num_fs = 16 / fs_type.length; /* number of loops per 4x4 stamp */ /* for 1d resources only run "upper half" of stamp */ @@ -2724,7 +2724,7 @@ generate_fragment(struct llvmpipe_context *lp, static void -dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key) +dump_fs_variant_key(struct lp_fragment_shader_variant_key *key) { unsigned i; @@ -2779,7 +2779,7 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key) debug_printf("blend.alpha_to_coverage is enabled\n"); } for (i = 0; i < key->nr_samplers; ++i) { - const struct lp_static_sampler_state *sampler = &key->state[i].sampler_state; + const struct lp_static_sampler_state *sampler = &key->samplers[i].sampler_state; debug_printf("sampler[%u] = \n", i); debug_printf(" .wrap = %s %s %s\n", util_str_tex_wrap(sampler->wrap_s, TRUE), @@ -2800,7 +2800,7 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key) debug_printf(" .apply_max_lod = %u\n", sampler->apply_max_lod); } for (i = 0; i < key->nr_sampler_views; ++i) { - const struct lp_static_texture_state *texture = &key->state[i].texture_state; + const struct lp_static_texture_state *texture = &key->samplers[i].texture_state; debug_printf("texture[%u] = \n", i); debug_printf(" .format = %s\n", util_format_name(texture->format)); @@ -2817,7 +2817,7 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key) void -lp_debug_fs_variant(const struct lp_fragment_shader_variant *variant) +lp_debug_fs_variant(struct lp_fragment_shader_variant *variant) { debug_printf("llvmpipe: Fragment shader #%u variant #%u:\n", variant->shader->no, variant->no); @@ -2842,10 +2842,11 @@ generate_variant(struct llvmpipe_context *lp, boolean fullcolormask; char module_name[64]; - variant = CALLOC_STRUCT(lp_fragment_shader_variant); + variant = MALLOC(sizeof *variant + shader->variant_key_size - sizeof variant->key); if (!variant) return NULL; + memset(variant, 0, sizeof(*variant)); snprintf(module_name, sizeof(module_name), "fs%u_variant%u", shader->no, shader->variants_created); @@ -2960,8 +2961,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe, nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1; nr_sampler_views = shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; - shader->variant_key_size = Offset(struct lp_fragment_shader_variant_key, - state[MAX2(nr_samplers, nr_sampler_views)]); + shader->variant_key_size = lp_fs_variant_key_size(MAX2(nr_samplers, nr_sampler_views)); for (i = 0; i < shader->info.base.num_inputs; i++) { shader->inputs[i].usage_mask = shader->info.base.input_usage_mask[i]; @@ -3216,14 +3216,17 @@ force_dst_alpha_one(unsigned factor, boolean clamped_zero) * TODO: there is actually no reason to tie this to context state -- the * generated code could be cached globally in the screen. */ -static void +static struct lp_fragment_shader_variant_key * make_variant_key(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, - struct lp_fragment_shader_variant_key *key) + char *store) { unsigned i; + struct lp_fragment_shader_variant_key *key; + + key = (struct lp_fragment_shader_variant_key *)store; - memset(key, 0, shader->variant_key_size); + memset(key, 0, offsetof(struct lp_fragment_shader_variant_key, samplers[1])); if (lp->framebuffer.zsbuf) { enum pipe_format zsbuf_format = lp->framebuffer.zsbuf->format; @@ -3369,9 +3372,15 @@ make_variant_key(struct llvmpipe_context *lp, */ key->nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1; + struct lp_sampler_static_state *fs_sampler; + + fs_sampler = key->samplers; + + memset(fs_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *fs_sampler); + for(i = 0; i < key->nr_samplers; ++i) { if(shader->info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) { - lp_sampler_static_sampler_state(&key->state[i].sampler_state, + lp_sampler_static_sampler_state(&fs_sampler[i].sampler_state, lp->samplers[PIPE_SHADER_FRAGMENT][i]); } } @@ -3390,7 +3399,7 @@ make_variant_key(struct llvmpipe_context *lp, * used views may be included in the shader key. */ if(shader->info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1u << (i & 31))) { - lp_sampler_static_texture_state(&key->state[i].texture_state, + lp_sampler_static_texture_state(&fs_sampler[i].texture_state, lp->sampler_views[PIPE_SHADER_FRAGMENT][i]); } } @@ -3399,11 +3408,12 @@ make_variant_key(struct llvmpipe_context *lp, key->nr_sampler_views = key->nr_samplers; for(i = 0; i < key->nr_sampler_views; ++i) { if(shader->info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) { - lp_sampler_static_texture_state(&key->state[i].texture_state, + lp_sampler_static_texture_state(&fs_sampler[i].texture_state, lp->sampler_views[PIPE_SHADER_FRAGMENT][i]); } } } + return key; } @@ -3416,16 +3426,17 @@ void llvmpipe_update_fs(struct llvmpipe_context *lp) { struct lp_fragment_shader *shader = lp->fs; - struct lp_fragment_shader_variant_key key; + struct lp_fragment_shader_variant_key *key; struct lp_fragment_shader_variant *variant = NULL; struct lp_fs_variant_list_item *li; + char store[LP_FS_MAX_VARIANT_KEY_SIZE]; - make_variant_key(lp, shader, &key); + key = make_variant_key(lp, shader, store); /* Search the variants for one which matches the key */ li = first_elem(&shader->variants); while(!at_end(&shader->variants, li)) { - if(memcmp(&li->base->key, &key, shader->variant_key_size) == 0) { + if(memcmp(&li->base->key, key, shader->variant_key_size) == 0) { variant = li->base; break; } @@ -3497,7 +3508,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) * Generate the new variant. */ t0 = os_time_get(); - variant = generate_variant(lp, shader, &key); + variant = generate_variant(lp, shader, key); t1 = os_time_get(); dt = t1 - t0; LP_COUNT_ADD(llvm_compile_time, dt); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h index dc04df8..02e9de8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h @@ -81,9 +81,20 @@ struct lp_fragment_shader_variant_key enum pipe_format zsbuf_format; enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS]; - struct lp_sampler_static_state state[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + struct lp_sampler_static_state samplers[1]; }; +#define LP_FS_MAX_VARIANT_KEY_SIZE \ + (sizeof(struct lp_fragment_shader_variant_key) + \ + PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct lp_sampler_static_state)) + +static inline size_t +lp_fs_variant_key_size(unsigned nr_samplers) +{ + unsigned samplers = nr_samplers > 1 ? (nr_samplers - 1) : 0; + return (sizeof(struct lp_fragment_shader_variant_key) + + samplers * sizeof(struct lp_sampler_static_state)); +} /** doubly-linked list item */ struct lp_fs_variant_list_item @@ -95,7 +106,6 @@ struct lp_fs_variant_list_item struct lp_fragment_shader_variant { - struct lp_fragment_shader_variant_key key; boolean opaque; @@ -117,6 +127,9 @@ struct lp_fragment_shader_variant /* For debugging/profiling purposes */ unsigned no; + + /* key is variable-sized, must be last */ + struct lp_fragment_shader_variant_key key; }; @@ -143,6 +156,6 @@ struct lp_fragment_shader void -lp_debug_fs_variant(const struct lp_fragment_shader_variant *variant); +lp_debug_fs_variant(struct lp_fragment_shader_variant *variant); #endif /* LP_STATE_FS_H_ */ -- 2.7.4