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 "core/ilo_format.h"
29 #include "core/ilo_state_3d.h"
30 #include "util/u_dynarray.h"
31 #include "util/u_helpers.h"
32 #include "util/u_resource.h"
33 #include "util/u_upload_mgr.h"
35 #include "ilo_context.h"
36 #include "ilo_resource.h"
37 #include "ilo_shader.h"
38 #include "ilo_state.h"
40 static enum gen_mip_filter
41 ilo_translate_mip_filter(unsigned filter
)
44 case PIPE_TEX_MIPFILTER_NEAREST
: return GEN6_MIPFILTER_NEAREST
;
45 case PIPE_TEX_MIPFILTER_LINEAR
: return GEN6_MIPFILTER_LINEAR
;
46 case PIPE_TEX_MIPFILTER_NONE
: return GEN6_MIPFILTER_NONE
;
48 assert(!"unknown mipfilter");
49 return GEN6_MIPFILTER_NONE
;
54 ilo_translate_img_filter(unsigned filter
)
57 case PIPE_TEX_FILTER_NEAREST
: return GEN6_MAPFILTER_NEAREST
;
58 case PIPE_TEX_FILTER_LINEAR
: return GEN6_MAPFILTER_LINEAR
;
60 assert(!"unknown sampler filter");
61 return GEN6_MAPFILTER_NEAREST
;
65 static enum gen_texcoord_mode
66 ilo_translate_address_wrap(unsigned wrap
)
69 case PIPE_TEX_WRAP_CLAMP
: return GEN8_TEXCOORDMODE_HALF_BORDER
;
70 case PIPE_TEX_WRAP_REPEAT
: return GEN6_TEXCOORDMODE_WRAP
;
71 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
: return GEN6_TEXCOORDMODE_CLAMP
;
72 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
: return GEN6_TEXCOORDMODE_CLAMP_BORDER
;
73 case PIPE_TEX_WRAP_MIRROR_REPEAT
: return GEN6_TEXCOORDMODE_MIRROR
;
74 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
75 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
76 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
78 assert(!"unknown sampler wrap mode");
79 return GEN6_TEXCOORDMODE_WRAP
;
83 static enum gen_aniso_ratio
84 ilo_translate_max_anisotropy(unsigned max_anisotropy
)
86 switch (max_anisotropy
) {
87 case 0: case 1: case 2: return GEN6_ANISORATIO_2
;
88 case 3: case 4: return GEN6_ANISORATIO_4
;
89 case 5: case 6: return GEN6_ANISORATIO_6
;
90 case 7: case 8: return GEN6_ANISORATIO_8
;
91 case 9: case 10: return GEN6_ANISORATIO_10
;
92 case 11: case 12: return GEN6_ANISORATIO_12
;
93 case 13: case 14: return GEN6_ANISORATIO_14
;
94 default: return GEN6_ANISORATIO_16
;
98 static enum gen_prefilter_op
99 ilo_translate_shadow_func(unsigned func
)
102 * For PIPE_FUNC_x, the reference value is on the left-hand side of the
103 * comparison, and 1.0 is returned when the comparison is true.
105 * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
106 * the comparison, and 0.0 is returned when the comparison is true.
109 case PIPE_FUNC_NEVER
: return GEN6_PREFILTEROP_ALWAYS
;
110 case PIPE_FUNC_LESS
: return GEN6_PREFILTEROP_LEQUAL
;
111 case PIPE_FUNC_EQUAL
: return GEN6_PREFILTEROP_NOTEQUAL
;
112 case PIPE_FUNC_LEQUAL
: return GEN6_PREFILTEROP_LESS
;
113 case PIPE_FUNC_GREATER
: return GEN6_PREFILTEROP_GEQUAL
;
114 case PIPE_FUNC_NOTEQUAL
: return GEN6_PREFILTEROP_EQUAL
;
115 case PIPE_FUNC_GEQUAL
: return GEN6_PREFILTEROP_GREATER
;
116 case PIPE_FUNC_ALWAYS
: return GEN6_PREFILTEROP_NEVER
;
118 assert(!"unknown shadow compare function");
119 return GEN6_PREFILTEROP_NEVER
;
124 finalize_shader_states(struct ilo_state_vector
*vec
)
128 for (type
= 0; type
< PIPE_SHADER_TYPES
; type
++) {
129 struct ilo_shader_state
*shader
;
133 case PIPE_SHADER_VERTEX
:
135 state
= ILO_DIRTY_VS
;
137 case PIPE_SHADER_GEOMETRY
:
139 state
= ILO_DIRTY_GS
;
141 case PIPE_SHADER_FRAGMENT
:
143 state
= ILO_DIRTY_FS
;
154 /* compile if the shader or the states it depends on changed */
155 if (vec
->dirty
& state
) {
156 ilo_shader_select_kernel(shader
, vec
, ILO_DIRTY_ALL
);
158 else if (ilo_shader_select_kernel(shader
, vec
, vec
->dirty
)) {
159 /* mark the state dirty if a new kernel is selected */
163 /* need to setup SBE for FS */
164 if (type
== PIPE_SHADER_FRAGMENT
&& vec
->dirty
&
165 (state
| ILO_DIRTY_GS
| ILO_DIRTY_VS
| ILO_DIRTY_RASTERIZER
)) {
166 if (ilo_shader_select_kernel_routing(shader
,
167 (vec
->gs
) ? vec
->gs
: vec
->vs
, vec
->rasterizer
))
174 finalize_cbuf_state(struct ilo_context
*ilo
,
175 struct ilo_cbuf_state
*cbuf
,
176 const struct ilo_shader_state
*sh
)
178 uint32_t upload_mask
= cbuf
->enabled_mask
;
180 /* skip CBUF0 if the kernel does not need it */
182 ~ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SKIP_CBUF0_UPLOAD
);
184 while (upload_mask
) {
187 i
= u_bit_scan(&upload_mask
);
188 /* no need to upload */
189 if (cbuf
->cso
[i
].resource
)
192 u_upload_data(ilo
->uploader
, 0, cbuf
->cso
[i
].info
.size
,
193 cbuf
->cso
[i
].user_buffer
, &offset
, &cbuf
->cso
[i
].resource
);
195 cbuf
->cso
[i
].info
.buf
= ilo_buffer(cbuf
->cso
[i
].resource
);
196 cbuf
->cso
[i
].info
.offset
= offset
;
198 memset(&cbuf
->cso
[i
].surface
, 0, sizeof(cbuf
->cso
[i
].surface
));
199 ilo_state_surface_init_for_buffer(&cbuf
->cso
[i
].surface
,
200 ilo
->dev
, &cbuf
->cso
[i
].info
);
201 cbuf
->cso
[i
].surface
.bo
= cbuf
->cso
[i
].info
.buf
->bo
;
203 ilo
->state_vector
.dirty
|= ILO_DIRTY_CBUF
;
208 finalize_constant_buffers(struct ilo_context
*ilo
)
210 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
212 if (vec
->dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_VS
))
213 finalize_cbuf_state(ilo
, &vec
->cbuf
[PIPE_SHADER_VERTEX
], vec
->vs
);
215 if (ilo
->state_vector
.dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_FS
))
216 finalize_cbuf_state(ilo
, &vec
->cbuf
[PIPE_SHADER_FRAGMENT
], vec
->fs
);
220 finalize_index_buffer(struct ilo_context
*ilo
)
222 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
223 const bool need_upload
= (vec
->draw
->indexed
&&
224 (vec
->ib
.user_buffer
|| vec
->ib
.offset
% vec
->ib
.index_size
));
225 struct pipe_resource
*current_hw_res
= NULL
;
227 if (!(vec
->dirty
& ILO_DIRTY_IB
) && !need_upload
)
230 pipe_resource_reference(¤t_hw_res
, vec
->ib
.hw_resource
);
233 const unsigned offset
= vec
->ib
.index_size
* vec
->draw
->start
;
234 const unsigned size
= vec
->ib
.index_size
* vec
->draw
->count
;
237 if (vec
->ib
.user_buffer
) {
238 u_upload_data(ilo
->uploader
, 0, size
,
239 vec
->ib
.user_buffer
+ offset
, &hw_offset
, &vec
->ib
.hw_resource
);
242 u_upload_buffer(ilo
->uploader
, 0, vec
->ib
.offset
+ offset
, size
,
243 vec
->ib
.buffer
, &hw_offset
, &vec
->ib
.hw_resource
);
246 /* the HW offset should be aligned */
247 assert(hw_offset
% vec
->ib
.index_size
== 0);
248 vec
->ib
.draw_start_offset
= hw_offset
/ vec
->ib
.index_size
;
251 * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
254 vec
->ib
.draw_start_offset
-= vec
->draw
->start
;
257 pipe_resource_reference(&vec
->ib
.hw_resource
, vec
->ib
.buffer
);
259 /* note that index size may be zero when the draw is not indexed */
260 if (vec
->draw
->indexed
)
261 vec
->ib
.draw_start_offset
= vec
->ib
.offset
/ vec
->ib
.index_size
;
263 vec
->ib
.draw_start_offset
= 0;
266 /* treat the IB as clean if the HW states do not change */
267 if (vec
->ib
.hw_resource
== current_hw_res
&&
268 vec
->ib
.hw_index_size
== vec
->ib
.index_size
)
269 vec
->dirty
&= ~ILO_DIRTY_IB
;
271 vec
->ib
.hw_index_size
= vec
->ib
.index_size
;
273 pipe_resource_reference(¤t_hw_res
, NULL
);
277 finalize_vertex_elements(struct ilo_context
*ilo
)
279 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
281 if (!(vec
->dirty
& (ILO_DIRTY_VE
| ILO_DIRTY_VS
)))
284 vec
->dirty
|= ILO_DIRTY_VE
;
286 vec
->ve
->last_cso_edgeflag
= false;
287 if (vec
->ve
->count
&& vec
->vs
&&
288 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_VS_INPUT_EDGEFLAG
)) {
289 vec
->ve
->edgeflag_cso
= vec
->ve
->cso
[vec
->ve
->count
- 1];
290 ilo_gpe_set_ve_edgeflag(ilo
->dev
, &vec
->ve
->edgeflag_cso
);
291 vec
->ve
->last_cso_edgeflag
= true;
294 vec
->ve
->prepend_nosrc_cso
= false;
296 (ilo_shader_get_kernel_param(vec
->vs
,
297 ILO_KERNEL_VS_INPUT_INSTANCEID
) ||
298 ilo_shader_get_kernel_param(vec
->vs
,
299 ILO_KERNEL_VS_INPUT_VERTEXID
))) {
300 ilo_gpe_init_ve_nosrc(ilo
->dev
,
301 GEN6_VFCOMP_STORE_VID
,
302 GEN6_VFCOMP_STORE_IID
,
305 &vec
->ve
->nosrc_cso
);
306 vec
->ve
->prepend_nosrc_cso
= true;
307 } else if (!vec
->vs
) {
308 /* generate VUE header */
309 ilo_gpe_init_ve_nosrc(ilo
->dev
,
310 GEN6_VFCOMP_STORE_0
, /* Reserved */
311 GEN6_VFCOMP_STORE_0
, /* Render Target Array Index */
312 GEN6_VFCOMP_STORE_0
, /* Viewport Index */
313 GEN6_VFCOMP_STORE_0
, /* Point Width */
314 &vec
->ve
->nosrc_cso
);
315 vec
->ve
->prepend_nosrc_cso
= true;
316 } else if (!vec
->ve
->count
) {
318 * From the Sandy Bridge PRM, volume 2 part 1, page 92:
320 * "SW must ensure that at least one vertex element is defined prior
321 * to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
323 ilo_gpe_init_ve_nosrc(ilo
->dev
,
327 GEN6_VFCOMP_STORE_1_FP
,
328 &vec
->ve
->nosrc_cso
);
329 vec
->ve
->prepend_nosrc_cso
= true;
334 finalize_viewport(struct ilo_context
*ilo
)
336 const struct ilo_dev
*dev
= ilo
->dev
;
337 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
339 if (vec
->dirty
& ILO_DIRTY_VIEWPORT
) {
340 ilo_state_viewport_set_params(&vec
->viewport
.vp
,
341 dev
, &vec
->viewport
.params
, false);
342 } else if (vec
->dirty
& ILO_DIRTY_SCISSOR
) {
343 ilo_state_viewport_set_params(&vec
->viewport
.vp
,
344 dev
, &vec
->viewport
.params
, true);
345 vec
->dirty
|= ILO_DIRTY_VIEWPORT
;
350 * Finalize states. Some states depend on other states and are
351 * incomplete/invalid until finalized.
354 ilo_finalize_3d_states(struct ilo_context
*ilo
,
355 const struct pipe_draw_info
*draw
)
357 ilo
->state_vector
.draw
= draw
;
359 finalize_shader_states(&ilo
->state_vector
);
360 finalize_constant_buffers(ilo
);
361 finalize_index_buffer(ilo
);
362 finalize_vertex_elements(ilo
);
364 finalize_viewport(ilo
);
366 u_upload_unmap(ilo
->uploader
);
370 finalize_global_binding(struct ilo_state_vector
*vec
)
372 struct ilo_shader_state
*cs
= vec
->cs
;
373 int base
, count
, shift
;
376 count
= ilo_shader_get_kernel_param(cs
,
377 ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT
);
381 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE
);
382 shift
= 32 - util_last_bit(base
+ count
- 1);
384 if (count
> vec
->global_binding
.count
)
385 count
= vec
->global_binding
.count
;
387 for (i
= 0; i
< count
; i
++) {
388 struct ilo_global_binding_cso
*cso
=
389 util_dynarray_element(&vec
->global_binding
.bindings
,
390 struct ilo_global_binding_cso
, i
);
391 const uint32_t offset
= *cso
->handle
& ((1 << shift
) - 1);
393 *cso
->handle
= ((base
+ i
) << shift
) | offset
;
398 ilo_finalize_compute_states(struct ilo_context
*ilo
)
400 finalize_global_binding(&ilo
->state_vector
);
404 ilo_create_blend_state(struct pipe_context
*pipe
,
405 const struct pipe_blend_state
*state
)
407 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
408 struct ilo_blend_state
*blend
;
410 blend
= MALLOC_STRUCT(ilo_blend_state
);
413 ilo_gpe_init_blend(dev
, state
, blend
);
419 ilo_bind_blend_state(struct pipe_context
*pipe
, void *state
)
421 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
425 vec
->dirty
|= ILO_DIRTY_BLEND
;
429 ilo_delete_blend_state(struct pipe_context
*pipe
, void *state
)
435 ilo_create_sampler_state(struct pipe_context
*pipe
,
436 const struct pipe_sampler_state
*state
)
438 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
439 struct ilo_sampler_cso
*sampler
;
440 struct ilo_state_sampler_info info
;
441 struct ilo_state_sampler_border_info border
;
443 sampler
= CALLOC_STRUCT(ilo_sampler_cso
);
446 memset(&info
, 0, sizeof(info
));
448 info
.non_normalized
= !state
->normalized_coords
;
449 if (state
->normalized_coords
) {
450 info
.lod_bias
= state
->lod_bias
;
451 info
.min_lod
= state
->min_lod
;
452 info
.max_lod
= state
->max_lod
;
454 info
.mip_filter
= ilo_translate_mip_filter(state
->min_mip_filter
);
456 /* work around a bug in util_blitter */
457 info
.mip_filter
= GEN6_MIPFILTER_NONE
;
460 if (state
->max_anisotropy
) {
461 info
.min_filter
= GEN6_MAPFILTER_ANISOTROPIC
;
462 info
.mag_filter
= GEN6_MAPFILTER_ANISOTROPIC
;
464 info
.min_filter
= ilo_translate_img_filter(state
->min_img_filter
);
465 info
.mag_filter
= ilo_translate_img_filter(state
->mag_img_filter
);
468 info
.max_anisotropy
= ilo_translate_max_anisotropy(state
->max_anisotropy
);
470 /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
471 if (info
.mip_filter
== GEN6_MIPFILTER_NONE
&& info
.min_lod
> 0.0f
) {
473 info
.mag_filter
= info
.min_filter
;
476 if (state
->seamless_cube_map
) {
477 if (state
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
||
478 state
->mag_img_filter
== PIPE_TEX_FILTER_NEAREST
) {
479 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
480 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
481 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
483 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
484 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
485 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
488 info
.tcx_ctrl
= ilo_translate_address_wrap(state
->wrap_s
);
489 info
.tcy_ctrl
= ilo_translate_address_wrap(state
->wrap_t
);
490 info
.tcz_ctrl
= ilo_translate_address_wrap(state
->wrap_r
);
492 if (ilo_dev_gen(dev
) < ILO_GEN(8)) {
494 * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
495 * PIPE_TEX_WRAP_CLAMP_TO_EDGE; for linear filtering,
496 * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
497 * additionally clamping the texture coordinates to [0.0, 1.0].
499 * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8. The
500 * clamping has to be taken care of in the shaders. There are two
501 * filters here, but let the minification one has a say.
503 const bool clamp_is_to_edge
=
504 (state
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
);
506 if (clamp_is_to_edge
) {
507 if (info
.tcx_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
508 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
509 if (info
.tcy_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
510 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
511 if (info
.tcz_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
512 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
514 if (info
.tcx_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
515 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
516 sampler
->saturate_s
= true;
518 if (info
.tcy_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
519 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
520 sampler
->saturate_t
= true;
522 if (info
.tcz_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
523 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
524 sampler
->saturate_r
= true;
530 if (state
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
531 info
.shadow_func
= ilo_translate_shadow_func(state
->compare_func
);
533 ilo_state_sampler_init(&sampler
->sampler
, dev
, &info
);
535 memset(&border
, 0, sizeof(border
));
536 memcpy(border
.rgba
.f
, state
->border_color
.f
, sizeof(border
.rgba
.f
));
538 ilo_state_sampler_border_init(&sampler
->border
, dev
, &border
);
544 ilo_bind_sampler_states(struct pipe_context
*pipe
, unsigned shader
,
545 unsigned start
, unsigned count
, void **samplers
)
547 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
548 struct ilo_sampler_state
*dst
= &vec
->sampler
[shader
];
549 bool changed
= false;
552 assert(start
+ count
<= Elements(dst
->cso
));
555 for (i
= 0; i
< count
; i
++) {
556 if (dst
->cso
[start
+ i
] != samplers
[i
]) {
557 dst
->cso
[start
+ i
] = samplers
[i
];
560 * This function is sometimes called to reduce the number of bound
561 * samplers. Do not consider that as a state change (and create a
562 * new array of SAMPLER_STATE).
570 for (i
= 0; i
< count
; i
++)
571 dst
->cso
[start
+ i
] = NULL
;
576 case PIPE_SHADER_VERTEX
:
577 vec
->dirty
|= ILO_DIRTY_SAMPLER_VS
;
579 case PIPE_SHADER_GEOMETRY
:
580 vec
->dirty
|= ILO_DIRTY_SAMPLER_GS
;
582 case PIPE_SHADER_FRAGMENT
:
583 vec
->dirty
|= ILO_DIRTY_SAMPLER_FS
;
585 case PIPE_SHADER_COMPUTE
:
586 vec
->dirty
|= ILO_DIRTY_SAMPLER_CS
;
593 ilo_delete_sampler_state(struct pipe_context
*pipe
, void *state
)
599 ilo_create_rasterizer_state(struct pipe_context
*pipe
,
600 const struct pipe_rasterizer_state
*state
)
602 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
603 struct ilo_rasterizer_state
*rast
;
605 rast
= MALLOC_STRUCT(ilo_rasterizer_state
);
608 rast
->state
= *state
;
609 ilo_gpe_init_rasterizer(dev
, state
, rast
);
615 ilo_bind_rasterizer_state(struct pipe_context
*pipe
, void *state
)
617 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
619 vec
->rasterizer
= state
;
621 vec
->dirty
|= ILO_DIRTY_RASTERIZER
;
625 ilo_delete_rasterizer_state(struct pipe_context
*pipe
, void *state
)
631 ilo_create_depth_stencil_alpha_state(struct pipe_context
*pipe
,
632 const struct pipe_depth_stencil_alpha_state
*state
)
634 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
635 struct ilo_dsa_state
*dsa
;
637 dsa
= MALLOC_STRUCT(ilo_dsa_state
);
640 ilo_gpe_init_dsa(dev
, state
, dsa
);
646 ilo_bind_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
648 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
652 vec
->dirty
|= ILO_DIRTY_DSA
;
656 ilo_delete_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
662 ilo_create_fs_state(struct pipe_context
*pipe
,
663 const struct pipe_shader_state
*state
)
665 struct ilo_context
*ilo
= ilo_context(pipe
);
666 struct ilo_shader_state
*shader
;
668 shader
= ilo_shader_create_fs(ilo
->dev
, state
, &ilo
->state_vector
);
671 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
677 ilo_bind_fs_state(struct pipe_context
*pipe
, void *state
)
679 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
683 vec
->dirty
|= ILO_DIRTY_FS
;
687 ilo_delete_fs_state(struct pipe_context
*pipe
, void *state
)
689 struct ilo_context
*ilo
= ilo_context(pipe
);
690 struct ilo_shader_state
*fs
= (struct ilo_shader_state
*) state
;
692 ilo_shader_cache_remove(ilo
->shader_cache
, fs
);
693 ilo_shader_destroy(fs
);
697 ilo_create_vs_state(struct pipe_context
*pipe
,
698 const struct pipe_shader_state
*state
)
700 struct ilo_context
*ilo
= ilo_context(pipe
);
701 struct ilo_shader_state
*shader
;
703 shader
= ilo_shader_create_vs(ilo
->dev
, state
, &ilo
->state_vector
);
706 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
712 ilo_bind_vs_state(struct pipe_context
*pipe
, void *state
)
714 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
718 vec
->dirty
|= ILO_DIRTY_VS
;
722 ilo_delete_vs_state(struct pipe_context
*pipe
, void *state
)
724 struct ilo_context
*ilo
= ilo_context(pipe
);
725 struct ilo_shader_state
*vs
= (struct ilo_shader_state
*) state
;
727 ilo_shader_cache_remove(ilo
->shader_cache
, vs
);
728 ilo_shader_destroy(vs
);
732 ilo_create_gs_state(struct pipe_context
*pipe
,
733 const struct pipe_shader_state
*state
)
735 struct ilo_context
*ilo
= ilo_context(pipe
);
736 struct ilo_shader_state
*shader
;
738 shader
= ilo_shader_create_gs(ilo
->dev
, state
, &ilo
->state_vector
);
741 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
747 ilo_bind_gs_state(struct pipe_context
*pipe
, void *state
)
749 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
751 /* util_blitter may set this unnecessarily */
752 if (vec
->gs
== state
)
757 vec
->dirty
|= ILO_DIRTY_GS
;
761 ilo_delete_gs_state(struct pipe_context
*pipe
, void *state
)
763 struct ilo_context
*ilo
= ilo_context(pipe
);
764 struct ilo_shader_state
*gs
= (struct ilo_shader_state
*) state
;
766 ilo_shader_cache_remove(ilo
->shader_cache
, gs
);
767 ilo_shader_destroy(gs
);
771 ilo_create_vertex_elements_state(struct pipe_context
*pipe
,
772 unsigned num_elements
,
773 const struct pipe_vertex_element
*elements
)
775 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
776 struct ilo_ve_state
*ve
;
778 ve
= MALLOC_STRUCT(ilo_ve_state
);
781 ilo_gpe_init_ve(dev
, num_elements
, elements
, ve
);
787 ilo_bind_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
789 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
793 vec
->dirty
|= ILO_DIRTY_VE
;
797 ilo_delete_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
799 struct ilo_ve_state
*ve
= state
;
805 ilo_set_blend_color(struct pipe_context
*pipe
,
806 const struct pipe_blend_color
*state
)
808 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
810 vec
->blend_color
= *state
;
812 vec
->dirty
|= ILO_DIRTY_BLEND_COLOR
;
816 ilo_set_stencil_ref(struct pipe_context
*pipe
,
817 const struct pipe_stencil_ref
*state
)
819 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
821 /* util_blitter may set this unnecessarily */
822 if (!memcmp(&vec
->stencil_ref
, state
, sizeof(*state
)))
825 vec
->stencil_ref
= *state
;
827 vec
->dirty
|= ILO_DIRTY_STENCIL_REF
;
831 ilo_set_sample_mask(struct pipe_context
*pipe
,
832 unsigned sample_mask
)
834 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
836 /* util_blitter may set this unnecessarily */
837 if (vec
->sample_mask
== sample_mask
)
840 vec
->sample_mask
= sample_mask
;
842 vec
->dirty
|= ILO_DIRTY_SAMPLE_MASK
;
846 ilo_set_clip_state(struct pipe_context
*pipe
,
847 const struct pipe_clip_state
*state
)
849 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
853 vec
->dirty
|= ILO_DIRTY_CLIP
;
857 ilo_set_constant_buffer(struct pipe_context
*pipe
,
858 uint shader
, uint index
,
859 struct pipe_constant_buffer
*buf
)
861 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
862 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
863 struct ilo_cbuf_state
*cbuf
= &vec
->cbuf
[shader
];
864 const unsigned count
= 1;
867 assert(shader
< Elements(vec
->cbuf
));
868 assert(index
+ count
<= Elements(vec
->cbuf
[shader
].cso
));
871 for (i
= 0; i
< count
; i
++) {
872 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
874 pipe_resource_reference(&cso
->resource
, buf
[i
].buffer
);
876 cso
->info
.access
= ILO_STATE_SURFACE_ACCESS_DP_DATA
;
877 cso
->info
.format
= GEN6_FORMAT_R32G32B32A32_FLOAT
;
878 cso
->info
.format_size
= 16;
879 cso
->info
.struct_size
= 16;
880 cso
->info
.readonly
= true;
881 cso
->info
.size
= buf
[i
].buffer_size
;
884 cso
->info
.buf
= ilo_buffer(buf
[i
].buffer
);
885 cso
->info
.offset
= buf
[i
].buffer_offset
;
887 memset(&cso
->surface
, 0, sizeof(cso
->surface
));
888 ilo_state_surface_init_for_buffer(&cso
->surface
, dev
, &cso
->info
);
889 cso
->surface
.bo
= cso
->info
.buf
->bo
;
891 cso
->user_buffer
= NULL
;
893 cbuf
->enabled_mask
|= 1 << (index
+ i
);
894 } else if (buf
[i
].user_buffer
) {
895 cso
->info
.buf
= NULL
;
896 /* buffer_offset does not apply for user buffer */
897 cso
->user_buffer
= buf
[i
].user_buffer
;
899 cbuf
->enabled_mask
|= 1 << (index
+ i
);
901 cso
->info
.buf
= NULL
;
903 cso
->user_buffer
= NULL
;
905 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
909 for (i
= 0; i
< count
; i
++) {
910 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
912 pipe_resource_reference(&cso
->resource
, NULL
);
914 cso
->info
.buf
= NULL
;
916 cso
->user_buffer
= NULL
;
918 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
922 vec
->dirty
|= ILO_DIRTY_CBUF
;
926 ilo_set_framebuffer_state(struct pipe_context
*pipe
,
927 const struct pipe_framebuffer_state
*state
)
929 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
930 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
932 ilo_gpe_set_fb(dev
, state
, &vec
->fb
);
934 vec
->dirty
|= ILO_DIRTY_FB
;
938 ilo_set_polygon_stipple(struct pipe_context
*pipe
,
939 const struct pipe_poly_stipple
*state
)
941 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
943 vec
->poly_stipple
= *state
;
945 vec
->dirty
|= ILO_DIRTY_POLY_STIPPLE
;
949 ilo_set_scissor_states(struct pipe_context
*pipe
,
951 unsigned num_scissors
,
952 const struct pipe_scissor_state
*scissors
)
954 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
957 for (i
= 0; i
< num_scissors
; i
++) {
958 struct ilo_state_viewport_scissor_info
*info
=
959 &vec
->viewport
.scissors
[start_slot
+ i
];
961 if (scissors
[i
].minx
< scissors
[i
].maxx
&&
962 scissors
[i
].miny
< scissors
[i
].maxy
) {
963 info
->min_x
= scissors
[i
].minx
;
964 info
->min_y
= scissors
[i
].miny
;
965 info
->max_x
= scissors
[i
].maxx
- 1;
966 info
->max_y
= scissors
[i
].maxy
- 1;
975 vec
->dirty
|= ILO_DIRTY_SCISSOR
;
979 ilo_set_viewport_states(struct pipe_context
*pipe
,
981 unsigned num_viewports
,
982 const struct pipe_viewport_state
*viewports
)
984 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
989 for (i
= 0; i
< num_viewports
; i
++) {
990 struct ilo_state_viewport_matrix_info
*info
=
991 &vec
->viewport
.matrices
[start_slot
+ i
];
993 memcpy(info
->scale
, viewports
[i
].scale
, sizeof(info
->scale
));
994 memcpy(info
->translate
, viewports
[i
].translate
,
995 sizeof(info
->translate
));
998 if (vec
->viewport
.params
.count
< start_slot
+ num_viewports
)
999 vec
->viewport
.params
.count
= start_slot
+ num_viewports
;
1001 /* need to save viewport 0 for util_blitter */
1002 if (!start_slot
&& num_viewports
)
1003 vec
->viewport
.viewport0
= viewports
[0];
1006 if (vec
->viewport
.params
.count
<= start_slot
+ num_viewports
&&
1007 vec
->viewport
.params
.count
> start_slot
)
1008 vec
->viewport
.params
.count
= start_slot
;
1011 vec
->dirty
|= ILO_DIRTY_VIEWPORT
;
1015 ilo_set_sampler_views(struct pipe_context
*pipe
, unsigned shader
,
1016 unsigned start
, unsigned count
,
1017 struct pipe_sampler_view
**views
)
1019 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1020 struct ilo_view_state
*dst
= &vec
->view
[shader
];
1023 assert(start
+ count
<= Elements(dst
->states
));
1026 for (i
= 0; i
< count
; i
++)
1027 pipe_sampler_view_reference(&dst
->states
[start
+ i
], views
[i
]);
1030 for (i
= 0; i
< count
; i
++)
1031 pipe_sampler_view_reference(&dst
->states
[start
+ i
], NULL
);
1034 if (dst
->count
<= start
+ count
) {
1040 while (count
> 0 && !dst
->states
[count
- 1])
1047 case PIPE_SHADER_VERTEX
:
1048 vec
->dirty
|= ILO_DIRTY_VIEW_VS
;
1050 case PIPE_SHADER_GEOMETRY
:
1051 vec
->dirty
|= ILO_DIRTY_VIEW_GS
;
1053 case PIPE_SHADER_FRAGMENT
:
1054 vec
->dirty
|= ILO_DIRTY_VIEW_FS
;
1056 case PIPE_SHADER_COMPUTE
:
1057 vec
->dirty
|= ILO_DIRTY_VIEW_CS
;
1063 ilo_set_shader_resources(struct pipe_context
*pipe
,
1064 unsigned start
, unsigned count
,
1065 struct pipe_surface
**surfaces
)
1067 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1068 struct ilo_resource_state
*dst
= &vec
->resource
;
1071 assert(start
+ count
<= Elements(dst
->states
));
1074 for (i
= 0; i
< count
; i
++)
1075 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
1078 for (i
= 0; i
< count
; i
++)
1079 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
1082 if (dst
->count
<= start
+ count
) {
1088 while (count
> 0 && !dst
->states
[count
- 1])
1094 vec
->dirty
|= ILO_DIRTY_RESOURCE
;
1098 ilo_set_vertex_buffers(struct pipe_context
*pipe
,
1099 unsigned start_slot
, unsigned num_buffers
,
1100 const struct pipe_vertex_buffer
*buffers
)
1102 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1105 /* no PIPE_CAP_USER_VERTEX_BUFFERS */
1107 for (i
= 0; i
< num_buffers
; i
++)
1108 assert(!buffers
[i
].user_buffer
);
1111 util_set_vertex_buffers_mask(vec
->vb
.states
,
1112 &vec
->vb
.enabled_mask
, buffers
, start_slot
, num_buffers
);
1114 vec
->dirty
|= ILO_DIRTY_VB
;
1118 ilo_set_index_buffer(struct pipe_context
*pipe
,
1119 const struct pipe_index_buffer
*state
)
1121 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1124 pipe_resource_reference(&vec
->ib
.buffer
, state
->buffer
);
1125 vec
->ib
.user_buffer
= state
->user_buffer
;
1126 vec
->ib
.offset
= state
->offset
;
1127 vec
->ib
.index_size
= state
->index_size
;
1130 pipe_resource_reference(&vec
->ib
.buffer
, NULL
);
1131 vec
->ib
.user_buffer
= NULL
;
1133 vec
->ib
.index_size
= 0;
1136 vec
->dirty
|= ILO_DIRTY_IB
;
1139 static struct pipe_stream_output_target
*
1140 ilo_create_stream_output_target(struct pipe_context
*pipe
,
1141 struct pipe_resource
*res
,
1142 unsigned buffer_offset
,
1143 unsigned buffer_size
)
1145 struct pipe_stream_output_target
*target
;
1147 target
= MALLOC_STRUCT(pipe_stream_output_target
);
1150 pipe_reference_init(&target
->reference
, 1);
1151 target
->buffer
= NULL
;
1152 pipe_resource_reference(&target
->buffer
, res
);
1153 target
->context
= pipe
;
1154 target
->buffer_offset
= buffer_offset
;
1155 target
->buffer_size
= buffer_size
;
1161 ilo_set_stream_output_targets(struct pipe_context
*pipe
,
1162 unsigned num_targets
,
1163 struct pipe_stream_output_target
**targets
,
1164 const unsigned *offset
)
1166 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1168 unsigned append_bitmask
= 0;
1173 /* util_blitter may set this unnecessarily */
1174 if (!vec
->so
.count
&& !num_targets
)
1177 for (i
= 0; i
< num_targets
; i
++) {
1178 pipe_so_target_reference(&vec
->so
.states
[i
], targets
[i
]);
1179 if (offset
[i
] == (unsigned)-1)
1180 append_bitmask
|= 1 << i
;
1183 for (; i
< vec
->so
.count
; i
++)
1184 pipe_so_target_reference(&vec
->so
.states
[i
], NULL
);
1186 vec
->so
.count
= num_targets
;
1187 vec
->so
.append_bitmask
= append_bitmask
;
1189 vec
->so
.enabled
= (vec
->so
.count
> 0);
1191 vec
->dirty
|= ILO_DIRTY_SO
;
1195 ilo_stream_output_target_destroy(struct pipe_context
*pipe
,
1196 struct pipe_stream_output_target
*target
)
1198 pipe_resource_reference(&target
->buffer
, NULL
);
1202 static struct pipe_sampler_view
*
1203 ilo_create_sampler_view(struct pipe_context
*pipe
,
1204 struct pipe_resource
*res
,
1205 const struct pipe_sampler_view
*templ
)
1207 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1208 struct ilo_view_cso
*view
;
1210 view
= CALLOC_STRUCT(ilo_view_cso
);
1213 view
->base
= *templ
;
1214 pipe_reference_init(&view
->base
.reference
, 1);
1215 view
->base
.texture
= NULL
;
1216 pipe_resource_reference(&view
->base
.texture
, res
);
1217 view
->base
.context
= pipe
;
1219 if (res
->target
== PIPE_BUFFER
) {
1220 struct ilo_state_surface_buffer_info info
;
1222 memset(&info
, 0, sizeof(info
));
1223 info
.buf
= ilo_buffer(res
);
1224 info
.access
= ILO_STATE_SURFACE_ACCESS_SAMPLER
;
1225 info
.format
= ilo_format_translate_color(dev
, templ
->format
);
1226 info
.format_size
= util_format_get_blocksize(templ
->format
);
1227 info
.struct_size
= info
.format_size
;
1228 info
.readonly
= true;
1229 info
.offset
= templ
->u
.buf
.first_element
* info
.struct_size
;
1230 info
.size
= (templ
->u
.buf
.last_element
-
1231 templ
->u
.buf
.first_element
+ 1) * info
.struct_size
;
1233 ilo_state_surface_init_for_buffer(&view
->surface
, dev
, &info
);
1234 view
->surface
.bo
= info
.buf
->bo
;
1236 struct ilo_texture
*tex
= ilo_texture(res
);
1237 struct ilo_state_surface_image_info info
;
1239 /* warn about degraded performance because of a missing binding flag */
1240 if (tex
->image
.tiling
== GEN6_TILING_NONE
&&
1241 !(tex
->base
.bind
& PIPE_BIND_SAMPLER_VIEW
)) {
1242 ilo_warn("creating sampler view for a resource "
1243 "not created for sampling\n");
1246 memset(&info
, 0, sizeof(info
));
1247 info
.img
= &tex
->image
;
1249 info
.access
= ILO_STATE_SURFACE_ACCESS_SAMPLER
;
1251 if (templ
->format
== PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
&&
1252 tex
->image
.separate_stencil
) {
1253 info
.format
= ilo_format_translate_texture(dev
,
1254 PIPE_FORMAT_Z32_FLOAT
);
1256 info
.format
= ilo_format_translate_texture(dev
, templ
->format
);
1259 info
.is_cube_map
= (tex
->image
.target
== PIPE_TEXTURE_CUBE
||
1260 tex
->image
.target
== PIPE_TEXTURE_CUBE_ARRAY
);
1261 info
.is_array
= util_resource_is_array_texture(&tex
->base
);
1262 info
.readonly
= true;
1264 info
.level_base
= templ
->u
.tex
.first_level
;
1265 info
.level_count
= templ
->u
.tex
.last_level
-
1266 templ
->u
.tex
.first_level
+ 1;
1267 info
.slice_base
= templ
->u
.tex
.first_layer
;
1268 info
.slice_count
= templ
->u
.tex
.last_layer
-
1269 templ
->u
.tex
.first_layer
+ 1;
1271 ilo_state_surface_init_for_image(&view
->surface
, dev
, &info
);
1272 view
->surface
.bo
= info
.img
->bo
;
1279 ilo_sampler_view_destroy(struct pipe_context
*pipe
,
1280 struct pipe_sampler_view
*view
)
1282 pipe_resource_reference(&view
->texture
, NULL
);
1286 static struct pipe_surface
*
1287 ilo_create_surface(struct pipe_context
*pipe
,
1288 struct pipe_resource
*res
,
1289 const struct pipe_surface
*templ
)
1291 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1292 struct ilo_texture
*tex
= ilo_texture(res
);
1293 struct ilo_surface_cso
*surf
;
1295 surf
= CALLOC_STRUCT(ilo_surface_cso
);
1298 surf
->base
= *templ
;
1299 pipe_reference_init(&surf
->base
.reference
, 1);
1300 surf
->base
.texture
= NULL
;
1301 pipe_resource_reference(&surf
->base
.texture
, &tex
->base
);
1303 surf
->base
.context
= pipe
;
1304 surf
->base
.width
= u_minify(tex
->base
.width0
, templ
->u
.tex
.level
);
1305 surf
->base
.height
= u_minify(tex
->base
.height0
, templ
->u
.tex
.level
);
1307 surf
->is_rt
= !util_format_is_depth_or_stencil(templ
->format
);
1310 struct ilo_state_surface_image_info info
;
1313 assert(tex
->base
.target
!= PIPE_BUFFER
);
1315 memset(&info
, 0, sizeof(info
));
1316 info
.img
= &tex
->image
;
1317 info
.access
= ILO_STATE_SURFACE_ACCESS_DP_RENDER
;
1318 info
.format
= ilo_format_translate_render(dev
, templ
->format
);
1319 info
.is_array
= util_resource_is_array_texture(&tex
->base
);
1320 info
.level_base
= templ
->u
.tex
.level
;
1321 info
.level_count
= 1;
1322 info
.slice_base
= templ
->u
.tex
.first_layer
;
1323 info
.slice_count
= templ
->u
.tex
.last_layer
-
1324 templ
->u
.tex
.first_layer
+ 1;
1326 ilo_state_surface_init_for_image(&surf
->u
.rt
, dev
, &info
);
1327 surf
->u
.rt
.bo
= info
.img
->bo
;
1329 struct ilo_state_zs_info info
;
1331 assert(res
->target
!= PIPE_BUFFER
);
1333 memset(&info
, 0, sizeof(info
));
1335 if (templ
->format
== PIPE_FORMAT_S8_UINT
) {
1336 info
.s_img
= &tex
->image
;
1338 info
.z_img
= &tex
->image
;
1339 info
.s_img
= (tex
->separate_s8
) ? &tex
->separate_s8
->image
: NULL
;
1342 ilo_image_can_enable_aux(&tex
->image
, templ
->u
.tex
.level
);
1345 info
.level
= templ
->u
.tex
.level
;
1346 info
.slice_base
= templ
->u
.tex
.first_layer
;
1347 info
.slice_count
= templ
->u
.tex
.last_layer
-
1348 templ
->u
.tex
.first_layer
+ 1;
1350 ilo_state_zs_init(&surf
->u
.zs
, dev
, &info
);
1353 surf
->u
.zs
.depth_bo
= info
.z_img
->bo
;
1354 if (info
.hiz_enable
)
1355 surf
->u
.zs
.hiz_bo
= info
.z_img
->aux
.bo
;
1359 surf
->u
.zs
.stencil_bo
= info
.s_img
->bo
;
1366 ilo_surface_destroy(struct pipe_context
*pipe
,
1367 struct pipe_surface
*surface
)
1369 pipe_resource_reference(&surface
->texture
, NULL
);
1374 ilo_create_compute_state(struct pipe_context
*pipe
,
1375 const struct pipe_compute_state
*state
)
1377 struct ilo_context
*ilo
= ilo_context(pipe
);
1378 struct ilo_shader_state
*shader
;
1380 shader
= ilo_shader_create_cs(ilo
->dev
, state
, &ilo
->state_vector
);
1383 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1389 ilo_bind_compute_state(struct pipe_context
*pipe
, void *state
)
1391 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1395 vec
->dirty
|= ILO_DIRTY_CS
;
1399 ilo_delete_compute_state(struct pipe_context
*pipe
, void *state
)
1401 struct ilo_context
*ilo
= ilo_context(pipe
);
1402 struct ilo_shader_state
*cs
= (struct ilo_shader_state
*) state
;
1404 ilo_shader_cache_remove(ilo
->shader_cache
, cs
);
1405 ilo_shader_destroy(cs
);
1409 ilo_set_compute_resources(struct pipe_context
*pipe
,
1410 unsigned start
, unsigned count
,
1411 struct pipe_surface
**surfaces
)
1413 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1414 struct ilo_resource_state
*dst
= &vec
->cs_resource
;
1417 assert(start
+ count
<= Elements(dst
->states
));
1420 for (i
= 0; i
< count
; i
++)
1421 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
1424 for (i
= 0; i
< count
; i
++)
1425 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
1428 if (dst
->count
<= start
+ count
) {
1434 while (count
> 0 && !dst
->states
[count
- 1])
1440 vec
->dirty
|= ILO_DIRTY_CS_RESOURCE
;
1444 ilo_set_global_binding(struct pipe_context
*pipe
,
1445 unsigned start
, unsigned count
,
1446 struct pipe_resource
**resources
,
1449 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1450 struct ilo_global_binding_cso
*dst
;
1454 if (vec
->global_binding
.count
< start
+ count
) {
1456 const unsigned old_size
= vec
->global_binding
.bindings
.size
;
1457 const unsigned new_size
= sizeof(*dst
) * (start
+ count
);
1459 if (old_size
< new_size
) {
1460 util_dynarray_resize(&vec
->global_binding
.bindings
, new_size
);
1461 memset(vec
->global_binding
.bindings
.data
+ old_size
, 0,
1462 new_size
- old_size
);
1465 count
= vec
->global_binding
.count
- start
;
1469 dst
= util_dynarray_element(&vec
->global_binding
.bindings
,
1470 struct ilo_global_binding_cso
, start
);
1473 for (i
= 0; i
< count
; i
++) {
1474 pipe_resource_reference(&dst
[i
].resource
, resources
[i
]);
1475 dst
[i
].handle
= handles
[i
];
1478 for (i
= 0; i
< count
; i
++) {
1479 pipe_resource_reference(&dst
[i
].resource
, NULL
);
1480 dst
[i
].handle
= NULL
;
1484 if (vec
->global_binding
.count
<= start
+ count
) {
1485 dst
= util_dynarray_begin(&vec
->global_binding
.bindings
);
1492 while (count
> 0 && !dst
[count
- 1].resource
)
1495 vec
->global_binding
.count
= count
;
1498 vec
->dirty
|= ILO_DIRTY_GLOBAL_BINDING
;
1502 * Initialize state-related functions.
1505 ilo_init_state_functions(struct ilo_context
*ilo
)
1507 STATIC_ASSERT(ILO_STATE_COUNT
<= 32);
1509 ilo
->base
.create_blend_state
= ilo_create_blend_state
;
1510 ilo
->base
.bind_blend_state
= ilo_bind_blend_state
;
1511 ilo
->base
.delete_blend_state
= ilo_delete_blend_state
;
1512 ilo
->base
.create_sampler_state
= ilo_create_sampler_state
;
1513 ilo
->base
.bind_sampler_states
= ilo_bind_sampler_states
;
1514 ilo
->base
.delete_sampler_state
= ilo_delete_sampler_state
;
1515 ilo
->base
.create_rasterizer_state
= ilo_create_rasterizer_state
;
1516 ilo
->base
.bind_rasterizer_state
= ilo_bind_rasterizer_state
;
1517 ilo
->base
.delete_rasterizer_state
= ilo_delete_rasterizer_state
;
1518 ilo
->base
.create_depth_stencil_alpha_state
= ilo_create_depth_stencil_alpha_state
;
1519 ilo
->base
.bind_depth_stencil_alpha_state
= ilo_bind_depth_stencil_alpha_state
;
1520 ilo
->base
.delete_depth_stencil_alpha_state
= ilo_delete_depth_stencil_alpha_state
;
1521 ilo
->base
.create_fs_state
= ilo_create_fs_state
;
1522 ilo
->base
.bind_fs_state
= ilo_bind_fs_state
;
1523 ilo
->base
.delete_fs_state
= ilo_delete_fs_state
;
1524 ilo
->base
.create_vs_state
= ilo_create_vs_state
;
1525 ilo
->base
.bind_vs_state
= ilo_bind_vs_state
;
1526 ilo
->base
.delete_vs_state
= ilo_delete_vs_state
;
1527 ilo
->base
.create_gs_state
= ilo_create_gs_state
;
1528 ilo
->base
.bind_gs_state
= ilo_bind_gs_state
;
1529 ilo
->base
.delete_gs_state
= ilo_delete_gs_state
;
1530 ilo
->base
.create_vertex_elements_state
= ilo_create_vertex_elements_state
;
1531 ilo
->base
.bind_vertex_elements_state
= ilo_bind_vertex_elements_state
;
1532 ilo
->base
.delete_vertex_elements_state
= ilo_delete_vertex_elements_state
;
1534 ilo
->base
.set_blend_color
= ilo_set_blend_color
;
1535 ilo
->base
.set_stencil_ref
= ilo_set_stencil_ref
;
1536 ilo
->base
.set_sample_mask
= ilo_set_sample_mask
;
1537 ilo
->base
.set_clip_state
= ilo_set_clip_state
;
1538 ilo
->base
.set_constant_buffer
= ilo_set_constant_buffer
;
1539 ilo
->base
.set_framebuffer_state
= ilo_set_framebuffer_state
;
1540 ilo
->base
.set_polygon_stipple
= ilo_set_polygon_stipple
;
1541 ilo
->base
.set_scissor_states
= ilo_set_scissor_states
;
1542 ilo
->base
.set_viewport_states
= ilo_set_viewport_states
;
1543 ilo
->base
.set_sampler_views
= ilo_set_sampler_views
;
1544 ilo
->base
.set_shader_resources
= ilo_set_shader_resources
;
1545 ilo
->base
.set_vertex_buffers
= ilo_set_vertex_buffers
;
1546 ilo
->base
.set_index_buffer
= ilo_set_index_buffer
;
1548 ilo
->base
.create_stream_output_target
= ilo_create_stream_output_target
;
1549 ilo
->base
.stream_output_target_destroy
= ilo_stream_output_target_destroy
;
1550 ilo
->base
.set_stream_output_targets
= ilo_set_stream_output_targets
;
1552 ilo
->base
.create_sampler_view
= ilo_create_sampler_view
;
1553 ilo
->base
.sampler_view_destroy
= ilo_sampler_view_destroy
;
1555 ilo
->base
.create_surface
= ilo_create_surface
;
1556 ilo
->base
.surface_destroy
= ilo_surface_destroy
;
1558 ilo
->base
.create_compute_state
= ilo_create_compute_state
;
1559 ilo
->base
.bind_compute_state
= ilo_bind_compute_state
;
1560 ilo
->base
.delete_compute_state
= ilo_delete_compute_state
;
1561 ilo
->base
.set_compute_resources
= ilo_set_compute_resources
;
1562 ilo
->base
.set_global_binding
= ilo_set_global_binding
;
1566 ilo_state_vector_init(const struct ilo_dev
*dev
,
1567 struct ilo_state_vector
*vec
)
1569 ilo_state_viewport_init_data_only(&vec
->viewport
.vp
, dev
,
1570 vec
->viewport
.vp_data
, sizeof(vec
->viewport
.vp_data
));
1571 assert(vec
->viewport
.vp
.array_size
>= ILO_MAX_VIEWPORTS
);
1573 vec
->viewport
.params
.matrices
= vec
->viewport
.matrices
;
1574 vec
->viewport
.params
.scissors
= vec
->viewport
.scissors
;
1576 ilo_state_surface_init_for_null(&vec
->fb
.null_rt
, dev
);
1577 ilo_state_zs_init_for_null(&vec
->fb
.null_zs
, dev
);
1579 ilo_state_sampler_init_disabled(&vec
->disabled_sampler
, dev
);
1581 util_dynarray_init(&vec
->global_binding
.bindings
);
1583 vec
->dirty
= ILO_DIRTY_ALL
;
1587 ilo_state_vector_cleanup(struct ilo_state_vector
*vec
)
1591 for (i
= 0; i
< Elements(vec
->vb
.states
); i
++) {
1592 if (vec
->vb
.enabled_mask
& (1 << i
))
1593 pipe_resource_reference(&vec
->vb
.states
[i
].buffer
, NULL
);
1596 pipe_resource_reference(&vec
->ib
.buffer
, NULL
);
1597 pipe_resource_reference(&vec
->ib
.hw_resource
, NULL
);
1599 for (i
= 0; i
< vec
->so
.count
; i
++)
1600 pipe_so_target_reference(&vec
->so
.states
[i
], NULL
);
1602 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
1603 for (i
= 0; i
< vec
->view
[sh
].count
; i
++) {
1604 struct pipe_sampler_view
*view
= vec
->view
[sh
].states
[i
];
1605 pipe_sampler_view_reference(&view
, NULL
);
1608 for (i
= 0; i
< Elements(vec
->cbuf
[sh
].cso
); i
++) {
1609 struct ilo_cbuf_cso
*cbuf
= &vec
->cbuf
[sh
].cso
[i
];
1610 pipe_resource_reference(&cbuf
->resource
, NULL
);
1614 for (i
= 0; i
< vec
->resource
.count
; i
++)
1615 pipe_surface_reference(&vec
->resource
.states
[i
], NULL
);
1617 for (i
= 0; i
< vec
->fb
.state
.nr_cbufs
; i
++)
1618 pipe_surface_reference(&vec
->fb
.state
.cbufs
[i
], NULL
);
1620 if (vec
->fb
.state
.zsbuf
)
1621 pipe_surface_reference(&vec
->fb
.state
.zsbuf
, NULL
);
1623 for (i
= 0; i
< vec
->cs_resource
.count
; i
++)
1624 pipe_surface_reference(&vec
->cs_resource
.states
[i
], NULL
);
1626 for (i
= 0; i
< vec
->global_binding
.count
; i
++) {
1627 struct ilo_global_binding_cso
*cso
=
1628 util_dynarray_element(&vec
->global_binding
.bindings
,
1629 struct ilo_global_binding_cso
, i
);
1630 pipe_resource_reference(&cso
->resource
, NULL
);
1633 util_dynarray_fini(&vec
->global_binding
.bindings
);
1637 * Mark all states that have the resource dirty.
1640 ilo_state_vector_resource_renamed(struct ilo_state_vector
*vec
,
1641 struct pipe_resource
*res
)
1643 struct intel_bo
*bo
= ilo_resource_get_bo(res
);
1644 uint32_t states
= 0;
1647 if (res
->target
== PIPE_BUFFER
) {
1648 uint32_t vb_mask
= vec
->vb
.enabled_mask
;
1651 const unsigned idx
= u_bit_scan(&vb_mask
);
1653 if (vec
->vb
.states
[idx
].buffer
== res
) {
1654 states
|= ILO_DIRTY_VB
;
1659 if (vec
->ib
.buffer
== res
) {
1660 states
|= ILO_DIRTY_IB
;
1663 * finalize_index_buffer() has an optimization that clears
1664 * ILO_DIRTY_IB when the HW states do not change. However, it fails
1665 * to flush the VF cache when the HW states do not change, but the
1666 * contents of the IB has changed. Here, we set the index size to an
1667 * invalid value to avoid the optimization.
1669 vec
->ib
.hw_index_size
= 0;
1672 for (i
= 0; i
< vec
->so
.count
; i
++) {
1673 if (vec
->so
.states
[i
]->buffer
== res
) {
1674 states
|= ILO_DIRTY_SO
;
1680 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
1681 for (i
= 0; i
< vec
->view
[sh
].count
; i
++) {
1682 struct ilo_view_cso
*cso
= (struct ilo_view_cso
*) vec
->view
[sh
].states
[i
];
1684 if (cso
->base
.texture
== res
) {
1685 static const unsigned view_dirty_bits
[PIPE_SHADER_TYPES
] = {
1686 [PIPE_SHADER_VERTEX
] = ILO_DIRTY_VIEW_VS
,
1687 [PIPE_SHADER_FRAGMENT
] = ILO_DIRTY_VIEW_FS
,
1688 [PIPE_SHADER_GEOMETRY
] = ILO_DIRTY_VIEW_GS
,
1689 [PIPE_SHADER_COMPUTE
] = ILO_DIRTY_VIEW_CS
,
1691 cso
->surface
.bo
= bo
;
1693 states
|= view_dirty_bits
[sh
];
1698 if (res
->target
== PIPE_BUFFER
) {
1699 for (i
= 0; i
< Elements(vec
->cbuf
[sh
].cso
); i
++) {
1700 struct ilo_cbuf_cso
*cbuf
= &vec
->cbuf
[sh
].cso
[i
];
1702 if (cbuf
->resource
== res
) {
1703 cbuf
->surface
.bo
= bo
;
1704 states
|= ILO_DIRTY_CBUF
;
1711 for (i
= 0; i
< vec
->resource
.count
; i
++) {
1712 struct ilo_surface_cso
*cso
=
1713 (struct ilo_surface_cso
*) vec
->resource
.states
[i
];
1715 if (cso
->base
.texture
== res
) {
1717 states
|= ILO_DIRTY_RESOURCE
;
1723 if (res
->target
!= PIPE_BUFFER
) {
1724 for (i
= 0; i
< vec
->fb
.state
.nr_cbufs
; i
++) {
1725 struct ilo_surface_cso
*cso
=
1726 (struct ilo_surface_cso
*) vec
->fb
.state
.cbufs
[i
];
1727 if (cso
&& cso
->base
.texture
== res
) {
1729 states
|= ILO_DIRTY_FB
;
1734 if (vec
->fb
.state
.zsbuf
&& vec
->fb
.state
.zsbuf
->texture
== res
) {
1735 struct ilo_surface_cso
*cso
=
1736 (struct ilo_surface_cso
*) vec
->fb
.state
.zsbuf
;
1738 cso
->u
.zs
.depth_bo
= bo
;
1740 states
|= ILO_DIRTY_FB
;
1744 for (i
= 0; i
< vec
->cs_resource
.count
; i
++) {
1745 struct ilo_surface_cso
*cso
=
1746 (struct ilo_surface_cso
*) vec
->cs_resource
.states
[i
];
1747 if (cso
->base
.texture
== res
) {
1749 states
|= ILO_DIRTY_CS_RESOURCE
;
1754 for (i
= 0; i
< vec
->global_binding
.count
; i
++) {
1755 struct ilo_global_binding_cso
*cso
=
1756 util_dynarray_element(&vec
->global_binding
.bindings
,
1757 struct ilo_global_binding_cso
, i
);
1759 if (cso
->resource
== res
) {
1760 states
|= ILO_DIRTY_GLOBAL_BINDING
;
1765 vec
->dirty
|= states
;
1769 ilo_state_vector_dump_dirty(const struct ilo_state_vector
*vec
)
1771 static const char *state_names
[ILO_STATE_COUNT
] = {
1772 [ILO_STATE_VB
] = "VB",
1773 [ILO_STATE_VE
] = "VE",
1774 [ILO_STATE_IB
] = "IB",
1775 [ILO_STATE_VS
] = "VS",
1776 [ILO_STATE_GS
] = "GS",
1777 [ILO_STATE_SO
] = "SO",
1778 [ILO_STATE_CLIP
] = "CLIP",
1779 [ILO_STATE_VIEWPORT
] = "VIEWPORT",
1780 [ILO_STATE_SCISSOR
] = "SCISSOR",
1781 [ILO_STATE_RASTERIZER
] = "RASTERIZER",
1782 [ILO_STATE_POLY_STIPPLE
] = "POLY_STIPPLE",
1783 [ILO_STATE_SAMPLE_MASK
] = "SAMPLE_MASK",
1784 [ILO_STATE_FS
] = "FS",
1785 [ILO_STATE_DSA
] = "DSA",
1786 [ILO_STATE_STENCIL_REF
] = "STENCIL_REF",
1787 [ILO_STATE_BLEND
] = "BLEND",
1788 [ILO_STATE_BLEND_COLOR
] = "BLEND_COLOR",
1789 [ILO_STATE_FB
] = "FB",
1790 [ILO_STATE_SAMPLER_VS
] = "SAMPLER_VS",
1791 [ILO_STATE_SAMPLER_GS
] = "SAMPLER_GS",
1792 [ILO_STATE_SAMPLER_FS
] = "SAMPLER_FS",
1793 [ILO_STATE_SAMPLER_CS
] = "SAMPLER_CS",
1794 [ILO_STATE_VIEW_VS
] = "VIEW_VS",
1795 [ILO_STATE_VIEW_GS
] = "VIEW_GS",
1796 [ILO_STATE_VIEW_FS
] = "VIEW_FS",
1797 [ILO_STATE_VIEW_CS
] = "VIEW_CS",
1798 [ILO_STATE_CBUF
] = "CBUF",
1799 [ILO_STATE_RESOURCE
] = "RESOURCE",
1800 [ILO_STATE_CS
] = "CS",
1801 [ILO_STATE_CS_RESOURCE
] = "CS_RESOURCE",
1802 [ILO_STATE_GLOBAL_BINDING
] = "GLOBAL_BINDING",
1804 uint32_t dirty
= vec
->dirty
;
1807 ilo_printf("no state is dirty\n");
1811 dirty
&= (1U << ILO_STATE_COUNT
) - 1;
1813 ilo_printf("%2d states are dirty:", util_bitcount(dirty
));
1815 const enum ilo_state state
= u_bit_scan(&dirty
);
1816 ilo_printf(" %s", state_names
[state
]);