ilo: add ilo_dev_info shared by the screen and contexts
[mesa.git] / src / gallium / drivers / ilo / ilo_shader.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2013 LunarG, Inc.
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * 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
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "tgsi/tgsi_parse.h"
29 #include "intel_winsys.h"
30
31 #include "ilo_shader.h"
32
33 /**
34 * Initialize a shader variant.
35 */
36 void
37 ilo_shader_variant_init(struct ilo_shader_variant *variant,
38 const struct ilo_shader_info *info,
39 const struct ilo_context *ilo)
40 {
41 int num_views, i;
42
43 memset(variant, 0, sizeof(*variant));
44
45 switch (info->type) {
46 case PIPE_SHADER_VERTEX:
47 variant->u.vs.rasterizer_discard = ilo->rasterizer->rasterizer_discard;
48 variant->u.vs.num_ucps =
49 util_last_bit(ilo->rasterizer->clip_plane_enable);
50 break;
51 case PIPE_SHADER_GEOMETRY:
52 variant->u.gs.rasterizer_discard = ilo->rasterizer->rasterizer_discard;
53 variant->u.gs.num_inputs = ilo->vs->shader->out.count;
54 for (i = 0; i < ilo->vs->shader->out.count; i++) {
55 variant->u.gs.semantic_names[i] =
56 ilo->vs->shader->out.semantic_names[i];
57 variant->u.gs.semantic_indices[i] =
58 ilo->vs->shader->out.semantic_indices[i];
59 }
60 break;
61 case PIPE_SHADER_FRAGMENT:
62 variant->u.fs.flatshade =
63 (info->has_color_interp && ilo->rasterizer->flatshade);
64 variant->u.fs.fb_height = (info->has_pos) ?
65 ilo->framebuffer.height : 1;
66 variant->u.fs.num_cbufs = ilo->framebuffer.nr_cbufs;
67 break;
68 default:
69 assert(!"unknown shader type");
70 break;
71 }
72
73 num_views = ilo->sampler_views[info->type].num_views;
74 assert(info->num_samplers <= num_views);
75
76 variant->num_sampler_views = info->num_samplers;
77 for (i = 0; i < info->num_samplers; i++) {
78 const struct pipe_sampler_view *view =
79 ilo->sampler_views[info->type].views[i];
80 const struct pipe_sampler_state *sampler =
81 ilo->samplers[info->type].samplers[i];
82
83 if (view) {
84 variant->sampler_view_swizzles[i].r = view->swizzle_r;
85 variant->sampler_view_swizzles[i].g = view->swizzle_g;
86 variant->sampler_view_swizzles[i].b = view->swizzle_b;
87 variant->sampler_view_swizzles[i].a = view->swizzle_a;
88 }
89 else if (info->shadow_samplers & (1 << i)) {
90 variant->sampler_view_swizzles[i].r = PIPE_SWIZZLE_RED;
91 variant->sampler_view_swizzles[i].g = PIPE_SWIZZLE_RED;
92 variant->sampler_view_swizzles[i].b = PIPE_SWIZZLE_RED;
93 variant->sampler_view_swizzles[i].a = PIPE_SWIZZLE_ONE;
94 }
95 else {
96 variant->sampler_view_swizzles[i].r = PIPE_SWIZZLE_RED;
97 variant->sampler_view_swizzles[i].g = PIPE_SWIZZLE_GREEN;
98 variant->sampler_view_swizzles[i].b = PIPE_SWIZZLE_BLUE;
99 variant->sampler_view_swizzles[i].a = PIPE_SWIZZLE_ALPHA;
100 }
101
102 /*
103 * When non-nearest filter and PIPE_TEX_WRAP_CLAMP wrap mode is used,
104 * the HW wrap mode is set to BRW_TEXCOORDMODE_CLAMP_BORDER, and we need
105 * to manually saturate the texture coordinates.
106 */
107 if (sampler && sampler->min_img_filter != PIPE_TEX_FILTER_NEAREST) {
108 if (sampler->wrap_s == PIPE_TEX_WRAP_CLAMP)
109 variant->saturate_tex_coords[0] |= 1 << i;
110 if (sampler->wrap_t == PIPE_TEX_WRAP_CLAMP)
111 variant->saturate_tex_coords[1] |= 1 << i;
112 if (sampler->wrap_r == PIPE_TEX_WRAP_CLAMP)
113 variant->saturate_tex_coords[2] |= 1 << i;
114 }
115 }
116 }
117
118 /**
119 * Guess the shader variant, knowing that the context may still change.
120 */
121 static void
122 ilo_shader_variant_guess(struct ilo_shader_variant *variant,
123 const struct ilo_shader_info *info,
124 const struct ilo_context *ilo)
125 {
126 int i;
127
128 memset(variant, 0, sizeof(*variant));
129
130 switch (info->type) {
131 case PIPE_SHADER_VERTEX:
132 break;
133 case PIPE_SHADER_GEOMETRY:
134 break;
135 case PIPE_SHADER_FRAGMENT:
136 variant->u.fs.flatshade = false;
137 variant->u.fs.fb_height = (info->has_pos) ?
138 ilo->framebuffer.height : 1;
139 variant->u.fs.num_cbufs = 1;
140 break;
141 default:
142 assert(!"unknown shader type");
143 break;
144 }
145
146 variant->num_sampler_views = info->num_samplers;
147 for (i = 0; i < info->num_samplers; i++) {
148 if (info->shadow_samplers & (1 << i)) {
149 variant->sampler_view_swizzles[i].r = PIPE_SWIZZLE_RED;
150 variant->sampler_view_swizzles[i].g = PIPE_SWIZZLE_RED;
151 variant->sampler_view_swizzles[i].b = PIPE_SWIZZLE_RED;
152 variant->sampler_view_swizzles[i].a = PIPE_SWIZZLE_ONE;
153 }
154 else {
155 variant->sampler_view_swizzles[i].r = PIPE_SWIZZLE_RED;
156 variant->sampler_view_swizzles[i].g = PIPE_SWIZZLE_GREEN;
157 variant->sampler_view_swizzles[i].b = PIPE_SWIZZLE_BLUE;
158 variant->sampler_view_swizzles[i].a = PIPE_SWIZZLE_ALPHA;
159 }
160 }
161 }
162
163 /**
164 * Hash a shader variant.
165 */
166 static unsigned int
167 ilo_shader_variant_hash(const struct ilo_shader_variant *variant)
168 {
169 const int num_bytes = sizeof(*variant);
170 const unsigned char *bytes = (const unsigned char *) variant;
171 const unsigned int seed = 131;
172 unsigned int hash = 0;
173 int i;
174
175 for (i = 0; i < num_bytes; i++)
176 hash = hash * seed + bytes[i];
177
178 return hash;
179 }
180
181 /**
182 * Parse a TGSI instruction for the shader info.
183 */
184 static void
185 ilo_shader_info_parse_inst(struct ilo_shader_info *info,
186 const struct tgsi_full_instruction *inst)
187 {
188 int i;
189
190 /* look for edgeflag passthrough */
191 if (info->edgeflag_out >= 0 &&
192 inst->Instruction.Opcode == TGSI_OPCODE_MOV &&
193 inst->Dst[0].Register.File == TGSI_FILE_OUTPUT &&
194 inst->Dst[0].Register.Index == info->edgeflag_out) {
195
196 assert(inst->Src[0].Register.File == TGSI_FILE_INPUT);
197 info->edgeflag_in = inst->Src[0].Register.Index;
198 }
199
200 if (inst->Instruction.Texture) {
201 bool shadow;
202
203 switch (inst->Texture.Texture) {
204 case TGSI_TEXTURE_SHADOW1D:
205 case TGSI_TEXTURE_SHADOW2D:
206 case TGSI_TEXTURE_SHADOWRECT:
207 case TGSI_TEXTURE_SHADOW1D_ARRAY:
208 case TGSI_TEXTURE_SHADOW2D_ARRAY:
209 case TGSI_TEXTURE_SHADOWCUBE:
210 case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
211 shadow = true;
212 break;
213 default:
214 shadow = false;
215 break;
216 }
217
218 for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
219 const struct tgsi_full_src_register *src = &inst->Src[i];
220
221 if (src->Register.File == TGSI_FILE_SAMPLER) {
222 const int idx = src->Register.Index;
223
224 if (idx >= info->num_samplers)
225 info->num_samplers = idx + 1;
226
227 if (shadow)
228 info->shadow_samplers |= 1 << idx;
229 }
230 }
231 }
232 }
233
234 /**
235 * Parse a TGSI property for the shader info.
236 */
237 static void
238 ilo_shader_info_parse_prop(struct ilo_shader_info *info,
239 const struct tgsi_full_property *prop)
240 {
241 switch (prop->Property.PropertyName) {
242 case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
243 info->fs_color0_writes_all_cbufs = prop->u[0].Data;
244 break;
245 default:
246 break;
247 }
248 }
249
250 /**
251 * Parse a TGSI declaration for the shader info.
252 */
253 static void
254 ilo_shader_info_parse_decl(struct ilo_shader_info *info,
255 const struct tgsi_full_declaration *decl)
256 {
257 switch (decl->Declaration.File) {
258 case TGSI_FILE_INPUT:
259 if (decl->Declaration.Interpolate &&
260 decl->Interp.Interpolate == TGSI_INTERPOLATE_COLOR)
261 info->has_color_interp = true;
262 if (decl->Declaration.Semantic &&
263 decl->Semantic.Name == TGSI_SEMANTIC_POSITION)
264 info->has_pos = true;
265 break;
266 case TGSI_FILE_OUTPUT:
267 if (decl->Declaration.Semantic &&
268 decl->Semantic.Name == TGSI_SEMANTIC_EDGEFLAG)
269 info->edgeflag_out = decl->Range.First;
270 break;
271 case TGSI_FILE_SYSTEM_VALUE:
272 if (decl->Declaration.Semantic &&
273 decl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID)
274 info->has_instanceid = true;
275 if (decl->Declaration.Semantic &&
276 decl->Semantic.Name == TGSI_SEMANTIC_VERTEXID)
277 info->has_vertexid = true;
278 break;
279 default:
280 break;
281 }
282 }
283
284 static void
285 ilo_shader_info_parse_tokens(struct ilo_shader_info *info)
286 {
287 struct tgsi_parse_context parse;
288
289 info->edgeflag_in = -1;
290 info->edgeflag_out = -1;
291
292 tgsi_parse_init(&parse, info->tokens);
293 while (!tgsi_parse_end_of_tokens(&parse)) {
294 const union tgsi_full_token *token;
295
296 tgsi_parse_token(&parse);
297 token = &parse.FullToken;
298
299 switch (token->Token.Type) {
300 case TGSI_TOKEN_TYPE_DECLARATION:
301 ilo_shader_info_parse_decl(info, &token->FullDeclaration);
302 break;
303 case TGSI_TOKEN_TYPE_INSTRUCTION:
304 ilo_shader_info_parse_inst(info, &token->FullInstruction);
305 break;
306 case TGSI_TOKEN_TYPE_PROPERTY:
307 ilo_shader_info_parse_prop(info, &token->FullProperty);
308 break;
309 default:
310 break;
311 }
312 }
313 tgsi_parse_free(&parse);
314 }
315
316 /**
317 * Create a shader state.
318 */
319 struct ilo_shader_state *
320 ilo_shader_state_create(const struct ilo_context *ilo,
321 int type, const void *templ)
322 {
323 struct ilo_shader_state *state;
324 struct ilo_shader_variant variant;
325
326 state = CALLOC_STRUCT(ilo_shader_state);
327 if (!state)
328 return NULL;
329
330 state->info.type = type;
331 state->info.gen = ilo->dev->gen;
332
333 if (type == PIPE_SHADER_COMPUTE) {
334 const struct pipe_compute_state *c =
335 (const struct pipe_compute_state *) templ;
336
337 state->info.tokens = tgsi_dup_tokens(c->prog);
338 state->info.compute.req_local_mem = c->req_local_mem;
339 state->info.compute.req_private_mem = c->req_private_mem;
340 state->info.compute.req_input_mem = c->req_input_mem;
341 }
342 else {
343 const struct pipe_shader_state *s =
344 (const struct pipe_shader_state *) templ;
345
346 state->info.tokens = tgsi_dup_tokens(s->tokens);
347 state->info.stream_output = s->stream_output;
348 }
349
350 list_inithead(&state->variants);
351
352 ilo_shader_info_parse_tokens(&state->info);
353
354 /* guess and compile now */
355 ilo_shader_variant_guess(&variant, &state->info, ilo);
356 if (!ilo_shader_state_use_variant(state, &variant)) {
357 ilo_shader_state_destroy(state);
358 return NULL;
359 }
360
361 return state;
362 }
363
364 /**
365 * Destroy a shader state.
366 */
367 void
368 ilo_shader_state_destroy(struct ilo_shader_state *state)
369 {
370 struct ilo_shader *sh, *next;
371
372 LIST_FOR_EACH_ENTRY_SAFE(sh, next, &state->variants, list)
373 ilo_shader_destroy(sh);
374
375 FREE((struct tgsi_token *) state->info.tokens);
376 FREE(state);
377 }
378
379 /**
380 * Add a compiled shader to the shader state.
381 */
382 static void
383 ilo_shader_state_add_shader(struct ilo_shader_state *state,
384 struct ilo_shader *sh)
385 {
386 list_add(&sh->list, &state->variants);
387 state->num_variants++;
388 state->total_size += sh->kernel_size;
389 }
390
391 /**
392 * Remove a compiled shader from the shader state.
393 */
394 static void
395 ilo_shader_state_remove_shader(struct ilo_shader_state *state,
396 struct ilo_shader *sh)
397 {
398 list_del(&sh->list);
399 state->num_variants--;
400 state->total_size -= sh->kernel_size;
401 }
402
403 /**
404 * Garbage collect shader variants in the shader state.
405 */
406 static void
407 ilo_shader_state_gc(struct ilo_shader_state *state)
408 {
409 /* activate when the variants take up more than 4KiB of space */
410 const int limit = 4 * 1024;
411 struct ilo_shader *sh, *next;
412
413 if (state->total_size < limit)
414 return;
415
416 /* remove from the tail as the most recently ones are at the head */
417 LIST_FOR_EACH_ENTRY_SAFE_REV(sh, next, &state->variants, list) {
418 ilo_shader_state_remove_shader(state, sh);
419 ilo_shader_destroy(sh);
420
421 if (state->total_size <= limit / 2)
422 break;
423 }
424 }
425
426 /**
427 * Search for a shader variant.
428 */
429 static struct ilo_shader *
430 ilo_shader_state_search_variant(struct ilo_shader_state *state,
431 unsigned int hash,
432 const struct ilo_shader_variant *variant)
433 {
434 struct ilo_shader *sh = NULL, *tmp;
435
436 LIST_FOR_EACH_ENTRY(tmp, &state->variants, list) {
437 if (tmp->hash == hash &&
438 memcmp(&tmp->variant, variant, sizeof(*variant)) == 0) {
439 sh = tmp;
440 break;
441 }
442 }
443
444 return sh;
445 }
446
447 /**
448 * Add a shader variant to the shader state.
449 */
450 struct ilo_shader *
451 ilo_shader_state_add_variant(struct ilo_shader_state *state,
452 const struct ilo_shader_variant *variant)
453 {
454 const unsigned int hash = ilo_shader_variant_hash(variant);
455 struct ilo_shader *sh;
456
457 sh = ilo_shader_state_search_variant(state, hash, variant);
458 if (sh)
459 return sh;
460
461 ilo_shader_state_gc(state);
462
463 switch (state->info.type) {
464 case PIPE_SHADER_VERTEX:
465 sh = ilo_shader_compile_vs(state, variant);
466 break;
467 case PIPE_SHADER_FRAGMENT:
468 sh = ilo_shader_compile_fs(state, variant);
469 break;
470 case PIPE_SHADER_GEOMETRY:
471 sh = ilo_shader_compile_gs(state, variant);
472 break;
473 case PIPE_SHADER_COMPUTE:
474 sh = ilo_shader_compile_cs(state, variant);
475 break;
476 default:
477 sh = NULL;
478 break;
479 }
480 if (!sh) {
481 assert(!"failed to compile shader");
482 return NULL;
483 }
484
485 sh->variant = *variant;
486 sh->hash = hash;
487
488 ilo_shader_state_add_shader(state, sh);
489
490 return sh;
491 }
492
493 /**
494 * Update state->shader to point to a variant. If the variant does not exist,
495 * it will be added first.
496 */
497 bool
498 ilo_shader_state_use_variant(struct ilo_shader_state *state,
499 const struct ilo_shader_variant *variant)
500 {
501 struct ilo_shader *sh;
502
503 sh = ilo_shader_state_add_variant(state, variant);
504 if (!sh)
505 return false;
506
507 /* move to head */
508 if (state->variants.next != &sh->list) {
509 list_del(&sh->list);
510 list_add(&sh->list, &state->variants);
511 }
512
513 state->shader = sh;
514
515 return true;
516 }
517
518 /**
519 * Reset the shader cache.
520 */
521 static void
522 ilo_shader_cache_reset(struct ilo_shader_cache *shc)
523 {
524 if (shc->bo)
525 shc->bo->unreference(shc->bo);
526
527 shc->bo = shc->winsys->alloc_buffer(shc->winsys,
528 "shader cache", shc->size, 0);
529 shc->busy = false;
530 shc->cur = 0;
531 shc->seqno++;
532 if (!shc->seqno)
533 shc->seqno = 1;
534 }
535
536 /**
537 * Create a shader cache. A shader cache is a bo holding all compiled shaders.
538 * When the bo is full, a larger bo is allocated and all cached shaders are
539 * invalidated. This is how outdated shaders get dropped. Active shaders
540 * will be added to the new bo when used.
541 */
542 struct ilo_shader_cache *
543 ilo_shader_cache_create(struct intel_winsys *winsys)
544 {
545 struct ilo_shader_cache *shc;
546
547 shc = CALLOC_STRUCT(ilo_shader_cache);
548 if (!shc)
549 return NULL;
550
551 shc->winsys = winsys;
552 /* initial cache size */
553 shc->size = 4096;
554
555 ilo_shader_cache_reset(shc);
556
557 return shc;
558 }
559
560 /**
561 * Destroy a shader cache.
562 */
563 void
564 ilo_shader_cache_destroy(struct ilo_shader_cache *shc)
565 {
566 if (shc->bo)
567 shc->bo->unreference(shc->bo);
568
569 FREE(shc);
570 }
571
572 /**
573 * Add shaders to the cache. This may invalidate all other shaders in the
574 * cache.
575 */
576 void
577 ilo_shader_cache_set(struct ilo_shader_cache *shc,
578 struct ilo_shader **shaders,
579 int num_shaders)
580 {
581 int new_cur, i;
582
583 /* calculate the space needed */
584 new_cur = shc->cur;
585 for (i = 0; i < num_shaders; i++) {
586 if (shaders[i]->cache_seqno != shc->seqno)
587 new_cur = align(new_cur, 64) + shaders[i]->kernel_size;
588 }
589
590 /* all shaders are already in the cache */
591 if (new_cur == shc->cur)
592 return;
593
594 /*
595 * From the Sandy Bridge PRM, volume 4 part 2, page 112:
596 *
597 * "Due to prefetch of the instruction stream, the EUs may attempt to
598 * access up to 8 instructions (128 bytes) beyond the end of the kernel
599 * program - possibly into the next memory page. Although these
600 * instructions will not be executed, software must account for the
601 * prefetch in order to avoid invalid page access faults."
602 */
603 new_cur += 128;
604
605 /*
606 * we should be able to append data without being blocked even the bo
607 * is busy...
608 */
609
610 /* reallocate when the cache is full or busy */
611 if (new_cur > shc->size || shc->busy) {
612 while (new_cur > shc->size)
613 shc->size <<= 1;
614
615 ilo_shader_cache_reset(shc);
616 }
617
618 /* upload now */
619 for (i = 0; i < num_shaders; i++) {
620 if (shaders[i]->cache_seqno != shc->seqno) {
621 /* kernels must be aligned to 64-byte */
622 shc->cur = align(shc->cur, 64);
623 shc->bo->pwrite(shc->bo, shc->cur,
624 shaders[i]->kernel_size, shaders[i]->kernel);
625
626 shaders[i]->cache_seqno = shc->seqno;
627 shaders[i]->cache_offset = shc->cur;
628
629 shc->cur += shaders[i]->kernel_size;
630 }
631 }
632 }