draw: reduce the size of the llvm variant key

This commit is contained in:
Keith Whitwell
2010-08-21 22:51:38 +01:00
parent 8b15de2736
commit a1de6f48c3
4 changed files with 100 additions and 38 deletions
+42 -25
View File
@@ -285,15 +285,23 @@ draw_llvm_destroy(struct draw_llvm *llvm)
}
struct draw_llvm_variant *
draw_llvm_create_variant(struct draw_llvm *llvm, int num_inputs)
draw_llvm_create_variant(struct draw_llvm *llvm,
unsigned num_inputs,
const struct draw_llvm_variant_key *key)
{
struct draw_llvm_variant *variant = MALLOC(sizeof(struct draw_llvm_variant));
struct draw_llvm_variant *variant;
struct llvm_vertex_shader *shader =
llvm_vertex_shader(llvm->draw->vs.vertex_shader);
variant = MALLOC(sizeof *variant +
shader->variant_key_size -
sizeof variant->key);
if (variant == NULL)
return NULL;
variant->llvm = llvm;
draw_llvm_make_variant_key(llvm, &variant->key);
memcpy(&variant->key, key, shader->variant_key_size);
llvm->vertex_header_ptr_type = create_vertex_header(llvm, num_inputs);
@@ -731,8 +739,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
/* code generated texture sampling */
sampler = draw_llvm_sampler_soa_create(variant->key.sampler,
context_ptr);
sampler = draw_llvm_sampler_soa_create(
draw_llvm_variant_key_samplers(&variant->key),
context_ptr);
#if DEBUG_STORE
lp_build_printf(builder, "start = %d, end = %d, step = %d\n",
@@ -894,8 +903,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
/* code generated texture sampling */
sampler = draw_llvm_sampler_soa_create(variant->key.sampler,
context_ptr);
sampler = draw_llvm_sampler_soa_create(
draw_llvm_variant_key_samplers(&variant->key),
context_ptr);
fetch_max = LLVMBuildSub(builder, fetch_count,
LLVMConstInt(LLVMInt32Type(), 1, 0),
@@ -995,35 +1005,42 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
lp_func_delete_body(variant->function_elts);
}
void
draw_llvm_make_variant_key(struct draw_llvm *llvm,
struct draw_llvm_variant_key *key)
struct draw_llvm_variant_key *
draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
{
unsigned i;
struct draw_llvm_variant_key *key;
struct lp_sampler_static_state *sampler;
memset(key, 0, sizeof(struct draw_llvm_variant_key));
key = (struct draw_llvm_variant_key *)store;
/* Presumably all variants of the shader should have the same
* number of vertex elements - ie the number of shader inputs.
*/
key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements;
/* All variants of this shader will have the same value for
* nr_samplers. Not yet trying to compact away holes in the
* sampler array.
*/
key->nr_samplers = llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER] + 1;
sampler = draw_llvm_variant_key_samplers(key);
memcpy(key->vertex_element,
llvm->draw->pt.vertex_element,
sizeof(struct pipe_vertex_element) * key->nr_vertex_elements);
memset(sampler, 0, key->nr_samplers * sizeof *sampler);
memcpy(&key->vs,
&llvm->draw->vs.vertex_shader->state,
sizeof(struct pipe_shader_state));
/* if the driver implemented the sampling hooks then
* setup our sampling state */
if (llvm->draw->num_sampler_views && llvm->draw->num_samplers) {
for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) {
struct draw_vertex_shader *shader = llvm->draw->vs.vertex_shader;
if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
lp_sampler_static_state(&key->sampler[i],
llvm->draw->sampler_views[i],
llvm->draw->samplers[i]);
}
for (i = 0 ; i < key->nr_samplers; i++) {
lp_sampler_static_state(&sampler[i],
llvm->draw->sampler_views[i],
llvm->draw->samplers[i]);
}
return key;
}
void
+45 -9
View File
@@ -151,12 +151,43 @@ typedef void
struct draw_llvm_variant_key
{
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_elements;
struct pipe_shader_state vs;
struct lp_sampler_static_state sampler[PIPE_MAX_VERTEX_SAMPLERS];
unsigned nr_vertex_elements:16;
unsigned nr_samplers:16;
/* Variable number of vertex elements:
*/
struct pipe_vertex_element vertex_element[1];
/* Followed by variable number of samplers:
*/
/* struct lp_sampler_static_state sampler; */
};
#define DRAW_LLVM_MAX_VARIANT_KEY_SIZE \
(sizeof(struct draw_llvm_variant_key) + \
PIPE_MAX_VERTEX_SAMPLERS * sizeof(struct lp_sampler_static_state) + \
(PIPE_MAX_ATTRIBS-1) * sizeof(struct pipe_vertex_element))
static INLINE size_t
draw_llvm_variant_key_size(unsigned nr_vertex_elements,
unsigned nr_samplers)
{
return (sizeof(struct draw_llvm_variant_key) +
nr_samplers * sizeof(struct lp_sampler_static_state) +
(nr_vertex_elements - 1) * sizeof(struct pipe_vertex_element));
}
static INLINE struct lp_sampler_static_state *
draw_llvm_variant_key_samplers(struct draw_llvm_variant_key *key)
{
return (struct lp_sampler_static_state *)
&key->vertex_element[key->nr_vertex_elements];
}
struct draw_llvm_variant_list_item
{
struct draw_llvm_variant *base;
@@ -165,7 +196,6 @@ struct draw_llvm_variant_list_item
struct draw_llvm_variant
{
struct draw_llvm_variant_key key;
LLVMValueRef function;
LLVMValueRef function_elts;
draw_jit_vert_func jit_func;
@@ -176,11 +206,16 @@ struct draw_llvm_variant
struct draw_llvm *llvm;
struct draw_llvm_variant_list_item list_item_global;
struct draw_llvm_variant_list_item list_item_local;
/* key is variable-sized, must be last */
struct draw_llvm_variant_key key;
/* key is variable-sized, must be last */
};
struct llvm_vertex_shader {
struct draw_vertex_shader base;
unsigned variant_key_size;
struct draw_llvm_variant_list_item variants;
unsigned variants_created;
unsigned variants_cached;
@@ -220,14 +255,15 @@ void
draw_llvm_destroy(struct draw_llvm *llvm);
struct draw_llvm_variant *
draw_llvm_create_variant(struct draw_llvm *llvm, int num_inputs);
draw_llvm_create_variant(struct draw_llvm *llvm,
unsigned num_vertex_header_attribs,
const struct draw_llvm_variant_key *key);
void
draw_llvm_destroy_variant(struct draw_llvm_variant *variant);
void
draw_llvm_make_variant_key(struct draw_llvm *llvm,
struct draw_llvm_variant_key *key);
struct draw_llvm_variant_key *
draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store);
LLVMValueRef
draw_llvm_translate_from(LLVMBuilderRef builder,
@@ -66,7 +66,8 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
struct draw_context *draw = fpme->draw;
struct llvm_vertex_shader *shader =
llvm_vertex_shader(draw->vs.vertex_shader);
struct draw_llvm_variant_key key;
char store[DRAW_LLVM_MAX_VARIANT_KEY_SIZE];
struct draw_llvm_variant_key *key;
struct draw_llvm_variant *variant = NULL;
struct draw_llvm_variant_list_item *li;
unsigned i;
@@ -125,11 +126,14 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
*max_vertices = 4096;
}
draw_llvm_make_variant_key(fpme->llvm, &key);
/* return even number */
*max_vertices = *max_vertices & ~1;
key = draw_llvm_make_variant_key(fpme->llvm, store);
li = first_elem(&shader->variants);
while(!at_end(&shader->variants, li)) {
if(memcmp(&li->base->key, &key, sizeof key) == 0) {
if(memcmp(&li->base->key, key, shader->variant_key_size) == 0) {
variant = li->base;
break;
}
@@ -152,7 +156,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
}
}
variant = draw_llvm_create_variant(fpme->llvm, nr);
variant = draw_llvm_create_variant(fpme->llvm, nr, key);
if (variant) {
insert_at_head(&shader->variants, &variant->list_item_local);
@@ -109,6 +109,11 @@ draw_create_vs_llvm(struct draw_context *draw,
tgsi_scan_shader(state->tokens, &vs->base.info);
vs->variant_key_size =
draw_llvm_variant_key_size(
vs->base.info.file_max[TGSI_FILE_INPUT]+1,
vs->base.info.file_max[TGSI_FILE_SAMPLER]+1);
vs->base.draw = draw;
vs->base.prepare = vs_llvm_prepare;
vs->base.run_linear = vs_llvm_run_linear;