ed64a1f0d3cf2d5f585b654ddd4ca796962ead86
[mesa.git] / src / gallium / drivers / ilo / core / ilo_state_raster.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2015 LunarG, Inc.
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
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.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "ilo_debug.h"
29 #include "ilo_state_raster.h"
30
31 static bool
32 raster_validate_gen6_clip(const struct ilo_dev *dev,
33 const struct ilo_state_raster_info *info)
34 {
35 const struct ilo_state_raster_clip_info *clip = &info->clip;
36
37 ILO_DEV_ASSERT(dev, 6, 8);
38
39 assert(clip->viewport_count);
40
41 /*
42 * From the Sandy Bridge PRM, volume 2 part 1, page 188:
43 *
44 * ""Clip Distance Cull Test Enable Bitmask" and "Clip Distance Clip
45 * Test Enable Bitmask" should not have overlapping bits in the mask,
46 * else the results are undefined."
47 */
48 assert(!(clip->user_cull_enables & clip->user_clip_enables));
49
50 if (ilo_dev_gen(dev) < ILO_GEN(9))
51 assert(clip->z_near_enable == clip->z_far_enable);
52
53 return true;
54 }
55
56 static bool
57 raster_set_gen6_3DSTATE_CLIP(struct ilo_state_raster *rs,
58 const struct ilo_dev *dev,
59 const struct ilo_state_raster_info *info)
60 {
61 const struct ilo_state_raster_clip_info *clip = &info->clip;
62 const struct ilo_state_raster_setup_info *setup = &info->setup;
63 const struct ilo_state_raster_tri_info *tri = &info->tri;
64 const struct ilo_state_raster_scan_info *scan = &info->scan;
65 uint32_t dw1, dw2, dw3;
66
67 ILO_DEV_ASSERT(dev, 6, 8);
68
69 if (!raster_validate_gen6_clip(dev, info))
70 return false;
71
72 dw1 = clip->user_cull_enables << GEN6_CLIP_DW1_UCP_CULL_ENABLES__SHIFT;
73
74 if (clip->stats_enable)
75 dw1 |= GEN6_CLIP_DW1_STATISTICS;
76
77 if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
78 /*
79 * From the Ivy Bridge PRM, volume 2 part 1, page 219:
80 *
81 * "Workaround : Due to Hardware issue "EarlyCull" needs to be
82 * enabled only for the cases where the incoming primitive topology
83 * into the clipper guaranteed to be Trilist."
84 *
85 * What does this mean?
86 */
87 dw1 |= GEN7_CLIP_DW1_SUBPIXEL_8BITS |
88 GEN7_CLIP_DW1_EARLY_CULL_ENABLE;
89
90 if (ilo_dev_gen(dev) <= ILO_GEN(7.5)) {
91 dw1 |= tri->front_winding << GEN7_CLIP_DW1_FRONT_WINDING__SHIFT |
92 tri->cull_mode << GEN7_CLIP_DW1_CULL_MODE__SHIFT;
93 }
94 }
95
96 dw2 = clip->user_clip_enables << GEN6_CLIP_DW2_UCP_CLIP_ENABLES__SHIFT |
97 GEN6_CLIPMODE_NORMAL << GEN6_CLIP_DW2_CLIP_MODE__SHIFT;
98
99 if (clip->clip_enable)
100 dw2 |= GEN6_CLIP_DW2_CLIP_ENABLE;
101
102 if (clip->z_near_zero)
103 dw2 |= GEN6_CLIP_DW2_APIMODE_D3D;
104 else
105 dw2 |= GEN6_CLIP_DW2_APIMODE_OGL;
106
107 if (clip->xy_test_enable)
108 dw2 |= GEN6_CLIP_DW2_XY_TEST_ENABLE;
109
110 if (ilo_dev_gen(dev) < ILO_GEN(8) && clip->z_near_enable)
111 dw2 |= GEN6_CLIP_DW2_Z_TEST_ENABLE;
112
113 if (clip->gb_test_enable)
114 dw2 |= GEN6_CLIP_DW2_GB_TEST_ENABLE;
115
116 if (scan->barycentric_interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL |
117 GEN6_INTERP_NONPERSPECTIVE_CENTROID |
118 GEN6_INTERP_NONPERSPECTIVE_SAMPLE))
119 dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE;
120
121 if (setup->first_vertex_provoking) {
122 dw2 |= 0 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
123 0 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
124 1 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
125 } else {
126 dw2 |= 2 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT |
127 1 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT |
128 2 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT;
129 }
130
131 dw3 = 0x1 << GEN6_CLIP_DW3_MIN_POINT_WIDTH__SHIFT |
132 0x7ff << GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT |
133 (clip->viewport_count - 1) << GEN6_CLIP_DW3_MAX_VPINDEX__SHIFT;
134
135 if (clip->force_rtaindex_zero)
136 dw3 |= GEN6_CLIP_DW3_FORCE_RTAINDEX_ZERO;
137
138 STATIC_ASSERT(ARRAY_SIZE(rs->clip) >= 3);
139 rs->clip[0] = dw1;
140 rs->clip[1] = dw2;
141 rs->clip[2] = dw3;
142
143 return true;
144 }
145
146 static bool
147 raster_params_is_gen6_line_aa_allowed(const struct ilo_dev *dev,
148 const struct ilo_state_raster_params_info *params)
149 {
150 ILO_DEV_ASSERT(dev, 6, 8);
151
152 /*
153 * From the Sandy Bridge PRM, volume 2 part 1, page 251:
154 *
155 * "This field (Anti-aliasing Enable) must be disabled if any of the
156 * render targets have integer (UINT or SINT) surface format."
157 */
158 if (params->any_integer_rt)
159 return false;
160
161 /*
162 * From the Sandy Bridge PRM, volume 2 part 1, page 321:
163 *
164 * "[DevSNB+]: This field (Hierarchical Depth Buffer Enable) must be
165 * disabled if Anti-aliasing Enable in 3DSTATE_SF is enabled.
166 */
167 if (ilo_dev_gen(dev) == ILO_GEN(6) && params->hiz_enable)
168 return false;
169
170 return true;
171 }
172
173 static void
174 raster_get_gen6_effective_line(const struct ilo_dev *dev,
175 const struct ilo_state_raster_info *info,
176 struct ilo_state_raster_line_info *line)
177 {
178 const struct ilo_state_raster_setup_info *setup = &info->setup;
179 const struct ilo_state_raster_params_info *params = &info->params;
180
181 *line = info->line;
182
183 /*
184 * From the Sandy Bridge PRM, volume 2 part 1, page 251:
185 *
186 * "This field (Anti-aliasing Enable) is ignored when Multisample
187 * Rasterization Mode is MSRASTMODE_ON_xx."
188 *
189 * From the Sandy Bridge PRM, volume 2 part 1, page 251:
190 *
191 * "Setting a Line Width of 0.0 specifies the rasterization of the
192 * "thinnest" (one-pixel-wide), non-antialiased lines. Note that
193 * this effectively overrides the effect of AAEnable (though the
194 * AAEnable state variable is not modified). Lines rendered with
195 * zero Line Width are rasterized using GIQ (Grid Intersection
196 * Quantization) rules as specified by the GDI and Direct3D APIs."
197 *
198 * "Software must not program a value of 0.0 when running in
199 * MSRASTMODE_ON_xxx modes - zero-width lines are not available
200 * when multisampling rasterization is enabled."
201 *
202 * From the Sandy Bridge PRM, volume 2 part 1, page 294:
203 *
204 * "Line stipple, controlled via the Line Stipple Enable state variable
205 * in WM_STATE, discards certain pixels that are produced by non-AA
206 * line rasterization."
207 */
208 if (setup->line_msaa_enable ||
209 !raster_params_is_gen6_line_aa_allowed(dev, params))
210 line->aa_enable = false;
211 if (setup->line_msaa_enable || line->aa_enable) {
212 line->stipple_enable = false;
213 line->giq_enable = false;
214 line->giq_last_pixel = false;
215 }
216 }
217
218 static bool
219 raster_validate_gen8_raster(const struct ilo_dev *dev,
220 const struct ilo_state_raster_info *info)
221 {
222 const struct ilo_state_raster_setup_info *setup = &info->setup;
223 const struct ilo_state_raster_tri_info *tri = &info->tri;
224
225 ILO_DEV_ASSERT(dev, 6, 8);
226
227 /*
228 * From the Sandy Bridge PRM, volume 2 part 1, page 249:
229 *
230 * "This setting (SOLID) is required when rendering rectangle
231 * (RECTLIST) objects.
232 */
233 if (tri->fill_mode_front != GEN6_FILLMODE_SOLID ||
234 tri->fill_mode_back != GEN6_FILLMODE_SOLID)
235 assert(!setup->cv_is_rectangle);
236
237 return true;
238 }
239
240 static enum gen_msrast_mode
241 raster_setup_get_gen6_msrast_mode(const struct ilo_dev *dev,
242 const struct ilo_state_raster_setup_info *setup)
243 {
244 ILO_DEV_ASSERT(dev, 6, 8);
245
246 if (setup->line_msaa_enable) {
247 return (setup->msaa_enable) ? GEN6_MSRASTMODE_ON_PATTERN :
248 GEN6_MSRASTMODE_ON_PIXEL;
249 } else {
250 return (setup->msaa_enable) ? GEN6_MSRASTMODE_OFF_PATTERN :
251 GEN6_MSRASTMODE_OFF_PIXEL;
252 }
253 }
254
255 static int
256 get_gen6_line_width(const struct ilo_dev *dev, float fwidth,
257 bool line_aa_enable, bool line_giq_enable)
258 {
259 int line_width;
260
261 ILO_DEV_ASSERT(dev, 6, 8);
262
263 /* in U3.7 */
264 line_width = (int) (fwidth * 128.0f + 0.5f);
265
266 /*
267 * Smooth lines should intersect ceil(line_width) or (ceil(line_width) + 1)
268 * pixels in the minor direction. We have to make the lines slightly
269 * thicker, 0.5 pixel on both sides, so that they intersect that many
270 * pixels.
271 */
272 if (line_aa_enable)
273 line_width += 128;
274
275 line_width = CLAMP(line_width, 1, 1023);
276
277 if (line_giq_enable && line_width == 128)
278 line_width = 0;
279
280 return line_width;
281 }
282
283 static int
284 get_gen6_point_width(const struct ilo_dev *dev, float fwidth)
285 {
286 int point_width;
287
288 ILO_DEV_ASSERT(dev, 6, 8);
289
290 /* in U8.3 */
291 point_width = (int) (fwidth * 8.0f + 0.5f);
292 point_width = CLAMP(point_width, 1, 2047);
293
294 return point_width;
295 }
296
297 static bool
298 raster_set_gen7_3DSTATE_SF(struct ilo_state_raster *rs,
299 const struct ilo_dev *dev,
300 const struct ilo_state_raster_info *info,
301 const struct ilo_state_raster_line_info *line)
302 {
303 const struct ilo_state_raster_clip_info *clip = &info->clip;
304 const struct ilo_state_raster_setup_info *setup = &info->setup;
305 const struct ilo_state_raster_point_info *point = &info->point;
306 const struct ilo_state_raster_tri_info *tri = &info->tri;
307 const struct ilo_state_raster_params_info *params = &info->params;
308 const enum gen_msrast_mode msrast =
309 raster_setup_get_gen6_msrast_mode(dev, setup);
310 const int line_width = get_gen6_line_width(dev, params->line_width,
311 line->aa_enable, line->giq_enable);
312 const int point_width = get_gen6_point_width(dev, params->point_width);
313 uint32_t dw1, dw2, dw3;
314
315 ILO_DEV_ASSERT(dev, 6, 7.5);
316
317 if (!raster_validate_gen8_raster(dev, info))
318 return false;
319
320 dw1 = tri->fill_mode_front << GEN7_SF_DW1_FILL_MODE_FRONT__SHIFT |
321 tri->fill_mode_back << GEN7_SF_DW1_FILL_MODE_BACK__SHIFT |
322 tri->front_winding << GEN7_SF_DW1_FRONT_WINDING__SHIFT;
323
324 if (ilo_dev_gen(dev) >= ILO_GEN(7) && ilo_dev_gen(dev) <= ILO_GEN(7.5)) {
325 enum gen_depth_format format;
326
327 /* do it here as we want 0x0 to be valid */
328 switch (tri->depth_offset_format) {
329 case GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT:
330 format = GEN6_ZFORMAT_D32_FLOAT;
331 break;
332 case GEN6_ZFORMAT_D24_UNORM_S8_UINT:
333 format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
334 break;
335 default:
336 format = tri->depth_offset_format;
337 break;
338 }
339
340 dw1 |= format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT;
341 }
342
343 /*
344 * From the Sandy Bridge PRM, volume 2 part 1, page 248:
345 *
346 * "This bit (Statistics Enable) should be set whenever clipping is
347 * enabled and the Statistics Enable bit is set in CLIP_STATE. It
348 * should be cleared if clipping is disabled or Statistics Enable in
349 * CLIP_STATE is clear."
350 */
351 if (clip->stats_enable && clip->clip_enable)
352 dw1 |= GEN7_SF_DW1_STATISTICS;
353
354 /*
355 * From the Ivy Bridge PRM, volume 2 part 1, page 258:
356 *
357 * "This bit (Legacy Global Depth Bias Enable, Global Depth Offset
358 * Enable Solid , Global Depth Offset Enable Wireframe, and Global
359 * Depth Offset Enable Point) should be set whenever non zero depth
360 * bias (Slope, Bias) values are used. Setting this bit may have some
361 * degradation of performance for some workloads."
362 *
363 * But it seems fine to ignore that.
364 */
365 if (tri->depth_offset_solid)
366 dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_SOLID;
367 if (tri->depth_offset_wireframe)
368 dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME;
369 if (tri->depth_offset_point)
370 dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_POINT;
371
372 if (setup->viewport_transform)
373 dw1 |= GEN7_SF_DW1_VIEWPORT_TRANSFORM;
374
375 dw2 = tri->cull_mode << GEN7_SF_DW2_CULL_MODE__SHIFT |
376 line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT |
377 GEN7_SF_DW2_AA_LINE_CAP_1_0 |
378 msrast << GEN7_SF_DW2_MSRASTMODE__SHIFT;
379
380 if (line->aa_enable)
381 dw2 |= GEN7_SF_DW2_AA_LINE_ENABLE;
382
383 if (ilo_dev_gen(dev) == ILO_GEN(7.5) && line->stipple_enable)
384 dw2 |= GEN75_SF_DW2_LINE_STIPPLE_ENABLE;
385
386 if (setup->scissor_enable)
387 dw2 |= GEN7_SF_DW2_SCISSOR_ENABLE;
388
389 dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE |
390 GEN7_SF_DW3_SUBPIXEL_8BITS;
391
392 /* this has no effect when line_width != 0 */
393 if (line->giq_last_pixel)
394 dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE;
395
396 if (setup->first_vertex_provoking) {
397 dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
398 0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
399 1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
400 } else {
401 dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
402 1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
403 2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
404 }
405
406 /* setup->point_aa_enable is ignored */
407 if (!point->programmable_width) {
408 dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH |
409 point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
410 }
411
412 STATIC_ASSERT(ARRAY_SIZE(rs->sf) >= 3);
413 rs->sf[0] = dw1;
414 rs->sf[1] = dw2;
415 rs->sf[2] = dw3;
416
417 STATIC_ASSERT(ARRAY_SIZE(rs->raster) >= 4);
418 rs->raster[0] = 0;
419 rs->raster[1] = fui(params->depth_offset_const);
420 rs->raster[2] = fui(params->depth_offset_scale);
421 rs->raster[3] = fui(params->depth_offset_clamp);
422
423 rs->line_aa_enable = line->aa_enable;
424 rs->line_giq_enable = line->giq_enable;
425
426 return true;
427 }
428
429 static bool
430 raster_set_gen8_3DSTATE_SF(struct ilo_state_raster *rs,
431 const struct ilo_dev *dev,
432 const struct ilo_state_raster_info *info,
433 const struct ilo_state_raster_line_info *line)
434 {
435 const struct ilo_state_raster_clip_info *clip = &info->clip;
436 const struct ilo_state_raster_setup_info *setup = &info->setup;
437 const struct ilo_state_raster_point_info *point = &info->point;
438 const struct ilo_state_raster_params_info *params = &info->params;
439 const int line_width = get_gen6_line_width(dev, params->line_width,
440 line->aa_enable, line->giq_enable);
441 const int point_width = get_gen6_point_width(dev, params->point_width);
442 uint32_t dw1, dw2, dw3;
443
444 ILO_DEV_ASSERT(dev, 8, 8);
445
446 dw1 = 0;
447
448 if (clip->stats_enable && clip->clip_enable)
449 dw1 |= GEN7_SF_DW1_STATISTICS;
450
451 if (setup->viewport_transform)
452 dw1 |= GEN7_SF_DW1_VIEWPORT_TRANSFORM;
453
454 dw2 = line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT |
455 GEN7_SF_DW2_AA_LINE_CAP_1_0;
456
457 dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE |
458 GEN7_SF_DW3_SUBPIXEL_8BITS;
459
460 /* this has no effect when line_width != 0 */
461 if (line->giq_last_pixel)
462 dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE;
463
464 if (setup->first_vertex_provoking) {
465 dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
466 0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
467 1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
468 } else {
469 dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT |
470 1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT |
471 2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT;
472 }
473
474 if (!point->programmable_width) {
475 dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH |
476 point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
477 }
478
479 STATIC_ASSERT(ARRAY_SIZE(rs->sf) >= 3);
480 rs->sf[0] = dw1;
481 rs->sf[1] = dw2;
482 rs->sf[2] = dw3;
483
484 return true;
485 }
486
487 static bool
488 raster_set_gen8_3DSTATE_RASTER(struct ilo_state_raster *rs,
489 const struct ilo_dev *dev,
490 const struct ilo_state_raster_info *info,
491 const struct ilo_state_raster_line_info *line)
492 {
493 const struct ilo_state_raster_clip_info *clip = &info->clip;
494 const struct ilo_state_raster_setup_info *setup = &info->setup;
495 const struct ilo_state_raster_point_info *point = &info->point;
496 const struct ilo_state_raster_tri_info *tri = &info->tri;
497 const struct ilo_state_raster_params_info *params = &info->params;
498 uint32_t dw1;
499
500 ILO_DEV_ASSERT(dev, 8, 8);
501
502 if (!raster_validate_gen8_raster(dev, info))
503 return false;
504
505 dw1 = tri->front_winding << GEN8_RASTER_DW1_FRONT_WINDING__SHIFT |
506 tri->cull_mode << GEN8_RASTER_DW1_CULL_MODE__SHIFT |
507 tri->fill_mode_front << GEN8_RASTER_DW1_FILL_MODE_FRONT__SHIFT |
508 tri->fill_mode_back << GEN8_RASTER_DW1_FILL_MODE_BACK__SHIFT;
509
510 if (point->aa_enable)
511 dw1 |= GEN8_RASTER_DW1_SMOOTH_POINT_ENABLE;
512
513 /* where should line_msaa_enable be set? */
514 if (setup->msaa_enable)
515 dw1 |= GEN8_RASTER_DW1_API_MULTISAMPLE_ENABLE;
516
517 if (tri->depth_offset_solid)
518 dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_SOLID;
519 if (tri->depth_offset_wireframe)
520 dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_WIREFRAME;
521 if (tri->depth_offset_point)
522 dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_POINT;
523
524 if (line->aa_enable)
525 dw1 |= GEN8_RASTER_DW1_AA_LINE_ENABLE;
526
527 if (setup->scissor_enable)
528 dw1 |= GEN8_RASTER_DW1_SCISSOR_ENABLE;
529
530 if (ilo_dev_gen(dev) >= ILO_GEN(9)) {
531 if (clip->z_far_enable)
532 dw1 |= GEN9_RASTER_DW1_Z_TEST_FAR_ENABLE;
533 if (clip->z_near_enable)
534 dw1 |= GEN9_RASTER_DW1_Z_TEST_NEAR_ENABLE;
535 } else {
536 if (clip->z_near_enable)
537 dw1 |= GEN8_RASTER_DW1_Z_TEST_ENABLE;
538 }
539
540 STATIC_ASSERT(ARRAY_SIZE(rs->raster) >= 4);
541 rs->raster[0] = dw1;
542 rs->raster[1] = fui(params->depth_offset_const);
543 rs->raster[2] = fui(params->depth_offset_scale);
544 rs->raster[3] = fui(params->depth_offset_clamp);
545
546 rs->line_aa_enable = line->aa_enable;
547 rs->line_giq_enable = line->giq_enable;
548
549 return true;
550 }
551
552 static enum gen_sample_count
553 get_gen6_sample_count(const struct ilo_dev *dev, uint8_t sample_count)
554 {
555 enum gen_sample_count c;
556 int min_gen;
557
558 ILO_DEV_ASSERT(dev, 6, 8);
559
560 switch (sample_count) {
561 case 1:
562 c = GEN6_NUMSAMPLES_1;
563 min_gen = ILO_GEN(6);
564 break;
565 case 2:
566 c = GEN8_NUMSAMPLES_2;
567 min_gen = ILO_GEN(8);
568 break;
569 case 4:
570 c = GEN6_NUMSAMPLES_4;
571 min_gen = ILO_GEN(6);
572 break;
573 case 8:
574 c = GEN7_NUMSAMPLES_8;
575 min_gen = ILO_GEN(7);
576 break;
577 case 16:
578 c = GEN8_NUMSAMPLES_16;
579 min_gen = ILO_GEN(8);
580 break;
581 default:
582 assert(!"unexpected sample count");
583 c = GEN6_NUMSAMPLES_1;
584 break;
585 }
586
587 assert(ilo_dev_gen(dev) >= min_gen);
588
589 return c;
590 }
591
592 static bool
593 raster_set_gen8_3DSTATE_MULTISAMPLE(struct ilo_state_raster *rs,
594 const struct ilo_dev *dev,
595 const struct ilo_state_raster_info *info)
596 {
597 const struct ilo_state_raster_setup_info *setup = &info->setup;
598 const struct ilo_state_raster_scan_info *scan = &info->scan;
599 const enum gen_sample_count count =
600 get_gen6_sample_count(dev, scan->sample_count);
601 uint32_t dw1;
602
603 ILO_DEV_ASSERT(dev, 6, 8);
604
605 /*
606 * From the Sandy Bridge PRM, volume 2 part 1, page 307:
607 *
608 * "Setting Multisample Rasterization Mode to MSRASTMODE_xxx_PATTERN
609 * when Number of Multisamples == NUMSAMPLES_1 is UNDEFINED."
610 */
611 if (setup->msaa_enable)
612 assert(scan->sample_count > 1);
613
614 dw1 = scan->pixloc << GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__SHIFT |
615 count << GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__SHIFT;
616
617 STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 1);
618 rs->sample[0] = dw1;
619
620 return true;
621 }
622
623 static bool
624 raster_set_gen6_3DSTATE_SAMPLE_MASK(struct ilo_state_raster *rs,
625 const struct ilo_dev *dev,
626 const struct ilo_state_raster_info *info)
627 {
628 const struct ilo_state_raster_scan_info *scan = &info->scan;
629 /*
630 * From the Ivy Bridge PRM, volume 2 part 1, page 294:
631 *
632 * "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field
633 * (Sample Mask) must be zero.
634 *
635 * If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field
636 * must be zero."
637 */
638 const uint32_t mask = (1 << scan->sample_count) - 1;
639 uint32_t dw1;
640
641 ILO_DEV_ASSERT(dev, 6, 8);
642
643 dw1 = (scan->sample_mask & mask) << GEN6_SAMPLE_MASK_DW1_VAL__SHIFT;
644
645 STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 2);
646 rs->sample[1] = dw1;
647
648 return true;
649 }
650
651 static bool
652 raster_validate_gen6_wm(const struct ilo_dev *dev,
653 const struct ilo_state_raster_info *info)
654 {
655 const struct ilo_state_raster_scan_info *scan = &info->scan;
656
657 ILO_DEV_ASSERT(dev, 6, 8);
658
659 if (ilo_dev_gen(dev) == ILO_GEN(6))
660 assert(scan->earlyz_control == GEN7_EDSC_NORMAL);
661
662 /*
663 * From the Sandy Bridge PRM, volume 2 part 1, page 272:
664 *
665 * "This bit (Statistics Enable) must be disabled if either of these
666 * bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve
667 * Enable or Depth Buffer Resolve Enable."
668 */
669 if (scan->earlyz_op != ILO_STATE_RASTER_EARLYZ_NORMAL)
670 assert(!scan->stats_enable);
671
672 /*
673 * From the Sandy Bridge PRM, volume 2 part 1, page 273:
674 *
675 * "If this field (Depth Buffer Resolve Enable) is enabled, the Depth
676 * Buffer Clear and Hierarchical Depth Buffer Resolve Enable fields
677 * must both be disabled."
678 *
679 * "If this field (Hierarchical Depth Buffer Resolve Enable) is
680 * enabled, the Depth Buffer Clear and Depth Buffer Resolve Enable
681 * fields must both be disabled."
682 *
683 * This is guaranteed.
684 */
685
686 /*
687 * From the Sandy Bridge PRM, volume 2 part 1, page 314-315:
688 *
689 * "Stencil buffer clear can be performed at the same time by enabling
690 * Stencil Buffer Write Enable."
691 *
692 * "Note also that stencil buffer clear can be performed without depth
693 * buffer clear."
694 */
695 if (scan->earlyz_stencil_clear) {
696 assert(scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_NORMAL ||
697 scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR);
698 }
699
700 return true;
701 }
702
703 static bool
704 raster_set_gen6_3dstate_wm(struct ilo_state_raster *rs,
705 const struct ilo_dev *dev,
706 const struct ilo_state_raster_info *info,
707 const struct ilo_state_raster_line_info *line)
708 {
709 const struct ilo_state_raster_tri_info *tri = &info->tri;
710 const struct ilo_state_raster_setup_info *setup = &info->setup;
711 const struct ilo_state_raster_scan_info *scan = &info->scan;
712 const enum gen_msrast_mode msrast =
713 raster_setup_get_gen6_msrast_mode(dev, setup);
714 /* only scan conversion states are set, as in Gen8+ */
715 uint32_t dw4, dw5, dw6;
716
717 ILO_DEV_ASSERT(dev, 6, 6);
718
719 if (!raster_validate_gen6_wm(dev, info))
720 return false;
721
722 dw4 = 0;
723
724 if (scan->stats_enable)
725 dw4 |= GEN6_WM_DW4_STATISTICS;
726
727 switch (scan->earlyz_op) {
728 case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
729 dw4 |= GEN6_WM_DW4_DEPTH_CLEAR;
730 break;
731 case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
732 dw4 |= GEN6_WM_DW4_DEPTH_RESOLVE;
733 break;
734 case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
735 dw4 |= GEN6_WM_DW4_HIZ_RESOLVE;
736 break;
737 default:
738 if (scan->earlyz_stencil_clear)
739 dw4 |= GEN6_WM_DW4_DEPTH_CLEAR;
740 break;
741 }
742
743 dw5 = GEN6_WM_DW5_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */
744 GEN6_WM_DW5_AA_LINE_WIDTH_2_0;
745
746 if (tri->poly_stipple_enable)
747 dw5 |= GEN6_WM_DW5_POLY_STIPPLE_ENABLE;
748 if (line->stipple_enable)
749 dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE;
750
751 dw6 = scan->zw_interp << GEN6_WM_DW6_ZW_INTERP__SHIFT |
752 scan->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT |
753 GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT |
754 msrast << GEN6_WM_DW6_MSRASTMODE__SHIFT;
755
756 STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3);
757 rs->wm[0] = dw4;
758 rs->wm[1] = dw5;
759 rs->wm[2] = dw6;
760
761 return true;
762 }
763
764 static bool
765 raster_set_gen8_3DSTATE_WM(struct ilo_state_raster *rs,
766 const struct ilo_dev *dev,
767 const struct ilo_state_raster_info *info,
768 const struct ilo_state_raster_line_info *line)
769 {
770 const struct ilo_state_raster_tri_info *tri = &info->tri;
771 const struct ilo_state_raster_setup_info *setup = &info->setup;
772 const struct ilo_state_raster_scan_info *scan = &info->scan;
773 const enum gen_msrast_mode msrast =
774 raster_setup_get_gen6_msrast_mode(dev, setup);
775 uint32_t dw1;
776
777 ILO_DEV_ASSERT(dev, 7, 8);
778
779 if (!raster_validate_gen6_wm(dev, info))
780 return false;
781
782 dw1 = scan->earlyz_control << GEN7_WM_DW1_EDSC__SHIFT |
783 scan->zw_interp << GEN7_WM_DW1_ZW_INTERP__SHIFT |
784 scan->barycentric_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT |
785 GEN7_WM_DW1_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */
786 GEN7_WM_DW1_AA_LINE_WIDTH_2_0 |
787 GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
788
789 if (scan->stats_enable)
790 dw1 |= GEN7_WM_DW1_STATISTICS;
791
792 if (ilo_dev_gen(dev) < ILO_GEN(8)) {
793 switch (scan->earlyz_op) {
794 case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
795 dw1 |= GEN7_WM_DW1_DEPTH_CLEAR;
796 break;
797 case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
798 dw1 |= GEN7_WM_DW1_DEPTH_RESOLVE;
799 break;
800 case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
801 dw1 |= GEN7_WM_DW1_HIZ_RESOLVE;
802 break;
803 default:
804 if (scan->earlyz_stencil_clear)
805 dw1 |= GEN7_WM_DW1_DEPTH_CLEAR;
806 break;
807 }
808 }
809
810 if (tri->poly_stipple_enable)
811 dw1 |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
812 if (line->stipple_enable)
813 dw1 |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
814
815 if (ilo_dev_gen(dev) < ILO_GEN(8))
816 dw1 |= msrast << GEN7_WM_DW1_MSRASTMODE__SHIFT;
817
818 STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 1);
819 rs->wm[0] = dw1;
820
821 return true;
822 }
823
824 static bool
825 raster_set_gen8_3dstate_wm_hz_op(struct ilo_state_raster *rs,
826 const struct ilo_dev *dev,
827 const struct ilo_state_raster_info *info)
828 {
829 const struct ilo_state_raster_scan_info *scan = &info->scan;
830 const enum gen_sample_count count =
831 get_gen6_sample_count(dev, scan->sample_count);
832 const uint32_t mask = (1 << scan->sample_count) - 1;
833 uint32_t dw1, dw4;
834
835 ILO_DEV_ASSERT(dev, 8, 8);
836
837 dw1 = count << GEN8_WM_HZ_DW1_NUM_SAMPLES__SHIFT;
838
839 if (scan->earlyz_stencil_clear)
840 dw1 |= GEN8_WM_HZ_DW1_STENCIL_CLEAR;
841
842 switch (scan->earlyz_op) {
843 case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
844 dw1 |= GEN8_WM_HZ_DW1_DEPTH_CLEAR;
845 break;
846 case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
847 dw1 |= GEN8_WM_HZ_DW1_DEPTH_RESOLVE;
848 break;
849 case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
850 dw1 |= GEN8_WM_HZ_DW1_HIZ_RESOLVE;
851 break;
852 default:
853 break;
854 }
855
856 dw4 = (scan->sample_mask & mask) << GEN8_WM_HZ_DW4_SAMPLE_MASK__SHIFT;
857
858 STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3);
859 rs->wm[1] = dw1;
860 rs->wm[2] = dw4;
861
862 return true;
863 }
864
865 static bool
866 sample_pattern_get_gen6_packed_offsets(const struct ilo_dev *dev,
867 uint8_t sample_count,
868 const struct ilo_state_sample_pattern_offset_info *in,
869 uint8_t *out)
870 {
871 uint8_t max_dist, i;
872
873 ILO_DEV_ASSERT(dev, 6, 8);
874
875 max_dist = 0;
876 for (i = 0; i < sample_count; i++) {
877 const int8_t dist_x = (int8_t) in[i].x - 8;
878 const int8_t dist_y = (int8_t) in[i].y - 8;
879 const uint8_t dist = dist_x * dist_x + dist_y * dist_y;
880
881 /*
882 * From the Sandy Bridge PRM, volume 2 part 1, page 305:
883 *
884 * "Programming Note: When programming the sample offsets (for
885 * NUMSAMPLES_4 or _8 and MSRASTMODE_xxx_PATTERN), the order of the
886 * samples 0 to 3 (or 7 for 8X) must have monotonically increasing
887 * distance from the pixel center. This is required to get the
888 * correct centroid computation in the device."
889 */
890 assert(dist >= max_dist);
891 max_dist = dist;
892
893 assert(in[i].x < 16);
894 assert(in[i].y < 16);
895
896 out[i] = in[i].x << 4 | in[i].y;
897 }
898
899 return true;
900 }
901
902 static bool
903 line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(struct ilo_state_line_stipple *stipple,
904 const struct ilo_dev *dev,
905 const struct ilo_state_line_stipple_info *info)
906 {
907 uint32_t dw1, dw2;
908
909 ILO_DEV_ASSERT(dev, 6, 8);
910
911 assert(info->repeat_count >= 1 && info->repeat_count <= 256);
912
913 dw1 = info->pattern;
914 if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
915 /* in U1.16 */
916 const uint32_t inverse = 65536 / info->repeat_count;
917 dw2 = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
918 info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT;
919 } else {
920 /* in U1.13 */
921 const uint16_t inverse = 8192 / info->repeat_count;
922 dw2 = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
923 info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT;
924 }
925
926 STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 2);
927 stipple->stipple[0] = dw1;
928 stipple->stipple[1] = dw2;
929
930 return true;
931 }
932
933 static bool
934 sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern *pattern,
935 const struct ilo_dev *dev,
936 const struct ilo_state_sample_pattern_info *info)
937 {
938 ILO_DEV_ASSERT(dev, 6, 8);
939
940 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_1x) >= 1);
941 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_2x) >= 2);
942 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_4x) >= 4);
943 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_8x) >= 8);
944 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_16x) >= 16);
945
946 return (sample_pattern_get_gen6_packed_offsets(dev, 1,
947 info->pattern_1x, pattern->pattern_1x) &&
948 sample_pattern_get_gen6_packed_offsets(dev, 2,
949 info->pattern_2x, pattern->pattern_2x) &&
950 sample_pattern_get_gen6_packed_offsets(dev, 4,
951 info->pattern_4x, pattern->pattern_4x) &&
952 sample_pattern_get_gen6_packed_offsets(dev, 8,
953 info->pattern_8x, pattern->pattern_8x) &&
954 sample_pattern_get_gen6_packed_offsets(dev, 16,
955 info->pattern_16x, pattern->pattern_16x));
956
957 }
958
959 static bool
960 poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_state_poly_stipple *stipple,
961 const struct ilo_dev *dev,
962 const struct ilo_state_poly_stipple_info *info)
963 {
964 ILO_DEV_ASSERT(dev, 6, 8);
965
966 STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 32);
967 memcpy(stipple->stipple, info->pattern, sizeof(info->pattern));
968
969 return true;
970 }
971
972 bool
973 ilo_state_raster_init(struct ilo_state_raster *rs,
974 const struct ilo_dev *dev,
975 const struct ilo_state_raster_info *info)
976 {
977 assert(ilo_is_zeroed(rs, sizeof(*rs)));
978 return ilo_state_raster_set_info(rs, dev, info);
979 }
980
981 bool
982 ilo_state_raster_init_for_rectlist(struct ilo_state_raster *rs,
983 const struct ilo_dev *dev,
984 uint8_t sample_count,
985 enum ilo_state_raster_earlyz_op earlyz_op,
986 bool earlyz_stencil_clear)
987 {
988 struct ilo_state_raster_info info;
989
990 memset(&info, 0, sizeof(info));
991
992 info.clip.viewport_count = 1;
993 info.setup.cv_is_rectangle = true;
994 info.setup.msaa_enable = (sample_count > 1);
995 info.scan.sample_count = sample_count;
996 info.scan.sample_mask = ~0u;
997 info.scan.earlyz_op = earlyz_op;
998 info.scan.earlyz_stencil_clear = earlyz_stencil_clear;
999
1000 return ilo_state_raster_init(rs, dev, &info);
1001 }
1002
1003 bool
1004 ilo_state_raster_set_info(struct ilo_state_raster *rs,
1005 const struct ilo_dev *dev,
1006 const struct ilo_state_raster_info *info)
1007 {
1008 struct ilo_state_raster_line_info line;
1009 bool ret = true;
1010
1011 ret &= raster_set_gen6_3DSTATE_CLIP(rs, dev, info);
1012
1013 raster_get_gen6_effective_line(dev, info, &line);
1014
1015 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
1016 ret &= raster_set_gen8_3DSTATE_SF(rs, dev, info, &line);
1017 ret &= raster_set_gen8_3DSTATE_RASTER(rs, dev, info, &line);
1018 } else {
1019 ret &= raster_set_gen7_3DSTATE_SF(rs, dev, info, &line);
1020 }
1021
1022 ret &= raster_set_gen8_3DSTATE_MULTISAMPLE(rs, dev, info);
1023 ret &= raster_set_gen6_3DSTATE_SAMPLE_MASK(rs, dev, info);
1024
1025 if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
1026 ret &= raster_set_gen8_3DSTATE_WM(rs, dev, info, &line);
1027
1028 if (ilo_dev_gen(dev) >= ILO_GEN(8))
1029 ret &= raster_set_gen8_3dstate_wm_hz_op(rs, dev, info);
1030 } else {
1031 ret &= raster_set_gen6_3dstate_wm(rs, dev, info, &line);
1032 }
1033
1034 assert(ret);
1035
1036 return ret;
1037 }
1038
1039 bool
1040 ilo_state_raster_set_params(struct ilo_state_raster *rs,
1041 const struct ilo_dev *dev,
1042 const struct ilo_state_raster_params_info *params)
1043 {
1044 const bool line_aa_enable = (rs->line_aa_enable &&
1045 raster_params_is_gen6_line_aa_allowed(dev, params));
1046 const int line_width = get_gen6_line_width(dev, params->line_width,
1047 line_aa_enable, rs->line_giq_enable);
1048
1049 ILO_DEV_ASSERT(dev, 6, 8);
1050
1051 /* modify line AA enable */
1052 if (rs->line_aa_enable) {
1053 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
1054 if (line_aa_enable)
1055 rs->raster[0] |= GEN8_RASTER_DW1_AA_LINE_ENABLE;
1056 else
1057 rs->raster[0] &= ~GEN8_RASTER_DW1_AA_LINE_ENABLE;
1058 } else {
1059 if (line_aa_enable)
1060 rs->sf[1] |= GEN7_SF_DW2_AA_LINE_ENABLE;
1061 else
1062 rs->sf[1] &= ~GEN7_SF_DW2_AA_LINE_ENABLE;
1063 }
1064 }
1065
1066 /* modify line width */
1067 rs->sf[1] = (rs->sf[1] & ~GEN7_SF_DW2_LINE_WIDTH__MASK) |
1068 line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT;
1069
1070 /* modify point width */
1071 if (rs->sf[2] & GEN7_SF_DW3_USE_POINT_WIDTH) {
1072 const int point_width = get_gen6_point_width(dev, params->point_width);
1073
1074 rs->sf[2] = (rs->sf[2] & ~GEN7_SF_DW3_POINT_WIDTH__MASK) |
1075 point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
1076 }
1077
1078 /* modify depth offset */
1079 rs->raster[1] = fui(params->depth_offset_const);
1080 rs->raster[2] = fui(params->depth_offset_scale);
1081 rs->raster[3] = fui(params->depth_offset_clamp);
1082
1083 return true;
1084 }
1085
1086 void
1087 ilo_state_raster_full_delta(const struct ilo_state_raster *rs,
1088 const struct ilo_dev *dev,
1089 struct ilo_state_raster_delta *delta)
1090 {
1091 delta->dirty = ILO_STATE_RASTER_3DSTATE_CLIP |
1092 ILO_STATE_RASTER_3DSTATE_SF |
1093 ILO_STATE_RASTER_3DSTATE_MULTISAMPLE |
1094 ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK |
1095 ILO_STATE_RASTER_3DSTATE_WM |
1096 ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS;
1097
1098 if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
1099 delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER |
1100 ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
1101 }
1102 }
1103
1104 void
1105 ilo_state_raster_get_delta(const struct ilo_state_raster *rs,
1106 const struct ilo_dev *dev,
1107 const struct ilo_state_raster *old,
1108 struct ilo_state_raster_delta *delta)
1109 {
1110 delta->dirty = 0;
1111
1112 if (memcmp(rs->clip, old->clip, sizeof(rs->clip)))
1113 delta->dirty |= ILO_STATE_RASTER_3DSTATE_CLIP;
1114
1115 if (memcmp(rs->sf, old->sf, sizeof(rs->sf)))
1116 delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF;
1117
1118 if (memcmp(rs->raster, old->raster, sizeof(rs->raster))) {
1119 if (ilo_dev_gen(dev) >= ILO_GEN(8))
1120 delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER;
1121 else
1122 delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF;
1123 }
1124
1125 if (memcmp(rs->sample, old->sample, sizeof(rs->sample))) {
1126 delta->dirty |= ILO_STATE_RASTER_3DSTATE_MULTISAMPLE |
1127 ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK;
1128 }
1129
1130 if (memcmp(rs->wm, old->wm, sizeof(rs->wm))) {
1131 delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM;
1132
1133 if (ilo_dev_gen(dev) >= ILO_GEN(8))
1134 delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
1135 }
1136 }
1137
1138 bool
1139 ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern,
1140 const struct ilo_dev *dev,
1141 const struct ilo_state_sample_pattern_info *info)
1142 {
1143 bool ret = true;
1144
1145 ret &= sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(pattern, dev, info);
1146
1147 assert(ret);
1148
1149 return ret;
1150 }
1151
1152 bool
1153 ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern,
1154 const struct ilo_dev *dev)
1155 {
1156 static const struct ilo_state_sample_pattern_info default_info = {
1157 .pattern_1x = {
1158 { 8, 8 },
1159 },
1160
1161 .pattern_2x = {
1162 { 4, 4 }, { 12, 12 },
1163 },
1164
1165 .pattern_4x = {
1166 { 6, 2 }, { 14, 6 }, { 2, 10 }, { 10, 14 },
1167 },
1168
1169 /* \see brw_multisample_positions_8x */
1170 .pattern_8x = {
1171 { 7, 9 }, { 9, 13 }, { 11, 3 }, { 13, 11 },
1172 { 1, 7 }, { 5, 1 }, { 15, 5 }, { 3, 15 },
1173 },
1174
1175 .pattern_16x = {
1176 { 8, 10 }, { 11, 8 }, { 5, 6 }, { 6, 4 },
1177 { 12, 11 }, { 13, 9 }, { 14, 7 }, { 10, 2 },
1178 { 4, 13 }, { 3, 3 }, { 7, 1 }, { 15, 5 },
1179 { 1, 12 }, { 9, 0 }, { 2, 14 }, { 0, 15 },
1180 },
1181 };
1182
1183 return ilo_state_sample_pattern_init(pattern, dev, &default_info);
1184 }
1185
1186 const uint8_t *
1187 ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern,
1188 const struct ilo_dev *dev,
1189 uint8_t sample_count)
1190 {
1191 switch (sample_count) {
1192 case 1: return pattern->pattern_1x;
1193 case 2: return pattern->pattern_2x;
1194 case 4: return pattern->pattern_4x;
1195 case 8: return pattern->pattern_8x;
1196 case 16: return pattern->pattern_16x;
1197 default:
1198 assert(!"unknown sample count");
1199 return NULL;
1200 }
1201 }
1202
1203 void
1204 ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern,
1205 const struct ilo_dev *dev,
1206 uint8_t sample_count, uint8_t sample_index,
1207 uint8_t *x, uint8_t *y)
1208 {
1209 const const uint8_t *packed =
1210 ilo_state_sample_pattern_get_packed_offsets(pattern, dev, sample_count);
1211
1212 assert(sample_index < sample_count);
1213
1214 *x = (packed[sample_index] >> 4) & 0xf;
1215 *y = packed[sample_index] & 0xf;
1216 }
1217
1218 /**
1219 * No need to initialize first.
1220 */
1221 bool
1222 ilo_state_line_stipple_set_info(struct ilo_state_line_stipple *stipple,
1223 const struct ilo_dev *dev,
1224 const struct ilo_state_line_stipple_info *info)
1225 {
1226 bool ret = true;
1227
1228 ret &= line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(stipple,
1229 dev, info);
1230
1231 assert(ret);
1232
1233 return ret;
1234 }
1235
1236 /**
1237 * No need to initialize first.
1238 */
1239 bool
1240 ilo_state_poly_stipple_set_info(struct ilo_state_poly_stipple *stipple,
1241 const struct ilo_dev *dev,
1242 const struct ilo_state_poly_stipple_info *info)
1243 {
1244 bool ret = true;
1245
1246 ret &= poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(stipple,
1247 dev, info);
1248
1249 assert(ret);
1250
1251 return ret;
1252 }