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 "shader/ilo_shader_internal.h"
32 #include "ilo_state.h"
33 #include "ilo_shader.h"
35 struct ilo_shader_cache
{
36 struct list_head shaders
;
37 struct list_head changed
;
41 * Create a shader cache. A shader cache can manage shaders and upload them
44 struct ilo_shader_cache
*
45 ilo_shader_cache_create(void)
47 struct ilo_shader_cache
*shc
;
49 shc
= CALLOC_STRUCT(ilo_shader_cache
);
53 list_inithead(&shc
->shaders
);
54 list_inithead(&shc
->changed
);
60 * Destroy a shader cache.
63 ilo_shader_cache_destroy(struct ilo_shader_cache
*shc
)
69 * Add a shader to the cache.
72 ilo_shader_cache_add(struct ilo_shader_cache
*shc
,
73 struct ilo_shader_state
*shader
)
75 struct ilo_shader
*sh
;
78 LIST_FOR_EACH_ENTRY(sh
, &shader
->variants
, list
)
81 list_add(&shader
->list
, &shc
->changed
);
85 * Remove a shader from the cache.
88 ilo_shader_cache_remove(struct ilo_shader_cache
*shc
,
89 struct ilo_shader_state
*shader
)
91 list_del(&shader
->list
);
96 * Notify the cache that a managed shader has changed.
99 ilo_shader_cache_notify_change(struct ilo_shader_cache
*shc
,
100 struct ilo_shader_state
*shader
)
102 if (shader
->cache
== shc
) {
103 list_del(&shader
->list
);
104 list_add(&shader
->list
, &shc
->changed
);
109 * Upload a managed shader to the bo.
112 ilo_shader_cache_upload_shader(struct ilo_shader_cache
*shc
,
113 struct ilo_shader_state
*shader
,
114 struct intel_bo
*bo
, unsigned offset
,
117 const unsigned base
= offset
;
118 struct ilo_shader
*sh
;
120 LIST_FOR_EACH_ENTRY(sh
, &shader
->variants
, list
) {
123 if (incremental
&& sh
->uploaded
)
126 /* kernels must be aligned to 64-byte */
127 offset
= align(offset
, 64);
129 err
= intel_bo_pwrite(bo
, offset
, sh
->kernel_size
, sh
->kernel
);
134 sh
->cache_offset
= offset
;
136 offset
+= sh
->kernel_size
;
139 return (int) (offset
- base
);
143 * Similar to ilo_shader_cache_upload(), except no upload happens.
146 ilo_shader_cache_get_upload_size(struct ilo_shader_cache
*shc
,
150 const unsigned base
= offset
;
151 struct ilo_shader_state
*shader
;
154 LIST_FOR_EACH_ENTRY(shader
, &shc
->shaders
, list
) {
155 struct ilo_shader
*sh
;
157 /* see ilo_shader_cache_upload_shader() */
158 LIST_FOR_EACH_ENTRY(sh
, &shader
->variants
, list
) {
159 if (!incremental
|| !sh
->uploaded
)
160 offset
= align(offset
, 64) + sh
->kernel_size
;
165 LIST_FOR_EACH_ENTRY(shader
, &shc
->changed
, list
) {
166 struct ilo_shader
*sh
;
168 /* see ilo_shader_cache_upload_shader() */
169 LIST_FOR_EACH_ENTRY(sh
, &shader
->variants
, list
) {
170 if (!incremental
|| !sh
->uploaded
)
171 offset
= align(offset
, 64) + sh
->kernel_size
;
176 * From the Sandy Bridge PRM, volume 4 part 2, page 112:
178 * "Due to prefetch of the instruction stream, the EUs may attempt to
179 * access up to 8 instructions (128 bytes) beyond the end of the
180 * kernel program - possibly into the next memory page. Although
181 * these instructions will not be executed, software must account for
182 * the prefetch in order to avoid invalid page access faults."
187 return (int) (offset
- base
);
191 * Upload managed shaders to the bo. When incremental is true, only shaders
192 * that are changed or added after the last upload are uploaded.
195 ilo_shader_cache_upload(struct ilo_shader_cache
*shc
,
196 struct intel_bo
*bo
, unsigned offset
,
199 struct ilo_shader_state
*shader
, *next
;
203 return ilo_shader_cache_get_upload_size(shc
, offset
, incremental
);
206 LIST_FOR_EACH_ENTRY(shader
, &shc
->shaders
, list
) {
207 s
= ilo_shader_cache_upload_shader(shc
, shader
,
208 bo
, offset
, incremental
);
217 LIST_FOR_EACH_ENTRY_SAFE(shader
, next
, &shc
->changed
, list
) {
218 s
= ilo_shader_cache_upload_shader(shc
, shader
,
219 bo
, offset
, incremental
);
226 list_del(&shader
->list
);
227 list_add(&shader
->list
, &shc
->shaders
);
234 * Initialize a shader variant.
237 ilo_shader_variant_init(struct ilo_shader_variant
*variant
,
238 const struct ilo_shader_info
*info
,
239 const struct ilo_context
*ilo
)
243 memset(variant
, 0, sizeof(*variant
));
245 switch (info
->type
) {
246 case PIPE_SHADER_VERTEX
:
247 variant
->u
.vs
.rasterizer_discard
=
248 ilo
->rasterizer
->state
.rasterizer_discard
;
249 variant
->u
.vs
.num_ucps
=
250 util_last_bit(ilo
->rasterizer
->state
.clip_plane_enable
);
252 case PIPE_SHADER_GEOMETRY
:
253 variant
->u
.gs
.rasterizer_discard
=
254 ilo
->rasterizer
->state
.rasterizer_discard
;
255 variant
->u
.gs
.num_inputs
= ilo
->vs
->shader
->out
.count
;
256 for (i
= 0; i
< ilo
->vs
->shader
->out
.count
; i
++) {
257 variant
->u
.gs
.semantic_names
[i
] =
258 ilo
->vs
->shader
->out
.semantic_names
[i
];
259 variant
->u
.gs
.semantic_indices
[i
] =
260 ilo
->vs
->shader
->out
.semantic_indices
[i
];
263 case PIPE_SHADER_FRAGMENT
:
264 variant
->u
.fs
.flatshade
=
265 (info
->has_color_interp
&& ilo
->rasterizer
->state
.flatshade
);
266 variant
->u
.fs
.fb_height
= (info
->has_pos
) ?
267 ilo
->fb
.state
.height
: 1;
268 variant
->u
.fs
.num_cbufs
= ilo
->fb
.state
.nr_cbufs
;
271 assert(!"unknown shader type");
275 num_views
= ilo
->view
[info
->type
].count
;
276 assert(info
->num_samplers
<= num_views
);
278 variant
->num_sampler_views
= info
->num_samplers
;
279 for (i
= 0; i
< info
->num_samplers
; i
++) {
280 const struct pipe_sampler_view
*view
= ilo
->view
[info
->type
].states
[i
];
281 const struct ilo_sampler_cso
*sampler
= ilo
->sampler
[info
->type
].cso
[i
];
284 variant
->sampler_view_swizzles
[i
].r
= view
->swizzle_r
;
285 variant
->sampler_view_swizzles
[i
].g
= view
->swizzle_g
;
286 variant
->sampler_view_swizzles
[i
].b
= view
->swizzle_b
;
287 variant
->sampler_view_swizzles
[i
].a
= view
->swizzle_a
;
289 else if (info
->shadow_samplers
& (1 << i
)) {
290 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
291 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_RED
;
292 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_RED
;
293 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ONE
;
296 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
297 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_GREEN
;
298 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_BLUE
;
299 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ALPHA
;
303 * When non-nearest filter and PIPE_TEX_WRAP_CLAMP wrap mode is used,
304 * the HW wrap mode is set to BRW_TEXCOORDMODE_CLAMP_BORDER, and we need
305 * to manually saturate the texture coordinates.
308 variant
->saturate_tex_coords
[0] |= sampler
->saturate_s
<< i
;
309 variant
->saturate_tex_coords
[1] |= sampler
->saturate_t
<< i
;
310 variant
->saturate_tex_coords
[2] |= sampler
->saturate_r
<< i
;
316 * Guess the shader variant, knowing that the context may still change.
319 ilo_shader_variant_guess(struct ilo_shader_variant
*variant
,
320 const struct ilo_shader_info
*info
,
321 const struct ilo_context
*ilo
)
325 memset(variant
, 0, sizeof(*variant
));
327 switch (info
->type
) {
328 case PIPE_SHADER_VERTEX
:
330 case PIPE_SHADER_GEOMETRY
:
332 case PIPE_SHADER_FRAGMENT
:
333 variant
->u
.fs
.flatshade
= false;
334 variant
->u
.fs
.fb_height
= (info
->has_pos
) ?
335 ilo
->fb
.state
.height
: 1;
336 variant
->u
.fs
.num_cbufs
= 1;
339 assert(!"unknown shader type");
343 variant
->num_sampler_views
= info
->num_samplers
;
344 for (i
= 0; i
< info
->num_samplers
; i
++) {
345 if (info
->shadow_samplers
& (1 << i
)) {
346 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
347 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_RED
;
348 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_RED
;
349 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ONE
;
352 variant
->sampler_view_swizzles
[i
].r
= PIPE_SWIZZLE_RED
;
353 variant
->sampler_view_swizzles
[i
].g
= PIPE_SWIZZLE_GREEN
;
354 variant
->sampler_view_swizzles
[i
].b
= PIPE_SWIZZLE_BLUE
;
355 variant
->sampler_view_swizzles
[i
].a
= PIPE_SWIZZLE_ALPHA
;
362 * Parse a TGSI instruction for the shader info.
365 ilo_shader_info_parse_inst(struct ilo_shader_info
*info
,
366 const struct tgsi_full_instruction
*inst
)
370 /* look for edgeflag passthrough */
371 if (info
->edgeflag_out
>= 0 &&
372 inst
->Instruction
.Opcode
== TGSI_OPCODE_MOV
&&
373 inst
->Dst
[0].Register
.File
== TGSI_FILE_OUTPUT
&&
374 inst
->Dst
[0].Register
.Index
== info
->edgeflag_out
) {
376 assert(inst
->Src
[0].Register
.File
== TGSI_FILE_INPUT
);
377 info
->edgeflag_in
= inst
->Src
[0].Register
.Index
;
380 if (inst
->Instruction
.Texture
) {
383 switch (inst
->Texture
.Texture
) {
384 case TGSI_TEXTURE_SHADOW1D
:
385 case TGSI_TEXTURE_SHADOW2D
:
386 case TGSI_TEXTURE_SHADOWRECT
:
387 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
388 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
389 case TGSI_TEXTURE_SHADOWCUBE
:
390 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
398 for (i
= 0; i
< inst
->Instruction
.NumSrcRegs
; i
++) {
399 const struct tgsi_full_src_register
*src
= &inst
->Src
[i
];
401 if (src
->Register
.File
== TGSI_FILE_SAMPLER
) {
402 const int idx
= src
->Register
.Index
;
404 if (idx
>= info
->num_samplers
)
405 info
->num_samplers
= idx
+ 1;
408 info
->shadow_samplers
|= 1 << idx
;
415 * Parse a TGSI property for the shader info.
418 ilo_shader_info_parse_prop(struct ilo_shader_info
*info
,
419 const struct tgsi_full_property
*prop
)
421 switch (prop
->Property
.PropertyName
) {
422 case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS
:
423 info
->fs_color0_writes_all_cbufs
= prop
->u
[0].Data
;
431 * Parse a TGSI declaration for the shader info.
434 ilo_shader_info_parse_decl(struct ilo_shader_info
*info
,
435 const struct tgsi_full_declaration
*decl
)
437 switch (decl
->Declaration
.File
) {
438 case TGSI_FILE_INPUT
:
439 if (decl
->Declaration
.Interpolate
&&
440 decl
->Interp
.Interpolate
== TGSI_INTERPOLATE_COLOR
)
441 info
->has_color_interp
= true;
442 if (decl
->Declaration
.Semantic
&&
443 decl
->Semantic
.Name
== TGSI_SEMANTIC_POSITION
)
444 info
->has_pos
= true;
446 case TGSI_FILE_OUTPUT
:
447 if (decl
->Declaration
.Semantic
&&
448 decl
->Semantic
.Name
== TGSI_SEMANTIC_EDGEFLAG
)
449 info
->edgeflag_out
= decl
->Range
.First
;
451 case TGSI_FILE_SYSTEM_VALUE
:
452 if (decl
->Declaration
.Semantic
&&
453 decl
->Semantic
.Name
== TGSI_SEMANTIC_INSTANCEID
)
454 info
->has_instanceid
= true;
455 if (decl
->Declaration
.Semantic
&&
456 decl
->Semantic
.Name
== TGSI_SEMANTIC_VERTEXID
)
457 info
->has_vertexid
= true;
465 ilo_shader_info_parse_tokens(struct ilo_shader_info
*info
)
467 struct tgsi_parse_context parse
;
469 info
->edgeflag_in
= -1;
470 info
->edgeflag_out
= -1;
472 tgsi_parse_init(&parse
, info
->tokens
);
473 while (!tgsi_parse_end_of_tokens(&parse
)) {
474 const union tgsi_full_token
*token
;
476 tgsi_parse_token(&parse
);
477 token
= &parse
.FullToken
;
479 switch (token
->Token
.Type
) {
480 case TGSI_TOKEN_TYPE_DECLARATION
:
481 ilo_shader_info_parse_decl(info
, &token
->FullDeclaration
);
483 case TGSI_TOKEN_TYPE_INSTRUCTION
:
484 ilo_shader_info_parse_inst(info
, &token
->FullInstruction
);
486 case TGSI_TOKEN_TYPE_PROPERTY
:
487 ilo_shader_info_parse_prop(info
, &token
->FullProperty
);
493 tgsi_parse_free(&parse
);
497 * Create a shader state.
499 static struct ilo_shader_state
*
500 ilo_shader_state_create(const struct ilo_context
*ilo
,
501 int type
, const void *templ
)
503 struct ilo_shader_state
*state
;
504 struct ilo_shader_variant variant
;
506 state
= CALLOC_STRUCT(ilo_shader_state
);
510 state
->info
.dev
= ilo
->dev
;
511 state
->info
.type
= type
;
513 if (type
== PIPE_SHADER_COMPUTE
) {
514 const struct pipe_compute_state
*c
=
515 (const struct pipe_compute_state
*) templ
;
517 state
->info
.tokens
= tgsi_dup_tokens(c
->prog
);
518 state
->info
.compute
.req_local_mem
= c
->req_local_mem
;
519 state
->info
.compute
.req_private_mem
= c
->req_private_mem
;
520 state
->info
.compute
.req_input_mem
= c
->req_input_mem
;
523 const struct pipe_shader_state
*s
=
524 (const struct pipe_shader_state
*) templ
;
526 state
->info
.tokens
= tgsi_dup_tokens(s
->tokens
);
527 state
->info
.stream_output
= s
->stream_output
;
530 list_inithead(&state
->variants
);
532 ilo_shader_info_parse_tokens(&state
->info
);
534 /* guess and compile now */
535 ilo_shader_variant_guess(&variant
, &state
->info
, ilo
);
536 if (!ilo_shader_state_use_variant(state
, &variant
)) {
537 ilo_shader_destroy(state
);
545 * Add a compiled shader to the shader state.
548 ilo_shader_state_add_shader(struct ilo_shader_state
*state
,
549 struct ilo_shader
*sh
)
551 list_add(&sh
->list
, &state
->variants
);
552 state
->num_variants
++;
553 state
->total_size
+= sh
->kernel_size
;
556 ilo_shader_cache_notify_change(state
->cache
, state
);
560 * Remove a compiled shader from the shader state.
563 ilo_shader_state_remove_shader(struct ilo_shader_state
*state
,
564 struct ilo_shader
*sh
)
567 state
->num_variants
--;
568 state
->total_size
-= sh
->kernel_size
;
572 * Garbage collect shader variants in the shader state.
575 ilo_shader_state_gc(struct ilo_shader_state
*state
)
577 /* activate when the variants take up more than 4KiB of space */
578 const int limit
= 4 * 1024;
579 struct ilo_shader
*sh
, *next
;
581 if (state
->total_size
< limit
)
584 /* remove from the tail as the most recently ones are at the head */
585 LIST_FOR_EACH_ENTRY_SAFE_REV(sh
, next
, &state
->variants
, list
) {
586 ilo_shader_state_remove_shader(state
, sh
);
587 ilo_shader_destroy_kernel(sh
);
589 if (state
->total_size
<= limit
/ 2)
595 * Search for a shader variant.
597 static struct ilo_shader
*
598 ilo_shader_state_search_variant(struct ilo_shader_state
*state
,
599 const struct ilo_shader_variant
*variant
)
601 struct ilo_shader
*sh
= NULL
, *tmp
;
603 LIST_FOR_EACH_ENTRY(tmp
, &state
->variants
, list
) {
604 if (memcmp(&tmp
->variant
, variant
, sizeof(*variant
)) == 0) {
614 * Add a shader variant to the shader state.
616 static struct ilo_shader
*
617 ilo_shader_state_add_variant(struct ilo_shader_state
*state
,
618 const struct ilo_shader_variant
*variant
)
620 struct ilo_shader
*sh
;
622 switch (state
->info
.type
) {
623 case PIPE_SHADER_VERTEX
:
624 sh
= ilo_shader_compile_vs(state
, variant
);
626 case PIPE_SHADER_FRAGMENT
:
627 sh
= ilo_shader_compile_fs(state
, variant
);
629 case PIPE_SHADER_GEOMETRY
:
630 sh
= ilo_shader_compile_gs(state
, variant
);
632 case PIPE_SHADER_COMPUTE
:
633 sh
= ilo_shader_compile_cs(state
, variant
);
640 assert(!"failed to compile shader");
644 sh
->variant
= *variant
;
646 ilo_shader_state_add_shader(state
, sh
);
652 * Update state->shader to point to a variant. If the variant does not exist,
653 * it will be added first.
656 ilo_shader_state_use_variant(struct ilo_shader_state
*state
,
657 const struct ilo_shader_variant
*variant
)
659 struct ilo_shader
*sh
;
660 bool construct_cso
= false;
662 sh
= ilo_shader_state_search_variant(state
, variant
);
664 ilo_shader_state_gc(state
);
666 sh
= ilo_shader_state_add_variant(state
, variant
);
670 construct_cso
= true;
674 if (state
->variants
.next
!= &sh
->list
) {
676 list_add(&sh
->list
, &state
->variants
);
682 switch (state
->info
.type
) {
683 case PIPE_SHADER_VERTEX
:
684 ilo_gpe_init_vs_cso(state
->info
.dev
, state
, &sh
->cso
);
694 struct ilo_shader_state
*
695 ilo_shader_create_vs(const struct ilo_dev_info
*dev
,
696 const struct pipe_shader_state
*state
,
697 const struct ilo_context
*precompile
)
699 struct ilo_shader_state
*shader
;
701 shader
= ilo_shader_state_create(precompile
, PIPE_SHADER_VERTEX
, state
);
703 /* states used in ilo_shader_variant_init() */
704 shader
->info
.non_orthogonal_states
= ILO_DIRTY_VERTEX_SAMPLER_VIEWS
|
705 ILO_DIRTY_RASTERIZER
;
710 struct ilo_shader_state
*
711 ilo_shader_create_gs(const struct ilo_dev_info
*dev
,
712 const struct pipe_shader_state
*state
,
713 const struct ilo_context
*precompile
)
715 struct ilo_shader_state
*shader
;
717 shader
= ilo_shader_state_create(precompile
, PIPE_SHADER_GEOMETRY
, state
);
719 /* states used in ilo_shader_variant_init() */
720 shader
->info
.non_orthogonal_states
= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS
|
722 ILO_DIRTY_RASTERIZER
;
727 struct ilo_shader_state
*
728 ilo_shader_create_fs(const struct ilo_dev_info
*dev
,
729 const struct pipe_shader_state
*state
,
730 const struct ilo_context
*precompile
)
732 struct ilo_shader_state
*shader
;
734 shader
= ilo_shader_state_create(precompile
, PIPE_SHADER_FRAGMENT
, state
);
736 /* states used in ilo_shader_variant_init() */
737 shader
->info
.non_orthogonal_states
= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS
|
738 ILO_DIRTY_RASTERIZER
|
739 ILO_DIRTY_FRAMEBUFFER
;
744 struct ilo_shader_state
*
745 ilo_shader_create_cs(const struct ilo_dev_info
*dev
,
746 const struct pipe_compute_state
*state
,
747 const struct ilo_context
*precompile
)
749 struct ilo_shader_state
*shader
;
751 shader
= ilo_shader_state_create(precompile
, PIPE_SHADER_COMPUTE
, state
);
753 shader
->info
.non_orthogonal_states
= 0;
759 * Destroy a shader state.
762 ilo_shader_destroy(struct ilo_shader_state
*shader
)
764 struct ilo_shader
*sh
, *next
;
766 LIST_FOR_EACH_ENTRY_SAFE(sh
, next
, &shader
->variants
, list
)
767 ilo_shader_destroy_kernel(sh
);
769 FREE((struct tgsi_token
*) shader
->info
.tokens
);
774 * Return the type (PIPE_SHADER_x) of the shader.
777 ilo_shader_get_type(const struct ilo_shader_state
*shader
)
779 return shader
->info
.type
;
783 * Select a kernel for the given context. This will compile a new kernel if
784 * none of the existing kernels work with the context.
786 * \param ilo the context
787 * \param dirty states of the context that are considered changed
788 * \return true if a different kernel is selected
791 ilo_shader_select_kernel(struct ilo_shader_state
*shader
,
792 const struct ilo_context
*ilo
,
795 const struct ilo_shader
* const cur
= shader
->shader
;
796 struct ilo_shader_variant variant
;
798 if (!(shader
->info
.non_orthogonal_states
& dirty
))
801 ilo_shader_variant_init(&variant
, &shader
->info
, ilo
);
802 ilo_shader_state_use_variant(shader
, &variant
);
804 return (shader
->shader
!= cur
);
808 * Return the cache offset of the selected kernel. This must be called after
809 * ilo_shader_select_kernel() and ilo_shader_cache_upload().
812 ilo_shader_get_kernel_offset(const struct ilo_shader_state
*shader
)
814 const struct ilo_shader
*kernel
= shader
->shader
;
816 assert(kernel
&& kernel
->uploaded
);
818 return kernel
->cache_offset
;
822 * Query a kernel parameter for the selected kernel.
825 ilo_shader_get_kernel_param(const struct ilo_shader_state
*shader
,
826 enum ilo_kernel_param param
)
828 const struct ilo_shader
*kernel
= shader
->shader
;
834 case ILO_KERNEL_INPUT_COUNT
:
835 val
= kernel
->in
.count
;
837 case ILO_KERNEL_OUTPUT_COUNT
:
838 val
= kernel
->out
.count
;
840 case ILO_KERNEL_URB_DATA_START_REG
:
841 val
= kernel
->in
.start_grf
;
844 case ILO_KERNEL_VS_INPUT_INSTANCEID
:
845 val
= shader
->info
.has_instanceid
;
847 case ILO_KERNEL_VS_INPUT_VERTEXID
:
848 val
= shader
->info
.has_vertexid
;
850 case ILO_KERNEL_VS_INPUT_EDGEFLAG
:
851 if (shader
->info
.edgeflag_in
>= 0) {
852 /* we rely on the state tracker here */
853 assert(shader
->info
.edgeflag_in
== kernel
->in
.count
- 1);
860 case ILO_KERNEL_VS_PCB_UCP_SIZE
:
861 val
= kernel
->pcb
.clip_state_size
;
863 case ILO_KERNEL_VS_GEN6_SO
:
864 val
= kernel
->stream_output
;
866 case ILO_KERNEL_VS_GEN6_SO_START_REG
:
867 val
= kernel
->gs_start_grf
;
869 case ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET
:
870 val
= kernel
->gs_offsets
[0];
872 case ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET
:
873 val
= kernel
->gs_offsets
[1];
875 case ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET
:
876 val
= kernel
->gs_offsets
[2];
879 case ILO_KERNEL_GS_DISCARD_ADJACENCY
:
880 val
= kernel
->in
.discard_adj
;
882 case ILO_KERNEL_GS_GEN6_SVBI_POST_INC
:
883 val
= kernel
->svbi_post_inc
;
886 case ILO_KERNEL_FS_INPUT_Z
:
887 case ILO_KERNEL_FS_INPUT_W
:
888 val
= kernel
->in
.has_pos
;
890 case ILO_KERNEL_FS_OUTPUT_Z
:
891 val
= kernel
->out
.has_pos
;
893 case ILO_KERNEL_FS_USE_KILL
:
894 val
= kernel
->has_kill
;
896 case ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS
:
897 val
= kernel
->in
.barycentric_interpolation_mode
;
899 case ILO_KERNEL_FS_DISPATCH_16_OFFSET
:
904 assert(!"unknown kernel parameter");
913 * Return the CSO of the selected kernel.
915 const struct ilo_shader_cso
*
916 ilo_shader_get_kernel_cso(const struct ilo_shader_state
*shader
)
918 const struct ilo_shader
*kernel
= shader
->shader
;