2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
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 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.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "tgsi/tgsi_parse.h"
29 #include "intel_winsys.h"
31 #include "ilo_shader.h"
34 * Initialize a shader variant.
37 ilo_shader_variant_init(struct ilo_shader_variant
*variant
,
38 const struct ilo_shader_info
*info
,
39 const struct ilo_context
*ilo
)
43 memset(variant
, 0, sizeof(*variant
));
46 case PIPE_SHADER_VERTEX
:
47 variant
->u
.vs
.rasterizer_discard
=
48 ilo
->rasterizer
->state
.rasterizer_discard
;
49 variant
->u
.vs
.num_ucps
=
50 util_last_bit(ilo
->rasterizer
->state
.clip_plane_enable
);
52 case PIPE_SHADER_GEOMETRY
:
53 variant
->u
.gs
.rasterizer_discard
=
54 ilo
->rasterizer
->state
.rasterizer_discard
;
55 variant
->u
.gs
.num_inputs
= ilo
->vs
->shader
->out
.count
;
56 for (i
= 0; i
< ilo
->vs
->shader
->out
.count
; i
++) {
57 variant
->u
.gs
.semantic_names
[i
] =
58 ilo
->vs
->shader
->out
.semantic_names
[i
];
59 variant
->u
.gs
.semantic_indices
[i
] =
60 ilo
->vs
->shader
->out
.semantic_indices
[i
];
63 case PIPE_SHADER_FRAGMENT
:
64 variant
->u
.fs
.flatshade
=
65 (info
->has_color_interp
&& ilo
->rasterizer
->state
.flatshade
);
66 variant
->u
.fs
.fb_height
= (info
->has_pos
) ?
67 ilo
->fb
.state
.height
: 1;
68 variant
->u
.fs
.num_cbufs
= ilo
->fb
.state
.nr_cbufs
;
71 assert(!"unknown shader type");
75 num_views
= ilo
->view
[info
->type
].count
;
76 assert(info
->num_samplers
<= num_views
);
78 variant
->num_sampler_views
= info
->num_samplers
;
79 for (i
= 0; i
< info
->num_samplers
; i
++) {
80 const struct pipe_sampler_view
*view
=
81 ilo
->view
[info
->type
].states
[i
];
82 const struct ilo_sampler_cso
*sampler
=
83 ilo
->sampler
[info
->type
].cso
[i
];
86 variant
->sampler_view_swizzles
[i
].r
= view
->swizzle_r
;
87 variant
->sampler_view_swizzles
[i
].g
= view
->swizzle_g
;
88 variant
->sampler_view_swizzles
[i
].b
= view
->swizzle_b
;
89 variant
->sampler_view_swizzles
[i
].a
= view
->swizzle_a
;
91 else if (info
->shadow_samplers
& (1 << i
)) {
92 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
93 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_RED
;
94 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_RED
;
95 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ONE
;
98 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
99 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_GREEN
;
100 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_BLUE
;
101 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ALPHA
;
105 * When non-nearest filter and PIPE_TEX_WRAP_CLAMP wrap mode is used,
106 * the HW wrap mode is set to BRW_TEXCOORDMODE_CLAMP_BORDER, and we need
107 * to manually saturate the texture coordinates.
110 variant
->saturate_tex_coords
[0] |= sampler
->saturate_s
<< i
;
111 variant
->saturate_tex_coords
[1] |= sampler
->saturate_t
<< i
;
112 variant
->saturate_tex_coords
[2] |= sampler
->saturate_r
<< i
;
118 * Guess the shader variant, knowing that the context may still change.
121 ilo_shader_variant_guess(struct ilo_shader_variant
*variant
,
122 const struct ilo_shader_info
*info
,
123 const struct ilo_context
*ilo
)
127 memset(variant
, 0, sizeof(*variant
));
129 switch (info
->type
) {
130 case PIPE_SHADER_VERTEX
:
132 case PIPE_SHADER_GEOMETRY
:
134 case PIPE_SHADER_FRAGMENT
:
135 variant
->u
.fs
.flatshade
= false;
136 variant
->u
.fs
.fb_height
= (info
->has_pos
) ?
137 ilo
->fb
.state
.height
: 1;
138 variant
->u
.fs
.num_cbufs
= 1;
141 assert(!"unknown shader type");
145 variant
->num_sampler_views
= info
->num_samplers
;
146 for (i
= 0; i
< info
->num_samplers
; i
++) {
147 if (info
->shadow_samplers
& (1 << i
)) {
148 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
149 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_RED
;
150 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_RED
;
151 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ONE
;
154 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
155 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_GREEN
;
156 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_BLUE
;
157 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ALPHA
;
164 * Parse a TGSI instruction for the shader info.
167 ilo_shader_info_parse_inst(struct ilo_shader_info
*info
,
168 const struct tgsi_full_instruction
*inst
)
172 /* look for edgeflag passthrough */
173 if (info
->edgeflag_out
>= 0 &&
174 inst
->Instruction
.Opcode
== TGSI_OPCODE_MOV
&&
175 inst
->Dst
[0].Register
.File
== TGSI_FILE_OUTPUT
&&
176 inst
->Dst
[0].Register
.Index
== info
->edgeflag_out
) {
178 assert(inst
->Src
[0].Register
.File
== TGSI_FILE_INPUT
);
179 info
->edgeflag_in
= inst
->Src
[0].Register
.Index
;
182 if (inst
->Instruction
.Texture
) {
185 switch (inst
->Texture
.Texture
) {
186 case TGSI_TEXTURE_SHADOW1D
:
187 case TGSI_TEXTURE_SHADOW2D
:
188 case TGSI_TEXTURE_SHADOWRECT
:
189 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
190 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
191 case TGSI_TEXTURE_SHADOWCUBE
:
192 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
200 for (i
= 0; i
< inst
->Instruction
.NumSrcRegs
; i
++) {
201 const struct tgsi_full_src_register
*src
= &inst
->Src
[i
];
203 if (src
->Register
.File
== TGSI_FILE_SAMPLER
) {
204 const int idx
= src
->Register
.Index
;
206 if (idx
>= info
->num_samplers
)
207 info
->num_samplers
= idx
+ 1;
210 info
->shadow_samplers
|= 1 << idx
;
217 * Parse a TGSI property for the shader info.
220 ilo_shader_info_parse_prop(struct ilo_shader_info
*info
,
221 const struct tgsi_full_property
*prop
)
223 switch (prop
->Property
.PropertyName
) {
224 case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS
:
225 info
->fs_color0_writes_all_cbufs
= prop
->u
[0].Data
;
233 * Parse a TGSI declaration for the shader info.
236 ilo_shader_info_parse_decl(struct ilo_shader_info
*info
,
237 const struct tgsi_full_declaration
*decl
)
239 switch (decl
->Declaration
.File
) {
240 case TGSI_FILE_INPUT
:
241 if (decl
->Declaration
.Interpolate
&&
242 decl
->Interp
.Interpolate
== TGSI_INTERPOLATE_COLOR
)
243 info
->has_color_interp
= true;
244 if (decl
->Declaration
.Semantic
&&
245 decl
->Semantic
.Name
== TGSI_SEMANTIC_POSITION
)
246 info
->has_pos
= true;
248 case TGSI_FILE_OUTPUT
:
249 if (decl
->Declaration
.Semantic
&&
250 decl
->Semantic
.Name
== TGSI_SEMANTIC_EDGEFLAG
)
251 info
->edgeflag_out
= decl
->Range
.First
;
253 case TGSI_FILE_SYSTEM_VALUE
:
254 if (decl
->Declaration
.Semantic
&&
255 decl
->Semantic
.Name
== TGSI_SEMANTIC_INSTANCEID
)
256 info
->has_instanceid
= true;
257 if (decl
->Declaration
.Semantic
&&
258 decl
->Semantic
.Name
== TGSI_SEMANTIC_VERTEXID
)
259 info
->has_vertexid
= true;
267 ilo_shader_info_parse_tokens(struct ilo_shader_info
*info
)
269 struct tgsi_parse_context parse
;
271 info
->edgeflag_in
= -1;
272 info
->edgeflag_out
= -1;
274 tgsi_parse_init(&parse
, info
->tokens
);
275 while (!tgsi_parse_end_of_tokens(&parse
)) {
276 const union tgsi_full_token
*token
;
278 tgsi_parse_token(&parse
);
279 token
= &parse
.FullToken
;
281 switch (token
->Token
.Type
) {
282 case TGSI_TOKEN_TYPE_DECLARATION
:
283 ilo_shader_info_parse_decl(info
, &token
->FullDeclaration
);
285 case TGSI_TOKEN_TYPE_INSTRUCTION
:
286 ilo_shader_info_parse_inst(info
, &token
->FullInstruction
);
288 case TGSI_TOKEN_TYPE_PROPERTY
:
289 ilo_shader_info_parse_prop(info
, &token
->FullProperty
);
295 tgsi_parse_free(&parse
);
299 * Create a shader state.
301 struct ilo_shader_state
*
302 ilo_shader_state_create(const struct ilo_context
*ilo
,
303 int type
, const void *templ
)
305 struct ilo_shader_state
*state
;
306 struct ilo_shader_variant variant
;
308 state
= CALLOC_STRUCT(ilo_shader_state
);
312 state
->info
.dev
= ilo
->dev
;
313 state
->info
.type
= type
;
315 if (type
== PIPE_SHADER_COMPUTE
) {
316 const struct pipe_compute_state
*c
=
317 (const struct pipe_compute_state
*) templ
;
319 state
->info
.tokens
= tgsi_dup_tokens(c
->prog
);
320 state
->info
.compute
.req_local_mem
= c
->req_local_mem
;
321 state
->info
.compute
.req_private_mem
= c
->req_private_mem
;
322 state
->info
.compute
.req_input_mem
= c
->req_input_mem
;
325 const struct pipe_shader_state
*s
=
326 (const struct pipe_shader_state
*) templ
;
328 state
->info
.tokens
= tgsi_dup_tokens(s
->tokens
);
329 state
->info
.stream_output
= s
->stream_output
;
332 list_inithead(&state
->variants
);
334 ilo_shader_info_parse_tokens(&state
->info
);
336 /* guess and compile now */
337 ilo_shader_variant_guess(&variant
, &state
->info
, ilo
);
338 if (!ilo_shader_state_use_variant(state
, &variant
)) {
339 ilo_shader_state_destroy(state
);
347 * Destroy a shader state.
350 ilo_shader_state_destroy(struct ilo_shader_state
*state
)
352 struct ilo_shader
*sh
, *next
;
354 LIST_FOR_EACH_ENTRY_SAFE(sh
, next
, &state
->variants
, list
)
355 ilo_shader_destroy(sh
);
357 FREE((struct tgsi_token
*) state
->info
.tokens
);
362 * Add a compiled shader to the shader state.
365 ilo_shader_state_add_shader(struct ilo_shader_state
*state
,
366 struct ilo_shader
*sh
)
368 list_add(&sh
->list
, &state
->variants
);
369 state
->num_variants
++;
370 state
->total_size
+= sh
->kernel_size
;
374 * Remove a compiled shader from the shader state.
377 ilo_shader_state_remove_shader(struct ilo_shader_state
*state
,
378 struct ilo_shader
*sh
)
381 state
->num_variants
--;
382 state
->total_size
-= sh
->kernel_size
;
386 * Garbage collect shader variants in the shader state.
389 ilo_shader_state_gc(struct ilo_shader_state
*state
)
391 /* activate when the variants take up more than 4KiB of space */
392 const int limit
= 4 * 1024;
393 struct ilo_shader
*sh
, *next
;
395 if (state
->total_size
< limit
)
398 /* remove from the tail as the most recently ones are at the head */
399 LIST_FOR_EACH_ENTRY_SAFE_REV(sh
, next
, &state
->variants
, list
) {
400 ilo_shader_state_remove_shader(state
, sh
);
401 ilo_shader_destroy(sh
);
403 if (state
->total_size
<= limit
/ 2)
409 * Search for a shader variant.
411 static struct ilo_shader
*
412 ilo_shader_state_search_variant(struct ilo_shader_state
*state
,
413 const struct ilo_shader_variant
*variant
)
415 struct ilo_shader
*sh
= NULL
, *tmp
;
417 LIST_FOR_EACH_ENTRY(tmp
, &state
->variants
, list
) {
418 if (memcmp(&tmp
->variant
, variant
, sizeof(*variant
)) == 0) {
428 * Add a shader variant to the shader state.
431 ilo_shader_state_add_variant(struct ilo_shader_state
*state
,
432 const struct ilo_shader_variant
*variant
)
434 struct ilo_shader
*sh
;
436 sh
= ilo_shader_state_search_variant(state
, variant
);
440 ilo_shader_state_gc(state
);
442 switch (state
->info
.type
) {
443 case PIPE_SHADER_VERTEX
:
444 sh
= ilo_shader_compile_vs(state
, variant
);
446 case PIPE_SHADER_FRAGMENT
:
447 sh
= ilo_shader_compile_fs(state
, variant
);
449 case PIPE_SHADER_GEOMETRY
:
450 sh
= ilo_shader_compile_gs(state
, variant
);
452 case PIPE_SHADER_COMPUTE
:
453 sh
= ilo_shader_compile_cs(state
, variant
);
460 assert(!"failed to compile shader");
464 sh
->variant
= *variant
;
466 ilo_shader_state_add_shader(state
, sh
);
472 * Update state->shader to point to a variant. If the variant does not exist,
473 * it will be added first.
476 ilo_shader_state_use_variant(struct ilo_shader_state
*state
,
477 const struct ilo_shader_variant
*variant
)
479 struct ilo_shader
*sh
;
481 sh
= ilo_shader_state_add_variant(state
, variant
);
486 if (state
->variants
.next
!= &sh
->list
) {
488 list_add(&sh
->list
, &state
->variants
);
497 * Reset the shader cache.
500 ilo_shader_cache_reset(struct ilo_shader_cache
*shc
)
503 shc
->bo
->unreference(shc
->bo
);
505 shc
->bo
= shc
->winsys
->alloc_buffer(shc
->winsys
,
506 "shader cache", shc
->size
, 0);
515 * Create a shader cache. A shader cache is a bo holding all compiled shaders.
516 * When the bo is full, a larger bo is allocated and all cached shaders are
517 * invalidated. This is how outdated shaders get dropped. Active shaders
518 * will be added to the new bo when used.
520 struct ilo_shader_cache
*
521 ilo_shader_cache_create(struct intel_winsys
*winsys
)
523 struct ilo_shader_cache
*shc
;
525 shc
= CALLOC_STRUCT(ilo_shader_cache
);
529 shc
->winsys
= winsys
;
530 /* initial cache size */
533 ilo_shader_cache_reset(shc
);
539 * Destroy a shader cache.
542 ilo_shader_cache_destroy(struct ilo_shader_cache
*shc
)
545 shc
->bo
->unreference(shc
->bo
);
551 * Add shaders to the cache. This may invalidate all other shaders in the
555 ilo_shader_cache_set(struct ilo_shader_cache
*shc
,
556 struct ilo_shader
**shaders
,
561 /* calculate the space needed */
563 for (i
= 0; i
< num_shaders
; i
++) {
564 if (shaders
[i
]->cache_seqno
!= shc
->seqno
)
565 new_cur
= align(new_cur
, 64) + shaders
[i
]->kernel_size
;
568 /* all shaders are already in the cache */
569 if (new_cur
== shc
->cur
)
573 * From the Sandy Bridge PRM, volume 4 part 2, page 112:
575 * "Due to prefetch of the instruction stream, the EUs may attempt to
576 * access up to 8 instructions (128 bytes) beyond the end of the kernel
577 * program - possibly into the next memory page. Although these
578 * instructions will not be executed, software must account for the
579 * prefetch in order to avoid invalid page access faults."
584 * we should be able to append data without being blocked even the bo
588 /* reallocate when the cache is full or busy */
589 if (new_cur
> shc
->size
|| shc
->busy
) {
590 while (new_cur
> shc
->size
)
593 ilo_shader_cache_reset(shc
);
597 for (i
= 0; i
< num_shaders
; i
++) {
598 if (shaders
[i
]->cache_seqno
!= shc
->seqno
) {
599 /* kernels must be aligned to 64-byte */
600 shc
->cur
= align(shc
->cur
, 64);
601 shc
->bo
->pwrite(shc
->bo
, shc
->cur
,
602 shaders
[i
]->kernel_size
, shaders
[i
]->kernel
);
604 shaders
[i
]->cache_seqno
= shc
->seqno
;
605 shaders
[i
]->cache_offset
= shc
->cur
;
607 shc
->cur
+= shaders
[i
]->kernel_size
;