• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
raster_validate_gen6_clip(const struct ilo_dev * dev,const struct ilo_state_raster_info * info)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
raster_set_gen6_3DSTATE_CLIP(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info)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
raster_params_is_gen6_line_aa_allowed(const struct ilo_dev * dev,const struct ilo_state_raster_params_info * params)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
raster_get_gen6_effective_line(const struct ilo_dev * dev,const struct ilo_state_raster_info * info,struct ilo_state_raster_line_info * line)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
raster_validate_gen8_raster(const struct ilo_dev * dev,const struct ilo_state_raster_info * info)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
raster_setup_get_gen6_msrast_mode(const struct ilo_dev * dev,const struct ilo_state_raster_setup_info * setup)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
get_gen6_line_width(const struct ilo_dev * dev,float fwidth,bool line_aa_enable,bool line_giq_enable)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
get_gen6_point_width(const struct ilo_dev * dev,float fwidth)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
raster_set_gen7_3DSTATE_SF(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info,const struct ilo_state_raster_line_info * line)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
raster_set_gen8_3DSTATE_SF(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info,const struct ilo_state_raster_line_info * line)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
raster_set_gen8_3DSTATE_RASTER(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info,const struct ilo_state_raster_line_info * line)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_DX_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
get_gen6_sample_count(const struct ilo_dev * dev,uint8_t 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    default:
578       assert(!"unexpected sample count");
579       c = GEN6_NUMSAMPLES_1;
580       break;
581    }
582 
583    assert(ilo_dev_gen(dev) >= min_gen);
584 
585    return c;
586 }
587 
588 static bool
raster_set_gen8_3DSTATE_MULTISAMPLE(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info)589 raster_set_gen8_3DSTATE_MULTISAMPLE(struct ilo_state_raster *rs,
590                                     const struct ilo_dev *dev,
591                                     const struct ilo_state_raster_info *info)
592 {
593    const struct ilo_state_raster_setup_info *setup = &info->setup;
594    const struct ilo_state_raster_scan_info *scan = &info->scan;
595    const enum gen_sample_count count =
596       get_gen6_sample_count(dev, scan->sample_count);
597    uint32_t dw1;
598 
599    ILO_DEV_ASSERT(dev, 6, 8);
600 
601    /*
602     * From the Sandy Bridge PRM, volume 2 part 1, page 307:
603     *
604     *     "Setting Multisample Rasterization Mode to MSRASTMODE_xxx_PATTERN
605     *      when Number of Multisamples == NUMSAMPLES_1 is UNDEFINED."
606     */
607    if (setup->msaa_enable)
608       assert(scan->sample_count > 1);
609 
610    dw1 = scan->pixloc << GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__SHIFT |
611          count << GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__SHIFT;
612 
613    STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 1);
614    rs->sample[0] = dw1;
615 
616    return true;
617 }
618 
619 static bool
raster_set_gen6_3DSTATE_SAMPLE_MASK(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info)620 raster_set_gen6_3DSTATE_SAMPLE_MASK(struct ilo_state_raster *rs,
621                                     const struct ilo_dev *dev,
622                                     const struct ilo_state_raster_info *info)
623 {
624    const struct ilo_state_raster_scan_info *scan = &info->scan;
625    /*
626     * From the Ivy Bridge PRM, volume 2 part 1, page 294:
627     *
628     *     "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field
629     *      (Sample Mask) must be zero.
630     *
631     *      If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field
632     *      must be zero."
633     */
634    const uint32_t mask = (1 << scan->sample_count) - 1;
635    uint32_t dw1;
636 
637    ILO_DEV_ASSERT(dev, 6, 8);
638 
639    dw1 = (scan->sample_mask & mask) << GEN6_SAMPLE_MASK_DW1_VAL__SHIFT;
640 
641    STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 2);
642    rs->sample[1] = dw1;
643 
644    return true;
645 }
646 
647 static bool
raster_validate_gen6_wm(const struct ilo_dev * dev,const struct ilo_state_raster_info * info)648 raster_validate_gen6_wm(const struct ilo_dev *dev,
649                         const struct ilo_state_raster_info *info)
650 {
651    const struct ilo_state_raster_scan_info *scan = &info->scan;
652 
653    ILO_DEV_ASSERT(dev, 6, 8);
654 
655    if (ilo_dev_gen(dev) == ILO_GEN(6))
656       assert(scan->earlyz_control == GEN7_EDSC_NORMAL);
657 
658    /*
659     * From the Sandy Bridge PRM, volume 2 part 1, page 272:
660     *
661     *     "This bit (Statistics Enable) must be disabled if either of these
662     *      bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve
663     *      Enable or Depth Buffer Resolve Enable."
664     */
665    if (scan->earlyz_op != ILO_STATE_RASTER_EARLYZ_NORMAL)
666       assert(!scan->stats_enable);
667 
668    /*
669     * From the Sandy Bridge PRM, volume 2 part 1, page 273:
670     *
671     *     "If this field (Depth Buffer Resolve Enable) is enabled, the Depth
672     *      Buffer Clear and Hierarchical Depth Buffer Resolve Enable fields
673     *      must both be disabled."
674     *
675     *     "If this field (Hierarchical Depth Buffer Resolve Enable) is
676     *      enabled, the Depth Buffer Clear and Depth Buffer Resolve Enable
677     *      fields must both be disabled."
678     *
679     * This is guaranteed.
680     */
681 
682    /*
683     * From the Sandy Bridge PRM, volume 2 part 1, page 314-315:
684     *
685     *     "Stencil buffer clear can be performed at the same time by enabling
686     *      Stencil Buffer Write Enable."
687     *
688     *     "Note also that stencil buffer clear can be performed without depth
689     *      buffer clear."
690     */
691    if (scan->earlyz_stencil_clear) {
692       assert(scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_NORMAL ||
693              scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR);
694    }
695 
696    return true;
697 }
698 
699 static bool
raster_set_gen6_3dstate_wm(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info,const struct ilo_state_raster_line_info * line)700 raster_set_gen6_3dstate_wm(struct ilo_state_raster *rs,
701                            const struct ilo_dev *dev,
702                            const struct ilo_state_raster_info *info,
703                            const struct ilo_state_raster_line_info *line)
704 {
705    const struct ilo_state_raster_tri_info *tri = &info->tri;
706    const struct ilo_state_raster_setup_info *setup = &info->setup;
707    const struct ilo_state_raster_scan_info *scan = &info->scan;
708    const enum gen_msrast_mode msrast =
709       raster_setup_get_gen6_msrast_mode(dev, setup);
710    /* only scan conversion states are set, as in Gen8+ */
711    uint32_t dw4, dw5, dw6;
712 
713    ILO_DEV_ASSERT(dev, 6, 6);
714 
715    if (!raster_validate_gen6_wm(dev, info))
716       return false;
717 
718    dw4 = 0;
719 
720    if (scan->stats_enable)
721       dw4 |= GEN6_WM_DW4_STATISTICS;
722 
723    switch (scan->earlyz_op) {
724    case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
725       dw4 |= GEN6_WM_DW4_DEPTH_CLEAR;
726       break;
727    case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
728       dw4 |= GEN6_WM_DW4_DEPTH_RESOLVE;
729       break;
730    case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
731       dw4 |= GEN6_WM_DW4_HIZ_RESOLVE;
732       break;
733    default:
734       if (scan->earlyz_stencil_clear)
735          dw4 |= GEN6_WM_DW4_DEPTH_CLEAR;
736       break;
737    }
738 
739    dw5 = GEN6_WM_DW5_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */
740          GEN6_WM_DW5_AA_LINE_WIDTH_2_0;
741 
742    if (tri->poly_stipple_enable)
743       dw5 |= GEN6_WM_DW5_POLY_STIPPLE_ENABLE;
744    if (line->stipple_enable)
745       dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE;
746 
747    dw6 = scan->zw_interp << GEN6_WM_DW6_ZW_INTERP__SHIFT |
748          scan->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT |
749          GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT |
750          msrast << GEN6_WM_DW6_MSRASTMODE__SHIFT;
751 
752    STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3);
753    rs->wm[0] = dw4;
754    rs->wm[1] = dw5;
755    rs->wm[2] = dw6;
756 
757    return true;
758 }
759 
760 static bool
raster_set_gen8_3DSTATE_WM(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info,const struct ilo_state_raster_line_info * line)761 raster_set_gen8_3DSTATE_WM(struct ilo_state_raster *rs,
762                            const struct ilo_dev *dev,
763                            const struct ilo_state_raster_info *info,
764                            const struct ilo_state_raster_line_info *line)
765 {
766    const struct ilo_state_raster_tri_info *tri = &info->tri;
767    const struct ilo_state_raster_setup_info *setup = &info->setup;
768    const struct ilo_state_raster_scan_info *scan = &info->scan;
769    const enum gen_msrast_mode msrast =
770       raster_setup_get_gen6_msrast_mode(dev, setup);
771    uint32_t dw1;
772 
773    ILO_DEV_ASSERT(dev, 7, 8);
774 
775    if (!raster_validate_gen6_wm(dev, info))
776       return false;
777 
778    dw1 = scan->earlyz_control << GEN7_WM_DW1_EDSC__SHIFT |
779          scan->zw_interp << GEN7_WM_DW1_ZW_INTERP__SHIFT |
780          scan->barycentric_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT |
781          GEN7_WM_DW1_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */
782          GEN7_WM_DW1_AA_LINE_WIDTH_2_0 |
783          GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
784 
785    if (scan->stats_enable)
786       dw1 |= GEN7_WM_DW1_STATISTICS;
787 
788    if (ilo_dev_gen(dev) < ILO_GEN(8)) {
789       switch (scan->earlyz_op) {
790       case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
791          dw1 |= GEN7_WM_DW1_LEGACY_DEPTH_CLEAR;
792          break;
793       case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
794          dw1 |= GEN7_WM_DW1_LEGACY_DEPTH_RESOLVE;
795          break;
796       case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
797          dw1 |= GEN7_WM_DW1_LEGACY_HIZ_RESOLVE;
798          break;
799       default:
800          if (scan->earlyz_stencil_clear)
801             dw1 |= GEN7_WM_DW1_LEGACY_DEPTH_CLEAR;
802          break;
803       }
804    }
805 
806    if (tri->poly_stipple_enable)
807       dw1 |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
808    if (line->stipple_enable)
809       dw1 |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
810 
811    if (ilo_dev_gen(dev) < ILO_GEN(8))
812       dw1 |= msrast << GEN7_WM_DW1_MSRASTMODE__SHIFT;
813 
814    STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 1);
815    rs->wm[0] = dw1;
816 
817    return true;
818 }
819 
820 static bool
raster_set_gen8_3dstate_wm_hz_op(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info)821 raster_set_gen8_3dstate_wm_hz_op(struct ilo_state_raster *rs,
822                                  const struct ilo_dev *dev,
823                                  const struct ilo_state_raster_info *info)
824 {
825    const struct ilo_state_raster_scan_info *scan = &info->scan;
826    const enum gen_sample_count count =
827       get_gen6_sample_count(dev, scan->sample_count);
828    const uint32_t mask = (1 << scan->sample_count) - 1;
829    uint32_t dw1, dw4;
830 
831    ILO_DEV_ASSERT(dev, 8, 8);
832 
833    dw1 = count << GEN8_WM_HZ_DW1_NUM_SAMPLES__SHIFT;
834 
835    if (scan->earlyz_stencil_clear)
836       dw1 |= GEN8_WM_HZ_DW1_STENCIL_CLEAR;
837 
838    switch (scan->earlyz_op) {
839    case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR:
840       dw1 |= GEN8_WM_HZ_DW1_DEPTH_CLEAR;
841       break;
842    case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE:
843       dw1 |= GEN8_WM_HZ_DW1_DEPTH_RESOLVE;
844       break;
845    case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE:
846       dw1 |= GEN8_WM_HZ_DW1_HIZ_RESOLVE;
847       break;
848    default:
849       break;
850    }
851 
852    dw4 = (scan->sample_mask & mask) << GEN8_WM_HZ_DW4_SAMPLE_MASK__SHIFT;
853 
854    STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3);
855    rs->wm[1] = dw1;
856    rs->wm[2] = dw4;
857 
858    return true;
859 }
860 
861 static bool
sample_pattern_get_gen6_packed_offsets(const struct ilo_dev * dev,uint8_t sample_count,const struct ilo_state_sample_pattern_offset_info * in,uint8_t * out)862 sample_pattern_get_gen6_packed_offsets(const struct ilo_dev *dev,
863                                        uint8_t sample_count,
864                                        const struct ilo_state_sample_pattern_offset_info *in,
865                                        uint8_t *out)
866 {
867    uint8_t max_dist, i;
868 
869    ILO_DEV_ASSERT(dev, 6, 8);
870 
871    max_dist = 0;
872    for (i = 0; i < sample_count; i++) {
873       const int8_t dist_x = (int8_t) in[i].x - 8;
874       const int8_t dist_y = (int8_t) in[i].y - 8;
875       const uint8_t dist = dist_x * dist_x + dist_y * dist_y;
876 
877       /*
878        * From the Sandy Bridge PRM, volume 2 part 1, page 305:
879        *
880        *     "Programming Note: When programming the sample offsets (for
881        *      NUMSAMPLES_4 or _8 and MSRASTMODE_xxx_PATTERN), the order of the
882        *      samples 0 to 3 (or 7 for 8X) must have monotonically increasing
883        *      distance from the pixel center. This is required to get the
884        *      correct centroid computation in the device."
885        */
886       assert(dist >= max_dist);
887       max_dist = dist;
888 
889       assert(in[i].x < 16);
890       assert(in[i].y < 16);
891 
892       out[i] = in[i].x << 4 | in[i].y;
893    }
894 
895    return true;
896 }
897 
898 static bool
line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(struct ilo_state_line_stipple * stipple,const struct ilo_dev * dev,const struct ilo_state_line_stipple_info * info)899 line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(struct ilo_state_line_stipple *stipple,
900                                            const struct ilo_dev *dev,
901                                            const struct ilo_state_line_stipple_info *info)
902 {
903    uint32_t dw1, dw2;
904 
905    ILO_DEV_ASSERT(dev, 6, 8);
906 
907    assert(info->repeat_count >= 1 && info->repeat_count <= 256);
908 
909    dw1 = info->pattern;
910    if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
911       /* in U1.16 */
912       const uint32_t inverse = 65536 / info->repeat_count;
913       dw2 = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
914             info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT;
915    } else {
916       /* in U1.13 */
917       const uint16_t inverse = 8192 / info->repeat_count;
918       dw2 = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT |
919             info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT;
920    }
921 
922    STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 2);
923    stipple->stipple[0] = dw1;
924    stipple->stipple[1] = dw2;
925 
926    return true;
927 }
928 
929 static bool
sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern * pattern,const struct ilo_dev * dev,const struct ilo_state_sample_pattern_info * info)930 sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern *pattern,
931                                                const struct ilo_dev *dev,
932                                                const struct ilo_state_sample_pattern_info *info)
933 {
934    ILO_DEV_ASSERT(dev, 6, 8);
935 
936    STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_1x) >= 1);
937    STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_2x) >= 2);
938    STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_4x) >= 4);
939    STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_8x) >= 8);
940    STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_16x) >= 16);
941 
942    return (sample_pattern_get_gen6_packed_offsets(dev, 1,
943               info->pattern_1x, pattern->pattern_1x) &&
944            sample_pattern_get_gen6_packed_offsets(dev, 2,
945               info->pattern_2x, pattern->pattern_2x) &&
946            sample_pattern_get_gen6_packed_offsets(dev, 4,
947               info->pattern_4x, pattern->pattern_4x) &&
948            sample_pattern_get_gen6_packed_offsets(dev, 8,
949               info->pattern_8x, pattern->pattern_8x) &&
950            sample_pattern_get_gen6_packed_offsets(dev, 16,
951               info->pattern_16x, pattern->pattern_16x));
952 
953 }
954 
955 static bool
poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_state_poly_stipple * stipple,const struct ilo_dev * dev,const struct ilo_state_poly_stipple_info * info)956 poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_state_poly_stipple *stipple,
957                                                    const struct ilo_dev *dev,
958                                                    const struct ilo_state_poly_stipple_info *info)
959 {
960    ILO_DEV_ASSERT(dev, 6, 8);
961 
962    STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 32);
963    memcpy(stipple->stipple, info->pattern, sizeof(info->pattern));
964 
965    return true;
966 }
967 
968 bool
ilo_state_raster_init(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info)969 ilo_state_raster_init(struct ilo_state_raster *rs,
970                       const struct ilo_dev *dev,
971                       const struct ilo_state_raster_info *info)
972 {
973    assert(ilo_is_zeroed(rs, sizeof(*rs)));
974    return ilo_state_raster_set_info(rs, dev, info);
975 }
976 
977 bool
ilo_state_raster_init_for_rectlist(struct ilo_state_raster * rs,const struct ilo_dev * dev,uint8_t sample_count,enum ilo_state_raster_earlyz_op earlyz_op,bool earlyz_stencil_clear)978 ilo_state_raster_init_for_rectlist(struct ilo_state_raster *rs,
979                                    const struct ilo_dev *dev,
980                                    uint8_t sample_count,
981                                    enum ilo_state_raster_earlyz_op earlyz_op,
982                                    bool earlyz_stencil_clear)
983 {
984    struct ilo_state_raster_info info;
985 
986    memset(&info, 0, sizeof(info));
987 
988    info.clip.viewport_count = 1;
989    info.setup.cv_is_rectangle = true;
990    info.setup.msaa_enable = (sample_count > 1);
991    info.scan.sample_count = sample_count;
992    info.scan.sample_mask = ~0u;
993    info.scan.earlyz_op = earlyz_op;
994    info.scan.earlyz_stencil_clear = earlyz_stencil_clear;
995 
996    return ilo_state_raster_init(rs, dev, &info);
997 }
998 
999 bool
ilo_state_raster_set_info(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_info * info)1000 ilo_state_raster_set_info(struct ilo_state_raster *rs,
1001                           const struct ilo_dev *dev,
1002                           const struct ilo_state_raster_info *info)
1003 {
1004    struct ilo_state_raster_line_info line;
1005    bool ret = true;
1006 
1007    ret &= raster_set_gen6_3DSTATE_CLIP(rs, dev, info);
1008 
1009    raster_get_gen6_effective_line(dev, info, &line);
1010 
1011    if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
1012       ret &= raster_set_gen8_3DSTATE_SF(rs, dev, info, &line);
1013       ret &= raster_set_gen8_3DSTATE_RASTER(rs, dev, info, &line);
1014    } else {
1015       ret &= raster_set_gen7_3DSTATE_SF(rs, dev, info, &line);
1016    }
1017 
1018    ret &= raster_set_gen8_3DSTATE_MULTISAMPLE(rs, dev, info);
1019    ret &= raster_set_gen6_3DSTATE_SAMPLE_MASK(rs, dev, info);
1020 
1021    if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
1022       ret &= raster_set_gen8_3DSTATE_WM(rs, dev, info, &line);
1023 
1024       if (ilo_dev_gen(dev) >= ILO_GEN(8))
1025          ret &= raster_set_gen8_3dstate_wm_hz_op(rs, dev, info);
1026    } else {
1027       ret &= raster_set_gen6_3dstate_wm(rs, dev, info, &line);
1028    }
1029 
1030    assert(ret);
1031 
1032    return ret;
1033 }
1034 
1035 bool
ilo_state_raster_set_params(struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster_params_info * params)1036 ilo_state_raster_set_params(struct ilo_state_raster *rs,
1037                             const struct ilo_dev *dev,
1038                             const struct ilo_state_raster_params_info *params)
1039 {
1040    const bool line_aa_enable = (rs->line_aa_enable &&
1041          raster_params_is_gen6_line_aa_allowed(dev, params));
1042    const int line_width = get_gen6_line_width(dev, params->line_width,
1043          line_aa_enable, rs->line_giq_enable);
1044 
1045    ILO_DEV_ASSERT(dev, 6, 8);
1046 
1047    /* modify line AA enable */
1048    if (rs->line_aa_enable) {
1049       if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
1050          if (line_aa_enable)
1051             rs->raster[0] |= GEN8_RASTER_DW1_AA_LINE_ENABLE;
1052          else
1053             rs->raster[0] &= ~GEN8_RASTER_DW1_AA_LINE_ENABLE;
1054       } else {
1055          if (line_aa_enable)
1056             rs->sf[1] |= GEN7_SF_DW2_AA_LINE_ENABLE;
1057          else
1058             rs->sf[1] &= ~GEN7_SF_DW2_AA_LINE_ENABLE;
1059       }
1060    }
1061 
1062    /* modify line width */
1063    rs->sf[1] = (rs->sf[1] & ~GEN7_SF_DW2_LINE_WIDTH__MASK) |
1064                line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT;
1065 
1066    /* modify point width */
1067    if (rs->sf[2] & GEN7_SF_DW3_USE_POINT_WIDTH) {
1068       const int point_width = get_gen6_point_width(dev, params->point_width);
1069 
1070       rs->sf[2] = (rs->sf[2] & ~GEN7_SF_DW3_POINT_WIDTH__MASK) |
1071                   point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT;
1072    }
1073 
1074    /* modify depth offset */
1075    rs->raster[1] = fui(params->depth_offset_const);
1076    rs->raster[2] = fui(params->depth_offset_scale);
1077    rs->raster[3] = fui(params->depth_offset_clamp);
1078 
1079    return true;
1080 }
1081 
1082 void
ilo_state_raster_full_delta(const struct ilo_state_raster * rs,const struct ilo_dev * dev,struct ilo_state_raster_delta * delta)1083 ilo_state_raster_full_delta(const struct ilo_state_raster *rs,
1084                             const struct ilo_dev *dev,
1085                             struct ilo_state_raster_delta *delta)
1086 {
1087    delta->dirty = ILO_STATE_RASTER_3DSTATE_CLIP |
1088                   ILO_STATE_RASTER_3DSTATE_SF |
1089                   ILO_STATE_RASTER_3DSTATE_MULTISAMPLE |
1090                   ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK |
1091                   ILO_STATE_RASTER_3DSTATE_WM |
1092                   ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS;
1093 
1094    if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
1095       delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER |
1096                       ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
1097    }
1098 }
1099 
1100 void
ilo_state_raster_get_delta(const struct ilo_state_raster * rs,const struct ilo_dev * dev,const struct ilo_state_raster * old,struct ilo_state_raster_delta * delta)1101 ilo_state_raster_get_delta(const struct ilo_state_raster *rs,
1102                            const struct ilo_dev *dev,
1103                            const struct ilo_state_raster *old,
1104                            struct ilo_state_raster_delta *delta)
1105 {
1106    delta->dirty = 0;
1107 
1108    if (memcmp(rs->clip, old->clip, sizeof(rs->clip)))
1109       delta->dirty |= ILO_STATE_RASTER_3DSTATE_CLIP;
1110 
1111    if (memcmp(rs->sf, old->sf, sizeof(rs->sf)))
1112       delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF;
1113 
1114    if (memcmp(rs->raster, old->raster, sizeof(rs->raster))) {
1115       if (ilo_dev_gen(dev) >= ILO_GEN(8))
1116          delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER;
1117       else
1118          delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF;
1119    }
1120 
1121    if (memcmp(rs->sample, old->sample, sizeof(rs->sample))) {
1122       delta->dirty |= ILO_STATE_RASTER_3DSTATE_MULTISAMPLE |
1123                       ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK;
1124    }
1125 
1126    if (memcmp(rs->wm, old->wm, sizeof(rs->wm))) {
1127       delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM;
1128 
1129       if (ilo_dev_gen(dev) >= ILO_GEN(8))
1130          delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
1131    }
1132 }
1133 
1134 bool
ilo_state_sample_pattern_init(struct ilo_state_sample_pattern * pattern,const struct ilo_dev * dev,const struct ilo_state_sample_pattern_info * info)1135 ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern,
1136                               const struct ilo_dev *dev,
1137                               const struct ilo_state_sample_pattern_info *info)
1138 {
1139    bool ret = true;
1140 
1141    ret &= sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(pattern, dev, info);
1142 
1143    assert(ret);
1144 
1145    return ret;
1146 }
1147 
1148 bool
ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern * pattern,const struct ilo_dev * dev)1149 ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern,
1150                                       const struct ilo_dev *dev)
1151 {
1152    static const struct ilo_state_sample_pattern_info default_info = {
1153       .pattern_1x = {
1154          {  8,  8 },
1155       },
1156 
1157       .pattern_2x = {
1158          {  4,  4 }, { 12, 12 },
1159       },
1160 
1161       .pattern_4x = {
1162          {  6,  2 }, { 14,  6 }, {  2, 10 }, { 10, 14 },
1163       },
1164 
1165       /* \see brw_multisample_positions_8x */
1166       .pattern_8x = {
1167          {  7,  9 }, {  9, 13 }, { 11,  3 }, { 13, 11 },
1168          {  1,  7 }, {  5,  1 }, { 15,  5 }, {  3, 15 },
1169       },
1170 
1171       .pattern_16x = {
1172          {  8, 10 }, { 11,  8 }, {  5,  6 }, {  6,  4 },
1173          { 12, 11 }, { 13,  9 }, { 14,  7 }, { 10,  2 },
1174          {  4, 13 }, {  3,  3 }, {  7,  1 }, { 15,  5 },
1175          {  1, 12 }, {  9,  0 }, {  2, 14 }, {  0, 15 },
1176       },
1177    };
1178 
1179    return ilo_state_sample_pattern_init(pattern, dev, &default_info);
1180 }
1181 
1182 const uint8_t *
ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern * pattern,const struct ilo_dev * dev,uint8_t sample_count)1183 ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern,
1184                                             const struct ilo_dev *dev,
1185                                             uint8_t sample_count)
1186 {
1187    switch (sample_count) {
1188    case 1:  return pattern->pattern_1x;
1189    case 2:  return pattern->pattern_2x;
1190    case 4:  return pattern->pattern_4x;
1191    case 8:  return pattern->pattern_8x;
1192    case 16: return pattern->pattern_16x;
1193    default:
1194       assert(!"unknown sample count");
1195       return NULL;
1196    }
1197 }
1198 
1199 void
ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern * pattern,const struct ilo_dev * dev,uint8_t sample_count,uint8_t sample_index,uint8_t * x,uint8_t * y)1200 ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern,
1201                                     const struct ilo_dev *dev,
1202                                     uint8_t sample_count, uint8_t sample_index,
1203                                     uint8_t *x, uint8_t *y)
1204 {
1205    const const uint8_t *packed =
1206       ilo_state_sample_pattern_get_packed_offsets(pattern, dev, sample_count);
1207 
1208    assert(sample_index < sample_count);
1209 
1210    *x = (packed[sample_index] >> 4) & 0xf;
1211    *y = packed[sample_index] & 0xf;
1212 }
1213 
1214 /**
1215  * No need to initialize first.
1216  */
1217 bool
ilo_state_line_stipple_set_info(struct ilo_state_line_stipple * stipple,const struct ilo_dev * dev,const struct ilo_state_line_stipple_info * info)1218 ilo_state_line_stipple_set_info(struct ilo_state_line_stipple *stipple,
1219                                 const struct ilo_dev *dev,
1220                                 const struct ilo_state_line_stipple_info *info)
1221 {
1222    bool ret = true;
1223 
1224    ret &= line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(stipple,
1225          dev, info);
1226 
1227    assert(ret);
1228 
1229    return ret;
1230 }
1231 
1232 /**
1233  * No need to initialize first.
1234  */
1235 bool
ilo_state_poly_stipple_set_info(struct ilo_state_poly_stipple * stipple,const struct ilo_dev * dev,const struct ilo_state_poly_stipple_info * info)1236 ilo_state_poly_stipple_set_info(struct ilo_state_poly_stipple *stipple,
1237                                 const struct ilo_dev *dev,
1238                                 const struct ilo_state_poly_stipple_info *info)
1239 {
1240    bool ret = true;
1241 
1242    ret &= poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(stipple,
1243          dev, info);
1244 
1245    assert(ret);
1246 
1247    return ret;
1248 }
1249