2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2015 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 "ilo_debug.h"
30 #include "ilo_state_vf.h"
33 vf_validate_gen6_elements(const struct ilo_dev
*dev
,
34 const struct ilo_state_vf_info
*info
)
37 * From the Sandy Bridge PRM, volume 2 part 1, page 95:
39 * "(Source Element Offset (in bytes))
43 * From the Haswell PRM, volume 2d, page 415:
45 * "(Source Element Offset)
46 * Format: U12 byte offset
50 * From the Broadwell PRM, volume 2d, page 469:
52 * "(Source Element Offset)
53 * Format: U12 byte offset
57 const uint16_t max_vertex_offset
=
58 (ilo_dev_gen(dev
) == ILO_GEN(7.5)) ? 4096 : 2048;
61 ILO_DEV_ASSERT(dev
, 6, 8);
63 assert(info
->element_count
<= ILO_STATE_VF_MAX_ELEMENT_COUNT
);
65 for (i
= 0; i
< info
->element_count
; i
++) {
66 const struct ilo_state_vf_element_info
*elem
= &info
->elements
[i
];
68 assert(elem
->buffer
< ILO_STATE_VF_MAX_BUFFER_COUNT
);
69 assert(elem
->vertex_offset
< max_vertex_offset
);
70 assert(ilo_state_vf_valid_element_format(dev
, elem
->format
));
77 get_gen6_component_controls(const struct ilo_dev
*dev
,
78 enum gen_vf_component comp_x
,
79 enum gen_vf_component comp_y
,
80 enum gen_vf_component comp_z
,
81 enum gen_vf_component comp_w
)
83 ILO_DEV_ASSERT(dev
, 6, 8);
85 return comp_x
<< GEN6_VE_DW1_COMP0__SHIFT
|
86 comp_y
<< GEN6_VE_DW1_COMP1__SHIFT
|
87 comp_z
<< GEN6_VE_DW1_COMP2__SHIFT
|
88 comp_w
<< GEN6_VE_DW1_COMP3__SHIFT
;
92 get_gen6_edge_flag_format(const struct ilo_dev
*dev
,
93 const struct ilo_state_vf_element_info
*elem
,
94 enum gen_surface_format
*format
)
96 ILO_DEV_ASSERT(dev
, 6, 8);
99 * From the Sandy Bridge PRM, volume 2 part 1, page 94:
101 * "The Source Element Format must be set to the UINT format."
103 * From the Haswell PRM, volume 2d, page 413:
105 * "The SourceElementFormat needs to be a single-component format with
106 * an element which has edge flag enabled."
108 if (elem
->component_count
!= 1)
111 /* pick the format we like */
112 switch (elem
->format_size
) {
114 *format
= GEN6_FORMAT_R8_UINT
;
117 *format
= GEN6_FORMAT_R16_UINT
;
120 *format
= GEN6_FORMAT_R32_UINT
;
131 vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_state_vf
*vf
,
132 const struct ilo_dev
*dev
,
133 const struct ilo_state_vf_info
*info
)
135 enum gen_surface_format edge_flag_format
;
139 ILO_DEV_ASSERT(dev
, 6, 8);
141 if (!vf_validate_gen6_elements(dev
, info
))
144 for (i
= 0; i
< info
->element_count
; i
++) {
145 const struct ilo_state_vf_element_info
*elem
= &info
->elements
[i
];
146 enum gen_vf_component components
[4] = {
150 (elem
->is_integer
) ? GEN6_VFCOMP_STORE_1_INT
:
151 GEN6_VFCOMP_STORE_1_FP
,
154 switch (elem
->component_count
) {
155 case 4: components
[3] = GEN6_VFCOMP_STORE_SRC
; /* fall through */
156 case 3: components
[2] = GEN6_VFCOMP_STORE_SRC
; /* fall through */
157 case 2: components
[1] = GEN6_VFCOMP_STORE_SRC
; /* fall through */
158 case 1: components
[0] = GEN6_VFCOMP_STORE_SRC
; break;
160 assert(!"unexpected component count");
164 dw0
= elem
->buffer
<< GEN6_VE_DW0_VB_INDEX__SHIFT
|
166 elem
->format
<< GEN6_VE_DW0_FORMAT__SHIFT
|
167 elem
->vertex_offset
<< GEN6_VE_DW0_VB_OFFSET__SHIFT
;
168 dw1
= get_gen6_component_controls(dev
,
169 components
[0], components
[1],
170 components
[2], components
[3]);
172 STATIC_ASSERT(ARRAY_SIZE(vf
->user_ve
[i
]) >= 2);
173 vf
->user_ve
[i
][0] = dw0
;
174 vf
->user_ve
[i
][1] = dw1
;
177 vf
->user_ve_count
= i
;
179 vf
->edge_flag_supported
= (i
&& get_gen6_edge_flag_format(dev
,
180 &info
->elements
[i
- 1], &edge_flag_format
));
181 if (vf
->edge_flag_supported
) {
182 const struct ilo_state_vf_element_info
*elem
= &info
->elements
[i
- 1];
184 /* without edge flag enable */
185 vf
->last_user_ve
[0][0] = dw0
;
186 vf
->last_user_ve
[0][1] = dw1
;
189 * From the Sandy Bridge PRM, volume 2 part 1, page 94:
191 * "This bit (Edge Flag Enable) must only be ENABLED on the last
192 * valid VERTEX_ELEMENT structure.
194 * When set, Component 0 Control must be set to
195 * VFCOMP_STORE_SRC, and Component 1-3 Control must be set to
198 dw0
= elem
->buffer
<< GEN6_VE_DW0_VB_INDEX__SHIFT
|
200 edge_flag_format
<< GEN6_VE_DW0_FORMAT__SHIFT
|
201 GEN6_VE_DW0_EDGE_FLAG_ENABLE
|
202 elem
->vertex_offset
<< GEN6_VE_DW0_VB_OFFSET__SHIFT
;
203 dw1
= get_gen6_component_controls(dev
, GEN6_VFCOMP_STORE_SRC
,
204 GEN6_VFCOMP_NOSTORE
, GEN6_VFCOMP_NOSTORE
, GEN6_VFCOMP_NOSTORE
);
206 /* with edge flag enable */
207 vf
->last_user_ve
[1][0] = dw0
;
208 vf
->last_user_ve
[1][1] = dw1
;
215 vf_set_gen6_vertex_buffer_state(struct ilo_state_vf
*vf
,
216 const struct ilo_dev
*dev
,
217 const struct ilo_state_vf_info
*info
)
221 ILO_DEV_ASSERT(dev
, 6, 7.5);
223 memset(vf
->vb_to_first_elem
, -1, sizeof(vf
->vb_to_first_elem
));
225 for (i
= 0; i
< info
->element_count
; i
++) {
226 const struct ilo_state_vf_element_info
*elem
= &info
->elements
[i
];
228 STATIC_ASSERT(ARRAY_SIZE(vf
->user_instancing
[i
]) >= 2);
229 /* instancing enable only */
230 vf
->user_instancing
[i
][0] = (elem
->instancing_enable
) ?
231 GEN6_VB_DW0_ACCESS_INSTANCEDATA
:
232 GEN6_VB_DW0_ACCESS_VERTEXDATA
;
233 vf
->user_instancing
[i
][1] = elem
->instancing_step_rate
;
236 * Instancing is per VB, not per VE, before Gen8. Set up a VB-to-VE
239 if (vf
->vb_to_first_elem
[elem
->buffer
] < 0) {
240 vf
->vb_to_first_elem
[elem
->buffer
] = i
;
242 const struct ilo_state_vf_element_info
*first
=
243 &info
->elements
[vf
->vb_to_first_elem
[elem
->buffer
]];
245 assert(elem
->instancing_enable
== first
->instancing_enable
&&
246 elem
->instancing_step_rate
== first
->instancing_step_rate
);
254 vf_set_gen8_3DSTATE_VF_INSTANCING(struct ilo_state_vf
*vf
,
255 const struct ilo_dev
*dev
,
256 const struct ilo_state_vf_info
*info
)
260 ILO_DEV_ASSERT(dev
, 8, 8);
262 for (i
= 0; i
< info
->element_count
; i
++) {
263 const struct ilo_state_vf_element_info
*elem
= &info
->elements
[i
];
265 STATIC_ASSERT(ARRAY_SIZE(vf
->user_instancing
[i
]) >= 2);
266 vf
->user_instancing
[i
][0] = (elem
->instancing_enable
) ?
267 GEN8_INSTANCING_DW1_ENABLE
: 0;
268 vf
->user_instancing
[i
][1] = elem
->instancing_step_rate
;
275 get_gen6_component_zeros(const struct ilo_dev
*dev
)
277 ILO_DEV_ASSERT(dev
, 6, 8);
279 return get_gen6_component_controls(dev
,
283 GEN6_VFCOMP_STORE_0
);
287 get_gen6_component_ids(const struct ilo_dev
*dev
,
288 bool vertexid
, bool instanceid
)
290 ILO_DEV_ASSERT(dev
, 6, 7.5);
292 return get_gen6_component_controls(dev
,
293 (vertexid
) ? GEN6_VFCOMP_STORE_VID
: GEN6_VFCOMP_STORE_0
,
294 (instanceid
) ? GEN6_VFCOMP_STORE_IID
: GEN6_VFCOMP_STORE_0
,
296 GEN6_VFCOMP_STORE_0
);
300 vf_params_set_gen6_internal_ve(struct ilo_state_vf
*vf
,
301 const struct ilo_dev
*dev
,
302 const struct ilo_state_vf_params_info
*params
,
303 uint8_t user_ve_count
)
305 const bool prepend_ids
=
306 (params
->prepend_vertexid
|| params
->prepend_instanceid
);
307 uint8_t internal_ve_count
= 0, i
;
311 ILO_DEV_ASSERT(dev
, 6, 8);
314 * From the Sandy Bridge PRM, volume 2 part 1, page 92:
316 * "- At least one VERTEX_ELEMENT_STATE structure must be included.
318 * - Inclusion of partial VERTEX_ELEMENT_STATE structures is
321 * - SW must ensure that at least one vertex element is defined prior
322 * to issuing a 3DPRIMTIVE command, or operation is UNDEFINED.
324 * - There are no "holes" allowed in the destination vertex: NOSTORE
325 * components must be overwritten by subsequent components unless
326 * they are the trailing DWords of the vertex. Software must
327 * explicitly chose some value (probably 0) to be written into
328 * DWords that would otherwise be "holes"."
332 * - [DevILK+] Element[0] must be valid."
334 if (params
->prepend_zeros
|| (!user_ve_count
&& !prepend_ids
))
335 dw1
[internal_ve_count
++] = get_gen6_component_zeros(dev
);
338 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
339 /* placeholder for 3DSTATE_VF_SGVS */
340 dw1
[internal_ve_count
++] = get_gen6_component_zeros(dev
);
342 dw1
[internal_ve_count
++] = get_gen6_component_ids(dev
,
343 params
->prepend_vertexid
, params
->prepend_instanceid
);
347 for (i
= 0; i
< internal_ve_count
; i
++) {
348 STATIC_ASSERT(ARRAY_SIZE(vf
->internal_ve
[i
]) >= 2);
349 vf
->internal_ve
[i
][0] = GEN6_VE_DW0_VALID
;
350 vf
->internal_ve
[i
][1] = dw1
[i
];
353 vf
->internal_ve_count
= internal_ve_count
;
359 vf_params_set_gen8_3DSTATE_VF_SGVS(struct ilo_state_vf
*vf
,
360 const struct ilo_dev
*dev
,
361 const struct ilo_state_vf_params_info
*params
)
363 const uint8_t attr
= (params
->prepend_zeros
) ? 1 : 0;
366 ILO_DEV_ASSERT(dev
, 8, 8);
370 if (params
->prepend_instanceid
) {
371 dw1
|= GEN8_SGVS_DW1_IID_ENABLE
|
372 1 << GEN8_SGVS_DW1_IID_COMP__SHIFT
|
373 attr
<< GEN8_SGVS_DW1_IID_OFFSET__SHIFT
;
376 if (params
->prepend_vertexid
) {
377 dw1
|= GEN8_SGVS_DW1_VID_ENABLE
|
378 0 << GEN8_SGVS_DW1_VID_COMP__SHIFT
|
379 attr
<< GEN8_SGVS_DW1_VID_OFFSET__SHIFT
;
382 STATIC_ASSERT(ARRAY_SIZE(vf
->sgvs
) >= 1);
389 get_gen6_fixed_cut_index(const struct ilo_dev
*dev
,
390 enum gen_index_format format
)
392 const uint32_t fixed
= ~0u;
394 ILO_DEV_ASSERT(dev
, 6, 7);
397 case GEN6_INDEX_BYTE
: return (uint8_t) fixed
;
398 case GEN6_INDEX_WORD
: return (uint16_t) fixed
;
399 case GEN6_INDEX_DWORD
: return (uint32_t) fixed
;
401 assert(!"unknown index format");
407 get_gen6_cut_index_supported(const struct ilo_dev
*dev
,
408 enum gen_3dprim_type topology
)
410 ILO_DEV_ASSERT(dev
, 6, 8);
413 * See the Sandy Bridge PRM, volume 2 part 1, page 80 and the Haswell PRM,
414 * volume 7, page 456.
417 case GEN6_3DPRIM_TRIFAN
:
418 case GEN6_3DPRIM_QUADLIST
:
419 case GEN6_3DPRIM_QUADSTRIP
:
420 case GEN6_3DPRIM_POLYGON
:
421 case GEN6_3DPRIM_LINELOOP
:
422 return (ilo_dev_gen(dev
) >= ILO_GEN(7.5));
423 case GEN6_3DPRIM_RECTLIST
:
424 case GEN6_3DPRIM_TRIFAN_NOSTIPPLE
:
432 vf_params_set_gen6_3dstate_index_buffer(struct ilo_state_vf
*vf
,
433 const struct ilo_dev
*dev
,
434 const struct ilo_state_vf_params_info
*params
)
438 ILO_DEV_ASSERT(dev
, 6, 7);
440 /* cut index only, as in 3DSTATE_VF */
441 if (params
->cut_index_enable
) {
442 assert(get_gen6_cut_index_supported(dev
, params
->cv_topology
));
443 assert(get_gen6_fixed_cut_index(dev
, params
->cv_index_format
) ==
446 dw0
|= GEN6_IB_DW0_CUT_INDEX_ENABLE
;
449 STATIC_ASSERT(ARRAY_SIZE(vf
->cut
) >= 1);
456 vf_params_set_gen75_3DSTATE_VF(struct ilo_state_vf
*vf
,
457 const struct ilo_dev
*dev
,
458 const struct ilo_state_vf_params_info
*params
)
462 ILO_DEV_ASSERT(dev
, 7.5, 8);
464 if (params
->cut_index_enable
) {
465 assert(get_gen6_cut_index_supported(dev
, params
->cv_topology
));
466 dw0
|= GEN75_VF_DW0_CUT_INDEX_ENABLE
;
469 STATIC_ASSERT(ARRAY_SIZE(vf
->cut
) >= 2);
471 vf
->cut
[1] = params
->cut_index
;
477 vertex_buffer_validate_gen6(const struct ilo_dev
*dev
,
478 const struct ilo_state_vertex_buffer_info
*info
)
480 ILO_DEV_ASSERT(dev
, 6, 8);
483 assert(info
->size
&& info
->offset
+ info
->size
<= info
->vma
->vm_size
);
486 * From the Sandy Bridge PRM, volume 2 part 1, page 86:
489 * Range [DevCTG+]: [0,2048] Bytes"
491 assert(info
->stride
<= 2048);
494 * From the Sandy Bridge PRM, volume 2 part 1, page 86:
496 * "64-bit floating point values must be 64-bit aligned in memory, or
497 * UNPREDICTABLE data will be fetched. When accessing an element
498 * containing 64-bit floating point values, the Buffer Starting
499 * Address and Source Element Offset values must add to a 64-bit
500 * aligned address, and BufferPitch must be a multiple of 64-bits."
502 if (info
->cv_has_double
) {
504 assert(info
->vma
->vm_alignment
% 8 == 0);
506 assert(info
->stride
% 8 == 0);
507 assert((info
->offset
+ info
->cv_double_vertex_offset_mod_8
) % 8 == 0);
514 vertex_buffer_get_gen6_size(const struct ilo_dev
*dev
,
515 const struct ilo_state_vertex_buffer_info
*info
)
517 ILO_DEV_ASSERT(dev
, 6, 8);
518 return (info
->vma
) ? info
->size
: 0;
522 vertex_buffer_set_gen8_vertex_buffer_state(struct ilo_state_vertex_buffer
*vb
,
523 const struct ilo_dev
*dev
,
524 const struct ilo_state_vertex_buffer_info
*info
)
526 const uint32_t size
= vertex_buffer_get_gen6_size(dev
, info
);
529 ILO_DEV_ASSERT(dev
, 6, 8);
531 if (!vertex_buffer_validate_gen6(dev
, info
))
534 dw0
= info
->stride
<< GEN6_VB_DW0_PITCH__SHIFT
;
536 if (ilo_dev_gen(dev
) >= ILO_GEN(7))
537 dw0
|= GEN7_VB_DW0_ADDR_MODIFIED
;
539 dw0
|= GEN6_VB_DW0_IS_NULL
;
541 STATIC_ASSERT(ARRAY_SIZE(vb
->vb
) >= 3);
543 vb
->vb
[1] = info
->offset
;
545 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
548 /* address of the last valid byte */
549 vb
->vb
[2] = (size
) ? info
->offset
+ size
- 1 : 0;
558 get_index_format_size(enum gen_index_format format
)
561 case GEN6_INDEX_BYTE
: return 1;
562 case GEN6_INDEX_WORD
: return 2;
563 case GEN6_INDEX_DWORD
: return 4;
565 assert(!"unknown index format");
571 index_buffer_validate_gen6(const struct ilo_dev
*dev
,
572 const struct ilo_state_index_buffer_info
*info
)
574 const uint32_t format_size
= get_index_format_size(info
->format
);
576 ILO_DEV_ASSERT(dev
, 6, 8);
579 * From the Sandy Bridge PRM, volume 2 part 1, page 79:
581 * "This field (Buffer Starting Address) contains the size-aligned (as
582 * specified by Index Format) Graphics Address of the first element of
583 * interest within the index buffer."
585 assert(info
->offset
% format_size
== 0);
588 assert(info
->vma
->vm_alignment
% format_size
== 0);
589 assert(info
->size
&& info
->offset
+ info
->size
<= info
->vma
->vm_size
);
596 index_buffer_get_gen6_size(const struct ilo_dev
*dev
,
597 const struct ilo_state_index_buffer_info
*info
)
601 ILO_DEV_ASSERT(dev
, 6, 8);
607 if (ilo_dev_gen(dev
) < ILO_GEN(8)) {
608 const uint32_t format_size
= get_index_format_size(info
->format
);
609 size
-= (size
% format_size
);
616 index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(struct ilo_state_index_buffer
*ib
,
617 const struct ilo_dev
*dev
,
618 const struct ilo_state_index_buffer_info
*info
)
620 const uint32_t size
= index_buffer_get_gen6_size(dev
, info
);
622 ILO_DEV_ASSERT(dev
, 6, 8);
624 if (!index_buffer_validate_gen6(dev
, info
))
627 STATIC_ASSERT(ARRAY_SIZE(ib
->ib
) >= 3);
628 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
629 ib
->ib
[0] = info
->format
<< GEN8_IB_DW1_FORMAT__SHIFT
;
630 ib
->ib
[1] = info
->offset
;
633 ib
->ib
[0] = info
->format
<< GEN6_IB_DW0_FORMAT__SHIFT
;
634 ib
->ib
[1] = info
->offset
;
635 /* address of the last valid byte, or 0 */
636 ib
->ib
[2] = (size
) ? info
->offset
+ size
- 1 : 0;
645 ilo_state_vf_valid_element_format(const struct ilo_dev
*dev
,
646 enum gen_surface_format format
)
649 * This table is based on:
651 * - the Sandy Bridge PRM, volume 4 part 1, page 88-97
652 * - the Ivy Bridge PRM, volume 2 part 1, page 97-99
653 * - the Haswell PRM, volume 7, page 467-470
655 static const int vf_element_formats
[] = {
656 [GEN6_FORMAT_R32G32B32A32_FLOAT
] = ILO_GEN( 1),
657 [GEN6_FORMAT_R32G32B32A32_SINT
] = ILO_GEN( 1),
658 [GEN6_FORMAT_R32G32B32A32_UINT
] = ILO_GEN( 1),
659 [GEN6_FORMAT_R32G32B32A32_UNORM
] = ILO_GEN( 1),
660 [GEN6_FORMAT_R32G32B32A32_SNORM
] = ILO_GEN( 1),
661 [GEN6_FORMAT_R64G64_FLOAT
] = ILO_GEN( 1),
662 [GEN6_FORMAT_R32G32B32A32_SSCALED
] = ILO_GEN( 1),
663 [GEN6_FORMAT_R32G32B32A32_USCALED
] = ILO_GEN( 1),
664 [GEN6_FORMAT_R32G32B32A32_SFIXED
] = ILO_GEN(7.5),
665 [GEN6_FORMAT_R32G32B32_FLOAT
] = ILO_GEN( 1),
666 [GEN6_FORMAT_R32G32B32_SINT
] = ILO_GEN( 1),
667 [GEN6_FORMAT_R32G32B32_UINT
] = ILO_GEN( 1),
668 [GEN6_FORMAT_R32G32B32_UNORM
] = ILO_GEN( 1),
669 [GEN6_FORMAT_R32G32B32_SNORM
] = ILO_GEN( 1),
670 [GEN6_FORMAT_R32G32B32_SSCALED
] = ILO_GEN( 1),
671 [GEN6_FORMAT_R32G32B32_USCALED
] = ILO_GEN( 1),
672 [GEN6_FORMAT_R32G32B32_SFIXED
] = ILO_GEN(7.5),
673 [GEN6_FORMAT_R16G16B16A16_UNORM
] = ILO_GEN( 1),
674 [GEN6_FORMAT_R16G16B16A16_SNORM
] = ILO_GEN( 1),
675 [GEN6_FORMAT_R16G16B16A16_SINT
] = ILO_GEN( 1),
676 [GEN6_FORMAT_R16G16B16A16_UINT
] = ILO_GEN( 1),
677 [GEN6_FORMAT_R16G16B16A16_FLOAT
] = ILO_GEN( 1),
678 [GEN6_FORMAT_R32G32_FLOAT
] = ILO_GEN( 1),
679 [GEN6_FORMAT_R32G32_SINT
] = ILO_GEN( 1),
680 [GEN6_FORMAT_R32G32_UINT
] = ILO_GEN( 1),
681 [GEN6_FORMAT_R32G32_UNORM
] = ILO_GEN( 1),
682 [GEN6_FORMAT_R32G32_SNORM
] = ILO_GEN( 1),
683 [GEN6_FORMAT_R64_FLOAT
] = ILO_GEN( 1),
684 [GEN6_FORMAT_R16G16B16A16_SSCALED
] = ILO_GEN( 1),
685 [GEN6_FORMAT_R16G16B16A16_USCALED
] = ILO_GEN( 1),
686 [GEN6_FORMAT_R32G32_SSCALED
] = ILO_GEN( 1),
687 [GEN6_FORMAT_R32G32_USCALED
] = ILO_GEN( 1),
688 [GEN6_FORMAT_R32G32_SFIXED
] = ILO_GEN(7.5),
689 [GEN6_FORMAT_B8G8R8A8_UNORM
] = ILO_GEN( 1),
690 [GEN6_FORMAT_R10G10B10A2_UNORM
] = ILO_GEN( 1),
691 [GEN6_FORMAT_R10G10B10A2_UINT
] = ILO_GEN( 1),
692 [GEN6_FORMAT_R10G10B10_SNORM_A2_UNORM
] = ILO_GEN( 1),
693 [GEN6_FORMAT_R8G8B8A8_UNORM
] = ILO_GEN( 1),
694 [GEN6_FORMAT_R8G8B8A8_SNORM
] = ILO_GEN( 1),
695 [GEN6_FORMAT_R8G8B8A8_SINT
] = ILO_GEN( 1),
696 [GEN6_FORMAT_R8G8B8A8_UINT
] = ILO_GEN( 1),
697 [GEN6_FORMAT_R16G16_UNORM
] = ILO_GEN( 1),
698 [GEN6_FORMAT_R16G16_SNORM
] = ILO_GEN( 1),
699 [GEN6_FORMAT_R16G16_SINT
] = ILO_GEN( 1),
700 [GEN6_FORMAT_R16G16_UINT
] = ILO_GEN( 1),
701 [GEN6_FORMAT_R16G16_FLOAT
] = ILO_GEN( 1),
702 [GEN6_FORMAT_B10G10R10A2_UNORM
] = ILO_GEN(7.5),
703 [GEN6_FORMAT_R11G11B10_FLOAT
] = ILO_GEN( 1),
704 [GEN6_FORMAT_R32_SINT
] = ILO_GEN( 1),
705 [GEN6_FORMAT_R32_UINT
] = ILO_GEN( 1),
706 [GEN6_FORMAT_R32_FLOAT
] = ILO_GEN( 1),
707 [GEN6_FORMAT_R32_UNORM
] = ILO_GEN( 1),
708 [GEN6_FORMAT_R32_SNORM
] = ILO_GEN( 1),
709 [GEN6_FORMAT_R10G10B10X2_USCALED
] = ILO_GEN( 1),
710 [GEN6_FORMAT_R8G8B8A8_SSCALED
] = ILO_GEN( 1),
711 [GEN6_FORMAT_R8G8B8A8_USCALED
] = ILO_GEN( 1),
712 [GEN6_FORMAT_R16G16_SSCALED
] = ILO_GEN( 1),
713 [GEN6_FORMAT_R16G16_USCALED
] = ILO_GEN( 1),
714 [GEN6_FORMAT_R32_SSCALED
] = ILO_GEN( 1),
715 [GEN6_FORMAT_R32_USCALED
] = ILO_GEN( 1),
716 [GEN6_FORMAT_R8G8_UNORM
] = ILO_GEN( 1),
717 [GEN6_FORMAT_R8G8_SNORM
] = ILO_GEN( 1),
718 [GEN6_FORMAT_R8G8_SINT
] = ILO_GEN( 1),
719 [GEN6_FORMAT_R8G8_UINT
] = ILO_GEN( 1),
720 [GEN6_FORMAT_R16_UNORM
] = ILO_GEN( 1),
721 [GEN6_FORMAT_R16_SNORM
] = ILO_GEN( 1),
722 [GEN6_FORMAT_R16_SINT
] = ILO_GEN( 1),
723 [GEN6_FORMAT_R16_UINT
] = ILO_GEN( 1),
724 [GEN6_FORMAT_R16_FLOAT
] = ILO_GEN( 1),
725 [GEN6_FORMAT_R8G8_SSCALED
] = ILO_GEN( 1),
726 [GEN6_FORMAT_R8G8_USCALED
] = ILO_GEN( 1),
727 [GEN6_FORMAT_R16_SSCALED
] = ILO_GEN( 1),
728 [GEN6_FORMAT_R16_USCALED
] = ILO_GEN( 1),
729 [GEN6_FORMAT_R8_UNORM
] = ILO_GEN( 1),
730 [GEN6_FORMAT_R8_SNORM
] = ILO_GEN( 1),
731 [GEN6_FORMAT_R8_SINT
] = ILO_GEN( 1),
732 [GEN6_FORMAT_R8_UINT
] = ILO_GEN( 1),
733 [GEN6_FORMAT_R8_SSCALED
] = ILO_GEN( 1),
734 [GEN6_FORMAT_R8_USCALED
] = ILO_GEN( 1),
735 [GEN6_FORMAT_R8G8B8_UNORM
] = ILO_GEN( 1),
736 [GEN6_FORMAT_R8G8B8_SNORM
] = ILO_GEN( 1),
737 [GEN6_FORMAT_R8G8B8_SSCALED
] = ILO_GEN( 1),
738 [GEN6_FORMAT_R8G8B8_USCALED
] = ILO_GEN( 1),
739 [GEN6_FORMAT_R64G64B64A64_FLOAT
] = ILO_GEN( 1),
740 [GEN6_FORMAT_R64G64B64_FLOAT
] = ILO_GEN( 1),
741 [GEN6_FORMAT_R16G16B16_FLOAT
] = ILO_GEN( 6),
742 [GEN6_FORMAT_R16G16B16_UNORM
] = ILO_GEN( 1),
743 [GEN6_FORMAT_R16G16B16_SNORM
] = ILO_GEN( 1),
744 [GEN6_FORMAT_R16G16B16_SSCALED
] = ILO_GEN( 1),
745 [GEN6_FORMAT_R16G16B16_USCALED
] = ILO_GEN( 1),
746 [GEN6_FORMAT_R16G16B16_UINT
] = ILO_GEN(7.5),
747 [GEN6_FORMAT_R16G16B16_SINT
] = ILO_GEN(7.5),
748 [GEN6_FORMAT_R32_SFIXED
] = ILO_GEN(7.5),
749 [GEN6_FORMAT_R10G10B10A2_SNORM
] = ILO_GEN(7.5),
750 [GEN6_FORMAT_R10G10B10A2_USCALED
] = ILO_GEN(7.5),
751 [GEN6_FORMAT_R10G10B10A2_SSCALED
] = ILO_GEN(7.5),
752 [GEN6_FORMAT_R10G10B10A2_SINT
] = ILO_GEN(7.5),
753 [GEN6_FORMAT_B10G10R10A2_SNORM
] = ILO_GEN(7.5),
754 [GEN6_FORMAT_B10G10R10A2_USCALED
] = ILO_GEN(7.5),
755 [GEN6_FORMAT_B10G10R10A2_SSCALED
] = ILO_GEN(7.5),
756 [GEN6_FORMAT_B10G10R10A2_UINT
] = ILO_GEN(7.5),
757 [GEN6_FORMAT_B10G10R10A2_SINT
] = ILO_GEN(7.5),
758 [GEN6_FORMAT_R8G8B8_UINT
] = ILO_GEN(7.5),
759 [GEN6_FORMAT_R8G8B8_SINT
] = ILO_GEN(7.5),
762 ILO_DEV_ASSERT(dev
, 6, 8);
764 return (format
< ARRAY_SIZE(vf_element_formats
) &&
765 vf_element_formats
[format
] &&
766 ilo_dev_gen(dev
) >= vf_element_formats
[format
]);
770 ilo_state_vf_init(struct ilo_state_vf
*vf
,
771 const struct ilo_dev
*dev
,
772 const struct ilo_state_vf_info
*info
)
776 assert(ilo_is_zeroed(vf
, sizeof(*vf
)));
777 assert(ilo_is_zeroed(info
->data
, info
->data_size
));
779 assert(ilo_state_vf_data_size(dev
, info
->element_count
) <=
781 vf
->user_ve
= (uint32_t (*)[2]) info
->data
;
782 vf
->user_instancing
=
783 (uint32_t (*)[2]) (vf
->user_ve
+ info
->element_count
);
785 ret
&= vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(vf
, dev
, info
);
787 if (ilo_dev_gen(dev
) >= ILO_GEN(8))
788 ret
&= vf_set_gen8_3DSTATE_VF_INSTANCING(vf
, dev
, info
);
790 ret
&= vf_set_gen6_vertex_buffer_state(vf
, dev
, info
);
792 ret
&= ilo_state_vf_set_params(vf
, dev
, &info
->params
);
800 ilo_state_vf_init_for_rectlist(struct ilo_state_vf
*vf
,
801 const struct ilo_dev
*dev
,
802 void *data
, size_t data_size
,
803 const struct ilo_state_vf_element_info
*elements
,
804 uint8_t element_count
)
806 struct ilo_state_vf_info info
;
808 memset(&info
, 0, sizeof(info
));
811 info
.data_size
= data_size
;
813 info
.elements
= elements
;
814 info
.element_count
= element_count
;
820 * DW1: Render Target Array Index
821 * DW2: Viewport Index
824 info
.params
.prepend_zeros
= true;
826 return ilo_state_vf_init(vf
, dev
, &info
);
830 ilo_state_vf_set_params(struct ilo_state_vf
*vf
,
831 const struct ilo_dev
*dev
,
832 const struct ilo_state_vf_params_info
*params
)
836 ILO_DEV_ASSERT(dev
, 6, 8);
838 ret
&= vf_params_set_gen6_internal_ve(vf
, dev
, params
, vf
->user_ve_count
);
839 if (ilo_dev_gen(dev
) >= ILO_GEN(8))
840 ret
&= vf_params_set_gen8_3DSTATE_VF_SGVS(vf
, dev
, params
);
843 * From the Sandy Bridge PRM, volume 2 part 1, page 94:
845 * "Edge flags are supported for the following primitive topology types
846 * only, otherwise EdgeFlagEnable must not be ENABLED.
853 * "[DevSNB]: Edge Flags are not supported for QUADLIST primitives.
854 * Software may elect to convert QUADLIST primitives to some set of
855 * corresponding edge-flag-supported primitive types (e.g., POLYGONs)
856 * prior to submission to the 3D vf."
858 * From the Ivy Bridge PRM, volume 2 part 1, page 86:
860 * "Edge flags are supported for all primitive topology types."
862 * Both PRMs are confusing...
864 if (params
->last_element_edge_flag
) {
865 assert(vf
->edge_flag_supported
);
866 if (ilo_dev_gen(dev
) == ILO_GEN(6))
867 assert(params
->cv_topology
!= GEN6_3DPRIM_QUADLIST
);
870 if (vf
->edge_flag_supported
) {
871 assert(vf
->user_ve_count
);
872 memcpy(vf
->user_ve
[vf
->user_ve_count
- 1],
873 vf
->last_user_ve
[params
->last_element_edge_flag
],
874 sizeof(vf
->user_ve
[vf
->user_ve_count
- 1]));
877 if (ilo_dev_gen(dev
) >= ILO_GEN(7.5))
878 ret
&= vf_params_set_gen75_3DSTATE_VF(vf
, dev
, params
);
880 ret
&= vf_params_set_gen6_3dstate_index_buffer(vf
, dev
, params
);
888 ilo_state_vf_full_delta(const struct ilo_state_vf
*vf
,
889 const struct ilo_dev
*dev
,
890 struct ilo_state_vf_delta
*delta
)
892 delta
->dirty
= ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS
;
894 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
895 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VF_SGVS
|
896 ILO_STATE_VF_3DSTATE_VF_INSTANCING
;
898 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS
;
901 if (ilo_dev_gen(dev
) >= ILO_GEN(7.5))
902 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VF
;
904 delta
->dirty
|= ILO_STATE_VF_3DSTATE_INDEX_BUFFER
;
908 ilo_state_vf_get_delta(const struct ilo_state_vf
*vf
,
909 const struct ilo_dev
*dev
,
910 const struct ilo_state_vf
*old
,
911 struct ilo_state_vf_delta
*delta
)
913 /* no shallow copying */
914 assert(vf
->user_ve
!= old
->user_ve
&&
915 vf
->user_instancing
!= old
->user_instancing
);
919 if (vf
->internal_ve_count
!= old
->internal_ve_count
||
920 vf
->user_ve_count
!= old
->user_ve_count
||
921 memcmp(vf
->internal_ve
, old
->internal_ve
,
922 sizeof(vf
->internal_ve
[0]) * vf
->internal_ve_count
) ||
923 memcmp(vf
->user_ve
, old
->user_ve
,
924 sizeof(vf
->user_ve
[0]) * vf
->user_ve_count
))
925 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS
;
927 if (vf
->user_ve_count
!= old
->user_ve_count
||
928 memcmp(vf
->user_instancing
, old
->user_instancing
,
929 sizeof(vf
->user_instancing
[0]) * vf
->user_ve_count
)) {
930 if (ilo_dev_gen(dev
) >= ILO_GEN(8))
931 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VF_INSTANCING
;
933 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS
;
936 if (ilo_dev_gen(dev
) >= ILO_GEN(8)) {
937 if (vf
->sgvs
[0] != old
->sgvs
[0])
938 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VF_SGVS
;
941 if (ilo_dev_gen(dev
) >= ILO_GEN(7.5)) {
942 if (memcmp(vf
->cut
, old
->cut
, sizeof(vf
->cut
)))
943 delta
->dirty
|= ILO_STATE_VF_3DSTATE_VF
;
945 if (vf
->cut
[0] != old
->cut
[0])
946 delta
->dirty
|= ILO_STATE_VF_3DSTATE_INDEX_BUFFER
;
951 ilo_state_vertex_buffer_size(const struct ilo_dev
*dev
, uint32_t size
,
954 /* align for doubles without padding */
960 * No need to initialize first.
963 ilo_state_vertex_buffer_set_info(struct ilo_state_vertex_buffer
*vb
,
964 const struct ilo_dev
*dev
,
965 const struct ilo_state_vertex_buffer_info
*info
)
969 ret
&= vertex_buffer_set_gen8_vertex_buffer_state(vb
, dev
, info
);
977 ilo_state_index_buffer_size(const struct ilo_dev
*dev
, uint32_t size
,
980 /* align for the worst case without padding */
981 *alignment
= get_index_format_size(GEN6_INDEX_DWORD
);
986 * No need to initialize first.
989 ilo_state_index_buffer_set_info(struct ilo_state_index_buffer
*ib
,
990 const struct ilo_dev
*dev
,
991 const struct ilo_state_index_buffer_info
*info
)
995 ret
&= index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(ib
, dev
, info
);