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 "util/u_dual_blend.h"
29 #include "util/u_dynarray.h"
30 #include "util/u_framebuffer.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_format.h"
37 #include "ilo_resource.h"
38 #include "ilo_shader.h"
39 #include "ilo_state.h"
42 * Translate a pipe primitive type to the matching hardware primitive type.
44 static enum gen_3dprim_type
45 ilo_translate_draw_mode(unsigned mode
)
47 static const enum gen_3dprim_type prim_mapping
[PIPE_PRIM_MAX
] = {
48 [PIPE_PRIM_POINTS
] = GEN6_3DPRIM_POINTLIST
,
49 [PIPE_PRIM_LINES
] = GEN6_3DPRIM_LINELIST
,
50 [PIPE_PRIM_LINE_LOOP
] = GEN6_3DPRIM_LINELOOP
,
51 [PIPE_PRIM_LINE_STRIP
] = GEN6_3DPRIM_LINESTRIP
,
52 [PIPE_PRIM_TRIANGLES
] = GEN6_3DPRIM_TRILIST
,
53 [PIPE_PRIM_TRIANGLE_STRIP
] = GEN6_3DPRIM_TRISTRIP
,
54 [PIPE_PRIM_TRIANGLE_FAN
] = GEN6_3DPRIM_TRIFAN
,
55 [PIPE_PRIM_QUADS
] = GEN6_3DPRIM_QUADLIST
,
56 [PIPE_PRIM_QUAD_STRIP
] = GEN6_3DPRIM_QUADSTRIP
,
57 [PIPE_PRIM_POLYGON
] = GEN6_3DPRIM_POLYGON
,
58 [PIPE_PRIM_LINES_ADJACENCY
] = GEN6_3DPRIM_LINELIST_ADJ
,
59 [PIPE_PRIM_LINE_STRIP_ADJACENCY
] = GEN6_3DPRIM_LINESTRIP_ADJ
,
60 [PIPE_PRIM_TRIANGLES_ADJACENCY
] = GEN6_3DPRIM_TRILIST_ADJ
,
61 [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY
] = GEN6_3DPRIM_TRISTRIP_ADJ
,
64 assert(prim_mapping
[mode
]);
66 return prim_mapping
[mode
];
69 static enum gen_index_format
70 ilo_translate_index_size(unsigned index_size
)
73 case 1: return GEN6_INDEX_BYTE
;
74 case 2: return GEN6_INDEX_WORD
;
75 case 4: return GEN6_INDEX_DWORD
;
77 assert(!"unknown index size");
78 return GEN6_INDEX_BYTE
;
82 static enum gen_mip_filter
83 ilo_translate_mip_filter(unsigned filter
)
86 case PIPE_TEX_MIPFILTER_NEAREST
: return GEN6_MIPFILTER_NEAREST
;
87 case PIPE_TEX_MIPFILTER_LINEAR
: return GEN6_MIPFILTER_LINEAR
;
88 case PIPE_TEX_MIPFILTER_NONE
: return GEN6_MIPFILTER_NONE
;
90 assert(!"unknown mipfilter");
91 return GEN6_MIPFILTER_NONE
;
96 ilo_translate_img_filter(unsigned filter
)
99 case PIPE_TEX_FILTER_NEAREST
: return GEN6_MAPFILTER_NEAREST
;
100 case PIPE_TEX_FILTER_LINEAR
: return GEN6_MAPFILTER_LINEAR
;
102 assert(!"unknown sampler filter");
103 return GEN6_MAPFILTER_NEAREST
;
107 static enum gen_texcoord_mode
108 ilo_translate_address_wrap(unsigned wrap
)
111 case PIPE_TEX_WRAP_CLAMP
: return GEN8_TEXCOORDMODE_HALF_BORDER
;
112 case PIPE_TEX_WRAP_REPEAT
: return GEN6_TEXCOORDMODE_WRAP
;
113 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
: return GEN6_TEXCOORDMODE_CLAMP
;
114 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
: return GEN6_TEXCOORDMODE_CLAMP_BORDER
;
115 case PIPE_TEX_WRAP_MIRROR_REPEAT
: return GEN6_TEXCOORDMODE_MIRROR
;
116 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
117 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
118 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
120 assert(!"unknown sampler wrap mode");
121 return GEN6_TEXCOORDMODE_WRAP
;
125 static enum gen_aniso_ratio
126 ilo_translate_max_anisotropy(unsigned max_anisotropy
)
128 switch (max_anisotropy
) {
129 case 0: case 1: case 2: return GEN6_ANISORATIO_2
;
130 case 3: case 4: return GEN6_ANISORATIO_4
;
131 case 5: case 6: return GEN6_ANISORATIO_6
;
132 case 7: case 8: return GEN6_ANISORATIO_8
;
133 case 9: case 10: return GEN6_ANISORATIO_10
;
134 case 11: case 12: return GEN6_ANISORATIO_12
;
135 case 13: case 14: return GEN6_ANISORATIO_14
;
136 default: return GEN6_ANISORATIO_16
;
140 static enum gen_prefilter_op
141 ilo_translate_shadow_func(unsigned func
)
144 * For PIPE_FUNC_x, the reference value is on the left-hand side of the
145 * comparison, and 1.0 is returned when the comparison is true.
147 * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
148 * the comparison, and 0.0 is returned when the comparison is true.
151 case PIPE_FUNC_NEVER
: return GEN6_PREFILTEROP_ALWAYS
;
152 case PIPE_FUNC_LESS
: return GEN6_PREFILTEROP_LEQUAL
;
153 case PIPE_FUNC_EQUAL
: return GEN6_PREFILTEROP_NOTEQUAL
;
154 case PIPE_FUNC_LEQUAL
: return GEN6_PREFILTEROP_LESS
;
155 case PIPE_FUNC_GREATER
: return GEN6_PREFILTEROP_GEQUAL
;
156 case PIPE_FUNC_NOTEQUAL
: return GEN6_PREFILTEROP_EQUAL
;
157 case PIPE_FUNC_GEQUAL
: return GEN6_PREFILTEROP_GREATER
;
158 case PIPE_FUNC_ALWAYS
: return GEN6_PREFILTEROP_NEVER
;
160 assert(!"unknown shadow compare function");
161 return GEN6_PREFILTEROP_NEVER
;
165 static enum gen_front_winding
166 ilo_translate_front_ccw(unsigned front_ccw
)
168 return (front_ccw
) ? GEN6_FRONTWINDING_CCW
: GEN6_FRONTWINDING_CW
;
171 static enum gen_cull_mode
172 ilo_translate_cull_face(unsigned cull_face
)
175 case PIPE_FACE_NONE
: return GEN6_CULLMODE_NONE
;
176 case PIPE_FACE_FRONT
: return GEN6_CULLMODE_FRONT
;
177 case PIPE_FACE_BACK
: return GEN6_CULLMODE_BACK
;
178 case PIPE_FACE_FRONT_AND_BACK
: return GEN6_CULLMODE_BOTH
;
180 assert(!"unknown face culling");
181 return GEN6_CULLMODE_NONE
;
185 static enum gen_fill_mode
186 ilo_translate_poly_mode(unsigned poly_mode
)
189 case PIPE_POLYGON_MODE_FILL
: return GEN6_FILLMODE_SOLID
;
190 case PIPE_POLYGON_MODE_LINE
: return GEN6_FILLMODE_WIREFRAME
;
191 case PIPE_POLYGON_MODE_POINT
: return GEN6_FILLMODE_POINT
;
193 assert(!"unknown polygon mode");
194 return GEN6_FILLMODE_SOLID
;
198 static enum gen_pixel_location
199 ilo_translate_half_pixel_center(bool half_pixel_center
)
201 return (half_pixel_center
) ? GEN6_PIXLOC_CENTER
: GEN6_PIXLOC_UL_CORNER
;
204 static enum gen_compare_function
205 ilo_translate_compare_func(unsigned func
)
208 case PIPE_FUNC_NEVER
: return GEN6_COMPAREFUNCTION_NEVER
;
209 case PIPE_FUNC_LESS
: return GEN6_COMPAREFUNCTION_LESS
;
210 case PIPE_FUNC_EQUAL
: return GEN6_COMPAREFUNCTION_EQUAL
;
211 case PIPE_FUNC_LEQUAL
: return GEN6_COMPAREFUNCTION_LEQUAL
;
212 case PIPE_FUNC_GREATER
: return GEN6_COMPAREFUNCTION_GREATER
;
213 case PIPE_FUNC_NOTEQUAL
: return GEN6_COMPAREFUNCTION_NOTEQUAL
;
214 case PIPE_FUNC_GEQUAL
: return GEN6_COMPAREFUNCTION_GEQUAL
;
215 case PIPE_FUNC_ALWAYS
: return GEN6_COMPAREFUNCTION_ALWAYS
;
217 assert(!"unknown compare function");
218 return GEN6_COMPAREFUNCTION_NEVER
;
222 static enum gen_stencil_op
223 ilo_translate_stencil_op(unsigned stencil_op
)
225 switch (stencil_op
) {
226 case PIPE_STENCIL_OP_KEEP
: return GEN6_STENCILOP_KEEP
;
227 case PIPE_STENCIL_OP_ZERO
: return GEN6_STENCILOP_ZERO
;
228 case PIPE_STENCIL_OP_REPLACE
: return GEN6_STENCILOP_REPLACE
;
229 case PIPE_STENCIL_OP_INCR
: return GEN6_STENCILOP_INCRSAT
;
230 case PIPE_STENCIL_OP_DECR
: return GEN6_STENCILOP_DECRSAT
;
231 case PIPE_STENCIL_OP_INCR_WRAP
: return GEN6_STENCILOP_INCR
;
232 case PIPE_STENCIL_OP_DECR_WRAP
: return GEN6_STENCILOP_DECR
;
233 case PIPE_STENCIL_OP_INVERT
: return GEN6_STENCILOP_INVERT
;
235 assert(!"unknown stencil op");
236 return GEN6_STENCILOP_KEEP
;
240 static enum gen_logic_op
241 ilo_translate_logicop(unsigned logicop
)
244 case PIPE_LOGICOP_CLEAR
: return GEN6_LOGICOP_CLEAR
;
245 case PIPE_LOGICOP_NOR
: return GEN6_LOGICOP_NOR
;
246 case PIPE_LOGICOP_AND_INVERTED
: return GEN6_LOGICOP_AND_INVERTED
;
247 case PIPE_LOGICOP_COPY_INVERTED
: return GEN6_LOGICOP_COPY_INVERTED
;
248 case PIPE_LOGICOP_AND_REVERSE
: return GEN6_LOGICOP_AND_REVERSE
;
249 case PIPE_LOGICOP_INVERT
: return GEN6_LOGICOP_INVERT
;
250 case PIPE_LOGICOP_XOR
: return GEN6_LOGICOP_XOR
;
251 case PIPE_LOGICOP_NAND
: return GEN6_LOGICOP_NAND
;
252 case PIPE_LOGICOP_AND
: return GEN6_LOGICOP_AND
;
253 case PIPE_LOGICOP_EQUIV
: return GEN6_LOGICOP_EQUIV
;
254 case PIPE_LOGICOP_NOOP
: return GEN6_LOGICOP_NOOP
;
255 case PIPE_LOGICOP_OR_INVERTED
: return GEN6_LOGICOP_OR_INVERTED
;
256 case PIPE_LOGICOP_COPY
: return GEN6_LOGICOP_COPY
;
257 case PIPE_LOGICOP_OR_REVERSE
: return GEN6_LOGICOP_OR_REVERSE
;
258 case PIPE_LOGICOP_OR
: return GEN6_LOGICOP_OR
;
259 case PIPE_LOGICOP_SET
: return GEN6_LOGICOP_SET
;
261 assert(!"unknown logicop function");
262 return GEN6_LOGICOP_CLEAR
;
267 ilo_translate_blend_func(unsigned blend
)
270 case PIPE_BLEND_ADD
: return GEN6_BLENDFUNCTION_ADD
;
271 case PIPE_BLEND_SUBTRACT
: return GEN6_BLENDFUNCTION_SUBTRACT
;
272 case PIPE_BLEND_REVERSE_SUBTRACT
: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT
;
273 case PIPE_BLEND_MIN
: return GEN6_BLENDFUNCTION_MIN
;
274 case PIPE_BLEND_MAX
: return GEN6_BLENDFUNCTION_MAX
;
276 assert(!"unknown blend function");
277 return GEN6_BLENDFUNCTION_ADD
;
282 ilo_translate_blend_factor(unsigned factor
)
285 case PIPE_BLENDFACTOR_ONE
: return GEN6_BLENDFACTOR_ONE
;
286 case PIPE_BLENDFACTOR_SRC_COLOR
: return GEN6_BLENDFACTOR_SRC_COLOR
;
287 case PIPE_BLENDFACTOR_SRC_ALPHA
: return GEN6_BLENDFACTOR_SRC_ALPHA
;
288 case PIPE_BLENDFACTOR_DST_ALPHA
: return GEN6_BLENDFACTOR_DST_ALPHA
;
289 case PIPE_BLENDFACTOR_DST_COLOR
: return GEN6_BLENDFACTOR_DST_COLOR
;
290 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE
;
291 case PIPE_BLENDFACTOR_CONST_COLOR
: return GEN6_BLENDFACTOR_CONST_COLOR
;
292 case PIPE_BLENDFACTOR_CONST_ALPHA
: return GEN6_BLENDFACTOR_CONST_ALPHA
;
293 case PIPE_BLENDFACTOR_SRC1_COLOR
: return GEN6_BLENDFACTOR_SRC1_COLOR
;
294 case PIPE_BLENDFACTOR_SRC1_ALPHA
: return GEN6_BLENDFACTOR_SRC1_ALPHA
;
295 case PIPE_BLENDFACTOR_ZERO
: return GEN6_BLENDFACTOR_ZERO
;
296 case PIPE_BLENDFACTOR_INV_SRC_COLOR
: return GEN6_BLENDFACTOR_INV_SRC_COLOR
;
297 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
: return GEN6_BLENDFACTOR_INV_SRC_ALPHA
;
298 case PIPE_BLENDFACTOR_INV_DST_ALPHA
: return GEN6_BLENDFACTOR_INV_DST_ALPHA
;
299 case PIPE_BLENDFACTOR_INV_DST_COLOR
: return GEN6_BLENDFACTOR_INV_DST_COLOR
;
300 case PIPE_BLENDFACTOR_INV_CONST_COLOR
: return GEN6_BLENDFACTOR_INV_CONST_COLOR
;
301 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
: return GEN6_BLENDFACTOR_INV_CONST_ALPHA
;
302 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
: return GEN6_BLENDFACTOR_INV_SRC1_COLOR
;
303 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA
;
305 assert(!"unknown blend factor");
306 return GEN6_BLENDFACTOR_ONE
;
311 finalize_shader_states(struct ilo_state_vector
*vec
)
315 for (type
= 0; type
< PIPE_SHADER_TYPES
; type
++) {
316 struct ilo_shader_state
*shader
;
320 case PIPE_SHADER_VERTEX
:
322 state
= ILO_DIRTY_VS
;
324 case PIPE_SHADER_GEOMETRY
:
326 state
= ILO_DIRTY_GS
;
328 case PIPE_SHADER_FRAGMENT
:
330 state
= ILO_DIRTY_FS
;
341 /* compile if the shader or the states it depends on changed */
342 if (vec
->dirty
& state
) {
343 ilo_shader_select_kernel(shader
, vec
, ILO_DIRTY_ALL
);
345 else if (ilo_shader_select_kernel(shader
, vec
, vec
->dirty
)) {
346 /* mark the state dirty if a new kernel is selected */
350 /* need to setup SBE for FS */
351 if (type
== PIPE_SHADER_FRAGMENT
&& vec
->dirty
&
352 (state
| ILO_DIRTY_GS
| ILO_DIRTY_VS
| ILO_DIRTY_RASTERIZER
)) {
353 if (ilo_shader_select_kernel_sbe(shader
,
354 (vec
->gs
) ? vec
->gs
: vec
->vs
, vec
->rasterizer
))
361 finalize_cbuf_state(struct ilo_context
*ilo
,
362 struct ilo_cbuf_state
*cbuf
,
363 const struct ilo_shader_state
*sh
)
365 uint32_t upload_mask
= cbuf
->enabled_mask
;
367 /* skip CBUF0 if the kernel does not need it */
369 ~ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SKIP_CBUF0_UPLOAD
);
371 while (upload_mask
) {
374 i
= u_bit_scan(&upload_mask
);
375 /* no need to upload */
376 if (cbuf
->cso
[i
].resource
)
379 u_upload_data(ilo
->uploader
, 0, cbuf
->cso
[i
].info
.size
, 16,
380 cbuf
->cso
[i
].user_buffer
, &offset
, &cbuf
->cso
[i
].resource
);
382 cbuf
->cso
[i
].info
.vma
= ilo_resource_get_vma(cbuf
->cso
[i
].resource
);
383 cbuf
->cso
[i
].info
.offset
= offset
;
385 memset(&cbuf
->cso
[i
].surface
, 0, sizeof(cbuf
->cso
[i
].surface
));
386 ilo_state_surface_init_for_buffer(&cbuf
->cso
[i
].surface
,
387 ilo
->dev
, &cbuf
->cso
[i
].info
);
389 ilo
->state_vector
.dirty
|= ILO_DIRTY_CBUF
;
394 finalize_constant_buffers(struct ilo_context
*ilo
)
396 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
398 if (vec
->dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_VS
))
399 finalize_cbuf_state(ilo
, &vec
->cbuf
[PIPE_SHADER_VERTEX
], vec
->vs
);
401 if (ilo
->state_vector
.dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_FS
))
402 finalize_cbuf_state(ilo
, &vec
->cbuf
[PIPE_SHADER_FRAGMENT
], vec
->fs
);
406 finalize_index_buffer(struct ilo_context
*ilo
)
408 const struct ilo_dev
*dev
= ilo
->dev
;
409 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
410 const bool need_upload
= (vec
->draw
->indexed
&&
411 (vec
->ib
.state
.user_buffer
||
412 vec
->ib
.state
.offset
% vec
->ib
.state
.index_size
));
413 struct pipe_resource
*current_hw_res
= NULL
;
414 struct ilo_state_index_buffer_info info
;
415 int64_t vertex_start_bias
= 0;
417 if (!(vec
->dirty
& ILO_DIRTY_IB
) && !need_upload
)
420 /* make sure vec->ib.hw_resource changes when reallocated */
421 pipe_resource_reference(¤t_hw_res
, vec
->ib
.hw_resource
);
424 const unsigned offset
= vec
->ib
.state
.index_size
* vec
->draw
->start
;
425 const unsigned size
= vec
->ib
.state
.index_size
* vec
->draw
->count
;
428 if (vec
->ib
.state
.user_buffer
) {
429 u_upload_data(ilo
->uploader
, 0, size
, 16,
430 vec
->ib
.state
.user_buffer
+ offset
,
431 &hw_offset
, &vec
->ib
.hw_resource
);
433 u_upload_buffer(ilo
->uploader
, 0,
434 vec
->ib
.state
.offset
+ offset
, size
, 16, vec
->ib
.state
.buffer
,
435 &hw_offset
, &vec
->ib
.hw_resource
);
438 /* the HW offset should be aligned */
439 assert(hw_offset
% vec
->ib
.state
.index_size
== 0);
440 vertex_start_bias
= hw_offset
/ vec
->ib
.state
.index_size
;
443 * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
446 vertex_start_bias
-= vec
->draw
->start
;
448 pipe_resource_reference(&vec
->ib
.hw_resource
, vec
->ib
.state
.buffer
);
450 /* note that index size may be zero when the draw is not indexed */
451 if (vec
->draw
->indexed
)
452 vertex_start_bias
= vec
->ib
.state
.offset
/ vec
->ib
.state
.index_size
;
455 vec
->draw_info
.vertex_start
+= vertex_start_bias
;
457 /* treat the IB as clean if the HW states do not change */
458 if (vec
->ib
.hw_resource
== current_hw_res
&&
459 vec
->ib
.hw_index_size
== vec
->ib
.state
.index_size
)
460 vec
->dirty
&= ~ILO_DIRTY_IB
;
462 vec
->ib
.hw_index_size
= vec
->ib
.state
.index_size
;
464 pipe_resource_reference(¤t_hw_res
, NULL
);
466 memset(&info
, 0, sizeof(info
));
467 if (vec
->ib
.hw_resource
) {
468 info
.vma
= ilo_resource_get_vma(vec
->ib
.hw_resource
);
469 info
.size
= info
.vma
->vm_size
;
470 info
.format
= ilo_translate_index_size(vec
->ib
.hw_index_size
);
473 ilo_state_index_buffer_set_info(&vec
->ib
.ib
, dev
, &info
);
477 finalize_vertex_elements(struct ilo_context
*ilo
)
479 const struct ilo_dev
*dev
= ilo
->dev
;
480 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
481 struct ilo_ve_state
*ve
= vec
->ve
;
482 const bool last_element_edge_flag
= (vec
->vs
&&
483 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_VS_INPUT_EDGEFLAG
));
484 const bool prepend_vertexid
= (vec
->vs
&&
485 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_VS_INPUT_VERTEXID
));
486 const bool prepend_instanceid
= (vec
->vs
&&
487 ilo_shader_get_kernel_param(vec
->vs
,
488 ILO_KERNEL_VS_INPUT_INSTANCEID
));
489 const enum gen_index_format index_format
= (vec
->draw
->indexed
) ?
490 ilo_translate_index_size(vec
->ib
.state
.index_size
) : GEN6_INDEX_DWORD
;
492 /* check for non-orthogonal states */
493 if (ve
->vf_params
.cv_topology
!= vec
->draw_info
.topology
||
494 ve
->vf_params
.prepend_vertexid
!= prepend_vertexid
||
495 ve
->vf_params
.prepend_instanceid
!= prepend_instanceid
||
496 ve
->vf_params
.last_element_edge_flag
!= last_element_edge_flag
||
497 ve
->vf_params
.cv_index_format
!= index_format
||
498 ve
->vf_params
.cut_index_enable
!= vec
->draw
->primitive_restart
||
499 ve
->vf_params
.cut_index
!= vec
->draw
->restart_index
) {
500 ve
->vf_params
.cv_topology
= vec
->draw_info
.topology
;
501 ve
->vf_params
.prepend_vertexid
= prepend_vertexid
;
502 ve
->vf_params
.prepend_instanceid
= prepend_instanceid
;
503 ve
->vf_params
.last_element_edge_flag
= last_element_edge_flag
;
504 ve
->vf_params
.cv_index_format
= index_format
;
505 ve
->vf_params
.cut_index_enable
= vec
->draw
->primitive_restart
;
506 ve
->vf_params
.cut_index
= vec
->draw
->restart_index
;
508 ilo_state_vf_set_params(&ve
->vf
, dev
, &ve
->vf_params
);
510 vec
->dirty
|= ILO_DIRTY_VE
;
515 finalize_vertex_buffers(struct ilo_context
*ilo
)
517 const struct ilo_dev
*dev
= ilo
->dev
;
518 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
519 struct ilo_state_vertex_buffer_info info
;
522 if (!(vec
->dirty
& (ILO_DIRTY_VE
| ILO_DIRTY_VB
)))
525 memset(&info
, 0, sizeof(info
));
527 for (i
= 0; i
< vec
->ve
->vb_count
; i
++) {
528 const unsigned pipe_idx
= vec
->ve
->vb_mapping
[i
];
529 const struct pipe_vertex_buffer
*cso
= &vec
->vb
.states
[pipe_idx
];
532 info
.vma
= ilo_resource_get_vma(cso
->buffer
);
533 info
.offset
= cso
->buffer_offset
;
534 info
.size
= info
.vma
->vm_size
- cso
->buffer_offset
;
536 info
.stride
= cso
->stride
;
538 memset(&info
, 0, sizeof(info
));
541 ilo_state_vertex_buffer_set_info(&vec
->vb
.vb
[i
], dev
, &info
);
546 finalize_urb(struct ilo_context
*ilo
)
548 const uint16_t attr_size
= sizeof(uint32_t) * 4;
549 const struct ilo_dev
*dev
= ilo
->dev
;
550 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
551 struct ilo_state_urb_info info
;
553 if (!(vec
->dirty
& (ILO_DIRTY_VE
| ILO_DIRTY_VS
|
554 ILO_DIRTY_GS
| ILO_DIRTY_FS
)))
557 memset(&info
, 0, sizeof(info
));
559 info
.ve_entry_size
= attr_size
* ilo_state_vf_get_attr_count(&vec
->ve
->vf
);
562 info
.vs_const_data
= (bool)
563 (ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_PCB_CBUF0_SIZE
) +
564 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_VS_PCB_UCP_SIZE
));
565 info
.vs_entry_size
= attr_size
*
566 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_OUTPUT_COUNT
);
570 info
.gs_const_data
= (bool)
571 ilo_shader_get_kernel_param(vec
->gs
, ILO_KERNEL_PCB_CBUF0_SIZE
);
574 * From the Ivy Bridge PRM, volume 2 part 1, page 189:
576 * "All outputs of a GS thread will be stored in the single GS
577 * thread output URB entry."
581 info
.gs_entry_size
= attr_size
*
582 ilo_shader_get_kernel_param(vec
->gs
, ILO_KERNEL_OUTPUT_COUNT
);
586 info
.ps_const_data
= (bool)
587 ilo_shader_get_kernel_param(vec
->fs
, ILO_KERNEL_PCB_CBUF0_SIZE
);
590 ilo_state_urb_set_info(&vec
->urb
, dev
, &info
);
594 finalize_viewport(struct ilo_context
*ilo
)
596 const struct ilo_dev
*dev
= ilo
->dev
;
597 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
599 if (vec
->dirty
& ILO_DIRTY_VIEWPORT
) {
600 ilo_state_viewport_set_params(&vec
->viewport
.vp
,
601 dev
, &vec
->viewport
.params
, false);
602 } else if (vec
->dirty
& ILO_DIRTY_SCISSOR
) {
603 ilo_state_viewport_set_params(&vec
->viewport
.vp
,
604 dev
, &vec
->viewport
.params
, true);
605 vec
->dirty
|= ILO_DIRTY_VIEWPORT
;
610 can_enable_gb_test(const struct ilo_rasterizer_state
*rasterizer
,
611 const struct ilo_viewport_state
*viewport
,
612 const struct ilo_fb_state
*fb
)
617 * There are several reasons that guard band test should be disabled
619 * - GL wide points (to avoid partially visibie object)
620 * - GL wide or AA lines (to avoid partially visibie object)
621 * - missing 2D clipping
623 if (rasterizer
->state
.point_size_per_vertex
||
624 rasterizer
->state
.point_size
> 1.0f
||
625 rasterizer
->state
.line_width
> 1.0f
||
626 rasterizer
->state
.line_smooth
)
629 for (i
= 0; i
< viewport
->params
.count
; i
++) {
630 const struct ilo_state_viewport_matrix_info
*mat
=
631 &viewport
->matrices
[i
];
632 float min_x
, max_x
, min_y
, max_y
;
634 min_x
= -1.0f
* fabsf(mat
->scale
[0]) + mat
->translate
[0];
635 max_x
= 1.0f
* fabsf(mat
->scale
[0]) + mat
->translate
[0];
636 min_y
= -1.0f
* fabsf(mat
->scale
[1]) + mat
->translate
[1];
637 max_y
= 1.0f
* fabsf(mat
->scale
[1]) + mat
->translate
[1];
639 if (min_x
> 0.0f
|| max_x
< fb
->state
.width
||
640 min_y
> 0.0f
|| max_y
< fb
->state
.height
)
648 finalize_rasterizer(struct ilo_context
*ilo
)
650 const struct ilo_dev
*dev
= ilo
->dev
;
651 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
652 struct ilo_rasterizer_state
*rasterizer
= vec
->rasterizer
;
653 struct ilo_state_raster_info
*info
= &vec
->rasterizer
->info
;
654 const bool gb_test_enable
=
655 can_enable_gb_test(rasterizer
, &vec
->viewport
, &vec
->fb
);
656 const bool multisample
=
657 (rasterizer
->state
.multisample
&& vec
->fb
.num_samples
> 1);
658 const uint8_t barycentric_interps
= ilo_shader_get_kernel_param(vec
->fs
,
659 ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS
);
661 /* check for non-orthogonal states */
662 if (info
->clip
.viewport_count
!= vec
->viewport
.params
.count
||
663 info
->clip
.gb_test_enable
!= gb_test_enable
||
664 info
->setup
.msaa_enable
!= multisample
||
665 info
->setup
.line_msaa_enable
!= multisample
||
666 info
->tri
.depth_offset_format
!= vec
->fb
.depth_offset_format
||
667 info
->scan
.sample_count
!= vec
->fb
.num_samples
||
668 info
->scan
.sample_mask
!= vec
->sample_mask
||
669 info
->scan
.barycentric_interps
!= barycentric_interps
||
670 info
->params
.any_integer_rt
!= vec
->fb
.has_integer_rt
||
671 info
->params
.hiz_enable
!= vec
->fb
.has_hiz
) {
672 info
->clip
.viewport_count
= vec
->viewport
.params
.count
;
673 info
->clip
.gb_test_enable
= gb_test_enable
;
674 info
->setup
.msaa_enable
= multisample
;
675 info
->setup
.line_msaa_enable
= multisample
;
676 info
->tri
.depth_offset_format
= vec
->fb
.depth_offset_format
;
677 info
->scan
.sample_count
= vec
->fb
.num_samples
;
678 info
->scan
.sample_mask
= vec
->sample_mask
;
679 info
->scan
.barycentric_interps
= barycentric_interps
;
680 info
->params
.any_integer_rt
= vec
->fb
.has_integer_rt
;
681 info
->params
.hiz_enable
= vec
->fb
.has_hiz
;
683 ilo_state_raster_set_info(&rasterizer
->rs
, dev
, &rasterizer
->info
);
685 vec
->dirty
|= ILO_DIRTY_RASTERIZER
;
690 finalize_blend_rt(struct ilo_context
*ilo
)
692 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
693 const struct ilo_fb_state
*fb
= &vec
->fb
;
694 struct ilo_blend_state
*blend
= vec
->blend
;
695 struct ilo_state_cc_blend_info
*info
= &vec
->blend
->info
.blend
;
696 bool changed
= false;
699 if (!(vec
->dirty
& (ILO_DIRTY_FB
| ILO_DIRTY_BLEND
)))
702 /* set up one for dummy RT writes */
703 if (!fb
->state
.nr_cbufs
) {
704 if (info
->rt
!= &blend
->dummy_rt
) {
705 info
->rt
= &blend
->dummy_rt
;
713 if (info
->rt
!= blend
->effective_rt
||
714 info
->rt_count
!= fb
->state
.nr_cbufs
) {
715 info
->rt
= blend
->effective_rt
;
716 info
->rt_count
= fb
->state
.nr_cbufs
;
720 for (i
= 0; i
< fb
->state
.nr_cbufs
; i
++) {
721 const struct ilo_fb_blend_caps
*caps
= &fb
->blend_caps
[i
];
722 struct ilo_state_cc_blend_rt_info
*rt
= &blend
->effective_rt
[i
];
723 /* ignore logicop when not UNORM */
724 const bool logicop_enable
=
725 (blend
->rt
[i
].logicop_enable
&& caps
->is_unorm
);
727 if (rt
->cv_is_unorm
!= caps
->is_unorm
||
728 rt
->cv_is_integer
!= caps
->is_integer
||
729 rt
->logicop_enable
!= logicop_enable
||
730 rt
->force_dst_alpha_one
!= caps
->force_dst_alpha_one
) {
731 rt
->cv_is_unorm
= caps
->is_unorm
;
732 rt
->cv_is_integer
= caps
->is_integer
;
733 rt
->logicop_enable
= logicop_enable
;
734 rt
->force_dst_alpha_one
= caps
->force_dst_alpha_one
;
744 finalize_blend(struct ilo_context
*ilo
)
746 const struct ilo_dev
*dev
= ilo
->dev
;
747 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
748 struct ilo_blend_state
*blend
= vec
->blend
;
749 struct ilo_state_cc_info
*info
= &blend
->info
;
750 const bool sample_count_one
= (vec
->fb
.num_samples
<= 1);
751 const bool float_source0_alpha
=
752 (!vec
->fb
.state
.nr_cbufs
|| !vec
->fb
.state
.cbufs
[0] ||
753 !util_format_is_pure_integer(vec
->fb
.state
.cbufs
[0]->format
));
755 /* check for non-orthogonal states */
756 if (finalize_blend_rt(ilo
) ||
757 info
->alpha
.cv_sample_count_one
!= sample_count_one
||
758 info
->alpha
.cv_float_source0_alpha
!= float_source0_alpha
||
759 info
->alpha
.test_enable
!= vec
->dsa
->alpha_test
||
760 info
->alpha
.test_func
!= vec
->dsa
->alpha_func
||
761 memcmp(&info
->stencil
, &vec
->dsa
->stencil
, sizeof(info
->stencil
)) ||
762 memcmp(&info
->depth
, &vec
->dsa
->depth
, sizeof(info
->depth
)) ||
763 memcmp(&info
->params
, &vec
->cc_params
, sizeof(info
->params
))) {
764 info
->alpha
.cv_sample_count_one
= sample_count_one
;
765 info
->alpha
.cv_float_source0_alpha
= float_source0_alpha
;
766 info
->alpha
.test_enable
= vec
->dsa
->alpha_test
;
767 info
->alpha
.test_func
= vec
->dsa
->alpha_func
;
768 info
->stencil
= vec
->dsa
->stencil
;
769 info
->depth
= vec
->dsa
->depth
;
770 info
->params
= vec
->cc_params
;
772 ilo_state_cc_set_info(&blend
->cc
, dev
, info
);
774 blend
->alpha_may_kill
= (info
->alpha
.alpha_to_coverage
||
775 info
->alpha
.test_enable
);
777 vec
->dirty
|= ILO_DIRTY_BLEND
;
782 * Finalize states. Some states depend on other states and are
783 * incomplete/invalid until finalized.
786 ilo_finalize_3d_states(struct ilo_context
*ilo
,
787 const struct pipe_draw_info
*draw
)
789 ilo
->state_vector
.draw
= draw
;
791 ilo
->state_vector
.draw_info
.topology
= ilo_translate_draw_mode(draw
->mode
);
792 ilo
->state_vector
.draw_info
.indexed
= draw
->indexed
;
793 ilo
->state_vector
.draw_info
.vertex_count
= draw
->count
;
794 ilo
->state_vector
.draw_info
.vertex_start
= draw
->start
;
795 ilo
->state_vector
.draw_info
.instance_count
= draw
->instance_count
;
796 ilo
->state_vector
.draw_info
.instance_start
= draw
->start_instance
;
797 ilo
->state_vector
.draw_info
.vertex_base
= draw
->index_bias
;
800 finalize_shader_states(&ilo
->state_vector
);
801 finalize_constant_buffers(ilo
);
802 finalize_index_buffer(ilo
);
803 finalize_vertex_elements(ilo
);
804 finalize_vertex_buffers(ilo
);
807 finalize_rasterizer(ilo
);
808 finalize_viewport(ilo
);
810 u_upload_unmap(ilo
->uploader
);
814 finalize_global_binding(struct ilo_state_vector
*vec
)
816 struct ilo_shader_state
*cs
= vec
->cs
;
817 int base
, count
, shift
;
820 count
= ilo_shader_get_kernel_param(cs
,
821 ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT
);
825 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE
);
826 shift
= 32 - util_last_bit(base
+ count
- 1);
828 if (count
> vec
->global_binding
.count
)
829 count
= vec
->global_binding
.count
;
831 for (i
= 0; i
< count
; i
++) {
832 struct ilo_global_binding_cso
*cso
=
833 util_dynarray_element(&vec
->global_binding
.bindings
,
834 struct ilo_global_binding_cso
, i
);
835 const uint32_t offset
= *cso
->handle
& ((1 << shift
) - 1);
837 *cso
->handle
= ((base
+ i
) << shift
) | offset
;
842 ilo_finalize_compute_states(struct ilo_context
*ilo
)
844 finalize_global_binding(&ilo
->state_vector
);
848 ilo_create_blend_state(struct pipe_context
*pipe
,
849 const struct pipe_blend_state
*state
)
851 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
852 struct ilo_state_cc_info
*info
;
853 struct ilo_blend_state
*blend
;
856 blend
= CALLOC_STRUCT(ilo_blend_state
);
861 info
->alpha
.cv_float_source0_alpha
= true;
862 info
->alpha
.cv_sample_count_one
= true;
863 info
->alpha
.alpha_to_one
= state
->alpha_to_one
;
864 info
->alpha
.alpha_to_coverage
= state
->alpha_to_coverage
;
865 info
->alpha
.test_enable
= false;
866 info
->alpha
.test_func
= GEN6_COMPAREFUNCTION_ALWAYS
;
868 info
->stencil
.cv_has_buffer
= true;
869 info
->depth
.cv_has_buffer
= true;
871 info
->blend
.rt
= blend
->effective_rt
;
872 info
->blend
.rt_count
= 1;
873 info
->blend
.dither_enable
= state
->dither
;
875 for (i
= 0; i
< ARRAY_SIZE(blend
->rt
); i
++) {
876 const struct pipe_rt_blend_state
*rt
= &state
->rt
[i
];
877 struct ilo_state_cc_blend_rt_info
*rt_info
= &blend
->rt
[i
];
879 rt_info
->cv_has_buffer
= true;
880 rt_info
->cv_is_unorm
= true;
881 rt_info
->cv_is_integer
= false;
883 /* logic op takes precedence over blending */
884 if (state
->logicop_enable
) {
885 rt_info
->logicop_enable
= true;
886 rt_info
->logicop_func
= ilo_translate_logicop(state
->logicop_func
);
887 } else if (rt
->blend_enable
) {
888 rt_info
->blend_enable
= true;
890 rt_info
->rgb_src
= ilo_translate_blend_factor(rt
->rgb_src_factor
);
891 rt_info
->rgb_dst
= ilo_translate_blend_factor(rt
->rgb_dst_factor
);
892 rt_info
->rgb_func
= ilo_translate_blend_func(rt
->rgb_func
);
894 rt_info
->a_src
= ilo_translate_blend_factor(rt
->alpha_src_factor
);
895 rt_info
->a_dst
= ilo_translate_blend_factor(rt
->alpha_dst_factor
);
896 rt_info
->a_func
= ilo_translate_blend_func(rt
->alpha_func
);
899 if (!(rt
->colormask
& PIPE_MASK_A
))
900 rt_info
->argb_write_disables
|= (1 << 3);
901 if (!(rt
->colormask
& PIPE_MASK_R
))
902 rt_info
->argb_write_disables
|= (1 << 2);
903 if (!(rt
->colormask
& PIPE_MASK_G
))
904 rt_info
->argb_write_disables
|= (1 << 1);
905 if (!(rt
->colormask
& PIPE_MASK_B
))
906 rt_info
->argb_write_disables
|= (1 << 0);
908 if (!state
->independent_blend_enable
) {
909 for (i
= 1; i
< ARRAY_SIZE(blend
->rt
); i
++)
910 blend
->rt
[i
] = *rt_info
;
915 memcpy(blend
->effective_rt
, blend
->rt
, sizeof(blend
->rt
));
917 blend
->dummy_rt
.argb_write_disables
= 0xf;
919 if (!ilo_state_cc_init(&blend
->cc
, dev
, &blend
->info
)) {
924 blend
->dual_blend
= util_blend_state_is_dual(state
, 0);
930 ilo_bind_blend_state(struct pipe_context
*pipe
, void *state
)
932 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
936 vec
->dirty
|= ILO_DIRTY_BLEND
;
940 ilo_delete_blend_state(struct pipe_context
*pipe
, void *state
)
946 ilo_create_sampler_state(struct pipe_context
*pipe
,
947 const struct pipe_sampler_state
*state
)
949 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
950 struct ilo_sampler_cso
*sampler
;
951 struct ilo_state_sampler_info info
;
952 struct ilo_state_sampler_border_info border
;
954 sampler
= CALLOC_STRUCT(ilo_sampler_cso
);
957 memset(&info
, 0, sizeof(info
));
959 info
.non_normalized
= !state
->normalized_coords
;
960 if (state
->normalized_coords
) {
961 info
.lod_bias
= state
->lod_bias
;
962 info
.min_lod
= state
->min_lod
;
963 info
.max_lod
= state
->max_lod
;
965 info
.mip_filter
= ilo_translate_mip_filter(state
->min_mip_filter
);
967 /* work around a bug in util_blitter */
968 info
.mip_filter
= GEN6_MIPFILTER_NONE
;
971 if (state
->max_anisotropy
) {
972 info
.min_filter
= GEN6_MAPFILTER_ANISOTROPIC
;
973 info
.mag_filter
= GEN6_MAPFILTER_ANISOTROPIC
;
975 info
.min_filter
= ilo_translate_img_filter(state
->min_img_filter
);
976 info
.mag_filter
= ilo_translate_img_filter(state
->mag_img_filter
);
979 info
.max_anisotropy
= ilo_translate_max_anisotropy(state
->max_anisotropy
);
981 /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
982 if (info
.mip_filter
== GEN6_MIPFILTER_NONE
&& info
.min_lod
> 0.0f
) {
984 info
.mag_filter
= info
.min_filter
;
987 if (state
->seamless_cube_map
) {
988 if (state
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
||
989 state
->mag_img_filter
== PIPE_TEX_FILTER_NEAREST
) {
990 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
991 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
992 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
994 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
995 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
996 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
999 info
.tcx_ctrl
= ilo_translate_address_wrap(state
->wrap_s
);
1000 info
.tcy_ctrl
= ilo_translate_address_wrap(state
->wrap_t
);
1001 info
.tcz_ctrl
= ilo_translate_address_wrap(state
->wrap_r
);
1003 if (ilo_dev_gen(dev
) < ILO_GEN(8)) {
1005 * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
1006 * PIPE_TEX_WRAP_CLAMP_TO_EDGE; for linear filtering,
1007 * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
1008 * additionally clamping the texture coordinates to [0.0, 1.0].
1010 * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8. The
1011 * clamping has to be taken care of in the shaders. There are two
1012 * filters here, but let the minification one has a say.
1014 const bool clamp_is_to_edge
=
1015 (state
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
);
1017 if (clamp_is_to_edge
) {
1018 if (info
.tcx_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
1019 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
1020 if (info
.tcy_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
1021 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
1022 if (info
.tcz_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
1023 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
1025 if (info
.tcx_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
1026 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
1027 sampler
->saturate_s
= true;
1029 if (info
.tcy_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
1030 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
1031 sampler
->saturate_t
= true;
1033 if (info
.tcz_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
1034 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
1035 sampler
->saturate_r
= true;
1041 if (state
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
1042 info
.shadow_func
= ilo_translate_shadow_func(state
->compare_func
);
1044 ilo_state_sampler_init(&sampler
->sampler
, dev
, &info
);
1046 memset(&border
, 0, sizeof(border
));
1047 memcpy(border
.rgba
.f
, state
->border_color
.f
, sizeof(border
.rgba
.f
));
1049 ilo_state_sampler_border_init(&sampler
->border
, dev
, &border
);
1055 ilo_bind_sampler_states(struct pipe_context
*pipe
, unsigned shader
,
1056 unsigned start
, unsigned count
, void **samplers
)
1058 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1059 struct ilo_sampler_state
*dst
= &vec
->sampler
[shader
];
1060 bool changed
= false;
1063 assert(start
+ count
<= Elements(dst
->cso
));
1066 for (i
= 0; i
< count
; i
++) {
1067 if (dst
->cso
[start
+ i
] != samplers
[i
]) {
1068 dst
->cso
[start
+ i
] = samplers
[i
];
1071 * This function is sometimes called to reduce the number of bound
1072 * samplers. Do not consider that as a state change (and create a
1073 * new array of SAMPLER_STATE).
1081 for (i
= 0; i
< count
; i
++)
1082 dst
->cso
[start
+ i
] = NULL
;
1087 case PIPE_SHADER_VERTEX
:
1088 vec
->dirty
|= ILO_DIRTY_SAMPLER_VS
;
1090 case PIPE_SHADER_GEOMETRY
:
1091 vec
->dirty
|= ILO_DIRTY_SAMPLER_GS
;
1093 case PIPE_SHADER_FRAGMENT
:
1094 vec
->dirty
|= ILO_DIRTY_SAMPLER_FS
;
1096 case PIPE_SHADER_COMPUTE
:
1097 vec
->dirty
|= ILO_DIRTY_SAMPLER_CS
;
1104 ilo_delete_sampler_state(struct pipe_context
*pipe
, void *state
)
1110 ilo_create_rasterizer_state(struct pipe_context
*pipe
,
1111 const struct pipe_rasterizer_state
*state
)
1113 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1114 struct ilo_rasterizer_state
*rast
;
1115 struct ilo_state_raster_info
*info
;
1117 rast
= CALLOC_STRUCT(ilo_rasterizer_state
);
1120 rast
->state
= *state
;
1124 info
->clip
.clip_enable
= true;
1125 info
->clip
.stats_enable
= true;
1126 info
->clip
.viewport_count
= 1;
1127 info
->clip
.force_rtaindex_zero
= true;
1128 info
->clip
.user_clip_enables
= state
->clip_plane_enable
;
1129 info
->clip
.gb_test_enable
= true;
1130 info
->clip
.xy_test_enable
= true;
1131 info
->clip
.z_far_enable
= state
->depth_clip
;
1132 info
->clip
.z_near_enable
= state
->depth_clip
;
1133 info
->clip
.z_near_zero
= state
->clip_halfz
;
1135 info
->setup
.first_vertex_provoking
= state
->flatshade_first
;
1136 info
->setup
.viewport_transform
= true;
1137 info
->setup
.scissor_enable
= state
->scissor
;
1138 info
->setup
.msaa_enable
= false;
1139 info
->setup
.line_msaa_enable
= false;
1140 info
->point
.aa_enable
= state
->point_smooth
;
1141 info
->point
.programmable_width
= state
->point_size_per_vertex
;
1142 info
->line
.aa_enable
= state
->line_smooth
;
1143 info
->line
.stipple_enable
= state
->line_stipple_enable
;
1144 info
->line
.giq_enable
= true;
1145 info
->line
.giq_last_pixel
= state
->line_last_pixel
;
1146 info
->tri
.front_winding
= ilo_translate_front_ccw(state
->front_ccw
);
1147 info
->tri
.cull_mode
= ilo_translate_cull_face(state
->cull_face
);
1148 info
->tri
.fill_mode_front
= ilo_translate_poly_mode(state
->fill_front
);
1149 info
->tri
.fill_mode_back
= ilo_translate_poly_mode(state
->fill_back
);
1150 info
->tri
.depth_offset_format
= GEN6_ZFORMAT_D24_UNORM_X8_UINT
;
1151 info
->tri
.depth_offset_solid
= state
->offset_tri
;
1152 info
->tri
.depth_offset_wireframe
= state
->offset_line
;
1153 info
->tri
.depth_offset_point
= state
->offset_point
;
1154 info
->tri
.poly_stipple_enable
= state
->poly_stipple_enable
;
1156 info
->scan
.stats_enable
= true;
1157 info
->scan
.sample_count
= 1;
1159 ilo_translate_half_pixel_center(state
->half_pixel_center
);
1160 info
->scan
.sample_mask
= ~0u;
1161 info
->scan
.zw_interp
= GEN6_ZW_INTERP_PIXEL
;
1162 info
->scan
.barycentric_interps
= GEN6_INTERP_PERSPECTIVE_PIXEL
;
1163 info
->scan
.earlyz_control
= GEN7_EDSC_NORMAL
;
1164 info
->scan
.earlyz_op
= ILO_STATE_RASTER_EARLYZ_NORMAL
;
1165 info
->scan
.earlyz_stencil_clear
= false;
1167 info
->params
.any_integer_rt
= false;
1168 info
->params
.hiz_enable
= true;
1169 info
->params
.point_width
=
1170 (state
->point_size
== 0.0f
) ? 1.0f
: state
->point_size
;
1171 info
->params
.line_width
=
1172 (state
->line_width
== 0.0f
) ? 1.0f
: state
->line_width
;
1174 info
->params
.depth_offset_scale
= state
->offset_scale
;
1176 * Scale the constant term. The minimum representable value used by the HW
1177 * is not large enouch to be the minimum resolvable difference.
1179 info
->params
.depth_offset_const
= state
->offset_units
* 2.0f
;
1180 info
->params
.depth_offset_clamp
= state
->offset_clamp
;
1182 ilo_state_raster_init(&rast
->rs
, dev
, info
);
1188 ilo_bind_rasterizer_state(struct pipe_context
*pipe
, void *state
)
1190 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1191 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1193 vec
->rasterizer
= state
;
1195 if (vec
->rasterizer
) {
1196 struct ilo_state_line_stipple_info info
;
1198 info
.pattern
= vec
->rasterizer
->state
.line_stipple_pattern
;
1199 info
.repeat_count
= vec
->rasterizer
->state
.line_stipple_factor
+ 1;
1201 ilo_state_line_stipple_set_info(&vec
->line_stipple
, dev
, &info
);
1204 vec
->dirty
|= ILO_DIRTY_RASTERIZER
;
1208 ilo_delete_rasterizer_state(struct pipe_context
*pipe
, void *state
)
1214 ilo_create_depth_stencil_alpha_state(struct pipe_context
*pipe
,
1215 const struct pipe_depth_stencil_alpha_state
*state
)
1217 struct ilo_dsa_state
*dsa
;
1220 dsa
= CALLOC_STRUCT(ilo_dsa_state
);
1223 dsa
->depth
.cv_has_buffer
= true;
1224 dsa
->depth
.test_enable
= state
->depth
.enabled
;
1225 dsa
->depth
.write_enable
= state
->depth
.writemask
;
1226 dsa
->depth
.test_func
= ilo_translate_compare_func(state
->depth
.func
);
1228 dsa
->stencil
.cv_has_buffer
= true;
1229 for (i
= 0; i
< ARRAY_SIZE(state
->stencil
); i
++) {
1230 const struct pipe_stencil_state
*stencil
= &state
->stencil
[i
];
1231 struct ilo_state_cc_stencil_op_info
*op
;
1233 if (!stencil
->enabled
)
1237 dsa
->stencil
.test_enable
= true;
1238 dsa
->stencil_front
.test_mask
= stencil
->valuemask
;
1239 dsa
->stencil_front
.write_mask
= stencil
->writemask
;
1241 op
= &dsa
->stencil
.front
;
1243 dsa
->stencil
.twosided_enable
= true;
1244 dsa
->stencil_back
.test_mask
= stencil
->valuemask
;
1245 dsa
->stencil_back
.write_mask
= stencil
->writemask
;
1247 op
= &dsa
->stencil
.back
;
1250 op
->test_func
= ilo_translate_compare_func(stencil
->func
);
1251 op
->fail_op
= ilo_translate_stencil_op(stencil
->fail_op
);
1252 op
->zfail_op
= ilo_translate_stencil_op(stencil
->zfail_op
);
1253 op
->zpass_op
= ilo_translate_stencil_op(stencil
->zpass_op
);
1256 dsa
->alpha_test
= state
->alpha
.enabled
;
1257 dsa
->alpha_ref
= state
->alpha
.ref_value
;
1258 dsa
->alpha_func
= ilo_translate_compare_func(state
->alpha
.func
);
1264 ilo_bind_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
1266 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1270 vec
->cc_params
.alpha_ref
= vec
->dsa
->alpha_ref
;
1271 vec
->cc_params
.stencil_front
.test_mask
=
1272 vec
->dsa
->stencil_front
.test_mask
;
1273 vec
->cc_params
.stencil_front
.write_mask
=
1274 vec
->dsa
->stencil_front
.write_mask
;
1275 vec
->cc_params
.stencil_back
.test_mask
=
1276 vec
->dsa
->stencil_back
.test_mask
;
1277 vec
->cc_params
.stencil_back
.write_mask
=
1278 vec
->dsa
->stencil_back
.write_mask
;
1281 vec
->dirty
|= ILO_DIRTY_DSA
;
1285 ilo_delete_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
1291 ilo_create_fs_state(struct pipe_context
*pipe
,
1292 const struct pipe_shader_state
*state
)
1294 struct ilo_context
*ilo
= ilo_context(pipe
);
1295 struct ilo_shader_state
*shader
;
1297 shader
= ilo_shader_create_fs(ilo
->dev
, state
, &ilo
->state_vector
);
1300 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1306 ilo_bind_fs_state(struct pipe_context
*pipe
, void *state
)
1308 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1312 vec
->dirty
|= ILO_DIRTY_FS
;
1316 ilo_delete_fs_state(struct pipe_context
*pipe
, void *state
)
1318 struct ilo_context
*ilo
= ilo_context(pipe
);
1319 struct ilo_shader_state
*fs
= (struct ilo_shader_state
*) state
;
1321 ilo_shader_cache_remove(ilo
->shader_cache
, fs
);
1322 ilo_shader_destroy(fs
);
1326 ilo_create_vs_state(struct pipe_context
*pipe
,
1327 const struct pipe_shader_state
*state
)
1329 struct ilo_context
*ilo
= ilo_context(pipe
);
1330 struct ilo_shader_state
*shader
;
1332 shader
= ilo_shader_create_vs(ilo
->dev
, state
, &ilo
->state_vector
);
1335 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1341 ilo_bind_vs_state(struct pipe_context
*pipe
, void *state
)
1343 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1347 vec
->dirty
|= ILO_DIRTY_VS
;
1351 ilo_delete_vs_state(struct pipe_context
*pipe
, void *state
)
1353 struct ilo_context
*ilo
= ilo_context(pipe
);
1354 struct ilo_shader_state
*vs
= (struct ilo_shader_state
*) state
;
1356 ilo_shader_cache_remove(ilo
->shader_cache
, vs
);
1357 ilo_shader_destroy(vs
);
1361 ilo_create_gs_state(struct pipe_context
*pipe
,
1362 const struct pipe_shader_state
*state
)
1364 struct ilo_context
*ilo
= ilo_context(pipe
);
1365 struct ilo_shader_state
*shader
;
1367 shader
= ilo_shader_create_gs(ilo
->dev
, state
, &ilo
->state_vector
);
1370 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1376 ilo_bind_gs_state(struct pipe_context
*pipe
, void *state
)
1378 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1380 /* util_blitter may set this unnecessarily */
1381 if (vec
->gs
== state
)
1386 vec
->dirty
|= ILO_DIRTY_GS
;
1390 ilo_delete_gs_state(struct pipe_context
*pipe
, void *state
)
1392 struct ilo_context
*ilo
= ilo_context(pipe
);
1393 struct ilo_shader_state
*gs
= (struct ilo_shader_state
*) state
;
1395 ilo_shader_cache_remove(ilo
->shader_cache
, gs
);
1396 ilo_shader_destroy(gs
);
1400 ilo_create_vertex_elements_state(struct pipe_context
*pipe
,
1401 unsigned num_elements
,
1402 const struct pipe_vertex_element
*elements
)
1404 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1405 struct ilo_state_vf_element_info vf_elements
[PIPE_MAX_ATTRIBS
];
1406 unsigned instance_divisors
[PIPE_MAX_ATTRIBS
];
1407 struct ilo_state_vf_info vf_info
;
1408 struct ilo_ve_state
*ve
;
1411 ve
= CALLOC_STRUCT(ilo_ve_state
);
1414 for (i
= 0; i
< num_elements
; i
++) {
1415 const struct pipe_vertex_element
*elem
= &elements
[i
];
1416 struct ilo_state_vf_element_info
*attr
= &vf_elements
[i
];
1420 * map the pipe vb to the hardware vb, which has a fixed instance
1423 for (hw_idx
= 0; hw_idx
< ve
->vb_count
; hw_idx
++) {
1424 if (ve
->vb_mapping
[hw_idx
] == elem
->vertex_buffer_index
&&
1425 instance_divisors
[hw_idx
] == elem
->instance_divisor
)
1429 /* create one if there is no matching hardware vb */
1430 if (hw_idx
>= ve
->vb_count
) {
1431 hw_idx
= ve
->vb_count
++;
1433 ve
->vb_mapping
[hw_idx
] = elem
->vertex_buffer_index
;
1434 instance_divisors
[hw_idx
] = elem
->instance_divisor
;
1437 attr
->buffer
= hw_idx
;
1438 attr
->vertex_offset
= elem
->src_offset
;
1439 attr
->format
= ilo_format_translate_vertex(dev
, elem
->src_format
);
1440 attr
->format_size
= util_format_get_blocksize(elem
->src_format
);
1441 attr
->component_count
= util_format_get_nr_components(elem
->src_format
);
1442 attr
->is_integer
= util_format_is_pure_integer(elem
->src_format
);
1444 attr
->instancing_enable
= (elem
->instance_divisor
!= 0);
1445 attr
->instancing_step_rate
= elem
->instance_divisor
;
1448 memset(&vf_info
, 0, sizeof(vf_info
));
1449 vf_info
.data
= ve
->vf_data
;
1450 vf_info
.data_size
= sizeof(ve
->vf_data
);
1451 vf_info
.elements
= vf_elements
;
1452 vf_info
.element_count
= num_elements
;
1453 /* vf_info.params and ve->vf_params are both zeroed */
1455 if (!ilo_state_vf_init(&ve
->vf
, dev
, &vf_info
)) {
1464 ilo_bind_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
1466 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1470 vec
->dirty
|= ILO_DIRTY_VE
;
1474 ilo_delete_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
1476 struct ilo_ve_state
*ve
= state
;
1482 ilo_set_blend_color(struct pipe_context
*pipe
,
1483 const struct pipe_blend_color
*state
)
1485 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1487 memcpy(vec
->cc_params
.blend_rgba
, state
->color
, sizeof(state
->color
));
1489 vec
->dirty
|= ILO_DIRTY_BLEND_COLOR
;
1493 ilo_set_stencil_ref(struct pipe_context
*pipe
,
1494 const struct pipe_stencil_ref
*state
)
1496 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1498 /* util_blitter may set this unnecessarily */
1499 if (!memcmp(&vec
->stencil_ref
, state
, sizeof(*state
)))
1502 vec
->stencil_ref
= *state
;
1504 vec
->cc_params
.stencil_front
.test_ref
= state
->ref_value
[0];
1505 vec
->cc_params
.stencil_back
.test_ref
= state
->ref_value
[1];
1507 vec
->dirty
|= ILO_DIRTY_STENCIL_REF
;
1511 ilo_set_sample_mask(struct pipe_context
*pipe
,
1512 unsigned sample_mask
)
1514 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1516 /* util_blitter may set this unnecessarily */
1517 if (vec
->sample_mask
== sample_mask
)
1520 vec
->sample_mask
= sample_mask
;
1522 vec
->dirty
|= ILO_DIRTY_SAMPLE_MASK
;
1526 ilo_set_clip_state(struct pipe_context
*pipe
,
1527 const struct pipe_clip_state
*state
)
1529 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1533 vec
->dirty
|= ILO_DIRTY_CLIP
;
1537 ilo_set_constant_buffer(struct pipe_context
*pipe
,
1538 uint shader
, uint index
,
1539 struct pipe_constant_buffer
*buf
)
1541 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1542 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1543 struct ilo_cbuf_state
*cbuf
= &vec
->cbuf
[shader
];
1544 const unsigned count
= 1;
1547 assert(shader
< Elements(vec
->cbuf
));
1548 assert(index
+ count
<= Elements(vec
->cbuf
[shader
].cso
));
1551 for (i
= 0; i
< count
; i
++) {
1552 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
1554 pipe_resource_reference(&cso
->resource
, buf
[i
].buffer
);
1556 cso
->info
.access
= ILO_STATE_SURFACE_ACCESS_DP_DATA
;
1557 cso
->info
.format
= GEN6_FORMAT_R32G32B32A32_FLOAT
;
1558 cso
->info
.format_size
= 16;
1559 cso
->info
.struct_size
= 16;
1560 cso
->info
.readonly
= true;
1561 cso
->info
.size
= buf
[i
].buffer_size
;
1563 if (buf
[i
].buffer
) {
1564 cso
->info
.vma
= ilo_resource_get_vma(buf
[i
].buffer
);
1565 cso
->info
.offset
= buf
[i
].buffer_offset
;
1567 memset(&cso
->surface
, 0, sizeof(cso
->surface
));
1568 ilo_state_surface_init_for_buffer(&cso
->surface
, dev
, &cso
->info
);
1570 cso
->user_buffer
= NULL
;
1572 cbuf
->enabled_mask
|= 1 << (index
+ i
);
1573 } else if (buf
[i
].user_buffer
) {
1574 cso
->info
.vma
= NULL
;
1575 /* buffer_offset does not apply for user buffer */
1576 cso
->user_buffer
= buf
[i
].user_buffer
;
1578 cbuf
->enabled_mask
|= 1 << (index
+ i
);
1580 cso
->info
.vma
= NULL
;
1582 cso
->user_buffer
= NULL
;
1584 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
1588 for (i
= 0; i
< count
; i
++) {
1589 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
1591 pipe_resource_reference(&cso
->resource
, NULL
);
1593 cso
->info
.vma
= NULL
;
1595 cso
->user_buffer
= NULL
;
1597 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
1601 vec
->dirty
|= ILO_DIRTY_CBUF
;
1605 fb_set_blend_caps(const struct ilo_dev
*dev
,
1606 enum pipe_format format
,
1607 struct ilo_fb_blend_caps
*caps
)
1609 const struct util_format_description
*desc
=
1610 util_format_description(format
);
1611 const int ch
= util_format_get_first_non_void_channel(format
);
1613 memset(caps
, 0, sizeof(*caps
));
1615 if (format
== PIPE_FORMAT_NONE
|| desc
->is_mixed
)
1618 caps
->is_unorm
= (ch
>= 0 && desc
->channel
[ch
].normalized
&&
1619 desc
->channel
[ch
].type
== UTIL_FORMAT_TYPE_UNSIGNED
&&
1620 desc
->colorspace
== UTIL_FORMAT_COLORSPACE_RGB
);
1621 caps
->is_integer
= util_format_is_pure_integer(format
);
1624 * From the Sandy Bridge PRM, volume 2 part 1, page 365:
1626 * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
1627 * variants), otherwise Logic Ops must be DISABLED."
1629 * According to the classic driver, this is lifted on Gen8+.
1631 caps
->can_logicop
= (ilo_dev_gen(dev
) >= ILO_GEN(8) || caps
->is_unorm
);
1633 /* no blending for pure integer formats */
1634 caps
->can_blend
= !caps
->is_integer
;
1637 * From the Sandy Bridge PRM, volume 2 part 1, page 382:
1639 * "Alpha Test can only be enabled if Pixel Shader outputs a float
1642 caps
->can_alpha_test
= !caps
->is_integer
;
1644 caps
->force_dst_alpha_one
=
1645 (ilo_format_translate_render(dev
, format
) !=
1646 ilo_format_translate_color(dev
, format
));
1649 if (caps
->force_dst_alpha_one
) {
1650 enum pipe_format render_format
;
1653 case PIPE_FORMAT_B8G8R8X8_UNORM
:
1654 render_format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
1657 render_format
= PIPE_FORMAT_NONE
;
1661 assert(ilo_format_translate_render(dev
, format
) ==
1662 ilo_format_translate_color(dev
, render_format
));
1667 ilo_set_framebuffer_state(struct pipe_context
*pipe
,
1668 const struct pipe_framebuffer_state
*state
)
1670 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1671 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1672 struct ilo_fb_state
*fb
= &vec
->fb
;
1673 const struct pipe_surface
*first_surf
= NULL
;
1676 util_copy_framebuffer_state(&fb
->state
, state
);
1678 fb
->has_integer_rt
= false;
1679 for (i
= 0; i
< state
->nr_cbufs
; i
++) {
1680 if (state
->cbufs
[i
]) {
1681 fb_set_blend_caps(dev
, state
->cbufs
[i
]->format
, &fb
->blend_caps
[i
]);
1683 fb
->has_integer_rt
|= fb
->blend_caps
[i
].is_integer
;
1686 first_surf
= state
->cbufs
[i
];
1688 fb_set_blend_caps(dev
, PIPE_FORMAT_NONE
, &fb
->blend_caps
[i
]);
1692 if (!first_surf
&& state
->zsbuf
)
1693 first_surf
= state
->zsbuf
;
1695 fb
->num_samples
= (first_surf
) ? first_surf
->texture
->nr_samples
: 1;
1696 if (!fb
->num_samples
)
1697 fb
->num_samples
= 1;
1700 const struct ilo_surface_cso
*cso
=
1701 (const struct ilo_surface_cso
*) state
->zsbuf
;
1702 const struct ilo_texture
*tex
= ilo_texture(cso
->base
.texture
);
1704 fb
->has_hiz
= cso
->u
.zs
.hiz_vma
;
1705 fb
->depth_offset_format
=
1706 ilo_format_translate_depth(dev
, tex
->image_format
);
1708 fb
->has_hiz
= false;
1709 fb
->depth_offset_format
= GEN6_ZFORMAT_D32_FLOAT
;
1713 * The PRMs list several restrictions when the framebuffer has more than
1714 * one surface. It seems they are actually lifted on GEN6+.
1717 vec
->dirty
|= ILO_DIRTY_FB
;
1721 ilo_set_polygon_stipple(struct pipe_context
*pipe
,
1722 const struct pipe_poly_stipple
*state
)
1724 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1725 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1726 struct ilo_state_poly_stipple_info info
;
1729 for (i
= 0; i
< 32; i
++)
1730 info
.pattern
[i
] = state
->stipple
[i
];
1732 ilo_state_poly_stipple_set_info(&vec
->poly_stipple
, dev
, &info
);
1734 vec
->dirty
|= ILO_DIRTY_POLY_STIPPLE
;
1738 ilo_set_scissor_states(struct pipe_context
*pipe
,
1739 unsigned start_slot
,
1740 unsigned num_scissors
,
1741 const struct pipe_scissor_state
*scissors
)
1743 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1746 for (i
= 0; i
< num_scissors
; i
++) {
1747 struct ilo_state_viewport_scissor_info
*info
=
1748 &vec
->viewport
.scissors
[start_slot
+ i
];
1750 if (scissors
[i
].minx
< scissors
[i
].maxx
&&
1751 scissors
[i
].miny
< scissors
[i
].maxy
) {
1752 info
->min_x
= scissors
[i
].minx
;
1753 info
->min_y
= scissors
[i
].miny
;
1754 info
->max_x
= scissors
[i
].maxx
- 1;
1755 info
->max_y
= scissors
[i
].maxy
- 1;
1764 vec
->dirty
|= ILO_DIRTY_SCISSOR
;
1768 ilo_set_viewport_states(struct pipe_context
*pipe
,
1769 unsigned start_slot
,
1770 unsigned num_viewports
,
1771 const struct pipe_viewport_state
*viewports
)
1773 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1778 for (i
= 0; i
< num_viewports
; i
++) {
1779 struct ilo_state_viewport_matrix_info
*info
=
1780 &vec
->viewport
.matrices
[start_slot
+ i
];
1782 memcpy(info
->scale
, viewports
[i
].scale
, sizeof(info
->scale
));
1783 memcpy(info
->translate
, viewports
[i
].translate
,
1784 sizeof(info
->translate
));
1787 if (vec
->viewport
.params
.count
< start_slot
+ num_viewports
)
1788 vec
->viewport
.params
.count
= start_slot
+ num_viewports
;
1790 /* need to save viewport 0 for util_blitter */
1791 if (!start_slot
&& num_viewports
)
1792 vec
->viewport
.viewport0
= viewports
[0];
1795 if (vec
->viewport
.params
.count
<= start_slot
+ num_viewports
&&
1796 vec
->viewport
.params
.count
> start_slot
)
1797 vec
->viewport
.params
.count
= start_slot
;
1800 vec
->dirty
|= ILO_DIRTY_VIEWPORT
;
1804 ilo_set_sampler_views(struct pipe_context
*pipe
, unsigned shader
,
1805 unsigned start
, unsigned count
,
1806 struct pipe_sampler_view
**views
)
1808 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1809 struct ilo_view_state
*dst
= &vec
->view
[shader
];
1812 assert(start
+ count
<= Elements(dst
->states
));
1815 for (i
= 0; i
< count
; i
++)
1816 pipe_sampler_view_reference(&dst
->states
[start
+ i
], views
[i
]);
1819 for (i
= 0; i
< count
; i
++)
1820 pipe_sampler_view_reference(&dst
->states
[start
+ i
], NULL
);
1823 if (dst
->count
<= start
+ count
) {
1829 while (count
> 0 && !dst
->states
[count
- 1])
1836 case PIPE_SHADER_VERTEX
:
1837 vec
->dirty
|= ILO_DIRTY_VIEW_VS
;
1839 case PIPE_SHADER_GEOMETRY
:
1840 vec
->dirty
|= ILO_DIRTY_VIEW_GS
;
1842 case PIPE_SHADER_FRAGMENT
:
1843 vec
->dirty
|= ILO_DIRTY_VIEW_FS
;
1845 case PIPE_SHADER_COMPUTE
:
1846 vec
->dirty
|= ILO_DIRTY_VIEW_CS
;
1852 ilo_set_shader_images(struct pipe_context
*pipe
, unsigned shader
,
1853 unsigned start
, unsigned count
,
1854 struct pipe_image_view
**views
)
1857 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1858 struct ilo_resource_state
*dst
= &vec
->resource
;
1861 assert(start
+ count
<= Elements(dst
->states
));
1864 for (i
= 0; i
< count
; i
++)
1865 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
1868 for (i
= 0; i
< count
; i
++)
1869 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
1872 if (dst
->count
<= start
+ count
) {
1878 while (count
> 0 && !dst
->states
[count
- 1])
1884 vec
->dirty
|= ILO_DIRTY_RESOURCE
;
1889 ilo_set_vertex_buffers(struct pipe_context
*pipe
,
1890 unsigned start_slot
, unsigned num_buffers
,
1891 const struct pipe_vertex_buffer
*buffers
)
1893 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1896 /* no PIPE_CAP_USER_VERTEX_BUFFERS */
1898 for (i
= 0; i
< num_buffers
; i
++)
1899 assert(!buffers
[i
].user_buffer
);
1902 util_set_vertex_buffers_mask(vec
->vb
.states
,
1903 &vec
->vb
.enabled_mask
, buffers
, start_slot
, num_buffers
);
1905 vec
->dirty
|= ILO_DIRTY_VB
;
1909 ilo_set_index_buffer(struct pipe_context
*pipe
,
1910 const struct pipe_index_buffer
*state
)
1912 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1915 pipe_resource_reference(&vec
->ib
.state
.buffer
, state
->buffer
);
1916 vec
->ib
.state
= *state
;
1918 pipe_resource_reference(&vec
->ib
.state
.buffer
, NULL
);
1919 memset(&vec
->ib
.state
, 0, sizeof(vec
->ib
.state
));
1922 vec
->dirty
|= ILO_DIRTY_IB
;
1925 static struct pipe_stream_output_target
*
1926 ilo_create_stream_output_target(struct pipe_context
*pipe
,
1927 struct pipe_resource
*res
,
1928 unsigned buffer_offset
,
1929 unsigned buffer_size
)
1931 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1932 struct ilo_stream_output_target
*target
;
1933 struct ilo_state_sol_buffer_info info
;
1935 target
= CALLOC_STRUCT(ilo_stream_output_target
);
1938 pipe_reference_init(&target
->base
.reference
, 1);
1939 pipe_resource_reference(&target
->base
.buffer
, res
);
1940 target
->base
.context
= pipe
;
1941 target
->base
.buffer_offset
= buffer_offset
;
1942 target
->base
.buffer_size
= buffer_size
;
1944 memset(&info
, 0, sizeof(info
));
1945 info
.vma
= ilo_resource_get_vma(res
);
1946 info
.offset
= buffer_offset
;
1947 info
.size
= buffer_size
;
1949 ilo_state_sol_buffer_init(&target
->sb
, dev
, &info
);
1951 return &target
->base
;
1955 ilo_set_stream_output_targets(struct pipe_context
*pipe
,
1956 unsigned num_targets
,
1957 struct pipe_stream_output_target
**targets
,
1958 const unsigned *offset
)
1960 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1962 unsigned append_bitmask
= 0;
1967 /* util_blitter may set this unnecessarily */
1968 if (!vec
->so
.count
&& !num_targets
)
1971 for (i
= 0; i
< num_targets
; i
++) {
1972 pipe_so_target_reference(&vec
->so
.states
[i
], targets
[i
]);
1973 if (offset
[i
] == (unsigned)-1)
1974 append_bitmask
|= 1 << i
;
1977 for (; i
< vec
->so
.count
; i
++)
1978 pipe_so_target_reference(&vec
->so
.states
[i
], NULL
);
1980 vec
->so
.count
= num_targets
;
1981 vec
->so
.append_bitmask
= append_bitmask
;
1983 vec
->so
.enabled
= (vec
->so
.count
> 0);
1985 vec
->dirty
|= ILO_DIRTY_SO
;
1989 ilo_stream_output_target_destroy(struct pipe_context
*pipe
,
1990 struct pipe_stream_output_target
*target
)
1992 pipe_resource_reference(&target
->buffer
, NULL
);
1996 static struct pipe_sampler_view
*
1997 ilo_create_sampler_view(struct pipe_context
*pipe
,
1998 struct pipe_resource
*res
,
1999 const struct pipe_sampler_view
*templ
)
2001 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
2002 struct ilo_view_cso
*view
;
2004 view
= CALLOC_STRUCT(ilo_view_cso
);
2007 view
->base
= *templ
;
2008 pipe_reference_init(&view
->base
.reference
, 1);
2009 view
->base
.texture
= NULL
;
2010 pipe_resource_reference(&view
->base
.texture
, res
);
2011 view
->base
.context
= pipe
;
2013 if (res
->target
== PIPE_BUFFER
) {
2014 struct ilo_state_surface_buffer_info info
;
2016 memset(&info
, 0, sizeof(info
));
2017 info
.vma
= ilo_resource_get_vma(res
);
2018 info
.offset
= templ
->u
.buf
.first_element
* info
.struct_size
;
2019 info
.size
= (templ
->u
.buf
.last_element
-
2020 templ
->u
.buf
.first_element
+ 1) * info
.struct_size
;
2021 info
.access
= ILO_STATE_SURFACE_ACCESS_SAMPLER
;
2022 info
.format
= ilo_format_translate_color(dev
, templ
->format
);
2023 info
.format_size
= util_format_get_blocksize(templ
->format
);
2024 info
.struct_size
= info
.format_size
;
2025 info
.readonly
= true;
2027 ilo_state_surface_init_for_buffer(&view
->surface
, dev
, &info
);
2029 struct ilo_texture
*tex
= ilo_texture(res
);
2030 struct ilo_state_surface_image_info info
;
2032 /* warn about degraded performance because of a missing binding flag */
2033 if (tex
->image
.tiling
== GEN6_TILING_NONE
&&
2034 !(tex
->base
.bind
& PIPE_BIND_SAMPLER_VIEW
)) {
2035 ilo_warn("creating sampler view for a resource "
2036 "not created for sampling\n");
2039 memset(&info
, 0, sizeof(info
));
2041 info
.img
= &tex
->image
;
2042 info
.level_base
= templ
->u
.tex
.first_level
;
2043 info
.level_count
= templ
->u
.tex
.last_level
-
2044 templ
->u
.tex
.first_level
+ 1;
2045 info
.slice_base
= templ
->u
.tex
.first_layer
;
2046 info
.slice_count
= templ
->u
.tex
.last_layer
-
2047 templ
->u
.tex
.first_layer
+ 1;
2049 info
.vma
= &tex
->vma
;
2050 info
.access
= ILO_STATE_SURFACE_ACCESS_SAMPLER
;
2051 info
.type
= tex
->image
.type
;
2053 if (templ
->format
== PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
&&
2055 info
.format
= ilo_format_translate_texture(dev
,
2056 PIPE_FORMAT_Z32_FLOAT
);
2058 info
.format
= ilo_format_translate_texture(dev
, templ
->format
);
2061 info
.is_array
= util_resource_is_array_texture(&tex
->base
);
2062 info
.readonly
= true;
2064 ilo_state_surface_init_for_image(&view
->surface
, dev
, &info
);
2071 ilo_sampler_view_destroy(struct pipe_context
*pipe
,
2072 struct pipe_sampler_view
*view
)
2074 pipe_resource_reference(&view
->texture
, NULL
);
2078 static struct pipe_surface
*
2079 ilo_create_surface(struct pipe_context
*pipe
,
2080 struct pipe_resource
*res
,
2081 const struct pipe_surface
*templ
)
2083 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
2084 struct ilo_texture
*tex
= ilo_texture(res
);
2085 struct ilo_surface_cso
*surf
;
2087 surf
= CALLOC_STRUCT(ilo_surface_cso
);
2090 surf
->base
= *templ
;
2091 pipe_reference_init(&surf
->base
.reference
, 1);
2092 surf
->base
.texture
= NULL
;
2093 pipe_resource_reference(&surf
->base
.texture
, &tex
->base
);
2095 surf
->base
.context
= pipe
;
2096 surf
->base
.width
= u_minify(tex
->base
.width0
, templ
->u
.tex
.level
);
2097 surf
->base
.height
= u_minify(tex
->base
.height0
, templ
->u
.tex
.level
);
2099 surf
->is_rt
= !util_format_is_depth_or_stencil(templ
->format
);
2102 struct ilo_state_surface_image_info info
;
2105 assert(tex
->base
.target
!= PIPE_BUFFER
);
2107 memset(&info
, 0, sizeof(info
));
2109 info
.img
= &tex
->image
;
2110 info
.level_base
= templ
->u
.tex
.level
;
2111 info
.level_count
= 1;
2112 info
.slice_base
= templ
->u
.tex
.first_layer
;
2113 info
.slice_count
= templ
->u
.tex
.last_layer
-
2114 templ
->u
.tex
.first_layer
+ 1;
2116 info
.vma
= &tex
->vma
;
2117 if (ilo_image_can_enable_aux(&tex
->image
, templ
->u
.tex
.level
))
2118 info
.aux_vma
= &tex
->aux_vma
;
2120 info
.access
= ILO_STATE_SURFACE_ACCESS_DP_RENDER
;
2122 info
.type
= (tex
->image
.type
== GEN6_SURFTYPE_CUBE
) ?
2123 GEN6_SURFTYPE_2D
: tex
->image
.type
;
2125 info
.format
= ilo_format_translate_render(dev
, templ
->format
);
2126 info
.is_array
= util_resource_is_array_texture(&tex
->base
);
2128 ilo_state_surface_init_for_image(&surf
->u
.rt
, dev
, &info
);
2130 struct ilo_state_zs_info info
;
2132 assert(res
->target
!= PIPE_BUFFER
);
2134 memset(&info
, 0, sizeof(info
));
2136 if (templ
->format
== PIPE_FORMAT_S8_UINT
) {
2137 info
.s_vma
= &tex
->vma
;
2138 info
.s_img
= &tex
->image
;
2140 info
.z_vma
= &tex
->vma
;
2141 info
.z_img
= &tex
->image
;
2143 if (tex
->separate_s8
) {
2144 info
.s_vma
= &tex
->separate_s8
->vma
;
2145 info
.s_img
= &tex
->separate_s8
->image
;
2148 if (ilo_image_can_enable_aux(&tex
->image
, templ
->u
.tex
.level
))
2149 info
.hiz_vma
= &tex
->aux_vma
;
2152 info
.level
= templ
->u
.tex
.level
;
2153 info
.slice_base
= templ
->u
.tex
.first_layer
;
2154 info
.slice_count
= templ
->u
.tex
.last_layer
-
2155 templ
->u
.tex
.first_layer
+ 1;
2157 info
.type
= (tex
->image
.type
== GEN6_SURFTYPE_CUBE
) ?
2158 GEN6_SURFTYPE_2D
: tex
->image
.type
;
2160 info
.format
= ilo_format_translate_depth(dev
, tex
->image_format
);
2161 if (ilo_dev_gen(dev
) == ILO_GEN(6) && !info
.hiz_vma
&&
2162 tex
->image_format
== PIPE_FORMAT_Z24X8_UNORM
)
2163 info
.format
= GEN6_ZFORMAT_D24_UNORM_S8_UINT
;
2165 ilo_state_zs_init(&surf
->u
.zs
, dev
, &info
);
2172 ilo_surface_destroy(struct pipe_context
*pipe
,
2173 struct pipe_surface
*surface
)
2175 pipe_resource_reference(&surface
->texture
, NULL
);
2180 ilo_create_compute_state(struct pipe_context
*pipe
,
2181 const struct pipe_compute_state
*state
)
2183 struct ilo_context
*ilo
= ilo_context(pipe
);
2184 struct ilo_shader_state
*shader
;
2186 shader
= ilo_shader_create_cs(ilo
->dev
, state
, &ilo
->state_vector
);
2189 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
2195 ilo_bind_compute_state(struct pipe_context
*pipe
, void *state
)
2197 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
2201 vec
->dirty
|= ILO_DIRTY_CS
;
2205 ilo_delete_compute_state(struct pipe_context
*pipe
, void *state
)
2207 struct ilo_context
*ilo
= ilo_context(pipe
);
2208 struct ilo_shader_state
*cs
= (struct ilo_shader_state
*) state
;
2210 ilo_shader_cache_remove(ilo
->shader_cache
, cs
);
2211 ilo_shader_destroy(cs
);
2215 ilo_set_compute_resources(struct pipe_context
*pipe
,
2216 unsigned start
, unsigned count
,
2217 struct pipe_surface
**surfaces
)
2219 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
2220 struct ilo_resource_state
*dst
= &vec
->cs_resource
;
2223 assert(start
+ count
<= Elements(dst
->states
));
2226 for (i
= 0; i
< count
; i
++)
2227 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
2230 for (i
= 0; i
< count
; i
++)
2231 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
2234 if (dst
->count
<= start
+ count
) {
2240 while (count
> 0 && !dst
->states
[count
- 1])
2246 vec
->dirty
|= ILO_DIRTY_CS_RESOURCE
;
2250 ilo_set_global_binding(struct pipe_context
*pipe
,
2251 unsigned start
, unsigned count
,
2252 struct pipe_resource
**resources
,
2255 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
2256 struct ilo_global_binding_cso
*dst
;
2260 if (vec
->global_binding
.count
< start
+ count
) {
2262 const unsigned old_size
= vec
->global_binding
.bindings
.size
;
2263 const unsigned new_size
= sizeof(*dst
) * (start
+ count
);
2265 if (old_size
< new_size
) {
2266 util_dynarray_resize(&vec
->global_binding
.bindings
, new_size
);
2267 memset(vec
->global_binding
.bindings
.data
+ old_size
, 0,
2268 new_size
- old_size
);
2271 count
= vec
->global_binding
.count
- start
;
2275 dst
= util_dynarray_element(&vec
->global_binding
.bindings
,
2276 struct ilo_global_binding_cso
, start
);
2279 for (i
= 0; i
< count
; i
++) {
2280 pipe_resource_reference(&dst
[i
].resource
, resources
[i
]);
2281 dst
[i
].handle
= handles
[i
];
2284 for (i
= 0; i
< count
; i
++) {
2285 pipe_resource_reference(&dst
[i
].resource
, NULL
);
2286 dst
[i
].handle
= NULL
;
2290 if (vec
->global_binding
.count
<= start
+ count
) {
2291 dst
= util_dynarray_begin(&vec
->global_binding
.bindings
);
2298 while (count
> 0 && !dst
[count
- 1].resource
)
2301 vec
->global_binding
.count
= count
;
2304 vec
->dirty
|= ILO_DIRTY_GLOBAL_BINDING
;
2308 * Initialize state-related functions.
2311 ilo_init_state_functions(struct ilo_context
*ilo
)
2313 STATIC_ASSERT(ILO_STATE_COUNT
<= 32);
2315 ilo
->base
.create_blend_state
= ilo_create_blend_state
;
2316 ilo
->base
.bind_blend_state
= ilo_bind_blend_state
;
2317 ilo
->base
.delete_blend_state
= ilo_delete_blend_state
;
2318 ilo
->base
.create_sampler_state
= ilo_create_sampler_state
;
2319 ilo
->base
.bind_sampler_states
= ilo_bind_sampler_states
;
2320 ilo
->base
.delete_sampler_state
= ilo_delete_sampler_state
;
2321 ilo
->base
.create_rasterizer_state
= ilo_create_rasterizer_state
;
2322 ilo
->base
.bind_rasterizer_state
= ilo_bind_rasterizer_state
;
2323 ilo
->base
.delete_rasterizer_state
= ilo_delete_rasterizer_state
;
2324 ilo
->base
.create_depth_stencil_alpha_state
= ilo_create_depth_stencil_alpha_state
;
2325 ilo
->base
.bind_depth_stencil_alpha_state
= ilo_bind_depth_stencil_alpha_state
;
2326 ilo
->base
.delete_depth_stencil_alpha_state
= ilo_delete_depth_stencil_alpha_state
;
2327 ilo
->base
.create_fs_state
= ilo_create_fs_state
;
2328 ilo
->base
.bind_fs_state
= ilo_bind_fs_state
;
2329 ilo
->base
.delete_fs_state
= ilo_delete_fs_state
;
2330 ilo
->base
.create_vs_state
= ilo_create_vs_state
;
2331 ilo
->base
.bind_vs_state
= ilo_bind_vs_state
;
2332 ilo
->base
.delete_vs_state
= ilo_delete_vs_state
;
2333 ilo
->base
.create_gs_state
= ilo_create_gs_state
;
2334 ilo
->base
.bind_gs_state
= ilo_bind_gs_state
;
2335 ilo
->base
.delete_gs_state
= ilo_delete_gs_state
;
2336 ilo
->base
.create_vertex_elements_state
= ilo_create_vertex_elements_state
;
2337 ilo
->base
.bind_vertex_elements_state
= ilo_bind_vertex_elements_state
;
2338 ilo
->base
.delete_vertex_elements_state
= ilo_delete_vertex_elements_state
;
2340 ilo
->base
.set_blend_color
= ilo_set_blend_color
;
2341 ilo
->base
.set_stencil_ref
= ilo_set_stencil_ref
;
2342 ilo
->base
.set_sample_mask
= ilo_set_sample_mask
;
2343 ilo
->base
.set_clip_state
= ilo_set_clip_state
;
2344 ilo
->base
.set_constant_buffer
= ilo_set_constant_buffer
;
2345 ilo
->base
.set_framebuffer_state
= ilo_set_framebuffer_state
;
2346 ilo
->base
.set_polygon_stipple
= ilo_set_polygon_stipple
;
2347 ilo
->base
.set_scissor_states
= ilo_set_scissor_states
;
2348 ilo
->base
.set_viewport_states
= ilo_set_viewport_states
;
2349 ilo
->base
.set_sampler_views
= ilo_set_sampler_views
;
2350 ilo
->base
.set_shader_images
= ilo_set_shader_images
;
2351 ilo
->base
.set_vertex_buffers
= ilo_set_vertex_buffers
;
2352 ilo
->base
.set_index_buffer
= ilo_set_index_buffer
;
2354 ilo
->base
.create_stream_output_target
= ilo_create_stream_output_target
;
2355 ilo
->base
.stream_output_target_destroy
= ilo_stream_output_target_destroy
;
2356 ilo
->base
.set_stream_output_targets
= ilo_set_stream_output_targets
;
2358 ilo
->base
.create_sampler_view
= ilo_create_sampler_view
;
2359 ilo
->base
.sampler_view_destroy
= ilo_sampler_view_destroy
;
2361 ilo
->base
.create_surface
= ilo_create_surface
;
2362 ilo
->base
.surface_destroy
= ilo_surface_destroy
;
2364 ilo
->base
.create_compute_state
= ilo_create_compute_state
;
2365 ilo
->base
.bind_compute_state
= ilo_bind_compute_state
;
2366 ilo
->base
.delete_compute_state
= ilo_delete_compute_state
;
2367 ilo
->base
.set_compute_resources
= ilo_set_compute_resources
;
2368 ilo
->base
.set_global_binding
= ilo_set_global_binding
;
2372 ilo_state_vector_init(const struct ilo_dev
*dev
,
2373 struct ilo_state_vector
*vec
)
2375 struct ilo_state_urb_info urb_info
;
2377 vec
->sample_mask
= ~0u;
2379 ilo_state_viewport_init_data_only(&vec
->viewport
.vp
, dev
,
2380 vec
->viewport
.vp_data
, sizeof(vec
->viewport
.vp_data
));
2381 assert(vec
->viewport
.vp
.array_size
>= ILO_MAX_VIEWPORTS
);
2383 vec
->viewport
.params
.matrices
= vec
->viewport
.matrices
;
2384 vec
->viewport
.params
.scissors
= vec
->viewport
.scissors
;
2386 ilo_state_hs_init_disabled(&vec
->disabled_hs
, dev
);
2387 ilo_state_ds_init_disabled(&vec
->disabled_ds
, dev
);
2388 ilo_state_gs_init_disabled(&vec
->disabled_gs
, dev
);
2390 ilo_state_sol_buffer_init_disabled(&vec
->so
.dummy_sb
, dev
);
2392 ilo_state_surface_init_for_null(&vec
->fb
.null_rt
, dev
);
2393 ilo_state_zs_init_for_null(&vec
->fb
.null_zs
, dev
);
2395 ilo_state_sampler_init_disabled(&vec
->disabled_sampler
, dev
);
2397 memset(&urb_info
, 0, sizeof(urb_info
));
2398 ilo_state_urb_init(&vec
->urb
, dev
, &urb_info
);
2400 util_dynarray_init(&vec
->global_binding
.bindings
);
2402 vec
->dirty
= ILO_DIRTY_ALL
;
2406 ilo_state_vector_cleanup(struct ilo_state_vector
*vec
)
2410 for (i
= 0; i
< Elements(vec
->vb
.states
); i
++) {
2411 if (vec
->vb
.enabled_mask
& (1 << i
))
2412 pipe_resource_reference(&vec
->vb
.states
[i
].buffer
, NULL
);
2415 pipe_resource_reference(&vec
->ib
.state
.buffer
, NULL
);
2416 pipe_resource_reference(&vec
->ib
.hw_resource
, NULL
);
2418 for (i
= 0; i
< vec
->so
.count
; i
++)
2419 pipe_so_target_reference(&vec
->so
.states
[i
], NULL
);
2421 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
2422 for (i
= 0; i
< vec
->view
[sh
].count
; i
++) {
2423 struct pipe_sampler_view
*view
= vec
->view
[sh
].states
[i
];
2424 pipe_sampler_view_reference(&view
, NULL
);
2427 for (i
= 0; i
< Elements(vec
->cbuf
[sh
].cso
); i
++) {
2428 struct ilo_cbuf_cso
*cbuf
= &vec
->cbuf
[sh
].cso
[i
];
2429 pipe_resource_reference(&cbuf
->resource
, NULL
);
2433 for (i
= 0; i
< vec
->resource
.count
; i
++)
2434 pipe_surface_reference(&vec
->resource
.states
[i
], NULL
);
2436 for (i
= 0; i
< vec
->fb
.state
.nr_cbufs
; i
++)
2437 pipe_surface_reference(&vec
->fb
.state
.cbufs
[i
], NULL
);
2439 if (vec
->fb
.state
.zsbuf
)
2440 pipe_surface_reference(&vec
->fb
.state
.zsbuf
, NULL
);
2442 for (i
= 0; i
< vec
->cs_resource
.count
; i
++)
2443 pipe_surface_reference(&vec
->cs_resource
.states
[i
], NULL
);
2445 for (i
= 0; i
< vec
->global_binding
.count
; i
++) {
2446 struct ilo_global_binding_cso
*cso
=
2447 util_dynarray_element(&vec
->global_binding
.bindings
,
2448 struct ilo_global_binding_cso
, i
);
2449 pipe_resource_reference(&cso
->resource
, NULL
);
2452 util_dynarray_fini(&vec
->global_binding
.bindings
);
2456 * Mark all states that have the resource dirty.
2459 ilo_state_vector_resource_renamed(struct ilo_state_vector
*vec
,
2460 struct pipe_resource
*res
)
2462 uint32_t states
= 0;
2465 if (res
->target
== PIPE_BUFFER
) {
2466 uint32_t vb_mask
= vec
->vb
.enabled_mask
;
2469 const unsigned idx
= u_bit_scan(&vb_mask
);
2471 if (vec
->vb
.states
[idx
].buffer
== res
) {
2472 states
|= ILO_DIRTY_VB
;
2477 if (vec
->ib
.state
.buffer
== res
) {
2478 states
|= ILO_DIRTY_IB
;
2481 * finalize_index_buffer() has an optimization that clears
2482 * ILO_DIRTY_IB when the HW states do not change. However, it fails
2483 * to flush the VF cache when the HW states do not change, but the
2484 * contents of the IB has changed. Here, we set the index size to an
2485 * invalid value to avoid the optimization.
2487 vec
->ib
.hw_index_size
= 0;
2490 for (i
= 0; i
< vec
->so
.count
; i
++) {
2491 if (vec
->so
.states
[i
]->buffer
== res
) {
2492 states
|= ILO_DIRTY_SO
;
2498 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
2499 for (i
= 0; i
< vec
->view
[sh
].count
; i
++) {
2500 struct ilo_view_cso
*cso
= (struct ilo_view_cso
*) vec
->view
[sh
].states
[i
];
2502 if (cso
->base
.texture
== res
) {
2503 static const unsigned view_dirty_bits
[PIPE_SHADER_TYPES
] = {
2504 [PIPE_SHADER_VERTEX
] = ILO_DIRTY_VIEW_VS
,
2505 [PIPE_SHADER_FRAGMENT
] = ILO_DIRTY_VIEW_FS
,
2506 [PIPE_SHADER_GEOMETRY
] = ILO_DIRTY_VIEW_GS
,
2507 [PIPE_SHADER_COMPUTE
] = ILO_DIRTY_VIEW_CS
,
2510 states
|= view_dirty_bits
[sh
];
2515 if (res
->target
== PIPE_BUFFER
) {
2516 for (i
= 0; i
< Elements(vec
->cbuf
[sh
].cso
); i
++) {
2517 struct ilo_cbuf_cso
*cbuf
= &vec
->cbuf
[sh
].cso
[i
];
2519 if (cbuf
->resource
== res
) {
2520 states
|= ILO_DIRTY_CBUF
;
2527 for (i
= 0; i
< vec
->resource
.count
; i
++) {
2528 struct ilo_surface_cso
*cso
=
2529 (struct ilo_surface_cso
*) vec
->resource
.states
[i
];
2531 if (cso
->base
.texture
== res
) {
2532 states
|= ILO_DIRTY_RESOURCE
;
2538 if (res
->target
!= PIPE_BUFFER
) {
2539 for (i
= 0; i
< vec
->fb
.state
.nr_cbufs
; i
++) {
2540 struct ilo_surface_cso
*cso
=
2541 (struct ilo_surface_cso
*) vec
->fb
.state
.cbufs
[i
];
2542 if (cso
&& cso
->base
.texture
== res
) {
2543 states
|= ILO_DIRTY_FB
;
2548 if (vec
->fb
.state
.zsbuf
&& vec
->fb
.state
.zsbuf
->texture
== res
)
2549 states
|= ILO_DIRTY_FB
;
2552 for (i
= 0; i
< vec
->cs_resource
.count
; i
++) {
2553 struct ilo_surface_cso
*cso
=
2554 (struct ilo_surface_cso
*) vec
->cs_resource
.states
[i
];
2555 if (cso
->base
.texture
== res
) {
2556 states
|= ILO_DIRTY_CS_RESOURCE
;
2561 for (i
= 0; i
< vec
->global_binding
.count
; i
++) {
2562 struct ilo_global_binding_cso
*cso
=
2563 util_dynarray_element(&vec
->global_binding
.bindings
,
2564 struct ilo_global_binding_cso
, i
);
2566 if (cso
->resource
== res
) {
2567 states
|= ILO_DIRTY_GLOBAL_BINDING
;
2572 vec
->dirty
|= states
;
2576 ilo_state_vector_dump_dirty(const struct ilo_state_vector
*vec
)
2578 static const char *state_names
[ILO_STATE_COUNT
] = {
2579 [ILO_STATE_VB
] = "VB",
2580 [ILO_STATE_VE
] = "VE",
2581 [ILO_STATE_IB
] = "IB",
2582 [ILO_STATE_VS
] = "VS",
2583 [ILO_STATE_GS
] = "GS",
2584 [ILO_STATE_SO
] = "SO",
2585 [ILO_STATE_CLIP
] = "CLIP",
2586 [ILO_STATE_VIEWPORT
] = "VIEWPORT",
2587 [ILO_STATE_SCISSOR
] = "SCISSOR",
2588 [ILO_STATE_RASTERIZER
] = "RASTERIZER",
2589 [ILO_STATE_POLY_STIPPLE
] = "POLY_STIPPLE",
2590 [ILO_STATE_SAMPLE_MASK
] = "SAMPLE_MASK",
2591 [ILO_STATE_FS
] = "FS",
2592 [ILO_STATE_DSA
] = "DSA",
2593 [ILO_STATE_STENCIL_REF
] = "STENCIL_REF",
2594 [ILO_STATE_BLEND
] = "BLEND",
2595 [ILO_STATE_BLEND_COLOR
] = "BLEND_COLOR",
2596 [ILO_STATE_FB
] = "FB",
2597 [ILO_STATE_SAMPLER_VS
] = "SAMPLER_VS",
2598 [ILO_STATE_SAMPLER_GS
] = "SAMPLER_GS",
2599 [ILO_STATE_SAMPLER_FS
] = "SAMPLER_FS",
2600 [ILO_STATE_SAMPLER_CS
] = "SAMPLER_CS",
2601 [ILO_STATE_VIEW_VS
] = "VIEW_VS",
2602 [ILO_STATE_VIEW_GS
] = "VIEW_GS",
2603 [ILO_STATE_VIEW_FS
] = "VIEW_FS",
2604 [ILO_STATE_VIEW_CS
] = "VIEW_CS",
2605 [ILO_STATE_CBUF
] = "CBUF",
2606 [ILO_STATE_RESOURCE
] = "RESOURCE",
2607 [ILO_STATE_CS
] = "CS",
2608 [ILO_STATE_CS_RESOURCE
] = "CS_RESOURCE",
2609 [ILO_STATE_GLOBAL_BINDING
] = "GLOBAL_BINDING",
2611 uint32_t dirty
= vec
->dirty
;
2614 ilo_printf("no state is dirty\n");
2618 dirty
&= (1U << ILO_STATE_COUNT
) - 1;
2620 ilo_printf("%2d states are dirty:", util_bitcount(dirty
));
2622 const enum ilo_state state
= u_bit_scan(&dirty
);
2623 ilo_printf(" %s", state_names
[state
]);