1 /**************************************************************************
3 * Copyright 2019 Red Hat.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 **************************************************************************/
25 #include "util/u_memory.h"
26 #include "util/simple_list.h"
27 #include "util/os_time.h"
28 #include "tgsi/tgsi_dump.h"
29 #include "tgsi/tgsi_parse.h"
30 #include "gallivm/lp_bld_debug.h"
31 #include "lp_state_cs.h"
32 #include "lp_context.h"
38 llvmpipe_create_compute_state(struct pipe_context
*pipe
,
39 const struct pipe_compute_state
*templ
)
41 struct lp_compute_shader
*shader
;
43 shader
= CALLOC_STRUCT(lp_compute_shader
);
47 assert(templ
->ir_type
== PIPE_SHADER_IR_TGSI
);
48 shader
->base
.tokens
= tgsi_dup_tokens(templ
->prog
);
50 lp_build_tgsi_info(shader
->base
.tokens
, &shader
->info
);
51 make_empty_list(&shader
->variants
);
57 llvmpipe_bind_compute_state(struct pipe_context
*pipe
,
60 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
62 if (llvmpipe
->cs
== cs
)
65 llvmpipe
->cs
= (struct lp_compute_shader
*)cs
;
66 llvmpipe
->cs_dirty
|= LP_CSNEW_CS
;
70 * Remove shader variant from two lists: the shader's variant list
71 * and the context's variant list.
74 llvmpipe_remove_cs_shader_variant(struct llvmpipe_context
*lp
,
75 struct lp_compute_shader_variant
*variant
)
77 if ((LP_DEBUG
& DEBUG_CS
) || (gallivm_debug
& GALLIVM_DEBUG_IR
)) {
78 debug_printf("llvmpipe: del cs #%u var %u v created %u v cached %u "
79 "v total cached %u inst %u total inst %u\n",
80 variant
->shader
->no
, variant
->no
,
81 variant
->shader
->variants_created
,
82 variant
->shader
->variants_cached
,
83 lp
->nr_cs_variants
, variant
->nr_instrs
, lp
->nr_cs_instrs
);
86 gallivm_destroy(variant
->gallivm
);
88 /* remove from shader's list */
89 remove_from_list(&variant
->list_item_local
);
90 variant
->shader
->variants_cached
--;
92 /* remove from context's list */
93 remove_from_list(&variant
->list_item_global
);
95 lp
->nr_fs_instrs
-= variant
->nr_instrs
;
101 llvmpipe_delete_compute_state(struct pipe_context
*pipe
,
104 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
105 struct lp_compute_shader
*shader
= cs
;
106 struct lp_cs_variant_list_item
*li
;
108 /* Delete all the variants */
109 li
= first_elem(&shader
->variants
);
110 while(!at_end(&shader
->variants
, li
)) {
111 struct lp_cs_variant_list_item
*next
= next_elem(li
);
112 llvmpipe_remove_cs_shader_variant(llvmpipe
, li
->base
);
115 tgsi_free_tokens(shader
->base
.tokens
);
120 make_variant_key(struct llvmpipe_context
*lp
,
121 struct lp_compute_shader
*shader
,
122 struct lp_compute_shader_variant_key
*key
)
124 memset(key
, 0, shader
->variant_key_size
);
128 dump_cs_variant_key(const struct lp_compute_shader_variant_key
*key
)
130 debug_printf("cs variant %p:\n", (void *) key
);
134 lp_debug_cs_variant(const struct lp_compute_shader_variant
*variant
)
136 debug_printf("llvmpipe: Compute shader #%u variant #%u:\n",
137 variant
->shader
->no
, variant
->no
);
138 tgsi_dump(variant
->shader
->base
.tokens
, 0);
139 dump_cs_variant_key(&variant
->key
);
143 static struct lp_compute_shader_variant
*
144 generate_variant(struct llvmpipe_context
*lp
,
145 struct lp_compute_shader
*shader
,
146 const struct lp_compute_shader_variant_key
*key
)
148 struct lp_compute_shader_variant
*variant
;
149 char module_name
[64];
151 variant
= CALLOC_STRUCT(lp_compute_shader_variant
);
155 snprintf(module_name
, sizeof(module_name
), "cs%u_variant%u",
156 shader
->no
, shader
->variants_created
);
158 variant
->gallivm
= gallivm_create(module_name
, lp
->context
);
159 if (!variant
->gallivm
) {
164 variant
->shader
= shader
;
165 variant
->list_item_global
.base
= variant
;
166 variant
->list_item_local
.base
= variant
;
167 variant
->no
= shader
->variants_created
++;
169 memcpy(&variant
->key
, key
, shader
->variant_key_size
);
171 if ((LP_DEBUG
& DEBUG_CS
) || (gallivm_debug
& GALLIVM_DEBUG_IR
)) {
172 lp_debug_cs_variant(variant
);
175 lp_jit_init_cs_types(variant
);
177 gallivm_free_ir(variant
->gallivm
);
182 lp_cs_ctx_set_cs_variant( struct lp_cs_context
*csctx
,
183 struct lp_compute_shader_variant
*variant
)
185 csctx
->cs
.current
.variant
= variant
;
189 llvmpipe_update_cs(struct llvmpipe_context
*lp
)
191 struct lp_compute_shader
*shader
= lp
->cs
;
193 struct lp_compute_shader_variant_key key
;
194 struct lp_compute_shader_variant
*variant
= NULL
;
195 struct lp_cs_variant_list_item
*li
;
197 make_variant_key(lp
, shader
, &key
);
199 /* Search the variants for one which matches the key */
200 li
= first_elem(&shader
->variants
);
201 while(!at_end(&shader
->variants
, li
)) {
202 if(memcmp(&li
->base
->key
, &key
, shader
->variant_key_size
) == 0) {
210 /* Move this variant to the head of the list to implement LRU
211 * deletion of shader's when we have too many.
213 move_to_head(&lp
->cs_variants_list
, &variant
->list_item_global
);
216 /* variant not found, create it now */
219 unsigned variants_to_cull
;
221 if (LP_DEBUG
& DEBUG_CS
) {
222 debug_printf("%u variants,\t%u instrs,\t%u instrs/variant\n",
225 lp
->nr_cs_variants
? lp
->nr_cs_instrs
/ lp
->nr_cs_variants
: 0);
228 /* First, check if we've exceeded the max number of shader variants.
229 * If so, free 6.25% of them (the least recently used ones).
231 variants_to_cull
= lp
->nr_cs_variants
>= LP_MAX_SHADER_VARIANTS
? LP_MAX_SHADER_VARIANTS
/ 16 : 0;
233 if (variants_to_cull
||
234 lp
->nr_cs_instrs
>= LP_MAX_SHADER_INSTRUCTIONS
) {
235 if (gallivm_debug
& GALLIVM_DEBUG_PERF
) {
236 debug_printf("Evicting CS: %u cs variants,\t%u total variants,"
237 "\t%u instrs,\t%u instrs/variant\n",
238 shader
->variants_cached
,
239 lp
->nr_cs_variants
, lp
->nr_cs_instrs
,
240 lp
->nr_cs_instrs
/ lp
->nr_cs_variants
);
244 * We need to re-check lp->nr_cs_variants because an arbitrarliy large
245 * number of shader variants (potentially all of them) could be
246 * pending for destruction on flush.
249 for (i
= 0; i
< variants_to_cull
|| lp
->nr_cs_instrs
>= LP_MAX_SHADER_INSTRUCTIONS
; i
++) {
250 struct lp_cs_variant_list_item
*item
;
251 if (is_empty_list(&lp
->cs_variants_list
)) {
254 item
= last_elem(&lp
->cs_variants_list
);
257 llvmpipe_remove_cs_shader_variant(lp
, item
->base
);
261 * Generate the new variant.
264 variant
= generate_variant(lp
, shader
, &key
);
267 LP_COUNT_ADD(llvm_compile_time
, dt
);
268 LP_COUNT_ADD(nr_llvm_compiles
, 2); /* emit vs. omit in/out test */
270 /* Put the new variant into the list */
272 insert_at_head(&shader
->variants
, &variant
->list_item_local
);
273 insert_at_head(&lp
->cs_variants_list
, &variant
->list_item_global
);
274 lp
->nr_cs_variants
++;
275 lp
->nr_cs_instrs
+= variant
->nr_instrs
;
276 shader
->variants_cached
++;
279 /* Bind this variant */
280 lp_cs_ctx_set_cs_variant(lp
->csctx
, variant
);
284 llvmpipe_cs_update_derived(struct llvmpipe_context
*llvmpipe
)
286 if (llvmpipe
->cs_dirty
& (LP_CSNEW_CS
))
287 llvmpipe_update_cs(llvmpipe
);
289 llvmpipe
->cs_dirty
= 0;
292 static void llvmpipe_launch_grid(struct pipe_context
*pipe
,
293 const struct pipe_grid_info
*info
)
295 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
297 llvmpipe_cs_update_derived(llvmpipe
);
301 llvmpipe_init_compute_funcs(struct llvmpipe_context
*llvmpipe
)
303 llvmpipe
->pipe
.create_compute_state
= llvmpipe_create_compute_state
;
304 llvmpipe
->pipe
.bind_compute_state
= llvmpipe_bind_compute_state
;
305 llvmpipe
->pipe
.delete_compute_state
= llvmpipe_delete_compute_state
;
306 llvmpipe
->pipe
.launch_grid
= llvmpipe_launch_grid
;
310 lp_csctx_destroy(struct lp_cs_context
*csctx
)
315 struct lp_cs_context
*lp_csctx_create(struct pipe_context
*pipe
)
317 struct lp_cs_context
*csctx
;
319 csctx
= CALLOC_STRUCT(lp_cs_context
);