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_builder_3d.h" /* for gen6_3d_translate_pipe_prim() */
29 #include "core/ilo_format.h"
30 #include "core/ilo_state_3d.h"
31 #include "util/u_dual_blend.h"
32 #include "util/u_dynarray.h"
33 #include "util/u_helpers.h"
34 #include "util/u_resource.h"
35 #include "util/u_upload_mgr.h"
37 #include "ilo_context.h"
38 #include "ilo_resource.h"
39 #include "ilo_shader.h"
40 #include "ilo_state.h"
42 static enum gen_mip_filter
43 ilo_translate_mip_filter(unsigned filter
)
46 case PIPE_TEX_MIPFILTER_NEAREST
: return GEN6_MIPFILTER_NEAREST
;
47 case PIPE_TEX_MIPFILTER_LINEAR
: return GEN6_MIPFILTER_LINEAR
;
48 case PIPE_TEX_MIPFILTER_NONE
: return GEN6_MIPFILTER_NONE
;
50 assert(!"unknown mipfilter");
51 return GEN6_MIPFILTER_NONE
;
56 ilo_translate_img_filter(unsigned filter
)
59 case PIPE_TEX_FILTER_NEAREST
: return GEN6_MAPFILTER_NEAREST
;
60 case PIPE_TEX_FILTER_LINEAR
: return GEN6_MAPFILTER_LINEAR
;
62 assert(!"unknown sampler filter");
63 return GEN6_MAPFILTER_NEAREST
;
67 static enum gen_texcoord_mode
68 ilo_translate_address_wrap(unsigned wrap
)
71 case PIPE_TEX_WRAP_CLAMP
: return GEN8_TEXCOORDMODE_HALF_BORDER
;
72 case PIPE_TEX_WRAP_REPEAT
: return GEN6_TEXCOORDMODE_WRAP
;
73 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
: return GEN6_TEXCOORDMODE_CLAMP
;
74 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
: return GEN6_TEXCOORDMODE_CLAMP_BORDER
;
75 case PIPE_TEX_WRAP_MIRROR_REPEAT
: return GEN6_TEXCOORDMODE_MIRROR
;
76 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
77 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
78 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
80 assert(!"unknown sampler wrap mode");
81 return GEN6_TEXCOORDMODE_WRAP
;
85 static enum gen_aniso_ratio
86 ilo_translate_max_anisotropy(unsigned max_anisotropy
)
88 switch (max_anisotropy
) {
89 case 0: case 1: case 2: return GEN6_ANISORATIO_2
;
90 case 3: case 4: return GEN6_ANISORATIO_4
;
91 case 5: case 6: return GEN6_ANISORATIO_6
;
92 case 7: case 8: return GEN6_ANISORATIO_8
;
93 case 9: case 10: return GEN6_ANISORATIO_10
;
94 case 11: case 12: return GEN6_ANISORATIO_12
;
95 case 13: case 14: return GEN6_ANISORATIO_14
;
96 default: return GEN6_ANISORATIO_16
;
100 static enum gen_prefilter_op
101 ilo_translate_shadow_func(unsigned func
)
104 * For PIPE_FUNC_x, the reference value is on the left-hand side of the
105 * comparison, and 1.0 is returned when the comparison is true.
107 * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
108 * the comparison, and 0.0 is returned when the comparison is true.
111 case PIPE_FUNC_NEVER
: return GEN6_PREFILTEROP_ALWAYS
;
112 case PIPE_FUNC_LESS
: return GEN6_PREFILTEROP_LEQUAL
;
113 case PIPE_FUNC_EQUAL
: return GEN6_PREFILTEROP_NOTEQUAL
;
114 case PIPE_FUNC_LEQUAL
: return GEN6_PREFILTEROP_LESS
;
115 case PIPE_FUNC_GREATER
: return GEN6_PREFILTEROP_GEQUAL
;
116 case PIPE_FUNC_NOTEQUAL
: return GEN6_PREFILTEROP_EQUAL
;
117 case PIPE_FUNC_GEQUAL
: return GEN6_PREFILTEROP_GREATER
;
118 case PIPE_FUNC_ALWAYS
: return GEN6_PREFILTEROP_NEVER
;
120 assert(!"unknown shadow compare function");
121 return GEN6_PREFILTEROP_NEVER
;
125 static enum gen_front_winding
126 ilo_translate_front_ccw(unsigned front_ccw
)
128 return (front_ccw
) ? GEN6_FRONTWINDING_CCW
: GEN6_FRONTWINDING_CW
;
131 static enum gen_cull_mode
132 ilo_translate_cull_face(unsigned cull_face
)
135 case PIPE_FACE_NONE
: return GEN6_CULLMODE_NONE
;
136 case PIPE_FACE_FRONT
: return GEN6_CULLMODE_FRONT
;
137 case PIPE_FACE_BACK
: return GEN6_CULLMODE_BACK
;
138 case PIPE_FACE_FRONT_AND_BACK
: return GEN6_CULLMODE_BOTH
;
140 assert(!"unknown face culling");
141 return GEN6_CULLMODE_NONE
;
145 static enum gen_fill_mode
146 ilo_translate_poly_mode(unsigned poly_mode
)
149 case PIPE_POLYGON_MODE_FILL
: return GEN6_FILLMODE_SOLID
;
150 case PIPE_POLYGON_MODE_LINE
: return GEN6_FILLMODE_WIREFRAME
;
151 case PIPE_POLYGON_MODE_POINT
: return GEN6_FILLMODE_POINT
;
153 assert(!"unknown polygon mode");
154 return GEN6_FILLMODE_SOLID
;
158 static enum gen_pixel_location
159 ilo_translate_half_pixel_center(bool half_pixel_center
)
161 return (half_pixel_center
) ? GEN6_PIXLOC_CENTER
: GEN6_PIXLOC_UL_CORNER
;
164 static enum gen_compare_function
165 ilo_translate_compare_func(unsigned func
)
168 case PIPE_FUNC_NEVER
: return GEN6_COMPAREFUNCTION_NEVER
;
169 case PIPE_FUNC_LESS
: return GEN6_COMPAREFUNCTION_LESS
;
170 case PIPE_FUNC_EQUAL
: return GEN6_COMPAREFUNCTION_EQUAL
;
171 case PIPE_FUNC_LEQUAL
: return GEN6_COMPAREFUNCTION_LEQUAL
;
172 case PIPE_FUNC_GREATER
: return GEN6_COMPAREFUNCTION_GREATER
;
173 case PIPE_FUNC_NOTEQUAL
: return GEN6_COMPAREFUNCTION_NOTEQUAL
;
174 case PIPE_FUNC_GEQUAL
: return GEN6_COMPAREFUNCTION_GEQUAL
;
175 case PIPE_FUNC_ALWAYS
: return GEN6_COMPAREFUNCTION_ALWAYS
;
177 assert(!"unknown compare function");
178 return GEN6_COMPAREFUNCTION_NEVER
;
182 static enum gen_stencil_op
183 ilo_translate_stencil_op(unsigned stencil_op
)
185 switch (stencil_op
) {
186 case PIPE_STENCIL_OP_KEEP
: return GEN6_STENCILOP_KEEP
;
187 case PIPE_STENCIL_OP_ZERO
: return GEN6_STENCILOP_ZERO
;
188 case PIPE_STENCIL_OP_REPLACE
: return GEN6_STENCILOP_REPLACE
;
189 case PIPE_STENCIL_OP_INCR
: return GEN6_STENCILOP_INCRSAT
;
190 case PIPE_STENCIL_OP_DECR
: return GEN6_STENCILOP_DECRSAT
;
191 case PIPE_STENCIL_OP_INCR_WRAP
: return GEN6_STENCILOP_INCR
;
192 case PIPE_STENCIL_OP_DECR_WRAP
: return GEN6_STENCILOP_DECR
;
193 case PIPE_STENCIL_OP_INVERT
: return GEN6_STENCILOP_INVERT
;
195 assert(!"unknown stencil op");
196 return GEN6_STENCILOP_KEEP
;
200 static enum gen_logic_op
201 ilo_translate_logicop(unsigned logicop
)
204 case PIPE_LOGICOP_CLEAR
: return GEN6_LOGICOP_CLEAR
;
205 case PIPE_LOGICOP_NOR
: return GEN6_LOGICOP_NOR
;
206 case PIPE_LOGICOP_AND_INVERTED
: return GEN6_LOGICOP_AND_INVERTED
;
207 case PIPE_LOGICOP_COPY_INVERTED
: return GEN6_LOGICOP_COPY_INVERTED
;
208 case PIPE_LOGICOP_AND_REVERSE
: return GEN6_LOGICOP_AND_REVERSE
;
209 case PIPE_LOGICOP_INVERT
: return GEN6_LOGICOP_INVERT
;
210 case PIPE_LOGICOP_XOR
: return GEN6_LOGICOP_XOR
;
211 case PIPE_LOGICOP_NAND
: return GEN6_LOGICOP_NAND
;
212 case PIPE_LOGICOP_AND
: return GEN6_LOGICOP_AND
;
213 case PIPE_LOGICOP_EQUIV
: return GEN6_LOGICOP_EQUIV
;
214 case PIPE_LOGICOP_NOOP
: return GEN6_LOGICOP_NOOP
;
215 case PIPE_LOGICOP_OR_INVERTED
: return GEN6_LOGICOP_OR_INVERTED
;
216 case PIPE_LOGICOP_COPY
: return GEN6_LOGICOP_COPY
;
217 case PIPE_LOGICOP_OR_REVERSE
: return GEN6_LOGICOP_OR_REVERSE
;
218 case PIPE_LOGICOP_OR
: return GEN6_LOGICOP_OR
;
219 case PIPE_LOGICOP_SET
: return GEN6_LOGICOP_SET
;
221 assert(!"unknown logicop function");
222 return GEN6_LOGICOP_CLEAR
;
227 ilo_translate_blend_func(unsigned blend
)
230 case PIPE_BLEND_ADD
: return GEN6_BLENDFUNCTION_ADD
;
231 case PIPE_BLEND_SUBTRACT
: return GEN6_BLENDFUNCTION_SUBTRACT
;
232 case PIPE_BLEND_REVERSE_SUBTRACT
: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT
;
233 case PIPE_BLEND_MIN
: return GEN6_BLENDFUNCTION_MIN
;
234 case PIPE_BLEND_MAX
: return GEN6_BLENDFUNCTION_MAX
;
236 assert(!"unknown blend function");
237 return GEN6_BLENDFUNCTION_ADD
;
242 ilo_translate_blend_factor(unsigned factor
)
245 case PIPE_BLENDFACTOR_ONE
: return GEN6_BLENDFACTOR_ONE
;
246 case PIPE_BLENDFACTOR_SRC_COLOR
: return GEN6_BLENDFACTOR_SRC_COLOR
;
247 case PIPE_BLENDFACTOR_SRC_ALPHA
: return GEN6_BLENDFACTOR_SRC_ALPHA
;
248 case PIPE_BLENDFACTOR_DST_ALPHA
: return GEN6_BLENDFACTOR_DST_ALPHA
;
249 case PIPE_BLENDFACTOR_DST_COLOR
: return GEN6_BLENDFACTOR_DST_COLOR
;
250 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE
;
251 case PIPE_BLENDFACTOR_CONST_COLOR
: return GEN6_BLENDFACTOR_CONST_COLOR
;
252 case PIPE_BLENDFACTOR_CONST_ALPHA
: return GEN6_BLENDFACTOR_CONST_ALPHA
;
253 case PIPE_BLENDFACTOR_SRC1_COLOR
: return GEN6_BLENDFACTOR_SRC1_COLOR
;
254 case PIPE_BLENDFACTOR_SRC1_ALPHA
: return GEN6_BLENDFACTOR_SRC1_ALPHA
;
255 case PIPE_BLENDFACTOR_ZERO
: return GEN6_BLENDFACTOR_ZERO
;
256 case PIPE_BLENDFACTOR_INV_SRC_COLOR
: return GEN6_BLENDFACTOR_INV_SRC_COLOR
;
257 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
: return GEN6_BLENDFACTOR_INV_SRC_ALPHA
;
258 case PIPE_BLENDFACTOR_INV_DST_ALPHA
: return GEN6_BLENDFACTOR_INV_DST_ALPHA
;
259 case PIPE_BLENDFACTOR_INV_DST_COLOR
: return GEN6_BLENDFACTOR_INV_DST_COLOR
;
260 case PIPE_BLENDFACTOR_INV_CONST_COLOR
: return GEN6_BLENDFACTOR_INV_CONST_COLOR
;
261 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
: return GEN6_BLENDFACTOR_INV_CONST_ALPHA
;
262 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
: return GEN6_BLENDFACTOR_INV_SRC1_COLOR
;
263 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA
;
265 assert(!"unknown blend factor");
266 return GEN6_BLENDFACTOR_ONE
;
271 finalize_shader_states(struct ilo_state_vector
*vec
)
275 for (type
= 0; type
< PIPE_SHADER_TYPES
; type
++) {
276 struct ilo_shader_state
*shader
;
280 case PIPE_SHADER_VERTEX
:
282 state
= ILO_DIRTY_VS
;
284 case PIPE_SHADER_GEOMETRY
:
286 state
= ILO_DIRTY_GS
;
288 case PIPE_SHADER_FRAGMENT
:
290 state
= ILO_DIRTY_FS
;
301 /* compile if the shader or the states it depends on changed */
302 if (vec
->dirty
& state
) {
303 ilo_shader_select_kernel(shader
, vec
, ILO_DIRTY_ALL
);
305 else if (ilo_shader_select_kernel(shader
, vec
, vec
->dirty
)) {
306 /* mark the state dirty if a new kernel is selected */
310 /* need to setup SBE for FS */
311 if (type
== PIPE_SHADER_FRAGMENT
&& vec
->dirty
&
312 (state
| ILO_DIRTY_GS
| ILO_DIRTY_VS
| ILO_DIRTY_RASTERIZER
)) {
313 if (ilo_shader_select_kernel_routing(shader
,
314 (vec
->gs
) ? vec
->gs
: vec
->vs
, vec
->rasterizer
))
321 finalize_cbuf_state(struct ilo_context
*ilo
,
322 struct ilo_cbuf_state
*cbuf
,
323 const struct ilo_shader_state
*sh
)
325 uint32_t upload_mask
= cbuf
->enabled_mask
;
327 /* skip CBUF0 if the kernel does not need it */
329 ~ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SKIP_CBUF0_UPLOAD
);
331 while (upload_mask
) {
334 i
= u_bit_scan(&upload_mask
);
335 /* no need to upload */
336 if (cbuf
->cso
[i
].resource
)
339 u_upload_data(ilo
->uploader
, 0, cbuf
->cso
[i
].info
.size
,
340 cbuf
->cso
[i
].user_buffer
, &offset
, &cbuf
->cso
[i
].resource
);
342 cbuf
->cso
[i
].info
.buf
= ilo_buffer(cbuf
->cso
[i
].resource
);
343 cbuf
->cso
[i
].info
.offset
= offset
;
345 memset(&cbuf
->cso
[i
].surface
, 0, sizeof(cbuf
->cso
[i
].surface
));
346 ilo_state_surface_init_for_buffer(&cbuf
->cso
[i
].surface
,
347 ilo
->dev
, &cbuf
->cso
[i
].info
);
348 cbuf
->cso
[i
].surface
.bo
= cbuf
->cso
[i
].info
.buf
->bo
;
350 ilo
->state_vector
.dirty
|= ILO_DIRTY_CBUF
;
355 finalize_constant_buffers(struct ilo_context
*ilo
)
357 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
359 if (vec
->dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_VS
))
360 finalize_cbuf_state(ilo
, &vec
->cbuf
[PIPE_SHADER_VERTEX
], vec
->vs
);
362 if (ilo
->state_vector
.dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_FS
))
363 finalize_cbuf_state(ilo
, &vec
->cbuf
[PIPE_SHADER_FRAGMENT
], vec
->fs
);
367 finalize_index_buffer(struct ilo_context
*ilo
)
369 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
370 const bool need_upload
= (vec
->draw
->indexed
&&
371 (vec
->ib
.user_buffer
|| vec
->ib
.offset
% vec
->ib
.index_size
));
372 struct pipe_resource
*current_hw_res
= NULL
;
374 if (!(vec
->dirty
& ILO_DIRTY_IB
) && !need_upload
)
377 pipe_resource_reference(¤t_hw_res
, vec
->ib
.hw_resource
);
380 const unsigned offset
= vec
->ib
.index_size
* vec
->draw
->start
;
381 const unsigned size
= vec
->ib
.index_size
* vec
->draw
->count
;
384 if (vec
->ib
.user_buffer
) {
385 u_upload_data(ilo
->uploader
, 0, size
,
386 vec
->ib
.user_buffer
+ offset
, &hw_offset
, &vec
->ib
.hw_resource
);
389 u_upload_buffer(ilo
->uploader
, 0, vec
->ib
.offset
+ offset
, size
,
390 vec
->ib
.buffer
, &hw_offset
, &vec
->ib
.hw_resource
);
393 /* the HW offset should be aligned */
394 assert(hw_offset
% vec
->ib
.index_size
== 0);
395 vec
->ib
.draw_start_offset
= hw_offset
/ vec
->ib
.index_size
;
398 * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
401 vec
->ib
.draw_start_offset
-= vec
->draw
->start
;
404 pipe_resource_reference(&vec
->ib
.hw_resource
, vec
->ib
.buffer
);
406 /* note that index size may be zero when the draw is not indexed */
407 if (vec
->draw
->indexed
)
408 vec
->ib
.draw_start_offset
= vec
->ib
.offset
/ vec
->ib
.index_size
;
410 vec
->ib
.draw_start_offset
= 0;
413 /* treat the IB as clean if the HW states do not change */
414 if (vec
->ib
.hw_resource
== current_hw_res
&&
415 vec
->ib
.hw_index_size
== vec
->ib
.index_size
)
416 vec
->dirty
&= ~ILO_DIRTY_IB
;
418 vec
->ib
.hw_index_size
= vec
->ib
.index_size
;
420 pipe_resource_reference(¤t_hw_res
, NULL
);
424 finalize_vertex_elements(struct ilo_context
*ilo
)
426 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
428 if (!(vec
->dirty
& (ILO_DIRTY_VE
| ILO_DIRTY_VS
)))
431 vec
->dirty
|= ILO_DIRTY_VE
;
433 vec
->ve
->last_cso_edgeflag
= false;
434 if (vec
->ve
->count
&& vec
->vs
&&
435 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_VS_INPUT_EDGEFLAG
)) {
436 vec
->ve
->edgeflag_cso
= vec
->ve
->cso
[vec
->ve
->count
- 1];
437 ilo_gpe_set_ve_edgeflag(ilo
->dev
, &vec
->ve
->edgeflag_cso
);
438 vec
->ve
->last_cso_edgeflag
= true;
441 vec
->ve
->prepend_nosrc_cso
= false;
443 (ilo_shader_get_kernel_param(vec
->vs
,
444 ILO_KERNEL_VS_INPUT_INSTANCEID
) ||
445 ilo_shader_get_kernel_param(vec
->vs
,
446 ILO_KERNEL_VS_INPUT_VERTEXID
))) {
447 ilo_gpe_init_ve_nosrc(ilo
->dev
,
448 GEN6_VFCOMP_STORE_VID
,
449 GEN6_VFCOMP_STORE_IID
,
452 &vec
->ve
->nosrc_cso
);
453 vec
->ve
->prepend_nosrc_cso
= true;
454 } else if (!vec
->vs
) {
455 /* generate VUE header */
456 ilo_gpe_init_ve_nosrc(ilo
->dev
,
457 GEN6_VFCOMP_STORE_0
, /* Reserved */
458 GEN6_VFCOMP_STORE_0
, /* Render Target Array Index */
459 GEN6_VFCOMP_STORE_0
, /* Viewport Index */
460 GEN6_VFCOMP_STORE_0
, /* Point Width */
461 &vec
->ve
->nosrc_cso
);
462 vec
->ve
->prepend_nosrc_cso
= true;
463 } else if (!vec
->ve
->count
) {
465 * From the Sandy Bridge PRM, volume 2 part 1, page 92:
467 * "SW must ensure that at least one vertex element is defined prior
468 * to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
470 ilo_gpe_init_ve_nosrc(ilo
->dev
,
474 GEN6_VFCOMP_STORE_1_FP
,
475 &vec
->ve
->nosrc_cso
);
476 vec
->ve
->prepend_nosrc_cso
= true;
481 finalize_urb(struct ilo_context
*ilo
)
483 const uint16_t attr_size
= sizeof(uint32_t) * 4;
484 const struct ilo_dev
*dev
= ilo
->dev
;
485 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
486 struct ilo_state_urb_info info
;
488 if (!(vec
->dirty
& (ILO_DIRTY_VE
| ILO_DIRTY_VS
|
489 ILO_DIRTY_GS
| ILO_DIRTY_FS
)))
492 memset(&info
, 0, sizeof(info
));
494 info
.ve_entry_size
= attr_size
*
495 (vec
->ve
->count
+ vec
->ve
->prepend_nosrc_cso
);
498 info
.vs_const_data
= (bool)
499 (ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_PCB_CBUF0_SIZE
) +
500 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_VS_PCB_UCP_SIZE
));
501 info
.vs_entry_size
= attr_size
*
502 ilo_shader_get_kernel_param(vec
->vs
, ILO_KERNEL_OUTPUT_COUNT
);
506 info
.gs_const_data
= (bool)
507 ilo_shader_get_kernel_param(vec
->gs
, ILO_KERNEL_PCB_CBUF0_SIZE
);
510 * From the Ivy Bridge PRM, volume 2 part 1, page 189:
512 * "All outputs of a GS thread will be stored in the single GS
513 * thread output URB entry."
517 info
.gs_entry_size
= attr_size
*
518 ilo_shader_get_kernel_param(vec
->gs
, ILO_KERNEL_OUTPUT_COUNT
);
522 info
.ps_const_data
= (bool)
523 ilo_shader_get_kernel_param(vec
->fs
, ILO_KERNEL_PCB_CBUF0_SIZE
);
526 ilo_state_urb_set_info(&vec
->urb
, dev
, &info
);
530 finalize_viewport(struct ilo_context
*ilo
)
532 const struct ilo_dev
*dev
= ilo
->dev
;
533 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
535 if (vec
->dirty
& ILO_DIRTY_VIEWPORT
) {
536 ilo_state_viewport_set_params(&vec
->viewport
.vp
,
537 dev
, &vec
->viewport
.params
, false);
538 } else if (vec
->dirty
& ILO_DIRTY_SCISSOR
) {
539 ilo_state_viewport_set_params(&vec
->viewport
.vp
,
540 dev
, &vec
->viewport
.params
, true);
541 vec
->dirty
|= ILO_DIRTY_VIEWPORT
;
546 can_enable_gb_test(const struct ilo_rasterizer_state
*rasterizer
,
547 const struct ilo_viewport_state
*viewport
,
548 const struct ilo_fb_state
*fb
)
553 * There are several reasons that guard band test should be disabled
555 * - GL wide points (to avoid partially visibie object)
556 * - GL wide or AA lines (to avoid partially visibie object)
557 * - missing 2D clipping
559 if (rasterizer
->state
.point_size_per_vertex
||
560 rasterizer
->state
.point_size
> 1.0f
||
561 rasterizer
->state
.line_width
> 1.0f
||
562 rasterizer
->state
.line_smooth
)
565 for (i
= 0; i
< viewport
->params
.count
; i
++) {
566 const struct ilo_state_viewport_matrix_info
*mat
=
567 &viewport
->matrices
[i
];
568 float min_x
, max_x
, min_y
, max_y
;
570 min_x
= -1.0f
* fabsf(mat
->scale
[0]) + mat
->translate
[0];
571 max_x
= 1.0f
* fabsf(mat
->scale
[0]) + mat
->translate
[0];
572 min_y
= -1.0f
* fabsf(mat
->scale
[1]) + mat
->translate
[1];
573 max_y
= 1.0f
* fabsf(mat
->scale
[1]) + mat
->translate
[1];
575 if (min_x
> 0.0f
|| max_x
< fb
->state
.width
||
576 min_y
> 0.0f
|| max_y
< fb
->state
.height
)
584 finalize_rasterizer(struct ilo_context
*ilo
)
586 const struct ilo_dev
*dev
= ilo
->dev
;
587 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
588 struct ilo_rasterizer_state
*rasterizer
= vec
->rasterizer
;
589 struct ilo_state_raster_info
*info
= &vec
->rasterizer
->info
;
590 const bool gb_test_enable
=
591 can_enable_gb_test(rasterizer
, &vec
->viewport
, &vec
->fb
);
592 const bool multisample
=
593 (rasterizer
->state
.multisample
&& vec
->fb
.num_samples
> 1);
594 const uint8_t barycentric_interps
= ilo_shader_get_kernel_param(vec
->fs
,
595 ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS
);
597 /* check for non-orthogonal states */
598 if (info
->clip
.viewport_count
!= vec
->viewport
.params
.count
||
599 info
->clip
.gb_test_enable
!= gb_test_enable
||
600 info
->setup
.msaa_enable
!= multisample
||
601 info
->setup
.line_msaa_enable
!= multisample
||
602 info
->tri
.depth_offset_format
!= vec
->fb
.depth_offset_format
||
603 info
->scan
.sample_count
!= vec
->fb
.num_samples
||
604 info
->scan
.sample_mask
!= vec
->sample_mask
||
605 info
->scan
.barycentric_interps
!= barycentric_interps
||
606 info
->params
.any_integer_rt
!= vec
->fb
.has_integer_rt
||
607 info
->params
.hiz_enable
!= vec
->fb
.has_hiz
) {
608 info
->clip
.viewport_count
= vec
->viewport
.params
.count
;
609 info
->clip
.gb_test_enable
= gb_test_enable
;
610 info
->setup
.msaa_enable
= multisample
;
611 info
->setup
.line_msaa_enable
= multisample
;
612 info
->tri
.depth_offset_format
= vec
->fb
.depth_offset_format
;
613 info
->scan
.sample_count
= vec
->fb
.num_samples
;
614 info
->scan
.sample_mask
= vec
->sample_mask
;
615 info
->scan
.barycentric_interps
= barycentric_interps
;
616 info
->params
.any_integer_rt
= vec
->fb
.has_integer_rt
;
617 info
->params
.hiz_enable
= vec
->fb
.has_hiz
;
619 ilo_state_raster_set_info(&rasterizer
->rs
, dev
, &rasterizer
->info
);
621 vec
->dirty
|= ILO_DIRTY_RASTERIZER
;
626 finalize_blend_rt(struct ilo_context
*ilo
)
628 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
629 const struct ilo_fb_state
*fb
= &vec
->fb
;
630 struct ilo_blend_state
*blend
= vec
->blend
;
631 struct ilo_state_cc_blend_info
*info
= &vec
->blend
->info
.blend
;
632 bool changed
= false;
635 if (!(vec
->dirty
& (ILO_DIRTY_FB
| ILO_DIRTY_BLEND
)))
638 /* set up one for dummy RT writes */
639 if (!fb
->state
.nr_cbufs
) {
640 if (info
->rt
!= &blend
->dummy_rt
) {
641 info
->rt
= &blend
->dummy_rt
;
649 if (info
->rt
!= blend
->effective_rt
||
650 info
->rt_count
!= fb
->state
.nr_cbufs
) {
651 info
->rt
= blend
->effective_rt
;
652 info
->rt_count
= fb
->state
.nr_cbufs
;
656 for (i
= 0; i
< fb
->state
.nr_cbufs
; i
++) {
657 const struct ilo_fb_blend_caps
*caps
= &fb
->blend_caps
[i
];
658 struct ilo_state_cc_blend_rt_info
*rt
= &blend
->effective_rt
[i
];
659 /* ignore logicop when not UNORM */
660 const bool logicop_enable
=
661 (blend
->rt
[i
].logicop_enable
&& caps
->is_unorm
);
663 if (rt
->cv_is_unorm
!= caps
->is_unorm
||
664 rt
->cv_is_integer
!= caps
->is_integer
||
665 rt
->logicop_enable
!= logicop_enable
||
666 rt
->force_dst_alpha_one
!= caps
->force_dst_alpha_one
) {
667 rt
->cv_is_unorm
= caps
->is_unorm
;
668 rt
->cv_is_integer
= caps
->is_integer
;
669 rt
->logicop_enable
= logicop_enable
;
670 rt
->force_dst_alpha_one
= caps
->force_dst_alpha_one
;
680 finalize_blend(struct ilo_context
*ilo
)
682 const struct ilo_dev
*dev
= ilo
->dev
;
683 struct ilo_state_vector
*vec
= &ilo
->state_vector
;
684 struct ilo_blend_state
*blend
= vec
->blend
;
685 struct ilo_state_cc_info
*info
= &blend
->info
;
686 const bool sample_count_one
= (vec
->fb
.num_samples
<= 1);
687 const bool float_source0_alpha
=
688 (!vec
->fb
.state
.nr_cbufs
|| !vec
->fb
.state
.cbufs
[0] ||
689 !util_format_is_pure_integer(vec
->fb
.state
.cbufs
[0]->format
));
691 /* check for non-orthogonal states */
692 if (finalize_blend_rt(ilo
) ||
693 info
->alpha
.cv_sample_count_one
!= sample_count_one
||
694 info
->alpha
.cv_float_source0_alpha
!= float_source0_alpha
||
695 info
->alpha
.test_enable
!= vec
->dsa
->alpha_test
||
696 info
->alpha
.test_func
!= vec
->dsa
->alpha_func
||
697 memcmp(&info
->stencil
, &vec
->dsa
->stencil
, sizeof(info
->stencil
)) ||
698 memcmp(&info
->depth
, &vec
->dsa
->depth
, sizeof(info
->depth
)) ||
699 memcmp(&info
->params
, &vec
->cc_params
, sizeof(info
->params
))) {
700 info
->alpha
.cv_sample_count_one
= sample_count_one
;
701 info
->alpha
.cv_float_source0_alpha
= float_source0_alpha
;
702 info
->alpha
.test_enable
= vec
->dsa
->alpha_test
;
703 info
->alpha
.test_func
= vec
->dsa
->alpha_func
;
704 info
->stencil
= vec
->dsa
->stencil
;
705 info
->depth
= vec
->dsa
->depth
;
706 info
->params
= vec
->cc_params
;
708 ilo_state_cc_set_info(&blend
->cc
, dev
, info
);
710 blend
->alpha_may_kill
= (info
->alpha
.alpha_to_coverage
||
711 info
->alpha
.test_enable
);
713 vec
->dirty
|= ILO_DIRTY_BLEND
;
718 * Finalize states. Some states depend on other states and are
719 * incomplete/invalid until finalized.
722 ilo_finalize_3d_states(struct ilo_context
*ilo
,
723 const struct pipe_draw_info
*draw
)
725 ilo
->state_vector
.draw
= draw
;
727 finalize_shader_states(&ilo
->state_vector
);
728 finalize_constant_buffers(ilo
);
729 finalize_index_buffer(ilo
);
730 finalize_vertex_elements(ilo
);
733 finalize_rasterizer(ilo
);
734 finalize_viewport(ilo
);
737 u_upload_unmap(ilo
->uploader
);
741 finalize_global_binding(struct ilo_state_vector
*vec
)
743 struct ilo_shader_state
*cs
= vec
->cs
;
744 int base
, count
, shift
;
747 count
= ilo_shader_get_kernel_param(cs
,
748 ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT
);
752 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE
);
753 shift
= 32 - util_last_bit(base
+ count
- 1);
755 if (count
> vec
->global_binding
.count
)
756 count
= vec
->global_binding
.count
;
758 for (i
= 0; i
< count
; i
++) {
759 struct ilo_global_binding_cso
*cso
=
760 util_dynarray_element(&vec
->global_binding
.bindings
,
761 struct ilo_global_binding_cso
, i
);
762 const uint32_t offset
= *cso
->handle
& ((1 << shift
) - 1);
764 *cso
->handle
= ((base
+ i
) << shift
) | offset
;
769 ilo_finalize_compute_states(struct ilo_context
*ilo
)
771 finalize_global_binding(&ilo
->state_vector
);
775 ilo_create_blend_state(struct pipe_context
*pipe
,
776 const struct pipe_blend_state
*state
)
778 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
779 struct ilo_state_cc_info
*info
;
780 struct ilo_blend_state
*blend
;
783 blend
= CALLOC_STRUCT(ilo_blend_state
);
788 info
->alpha
.cv_float_source0_alpha
= true;
789 info
->alpha
.cv_sample_count_one
= true;
790 info
->alpha
.alpha_to_one
= state
->alpha_to_one
;
791 info
->alpha
.alpha_to_coverage
= state
->alpha_to_coverage
;
792 info
->alpha
.test_enable
= false;
793 info
->alpha
.test_func
= GEN6_COMPAREFUNCTION_ALWAYS
;
795 info
->stencil
.cv_has_buffer
= true;
796 info
->depth
.cv_has_buffer
= true;
798 info
->blend
.rt
= blend
->effective_rt
;
799 info
->blend
.rt_count
= 1;
800 info
->blend
.dither_enable
= state
->dither
;
802 for (i
= 0; i
< ARRAY_SIZE(blend
->rt
); i
++) {
803 const struct pipe_rt_blend_state
*rt
= &state
->rt
[i
];
804 struct ilo_state_cc_blend_rt_info
*rt_info
= &blend
->rt
[i
];
806 rt_info
->cv_has_buffer
= true;
807 rt_info
->cv_is_unorm
= true;
808 rt_info
->cv_is_integer
= false;
810 /* logic op takes precedence over blending */
811 if (state
->logicop_enable
) {
812 rt_info
->logicop_enable
= true;
813 rt_info
->logicop_func
= ilo_translate_logicop(state
->logicop_func
);
814 } else if (rt
->blend_enable
) {
815 rt_info
->blend_enable
= true;
817 rt_info
->rgb_src
= ilo_translate_blend_factor(rt
->rgb_src_factor
);
818 rt_info
->rgb_dst
= ilo_translate_blend_factor(rt
->rgb_dst_factor
);
819 rt_info
->rgb_func
= ilo_translate_blend_func(rt
->rgb_func
);
821 rt_info
->a_src
= ilo_translate_blend_factor(rt
->alpha_src_factor
);
822 rt_info
->a_dst
= ilo_translate_blend_factor(rt
->alpha_dst_factor
);
823 rt_info
->a_func
= ilo_translate_blend_func(rt
->alpha_func
);
826 if (!(rt
->colormask
& PIPE_MASK_A
))
827 rt_info
->argb_write_disables
|= (1 << 3);
828 if (!(rt
->colormask
& PIPE_MASK_R
))
829 rt_info
->argb_write_disables
|= (1 << 2);
830 if (!(rt
->colormask
& PIPE_MASK_G
))
831 rt_info
->argb_write_disables
|= (1 << 1);
832 if (!(rt
->colormask
& PIPE_MASK_B
))
833 rt_info
->argb_write_disables
|= (1 << 0);
835 if (!state
->independent_blend_enable
) {
836 for (i
= 1; i
< ARRAY_SIZE(blend
->rt
); i
++)
837 blend
->rt
[i
] = *rt_info
;
842 memcpy(blend
->effective_rt
, blend
->rt
, sizeof(blend
->rt
));
844 blend
->dummy_rt
.argb_write_disables
= 0xf;
846 if (!ilo_state_cc_init(&blend
->cc
, dev
, &blend
->info
)) {
851 blend
->dual_blend
= util_blend_state_is_dual(state
, 0);
857 ilo_bind_blend_state(struct pipe_context
*pipe
, void *state
)
859 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
863 vec
->dirty
|= ILO_DIRTY_BLEND
;
867 ilo_delete_blend_state(struct pipe_context
*pipe
, void *state
)
873 ilo_create_sampler_state(struct pipe_context
*pipe
,
874 const struct pipe_sampler_state
*state
)
876 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
877 struct ilo_sampler_cso
*sampler
;
878 struct ilo_state_sampler_info info
;
879 struct ilo_state_sampler_border_info border
;
881 sampler
= CALLOC_STRUCT(ilo_sampler_cso
);
884 memset(&info
, 0, sizeof(info
));
886 info
.non_normalized
= !state
->normalized_coords
;
887 if (state
->normalized_coords
) {
888 info
.lod_bias
= state
->lod_bias
;
889 info
.min_lod
= state
->min_lod
;
890 info
.max_lod
= state
->max_lod
;
892 info
.mip_filter
= ilo_translate_mip_filter(state
->min_mip_filter
);
894 /* work around a bug in util_blitter */
895 info
.mip_filter
= GEN6_MIPFILTER_NONE
;
898 if (state
->max_anisotropy
) {
899 info
.min_filter
= GEN6_MAPFILTER_ANISOTROPIC
;
900 info
.mag_filter
= GEN6_MAPFILTER_ANISOTROPIC
;
902 info
.min_filter
= ilo_translate_img_filter(state
->min_img_filter
);
903 info
.mag_filter
= ilo_translate_img_filter(state
->mag_img_filter
);
906 info
.max_anisotropy
= ilo_translate_max_anisotropy(state
->max_anisotropy
);
908 /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
909 if (info
.mip_filter
== GEN6_MIPFILTER_NONE
&& info
.min_lod
> 0.0f
) {
911 info
.mag_filter
= info
.min_filter
;
914 if (state
->seamless_cube_map
) {
915 if (state
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
||
916 state
->mag_img_filter
== PIPE_TEX_FILTER_NEAREST
) {
917 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
918 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
919 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
921 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
922 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
923 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CUBE
;
926 info
.tcx_ctrl
= ilo_translate_address_wrap(state
->wrap_s
);
927 info
.tcy_ctrl
= ilo_translate_address_wrap(state
->wrap_t
);
928 info
.tcz_ctrl
= ilo_translate_address_wrap(state
->wrap_r
);
930 if (ilo_dev_gen(dev
) < ILO_GEN(8)) {
932 * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
933 * PIPE_TEX_WRAP_CLAMP_TO_EDGE; for linear filtering,
934 * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
935 * additionally clamping the texture coordinates to [0.0, 1.0].
937 * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8. The
938 * clamping has to be taken care of in the shaders. There are two
939 * filters here, but let the minification one has a say.
941 const bool clamp_is_to_edge
=
942 (state
->min_img_filter
== PIPE_TEX_FILTER_NEAREST
);
944 if (clamp_is_to_edge
) {
945 if (info
.tcx_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
946 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
947 if (info
.tcy_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
948 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
949 if (info
.tcz_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
)
950 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP
;
952 if (info
.tcx_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
953 info
.tcx_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
954 sampler
->saturate_s
= true;
956 if (info
.tcy_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
957 info
.tcy_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
958 sampler
->saturate_t
= true;
960 if (info
.tcz_ctrl
== GEN8_TEXCOORDMODE_HALF_BORDER
) {
961 info
.tcz_ctrl
= GEN6_TEXCOORDMODE_CLAMP_BORDER
;
962 sampler
->saturate_r
= true;
968 if (state
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
969 info
.shadow_func
= ilo_translate_shadow_func(state
->compare_func
);
971 ilo_state_sampler_init(&sampler
->sampler
, dev
, &info
);
973 memset(&border
, 0, sizeof(border
));
974 memcpy(border
.rgba
.f
, state
->border_color
.f
, sizeof(border
.rgba
.f
));
976 ilo_state_sampler_border_init(&sampler
->border
, dev
, &border
);
982 ilo_bind_sampler_states(struct pipe_context
*pipe
, unsigned shader
,
983 unsigned start
, unsigned count
, void **samplers
)
985 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
986 struct ilo_sampler_state
*dst
= &vec
->sampler
[shader
];
987 bool changed
= false;
990 assert(start
+ count
<= Elements(dst
->cso
));
993 for (i
= 0; i
< count
; i
++) {
994 if (dst
->cso
[start
+ i
] != samplers
[i
]) {
995 dst
->cso
[start
+ i
] = samplers
[i
];
998 * This function is sometimes called to reduce the number of bound
999 * samplers. Do not consider that as a state change (and create a
1000 * new array of SAMPLER_STATE).
1008 for (i
= 0; i
< count
; i
++)
1009 dst
->cso
[start
+ i
] = NULL
;
1014 case PIPE_SHADER_VERTEX
:
1015 vec
->dirty
|= ILO_DIRTY_SAMPLER_VS
;
1017 case PIPE_SHADER_GEOMETRY
:
1018 vec
->dirty
|= ILO_DIRTY_SAMPLER_GS
;
1020 case PIPE_SHADER_FRAGMENT
:
1021 vec
->dirty
|= ILO_DIRTY_SAMPLER_FS
;
1023 case PIPE_SHADER_COMPUTE
:
1024 vec
->dirty
|= ILO_DIRTY_SAMPLER_CS
;
1031 ilo_delete_sampler_state(struct pipe_context
*pipe
, void *state
)
1037 ilo_create_rasterizer_state(struct pipe_context
*pipe
,
1038 const struct pipe_rasterizer_state
*state
)
1040 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1041 struct ilo_rasterizer_state
*rast
;
1042 struct ilo_state_raster_info
*info
;
1044 rast
= CALLOC_STRUCT(ilo_rasterizer_state
);
1047 rast
->state
= *state
;
1051 info
->clip
.clip_enable
= true;
1052 info
->clip
.stats_enable
= true;
1053 info
->clip
.viewport_count
= 1;
1054 info
->clip
.force_rtaindex_zero
= true;
1055 info
->clip
.user_clip_enables
= state
->clip_plane_enable
;
1056 info
->clip
.gb_test_enable
= true;
1057 info
->clip
.xy_test_enable
= true;
1058 info
->clip
.z_far_enable
= state
->depth_clip
;
1059 info
->clip
.z_near_enable
= state
->depth_clip
;
1060 info
->clip
.z_near_zero
= state
->clip_halfz
;
1062 info
->setup
.first_vertex_provoking
= state
->flatshade_first
;
1063 info
->setup
.viewport_transform
= true;
1064 info
->setup
.scissor_enable
= state
->scissor
;
1065 info
->setup
.msaa_enable
= false;
1066 info
->setup
.line_msaa_enable
= false;
1067 info
->point
.aa_enable
= state
->point_smooth
;
1068 info
->point
.programmable_width
= state
->point_size_per_vertex
;
1069 info
->line
.aa_enable
= state
->line_smooth
;
1070 info
->line
.stipple_enable
= state
->line_stipple_enable
;
1071 info
->line
.giq_enable
= true;
1072 info
->line
.giq_last_pixel
= state
->line_last_pixel
;
1073 info
->tri
.front_winding
= ilo_translate_front_ccw(state
->front_ccw
);
1074 info
->tri
.cull_mode
= ilo_translate_cull_face(state
->cull_face
);
1075 info
->tri
.fill_mode_front
= ilo_translate_poly_mode(state
->fill_front
);
1076 info
->tri
.fill_mode_back
= ilo_translate_poly_mode(state
->fill_back
);
1077 info
->tri
.depth_offset_format
= GEN6_ZFORMAT_D24_UNORM_X8_UINT
;
1078 info
->tri
.depth_offset_solid
= state
->offset_tri
;
1079 info
->tri
.depth_offset_wireframe
= state
->offset_line
;
1080 info
->tri
.depth_offset_point
= state
->offset_point
;
1081 info
->tri
.poly_stipple_enable
= state
->poly_stipple_enable
;
1083 info
->scan
.stats_enable
= true;
1084 info
->scan
.sample_count
= 1;
1086 ilo_translate_half_pixel_center(state
->half_pixel_center
);
1087 info
->scan
.sample_mask
= ~0u;
1088 info
->scan
.zw_interp
= GEN6_ZW_INTERP_PIXEL
;
1089 info
->scan
.barycentric_interps
= GEN6_INTERP_PERSPECTIVE_PIXEL
;
1090 info
->scan
.earlyz_control
= GEN7_EDSC_NORMAL
;
1091 info
->scan
.earlyz_op
= ILO_STATE_RASTER_EARLYZ_NORMAL
;
1092 info
->scan
.earlyz_stencil_clear
= false;
1094 info
->params
.any_integer_rt
= false;
1095 info
->params
.hiz_enable
= true;
1096 info
->params
.point_width
=
1097 (state
->point_size
== 0.0f
) ? 1.0f
: state
->point_size
;
1098 info
->params
.line_width
=
1099 (state
->line_width
== 0.0f
) ? 1.0f
: state
->line_width
;
1101 info
->params
.depth_offset_scale
= state
->offset_scale
;
1103 * Scale the constant term. The minimum representable value used by the HW
1104 * is not large enouch to be the minimum resolvable difference.
1106 info
->params
.depth_offset_const
= state
->offset_units
* 2.0f
;
1107 info
->params
.depth_offset_clamp
= state
->offset_clamp
;
1109 ilo_state_raster_init(&rast
->rs
, dev
, info
);
1115 ilo_bind_rasterizer_state(struct pipe_context
*pipe
, void *state
)
1117 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1119 vec
->rasterizer
= state
;
1121 vec
->dirty
|= ILO_DIRTY_RASTERIZER
;
1125 ilo_delete_rasterizer_state(struct pipe_context
*pipe
, void *state
)
1131 ilo_create_depth_stencil_alpha_state(struct pipe_context
*pipe
,
1132 const struct pipe_depth_stencil_alpha_state
*state
)
1134 struct ilo_dsa_state
*dsa
;
1137 dsa
= CALLOC_STRUCT(ilo_dsa_state
);
1140 dsa
->depth
.cv_has_buffer
= true;
1141 dsa
->depth
.test_enable
= state
->depth
.enabled
;
1142 dsa
->depth
.write_enable
= state
->depth
.writemask
;
1143 dsa
->depth
.test_func
= ilo_translate_compare_func(state
->depth
.func
);
1145 dsa
->stencil
.cv_has_buffer
= true;
1146 for (i
= 0; i
< ARRAY_SIZE(state
->stencil
); i
++) {
1147 const struct pipe_stencil_state
*stencil
= &state
->stencil
[i
];
1148 struct ilo_state_cc_stencil_op_info
*op
;
1150 if (!stencil
->enabled
)
1154 dsa
->stencil
.test_enable
= true;
1155 dsa
->stencil_front
.test_mask
= stencil
->valuemask
;
1156 dsa
->stencil_front
.write_mask
= stencil
->writemask
;
1158 op
= &dsa
->stencil
.front
;
1160 dsa
->stencil
.twosided_enable
= true;
1161 dsa
->stencil_back
.test_mask
= stencil
->valuemask
;
1162 dsa
->stencil_back
.write_mask
= stencil
->writemask
;
1164 op
= &dsa
->stencil
.back
;
1167 op
->test_func
= ilo_translate_compare_func(stencil
->func
);
1168 op
->fail_op
= ilo_translate_stencil_op(stencil
->fail_op
);
1169 op
->zfail_op
= ilo_translate_stencil_op(stencil
->zfail_op
);
1170 op
->zpass_op
= ilo_translate_stencil_op(stencil
->zpass_op
);
1173 dsa
->alpha_test
= state
->alpha
.enabled
;
1174 dsa
->alpha_ref
= state
->alpha
.ref_value
;
1175 dsa
->alpha_func
= ilo_translate_compare_func(state
->alpha
.func
);
1181 ilo_bind_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
1183 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1187 vec
->cc_params
.alpha_ref
= vec
->dsa
->alpha_ref
;
1188 vec
->cc_params
.stencil_front
.test_mask
=
1189 vec
->dsa
->stencil_front
.test_mask
;
1190 vec
->cc_params
.stencil_front
.write_mask
=
1191 vec
->dsa
->stencil_front
.write_mask
;
1192 vec
->cc_params
.stencil_back
.test_mask
=
1193 vec
->dsa
->stencil_back
.test_mask
;
1194 vec
->cc_params
.stencil_back
.write_mask
=
1195 vec
->dsa
->stencil_back
.write_mask
;
1198 vec
->dirty
|= ILO_DIRTY_DSA
;
1202 ilo_delete_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
1208 ilo_create_fs_state(struct pipe_context
*pipe
,
1209 const struct pipe_shader_state
*state
)
1211 struct ilo_context
*ilo
= ilo_context(pipe
);
1212 struct ilo_shader_state
*shader
;
1214 shader
= ilo_shader_create_fs(ilo
->dev
, state
, &ilo
->state_vector
);
1217 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1223 ilo_bind_fs_state(struct pipe_context
*pipe
, void *state
)
1225 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1229 vec
->dirty
|= ILO_DIRTY_FS
;
1233 ilo_delete_fs_state(struct pipe_context
*pipe
, void *state
)
1235 struct ilo_context
*ilo
= ilo_context(pipe
);
1236 struct ilo_shader_state
*fs
= (struct ilo_shader_state
*) state
;
1238 ilo_shader_cache_remove(ilo
->shader_cache
, fs
);
1239 ilo_shader_destroy(fs
);
1243 ilo_create_vs_state(struct pipe_context
*pipe
,
1244 const struct pipe_shader_state
*state
)
1246 struct ilo_context
*ilo
= ilo_context(pipe
);
1247 struct ilo_shader_state
*shader
;
1249 shader
= ilo_shader_create_vs(ilo
->dev
, state
, &ilo
->state_vector
);
1252 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1258 ilo_bind_vs_state(struct pipe_context
*pipe
, void *state
)
1260 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1264 vec
->dirty
|= ILO_DIRTY_VS
;
1268 ilo_delete_vs_state(struct pipe_context
*pipe
, void *state
)
1270 struct ilo_context
*ilo
= ilo_context(pipe
);
1271 struct ilo_shader_state
*vs
= (struct ilo_shader_state
*) state
;
1273 ilo_shader_cache_remove(ilo
->shader_cache
, vs
);
1274 ilo_shader_destroy(vs
);
1278 ilo_create_gs_state(struct pipe_context
*pipe
,
1279 const struct pipe_shader_state
*state
)
1281 struct ilo_context
*ilo
= ilo_context(pipe
);
1282 struct ilo_shader_state
*shader
;
1284 shader
= ilo_shader_create_gs(ilo
->dev
, state
, &ilo
->state_vector
);
1287 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1293 ilo_bind_gs_state(struct pipe_context
*pipe
, void *state
)
1295 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1297 /* util_blitter may set this unnecessarily */
1298 if (vec
->gs
== state
)
1303 vec
->dirty
|= ILO_DIRTY_GS
;
1307 ilo_delete_gs_state(struct pipe_context
*pipe
, void *state
)
1309 struct ilo_context
*ilo
= ilo_context(pipe
);
1310 struct ilo_shader_state
*gs
= (struct ilo_shader_state
*) state
;
1312 ilo_shader_cache_remove(ilo
->shader_cache
, gs
);
1313 ilo_shader_destroy(gs
);
1317 ilo_create_vertex_elements_state(struct pipe_context
*pipe
,
1318 unsigned num_elements
,
1319 const struct pipe_vertex_element
*elements
)
1321 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1322 struct ilo_ve_state
*ve
;
1324 ve
= MALLOC_STRUCT(ilo_ve_state
);
1327 ilo_gpe_init_ve(dev
, num_elements
, elements
, ve
);
1333 ilo_bind_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
1335 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1339 vec
->dirty
|= ILO_DIRTY_VE
;
1343 ilo_delete_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
1345 struct ilo_ve_state
*ve
= state
;
1351 ilo_set_blend_color(struct pipe_context
*pipe
,
1352 const struct pipe_blend_color
*state
)
1354 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1356 memcpy(vec
->cc_params
.blend_rgba
, state
->color
, sizeof(state
->color
));
1358 vec
->dirty
|= ILO_DIRTY_BLEND_COLOR
;
1362 ilo_set_stencil_ref(struct pipe_context
*pipe
,
1363 const struct pipe_stencil_ref
*state
)
1365 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1367 /* util_blitter may set this unnecessarily */
1368 if (!memcmp(&vec
->stencil_ref
, state
, sizeof(*state
)))
1371 vec
->stencil_ref
= *state
;
1373 vec
->cc_params
.stencil_front
.test_ref
= state
->ref_value
[0];
1374 vec
->cc_params
.stencil_back
.test_ref
= state
->ref_value
[1];
1376 vec
->dirty
|= ILO_DIRTY_STENCIL_REF
;
1380 ilo_set_sample_mask(struct pipe_context
*pipe
,
1381 unsigned sample_mask
)
1383 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1385 /* util_blitter may set this unnecessarily */
1386 if (vec
->sample_mask
== sample_mask
)
1389 vec
->sample_mask
= sample_mask
;
1391 vec
->dirty
|= ILO_DIRTY_SAMPLE_MASK
;
1395 ilo_set_clip_state(struct pipe_context
*pipe
,
1396 const struct pipe_clip_state
*state
)
1398 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1402 vec
->dirty
|= ILO_DIRTY_CLIP
;
1406 ilo_set_constant_buffer(struct pipe_context
*pipe
,
1407 uint shader
, uint index
,
1408 struct pipe_constant_buffer
*buf
)
1410 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1411 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1412 struct ilo_cbuf_state
*cbuf
= &vec
->cbuf
[shader
];
1413 const unsigned count
= 1;
1416 assert(shader
< Elements(vec
->cbuf
));
1417 assert(index
+ count
<= Elements(vec
->cbuf
[shader
].cso
));
1420 for (i
= 0; i
< count
; i
++) {
1421 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
1423 pipe_resource_reference(&cso
->resource
, buf
[i
].buffer
);
1425 cso
->info
.access
= ILO_STATE_SURFACE_ACCESS_DP_DATA
;
1426 cso
->info
.format
= GEN6_FORMAT_R32G32B32A32_FLOAT
;
1427 cso
->info
.format_size
= 16;
1428 cso
->info
.struct_size
= 16;
1429 cso
->info
.readonly
= true;
1430 cso
->info
.size
= buf
[i
].buffer_size
;
1432 if (buf
[i
].buffer
) {
1433 cso
->info
.buf
= ilo_buffer(buf
[i
].buffer
);
1434 cso
->info
.offset
= buf
[i
].buffer_offset
;
1436 memset(&cso
->surface
, 0, sizeof(cso
->surface
));
1437 ilo_state_surface_init_for_buffer(&cso
->surface
, dev
, &cso
->info
);
1438 cso
->surface
.bo
= cso
->info
.buf
->bo
;
1440 cso
->user_buffer
= NULL
;
1442 cbuf
->enabled_mask
|= 1 << (index
+ i
);
1443 } else if (buf
[i
].user_buffer
) {
1444 cso
->info
.buf
= NULL
;
1445 /* buffer_offset does not apply for user buffer */
1446 cso
->user_buffer
= buf
[i
].user_buffer
;
1448 cbuf
->enabled_mask
|= 1 << (index
+ i
);
1450 cso
->info
.buf
= NULL
;
1452 cso
->user_buffer
= NULL
;
1454 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
1458 for (i
= 0; i
< count
; i
++) {
1459 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
1461 pipe_resource_reference(&cso
->resource
, NULL
);
1463 cso
->info
.buf
= NULL
;
1465 cso
->user_buffer
= NULL
;
1467 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
1471 vec
->dirty
|= ILO_DIRTY_CBUF
;
1475 ilo_set_framebuffer_state(struct pipe_context
*pipe
,
1476 const struct pipe_framebuffer_state
*state
)
1478 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1479 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1481 ilo_gpe_set_fb(dev
, state
, &vec
->fb
);
1483 vec
->dirty
|= ILO_DIRTY_FB
;
1487 ilo_set_polygon_stipple(struct pipe_context
*pipe
,
1488 const struct pipe_poly_stipple
*state
)
1490 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1492 vec
->poly_stipple
= *state
;
1494 vec
->dirty
|= ILO_DIRTY_POLY_STIPPLE
;
1498 ilo_set_scissor_states(struct pipe_context
*pipe
,
1499 unsigned start_slot
,
1500 unsigned num_scissors
,
1501 const struct pipe_scissor_state
*scissors
)
1503 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1506 for (i
= 0; i
< num_scissors
; i
++) {
1507 struct ilo_state_viewport_scissor_info
*info
=
1508 &vec
->viewport
.scissors
[start_slot
+ i
];
1510 if (scissors
[i
].minx
< scissors
[i
].maxx
&&
1511 scissors
[i
].miny
< scissors
[i
].maxy
) {
1512 info
->min_x
= scissors
[i
].minx
;
1513 info
->min_y
= scissors
[i
].miny
;
1514 info
->max_x
= scissors
[i
].maxx
- 1;
1515 info
->max_y
= scissors
[i
].maxy
- 1;
1524 vec
->dirty
|= ILO_DIRTY_SCISSOR
;
1528 ilo_set_viewport_states(struct pipe_context
*pipe
,
1529 unsigned start_slot
,
1530 unsigned num_viewports
,
1531 const struct pipe_viewport_state
*viewports
)
1533 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1538 for (i
= 0; i
< num_viewports
; i
++) {
1539 struct ilo_state_viewport_matrix_info
*info
=
1540 &vec
->viewport
.matrices
[start_slot
+ i
];
1542 memcpy(info
->scale
, viewports
[i
].scale
, sizeof(info
->scale
));
1543 memcpy(info
->translate
, viewports
[i
].translate
,
1544 sizeof(info
->translate
));
1547 if (vec
->viewport
.params
.count
< start_slot
+ num_viewports
)
1548 vec
->viewport
.params
.count
= start_slot
+ num_viewports
;
1550 /* need to save viewport 0 for util_blitter */
1551 if (!start_slot
&& num_viewports
)
1552 vec
->viewport
.viewport0
= viewports
[0];
1555 if (vec
->viewport
.params
.count
<= start_slot
+ num_viewports
&&
1556 vec
->viewport
.params
.count
> start_slot
)
1557 vec
->viewport
.params
.count
= start_slot
;
1560 vec
->dirty
|= ILO_DIRTY_VIEWPORT
;
1564 ilo_set_sampler_views(struct pipe_context
*pipe
, unsigned shader
,
1565 unsigned start
, unsigned count
,
1566 struct pipe_sampler_view
**views
)
1568 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1569 struct ilo_view_state
*dst
= &vec
->view
[shader
];
1572 assert(start
+ count
<= Elements(dst
->states
));
1575 for (i
= 0; i
< count
; i
++)
1576 pipe_sampler_view_reference(&dst
->states
[start
+ i
], views
[i
]);
1579 for (i
= 0; i
< count
; i
++)
1580 pipe_sampler_view_reference(&dst
->states
[start
+ i
], NULL
);
1583 if (dst
->count
<= start
+ count
) {
1589 while (count
> 0 && !dst
->states
[count
- 1])
1596 case PIPE_SHADER_VERTEX
:
1597 vec
->dirty
|= ILO_DIRTY_VIEW_VS
;
1599 case PIPE_SHADER_GEOMETRY
:
1600 vec
->dirty
|= ILO_DIRTY_VIEW_GS
;
1602 case PIPE_SHADER_FRAGMENT
:
1603 vec
->dirty
|= ILO_DIRTY_VIEW_FS
;
1605 case PIPE_SHADER_COMPUTE
:
1606 vec
->dirty
|= ILO_DIRTY_VIEW_CS
;
1612 ilo_set_shader_resources(struct pipe_context
*pipe
,
1613 unsigned start
, unsigned count
,
1614 struct pipe_surface
**surfaces
)
1616 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1617 struct ilo_resource_state
*dst
= &vec
->resource
;
1620 assert(start
+ count
<= Elements(dst
->states
));
1623 for (i
= 0; i
< count
; i
++)
1624 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
1627 for (i
= 0; i
< count
; i
++)
1628 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
1631 if (dst
->count
<= start
+ count
) {
1637 while (count
> 0 && !dst
->states
[count
- 1])
1643 vec
->dirty
|= ILO_DIRTY_RESOURCE
;
1647 ilo_set_vertex_buffers(struct pipe_context
*pipe
,
1648 unsigned start_slot
, unsigned num_buffers
,
1649 const struct pipe_vertex_buffer
*buffers
)
1651 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1654 /* no PIPE_CAP_USER_VERTEX_BUFFERS */
1656 for (i
= 0; i
< num_buffers
; i
++)
1657 assert(!buffers
[i
].user_buffer
);
1660 util_set_vertex_buffers_mask(vec
->vb
.states
,
1661 &vec
->vb
.enabled_mask
, buffers
, start_slot
, num_buffers
);
1663 vec
->dirty
|= ILO_DIRTY_VB
;
1667 ilo_set_index_buffer(struct pipe_context
*pipe
,
1668 const struct pipe_index_buffer
*state
)
1670 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1673 pipe_resource_reference(&vec
->ib
.buffer
, state
->buffer
);
1674 vec
->ib
.user_buffer
= state
->user_buffer
;
1675 vec
->ib
.offset
= state
->offset
;
1676 vec
->ib
.index_size
= state
->index_size
;
1679 pipe_resource_reference(&vec
->ib
.buffer
, NULL
);
1680 vec
->ib
.user_buffer
= NULL
;
1682 vec
->ib
.index_size
= 0;
1685 vec
->dirty
|= ILO_DIRTY_IB
;
1688 static struct pipe_stream_output_target
*
1689 ilo_create_stream_output_target(struct pipe_context
*pipe
,
1690 struct pipe_resource
*res
,
1691 unsigned buffer_offset
,
1692 unsigned buffer_size
)
1694 struct pipe_stream_output_target
*target
;
1696 target
= MALLOC_STRUCT(pipe_stream_output_target
);
1699 pipe_reference_init(&target
->reference
, 1);
1700 target
->buffer
= NULL
;
1701 pipe_resource_reference(&target
->buffer
, res
);
1702 target
->context
= pipe
;
1703 target
->buffer_offset
= buffer_offset
;
1704 target
->buffer_size
= buffer_size
;
1710 ilo_set_stream_output_targets(struct pipe_context
*pipe
,
1711 unsigned num_targets
,
1712 struct pipe_stream_output_target
**targets
,
1713 const unsigned *offset
)
1715 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1717 unsigned append_bitmask
= 0;
1722 /* util_blitter may set this unnecessarily */
1723 if (!vec
->so
.count
&& !num_targets
)
1726 for (i
= 0; i
< num_targets
; i
++) {
1727 pipe_so_target_reference(&vec
->so
.states
[i
], targets
[i
]);
1728 if (offset
[i
] == (unsigned)-1)
1729 append_bitmask
|= 1 << i
;
1732 for (; i
< vec
->so
.count
; i
++)
1733 pipe_so_target_reference(&vec
->so
.states
[i
], NULL
);
1735 vec
->so
.count
= num_targets
;
1736 vec
->so
.append_bitmask
= append_bitmask
;
1738 vec
->so
.enabled
= (vec
->so
.count
> 0);
1740 vec
->dirty
|= ILO_DIRTY_SO
;
1744 ilo_stream_output_target_destroy(struct pipe_context
*pipe
,
1745 struct pipe_stream_output_target
*target
)
1747 pipe_resource_reference(&target
->buffer
, NULL
);
1751 static struct pipe_sampler_view
*
1752 ilo_create_sampler_view(struct pipe_context
*pipe
,
1753 struct pipe_resource
*res
,
1754 const struct pipe_sampler_view
*templ
)
1756 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1757 struct ilo_view_cso
*view
;
1759 view
= CALLOC_STRUCT(ilo_view_cso
);
1762 view
->base
= *templ
;
1763 pipe_reference_init(&view
->base
.reference
, 1);
1764 view
->base
.texture
= NULL
;
1765 pipe_resource_reference(&view
->base
.texture
, res
);
1766 view
->base
.context
= pipe
;
1768 if (res
->target
== PIPE_BUFFER
) {
1769 struct ilo_state_surface_buffer_info info
;
1771 memset(&info
, 0, sizeof(info
));
1772 info
.buf
= ilo_buffer(res
);
1773 info
.access
= ILO_STATE_SURFACE_ACCESS_SAMPLER
;
1774 info
.format
= ilo_format_translate_color(dev
, templ
->format
);
1775 info
.format_size
= util_format_get_blocksize(templ
->format
);
1776 info
.struct_size
= info
.format_size
;
1777 info
.readonly
= true;
1778 info
.offset
= templ
->u
.buf
.first_element
* info
.struct_size
;
1779 info
.size
= (templ
->u
.buf
.last_element
-
1780 templ
->u
.buf
.first_element
+ 1) * info
.struct_size
;
1782 ilo_state_surface_init_for_buffer(&view
->surface
, dev
, &info
);
1783 view
->surface
.bo
= info
.buf
->bo
;
1785 struct ilo_texture
*tex
= ilo_texture(res
);
1786 struct ilo_state_surface_image_info info
;
1788 /* warn about degraded performance because of a missing binding flag */
1789 if (tex
->image
.tiling
== GEN6_TILING_NONE
&&
1790 !(tex
->base
.bind
& PIPE_BIND_SAMPLER_VIEW
)) {
1791 ilo_warn("creating sampler view for a resource "
1792 "not created for sampling\n");
1795 memset(&info
, 0, sizeof(info
));
1796 info
.img
= &tex
->image
;
1798 info
.access
= ILO_STATE_SURFACE_ACCESS_SAMPLER
;
1800 if (templ
->format
== PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
&&
1801 tex
->image
.separate_stencil
) {
1802 info
.format
= ilo_format_translate_texture(dev
,
1803 PIPE_FORMAT_Z32_FLOAT
);
1805 info
.format
= ilo_format_translate_texture(dev
, templ
->format
);
1808 info
.is_cube_map
= (tex
->image
.target
== PIPE_TEXTURE_CUBE
||
1809 tex
->image
.target
== PIPE_TEXTURE_CUBE_ARRAY
);
1810 info
.is_array
= util_resource_is_array_texture(&tex
->base
);
1811 info
.readonly
= true;
1813 info
.level_base
= templ
->u
.tex
.first_level
;
1814 info
.level_count
= templ
->u
.tex
.last_level
-
1815 templ
->u
.tex
.first_level
+ 1;
1816 info
.slice_base
= templ
->u
.tex
.first_layer
;
1817 info
.slice_count
= templ
->u
.tex
.last_layer
-
1818 templ
->u
.tex
.first_layer
+ 1;
1820 ilo_state_surface_init_for_image(&view
->surface
, dev
, &info
);
1821 view
->surface
.bo
= info
.img
->bo
;
1828 ilo_sampler_view_destroy(struct pipe_context
*pipe
,
1829 struct pipe_sampler_view
*view
)
1831 pipe_resource_reference(&view
->texture
, NULL
);
1835 static struct pipe_surface
*
1836 ilo_create_surface(struct pipe_context
*pipe
,
1837 struct pipe_resource
*res
,
1838 const struct pipe_surface
*templ
)
1840 const struct ilo_dev
*dev
= ilo_context(pipe
)->dev
;
1841 struct ilo_texture
*tex
= ilo_texture(res
);
1842 struct ilo_surface_cso
*surf
;
1844 surf
= CALLOC_STRUCT(ilo_surface_cso
);
1847 surf
->base
= *templ
;
1848 pipe_reference_init(&surf
->base
.reference
, 1);
1849 surf
->base
.texture
= NULL
;
1850 pipe_resource_reference(&surf
->base
.texture
, &tex
->base
);
1852 surf
->base
.context
= pipe
;
1853 surf
->base
.width
= u_minify(tex
->base
.width0
, templ
->u
.tex
.level
);
1854 surf
->base
.height
= u_minify(tex
->base
.height0
, templ
->u
.tex
.level
);
1856 surf
->is_rt
= !util_format_is_depth_or_stencil(templ
->format
);
1859 struct ilo_state_surface_image_info info
;
1862 assert(tex
->base
.target
!= PIPE_BUFFER
);
1864 memset(&info
, 0, sizeof(info
));
1865 info
.img
= &tex
->image
;
1866 info
.access
= ILO_STATE_SURFACE_ACCESS_DP_RENDER
;
1867 info
.format
= ilo_format_translate_render(dev
, templ
->format
);
1868 info
.is_array
= util_resource_is_array_texture(&tex
->base
);
1869 info
.level_base
= templ
->u
.tex
.level
;
1870 info
.level_count
= 1;
1871 info
.slice_base
= templ
->u
.tex
.first_layer
;
1872 info
.slice_count
= templ
->u
.tex
.last_layer
-
1873 templ
->u
.tex
.first_layer
+ 1;
1875 ilo_state_surface_init_for_image(&surf
->u
.rt
, dev
, &info
);
1876 surf
->u
.rt
.bo
= info
.img
->bo
;
1878 struct ilo_state_zs_info info
;
1880 assert(res
->target
!= PIPE_BUFFER
);
1882 memset(&info
, 0, sizeof(info
));
1884 if (templ
->format
== PIPE_FORMAT_S8_UINT
) {
1885 info
.s_img
= &tex
->image
;
1887 info
.z_img
= &tex
->image
;
1888 info
.s_img
= (tex
->separate_s8
) ? &tex
->separate_s8
->image
: NULL
;
1891 ilo_image_can_enable_aux(&tex
->image
, templ
->u
.tex
.level
);
1894 info
.level
= templ
->u
.tex
.level
;
1895 info
.slice_base
= templ
->u
.tex
.first_layer
;
1896 info
.slice_count
= templ
->u
.tex
.last_layer
-
1897 templ
->u
.tex
.first_layer
+ 1;
1899 ilo_state_zs_init(&surf
->u
.zs
, dev
, &info
);
1902 surf
->u
.zs
.depth_bo
= info
.z_img
->bo
;
1903 if (info
.hiz_enable
)
1904 surf
->u
.zs
.hiz_bo
= info
.z_img
->aux
.bo
;
1908 surf
->u
.zs
.stencil_bo
= info
.s_img
->bo
;
1915 ilo_surface_destroy(struct pipe_context
*pipe
,
1916 struct pipe_surface
*surface
)
1918 pipe_resource_reference(&surface
->texture
, NULL
);
1923 ilo_create_compute_state(struct pipe_context
*pipe
,
1924 const struct pipe_compute_state
*state
)
1926 struct ilo_context
*ilo
= ilo_context(pipe
);
1927 struct ilo_shader_state
*shader
;
1929 shader
= ilo_shader_create_cs(ilo
->dev
, state
, &ilo
->state_vector
);
1932 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1938 ilo_bind_compute_state(struct pipe_context
*pipe
, void *state
)
1940 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1944 vec
->dirty
|= ILO_DIRTY_CS
;
1948 ilo_delete_compute_state(struct pipe_context
*pipe
, void *state
)
1950 struct ilo_context
*ilo
= ilo_context(pipe
);
1951 struct ilo_shader_state
*cs
= (struct ilo_shader_state
*) state
;
1953 ilo_shader_cache_remove(ilo
->shader_cache
, cs
);
1954 ilo_shader_destroy(cs
);
1958 ilo_set_compute_resources(struct pipe_context
*pipe
,
1959 unsigned start
, unsigned count
,
1960 struct pipe_surface
**surfaces
)
1962 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1963 struct ilo_resource_state
*dst
= &vec
->cs_resource
;
1966 assert(start
+ count
<= Elements(dst
->states
));
1969 for (i
= 0; i
< count
; i
++)
1970 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
1973 for (i
= 0; i
< count
; i
++)
1974 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
1977 if (dst
->count
<= start
+ count
) {
1983 while (count
> 0 && !dst
->states
[count
- 1])
1989 vec
->dirty
|= ILO_DIRTY_CS_RESOURCE
;
1993 ilo_set_global_binding(struct pipe_context
*pipe
,
1994 unsigned start
, unsigned count
,
1995 struct pipe_resource
**resources
,
1998 struct ilo_state_vector
*vec
= &ilo_context(pipe
)->state_vector
;
1999 struct ilo_global_binding_cso
*dst
;
2003 if (vec
->global_binding
.count
< start
+ count
) {
2005 const unsigned old_size
= vec
->global_binding
.bindings
.size
;
2006 const unsigned new_size
= sizeof(*dst
) * (start
+ count
);
2008 if (old_size
< new_size
) {
2009 util_dynarray_resize(&vec
->global_binding
.bindings
, new_size
);
2010 memset(vec
->global_binding
.bindings
.data
+ old_size
, 0,
2011 new_size
- old_size
);
2014 count
= vec
->global_binding
.count
- start
;
2018 dst
= util_dynarray_element(&vec
->global_binding
.bindings
,
2019 struct ilo_global_binding_cso
, start
);
2022 for (i
= 0; i
< count
; i
++) {
2023 pipe_resource_reference(&dst
[i
].resource
, resources
[i
]);
2024 dst
[i
].handle
= handles
[i
];
2027 for (i
= 0; i
< count
; i
++) {
2028 pipe_resource_reference(&dst
[i
].resource
, NULL
);
2029 dst
[i
].handle
= NULL
;
2033 if (vec
->global_binding
.count
<= start
+ count
) {
2034 dst
= util_dynarray_begin(&vec
->global_binding
.bindings
);
2041 while (count
> 0 && !dst
[count
- 1].resource
)
2044 vec
->global_binding
.count
= count
;
2047 vec
->dirty
|= ILO_DIRTY_GLOBAL_BINDING
;
2051 * Initialize state-related functions.
2054 ilo_init_state_functions(struct ilo_context
*ilo
)
2056 STATIC_ASSERT(ILO_STATE_COUNT
<= 32);
2058 ilo
->base
.create_blend_state
= ilo_create_blend_state
;
2059 ilo
->base
.bind_blend_state
= ilo_bind_blend_state
;
2060 ilo
->base
.delete_blend_state
= ilo_delete_blend_state
;
2061 ilo
->base
.create_sampler_state
= ilo_create_sampler_state
;
2062 ilo
->base
.bind_sampler_states
= ilo_bind_sampler_states
;
2063 ilo
->base
.delete_sampler_state
= ilo_delete_sampler_state
;
2064 ilo
->base
.create_rasterizer_state
= ilo_create_rasterizer_state
;
2065 ilo
->base
.bind_rasterizer_state
= ilo_bind_rasterizer_state
;
2066 ilo
->base
.delete_rasterizer_state
= ilo_delete_rasterizer_state
;
2067 ilo
->base
.create_depth_stencil_alpha_state
= ilo_create_depth_stencil_alpha_state
;
2068 ilo
->base
.bind_depth_stencil_alpha_state
= ilo_bind_depth_stencil_alpha_state
;
2069 ilo
->base
.delete_depth_stencil_alpha_state
= ilo_delete_depth_stencil_alpha_state
;
2070 ilo
->base
.create_fs_state
= ilo_create_fs_state
;
2071 ilo
->base
.bind_fs_state
= ilo_bind_fs_state
;
2072 ilo
->base
.delete_fs_state
= ilo_delete_fs_state
;
2073 ilo
->base
.create_vs_state
= ilo_create_vs_state
;
2074 ilo
->base
.bind_vs_state
= ilo_bind_vs_state
;
2075 ilo
->base
.delete_vs_state
= ilo_delete_vs_state
;
2076 ilo
->base
.create_gs_state
= ilo_create_gs_state
;
2077 ilo
->base
.bind_gs_state
= ilo_bind_gs_state
;
2078 ilo
->base
.delete_gs_state
= ilo_delete_gs_state
;
2079 ilo
->base
.create_vertex_elements_state
= ilo_create_vertex_elements_state
;
2080 ilo
->base
.bind_vertex_elements_state
= ilo_bind_vertex_elements_state
;
2081 ilo
->base
.delete_vertex_elements_state
= ilo_delete_vertex_elements_state
;
2083 ilo
->base
.set_blend_color
= ilo_set_blend_color
;
2084 ilo
->base
.set_stencil_ref
= ilo_set_stencil_ref
;
2085 ilo
->base
.set_sample_mask
= ilo_set_sample_mask
;
2086 ilo
->base
.set_clip_state
= ilo_set_clip_state
;
2087 ilo
->base
.set_constant_buffer
= ilo_set_constant_buffer
;
2088 ilo
->base
.set_framebuffer_state
= ilo_set_framebuffer_state
;
2089 ilo
->base
.set_polygon_stipple
= ilo_set_polygon_stipple
;
2090 ilo
->base
.set_scissor_states
= ilo_set_scissor_states
;
2091 ilo
->base
.set_viewport_states
= ilo_set_viewport_states
;
2092 ilo
->base
.set_sampler_views
= ilo_set_sampler_views
;
2093 ilo
->base
.set_shader_resources
= ilo_set_shader_resources
;
2094 ilo
->base
.set_vertex_buffers
= ilo_set_vertex_buffers
;
2095 ilo
->base
.set_index_buffer
= ilo_set_index_buffer
;
2097 ilo
->base
.create_stream_output_target
= ilo_create_stream_output_target
;
2098 ilo
->base
.stream_output_target_destroy
= ilo_stream_output_target_destroy
;
2099 ilo
->base
.set_stream_output_targets
= ilo_set_stream_output_targets
;
2101 ilo
->base
.create_sampler_view
= ilo_create_sampler_view
;
2102 ilo
->base
.sampler_view_destroy
= ilo_sampler_view_destroy
;
2104 ilo
->base
.create_surface
= ilo_create_surface
;
2105 ilo
->base
.surface_destroy
= ilo_surface_destroy
;
2107 ilo
->base
.create_compute_state
= ilo_create_compute_state
;
2108 ilo
->base
.bind_compute_state
= ilo_bind_compute_state
;
2109 ilo
->base
.delete_compute_state
= ilo_delete_compute_state
;
2110 ilo
->base
.set_compute_resources
= ilo_set_compute_resources
;
2111 ilo
->base
.set_global_binding
= ilo_set_global_binding
;
2115 ilo_state_vector_init(const struct ilo_dev
*dev
,
2116 struct ilo_state_vector
*vec
)
2118 struct ilo_state_urb_info urb_info
;
2120 vec
->sample_mask
= ~0u;
2122 ilo_state_viewport_init_data_only(&vec
->viewport
.vp
, dev
,
2123 vec
->viewport
.vp_data
, sizeof(vec
->viewport
.vp_data
));
2124 assert(vec
->viewport
.vp
.array_size
>= ILO_MAX_VIEWPORTS
);
2126 vec
->viewport
.params
.matrices
= vec
->viewport
.matrices
;
2127 vec
->viewport
.params
.scissors
= vec
->viewport
.scissors
;
2129 ilo_state_surface_init_for_null(&vec
->fb
.null_rt
, dev
);
2130 ilo_state_zs_init_for_null(&vec
->fb
.null_zs
, dev
);
2132 ilo_state_sampler_init_disabled(&vec
->disabled_sampler
, dev
);
2134 memset(&urb_info
, 0, sizeof(urb_info
));
2135 ilo_state_urb_init(&vec
->urb
, dev
, &urb_info
);
2137 util_dynarray_init(&vec
->global_binding
.bindings
);
2139 vec
->dirty
= ILO_DIRTY_ALL
;
2143 ilo_state_vector_cleanup(struct ilo_state_vector
*vec
)
2147 for (i
= 0; i
< Elements(vec
->vb
.states
); i
++) {
2148 if (vec
->vb
.enabled_mask
& (1 << i
))
2149 pipe_resource_reference(&vec
->vb
.states
[i
].buffer
, NULL
);
2152 pipe_resource_reference(&vec
->ib
.buffer
, NULL
);
2153 pipe_resource_reference(&vec
->ib
.hw_resource
, NULL
);
2155 for (i
= 0; i
< vec
->so
.count
; i
++)
2156 pipe_so_target_reference(&vec
->so
.states
[i
], NULL
);
2158 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
2159 for (i
= 0; i
< vec
->view
[sh
].count
; i
++) {
2160 struct pipe_sampler_view
*view
= vec
->view
[sh
].states
[i
];
2161 pipe_sampler_view_reference(&view
, NULL
);
2164 for (i
= 0; i
< Elements(vec
->cbuf
[sh
].cso
); i
++) {
2165 struct ilo_cbuf_cso
*cbuf
= &vec
->cbuf
[sh
].cso
[i
];
2166 pipe_resource_reference(&cbuf
->resource
, NULL
);
2170 for (i
= 0; i
< vec
->resource
.count
; i
++)
2171 pipe_surface_reference(&vec
->resource
.states
[i
], NULL
);
2173 for (i
= 0; i
< vec
->fb
.state
.nr_cbufs
; i
++)
2174 pipe_surface_reference(&vec
->fb
.state
.cbufs
[i
], NULL
);
2176 if (vec
->fb
.state
.zsbuf
)
2177 pipe_surface_reference(&vec
->fb
.state
.zsbuf
, NULL
);
2179 for (i
= 0; i
< vec
->cs_resource
.count
; i
++)
2180 pipe_surface_reference(&vec
->cs_resource
.states
[i
], NULL
);
2182 for (i
= 0; i
< vec
->global_binding
.count
; i
++) {
2183 struct ilo_global_binding_cso
*cso
=
2184 util_dynarray_element(&vec
->global_binding
.bindings
,
2185 struct ilo_global_binding_cso
, i
);
2186 pipe_resource_reference(&cso
->resource
, NULL
);
2189 util_dynarray_fini(&vec
->global_binding
.bindings
);
2193 * Mark all states that have the resource dirty.
2196 ilo_state_vector_resource_renamed(struct ilo_state_vector
*vec
,
2197 struct pipe_resource
*res
)
2199 struct intel_bo
*bo
= ilo_resource_get_bo(res
);
2200 uint32_t states
= 0;
2203 if (res
->target
== PIPE_BUFFER
) {
2204 uint32_t vb_mask
= vec
->vb
.enabled_mask
;
2207 const unsigned idx
= u_bit_scan(&vb_mask
);
2209 if (vec
->vb
.states
[idx
].buffer
== res
) {
2210 states
|= ILO_DIRTY_VB
;
2215 if (vec
->ib
.buffer
== res
) {
2216 states
|= ILO_DIRTY_IB
;
2219 * finalize_index_buffer() has an optimization that clears
2220 * ILO_DIRTY_IB when the HW states do not change. However, it fails
2221 * to flush the VF cache when the HW states do not change, but the
2222 * contents of the IB has changed. Here, we set the index size to an
2223 * invalid value to avoid the optimization.
2225 vec
->ib
.hw_index_size
= 0;
2228 for (i
= 0; i
< vec
->so
.count
; i
++) {
2229 if (vec
->so
.states
[i
]->buffer
== res
) {
2230 states
|= ILO_DIRTY_SO
;
2236 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
2237 for (i
= 0; i
< vec
->view
[sh
].count
; i
++) {
2238 struct ilo_view_cso
*cso
= (struct ilo_view_cso
*) vec
->view
[sh
].states
[i
];
2240 if (cso
->base
.texture
== res
) {
2241 static const unsigned view_dirty_bits
[PIPE_SHADER_TYPES
] = {
2242 [PIPE_SHADER_VERTEX
] = ILO_DIRTY_VIEW_VS
,
2243 [PIPE_SHADER_FRAGMENT
] = ILO_DIRTY_VIEW_FS
,
2244 [PIPE_SHADER_GEOMETRY
] = ILO_DIRTY_VIEW_GS
,
2245 [PIPE_SHADER_COMPUTE
] = ILO_DIRTY_VIEW_CS
,
2247 cso
->surface
.bo
= bo
;
2249 states
|= view_dirty_bits
[sh
];
2254 if (res
->target
== PIPE_BUFFER
) {
2255 for (i
= 0; i
< Elements(vec
->cbuf
[sh
].cso
); i
++) {
2256 struct ilo_cbuf_cso
*cbuf
= &vec
->cbuf
[sh
].cso
[i
];
2258 if (cbuf
->resource
== res
) {
2259 cbuf
->surface
.bo
= bo
;
2260 states
|= ILO_DIRTY_CBUF
;
2267 for (i
= 0; i
< vec
->resource
.count
; i
++) {
2268 struct ilo_surface_cso
*cso
=
2269 (struct ilo_surface_cso
*) vec
->resource
.states
[i
];
2271 if (cso
->base
.texture
== res
) {
2273 states
|= ILO_DIRTY_RESOURCE
;
2279 if (res
->target
!= PIPE_BUFFER
) {
2280 for (i
= 0; i
< vec
->fb
.state
.nr_cbufs
; i
++) {
2281 struct ilo_surface_cso
*cso
=
2282 (struct ilo_surface_cso
*) vec
->fb
.state
.cbufs
[i
];
2283 if (cso
&& cso
->base
.texture
== res
) {
2285 states
|= ILO_DIRTY_FB
;
2290 if (vec
->fb
.state
.zsbuf
&& vec
->fb
.state
.zsbuf
->texture
== res
) {
2291 struct ilo_surface_cso
*cso
=
2292 (struct ilo_surface_cso
*) vec
->fb
.state
.zsbuf
;
2294 cso
->u
.zs
.depth_bo
= bo
;
2296 states
|= ILO_DIRTY_FB
;
2300 for (i
= 0; i
< vec
->cs_resource
.count
; i
++) {
2301 struct ilo_surface_cso
*cso
=
2302 (struct ilo_surface_cso
*) vec
->cs_resource
.states
[i
];
2303 if (cso
->base
.texture
== res
) {
2305 states
|= ILO_DIRTY_CS_RESOURCE
;
2310 for (i
= 0; i
< vec
->global_binding
.count
; i
++) {
2311 struct ilo_global_binding_cso
*cso
=
2312 util_dynarray_element(&vec
->global_binding
.bindings
,
2313 struct ilo_global_binding_cso
, i
);
2315 if (cso
->resource
== res
) {
2316 states
|= ILO_DIRTY_GLOBAL_BINDING
;
2321 vec
->dirty
|= states
;
2325 ilo_state_vector_dump_dirty(const struct ilo_state_vector
*vec
)
2327 static const char *state_names
[ILO_STATE_COUNT
] = {
2328 [ILO_STATE_VB
] = "VB",
2329 [ILO_STATE_VE
] = "VE",
2330 [ILO_STATE_IB
] = "IB",
2331 [ILO_STATE_VS
] = "VS",
2332 [ILO_STATE_GS
] = "GS",
2333 [ILO_STATE_SO
] = "SO",
2334 [ILO_STATE_CLIP
] = "CLIP",
2335 [ILO_STATE_VIEWPORT
] = "VIEWPORT",
2336 [ILO_STATE_SCISSOR
] = "SCISSOR",
2337 [ILO_STATE_RASTERIZER
] = "RASTERIZER",
2338 [ILO_STATE_POLY_STIPPLE
] = "POLY_STIPPLE",
2339 [ILO_STATE_SAMPLE_MASK
] = "SAMPLE_MASK",
2340 [ILO_STATE_FS
] = "FS",
2341 [ILO_STATE_DSA
] = "DSA",
2342 [ILO_STATE_STENCIL_REF
] = "STENCIL_REF",
2343 [ILO_STATE_BLEND
] = "BLEND",
2344 [ILO_STATE_BLEND_COLOR
] = "BLEND_COLOR",
2345 [ILO_STATE_FB
] = "FB",
2346 [ILO_STATE_SAMPLER_VS
] = "SAMPLER_VS",
2347 [ILO_STATE_SAMPLER_GS
] = "SAMPLER_GS",
2348 [ILO_STATE_SAMPLER_FS
] = "SAMPLER_FS",
2349 [ILO_STATE_SAMPLER_CS
] = "SAMPLER_CS",
2350 [ILO_STATE_VIEW_VS
] = "VIEW_VS",
2351 [ILO_STATE_VIEW_GS
] = "VIEW_GS",
2352 [ILO_STATE_VIEW_FS
] = "VIEW_FS",
2353 [ILO_STATE_VIEW_CS
] = "VIEW_CS",
2354 [ILO_STATE_CBUF
] = "CBUF",
2355 [ILO_STATE_RESOURCE
] = "RESOURCE",
2356 [ILO_STATE_CS
] = "CS",
2357 [ILO_STATE_CS_RESOURCE
] = "CS_RESOURCE",
2358 [ILO_STATE_GLOBAL_BINDING
] = "GLOBAL_BINDING",
2360 uint32_t dirty
= vec
->dirty
;
2363 ilo_printf("no state is dirty\n");
2367 dirty
&= (1U << ILO_STATE_COUNT
) - 1;
2369 ilo_printf("%2d states are dirty:", util_bitcount(dirty
));
2371 const enum ilo_state state
= u_bit_scan(&dirty
);
2372 ilo_printf(" %s", state_names
[state
]);