• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "compiler/nir/nir.h"
25 #include "brw_context.h"
26 #include "brw_state.h"
27 #include "brw_defines.h"
28 #include "brw_util.h"
29 #include "main/macros.h"
30 #include "main/fbobject.h"
31 #include "intel_batchbuffer.h"
32 
33 static void
upload_sbe(struct brw_context * brw)34 upload_sbe(struct brw_context *brw)
35 {
36    struct gl_context *ctx = &brw->ctx;
37    /* BRW_NEW_FS_PROG_DATA */
38    const struct brw_wm_prog_data *wm_prog_data =
39       brw_wm_prog_data(brw->wm.base.prog_data);
40    uint32_t num_outputs = wm_prog_data->num_varying_inputs;
41    uint16_t attr_overrides[VARYING_SLOT_MAX];
42    uint32_t urb_entry_read_length;
43    uint32_t urb_entry_read_offset;
44    uint32_t point_sprite_enables;
45    int sbe_cmd_length;
46 
47    uint32_t dw1 =
48       GEN7_SBE_SWIZZLE_ENABLE |
49       num_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT;
50    uint32_t dw4 = 0;
51    uint32_t dw5 = 0;
52 
53    /* _NEW_BUFFERS */
54    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
55 
56    /* _NEW_POINT
57     *
58     * Window coordinates in an FBO are inverted, which means point
59     * sprite origin must be inverted.
60     */
61    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
62       dw1 |= GEN6_SF_POINT_SPRITE_LOWERLEFT;
63    else
64       dw1 |= GEN6_SF_POINT_SPRITE_UPPERLEFT;
65 
66    /* _NEW_POINT | _NEW_LIGHT | _NEW_PROGRAM,
67     * BRW_NEW_FS_PROG_DATA | BRW_NEW_FRAGMENT_PROGRAM |
68     * BRW_NEW_GS_PROG_DATA | BRW_NEW_PRIMITIVE | BRW_NEW_TES_PROG_DATA |
69     * BRW_NEW_VUE_MAP_GEOM_OUT
70     */
71    calculate_attr_overrides(brw, attr_overrides,
72                             &point_sprite_enables,
73                             &urb_entry_read_length,
74                             &urb_entry_read_offset);
75 
76    /* Typically, the URB entry read length and offset should be programmed in
77     * 3DSTATE_VS and 3DSTATE_GS; SBE inherits it from the last active stage
78     * which produces geometry.  However, we don't know the proper value until
79     * we call calculate_attr_overrides().
80     *
81     * To fit with our existing code, we override the inherited values and
82     * specify it here directly, as we did on previous generations.
83     */
84    dw1 |=
85       urb_entry_read_length << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
86       urb_entry_read_offset << GEN8_SBE_URB_ENTRY_READ_OFFSET_SHIFT |
87       GEN8_SBE_FORCE_URB_ENTRY_READ_LENGTH |
88       GEN8_SBE_FORCE_URB_ENTRY_READ_OFFSET;
89 
90    if (brw->gen == 8) {
91       sbe_cmd_length = 4;
92    } else {
93       sbe_cmd_length = 6;
94 
95       /* prepare the active component dwords */
96       int input_index = 0;
97       for (int attr = 0; attr < VARYING_SLOT_MAX; attr++) {
98          if (!(brw->fragment_program->info.inputs_read &
99                BITFIELD64_BIT(attr))) {
100             continue;
101          }
102 
103          assert(input_index < 32);
104 
105          if (input_index < 16)
106             dw4 |= (GEN9_SBE_ACTIVE_COMPONENT_XYZW << (input_index << 1));
107          else
108             dw5 |= (GEN9_SBE_ACTIVE_COMPONENT_XYZW << ((input_index - 16) << 1));
109 
110          ++input_index;
111       }
112    }
113    BEGIN_BATCH(sbe_cmd_length);
114    OUT_BATCH(_3DSTATE_SBE << 16 | (sbe_cmd_length - 2));
115    OUT_BATCH(dw1);
116    OUT_BATCH(point_sprite_enables);
117    OUT_BATCH(wm_prog_data->flat_inputs);
118    if (sbe_cmd_length >= 6) {
119       OUT_BATCH(dw4);
120       OUT_BATCH(dw5);
121    }
122    ADVANCE_BATCH();
123 
124    BEGIN_BATCH(11);
125    OUT_BATCH(_3DSTATE_SBE_SWIZ << 16 | (11 - 2));
126 
127    /* Output DWords 1 through 8: */
128    for (int i = 0; i < 8; i++) {
129       OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
130    }
131 
132    OUT_BATCH(0); /* wrapshortest enables 0-7 */
133    OUT_BATCH(0); /* wrapshortest enables 8-15 */
134    ADVANCE_BATCH();
135 }
136 
137 const struct brw_tracked_state gen8_sbe_state = {
138    .dirty = {
139       .mesa  = _NEW_BUFFERS |
140                _NEW_LIGHT |
141                _NEW_POINT |
142                _NEW_POLYGON |
143                _NEW_PROGRAM,
144       .brw   = BRW_NEW_BLORP |
145                BRW_NEW_CONTEXT |
146                BRW_NEW_FRAGMENT_PROGRAM |
147                BRW_NEW_FS_PROG_DATA |
148                BRW_NEW_GS_PROG_DATA |
149                BRW_NEW_TES_PROG_DATA |
150                BRW_NEW_VUE_MAP_GEOM_OUT,
151    },
152    .emit = upload_sbe,
153 };
154 
155 static void
upload_sf(struct brw_context * brw)156 upload_sf(struct brw_context *brw)
157 {
158    struct gl_context *ctx = &brw->ctx;
159    uint32_t dw1 = 0, dw2 = 0, dw3 = 0;
160    float point_size;
161 
162    dw1 = GEN6_SF_STATISTICS_ENABLE;
163 
164    if (brw->sf.viewport_transform_enable)
165        dw1 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
166 
167    /* _NEW_LINE */
168    uint32_t line_width_u3_7 = brw_get_line_width(brw);
169    if (brw->gen >= 9 || brw->is_cherryview) {
170       dw1 |= line_width_u3_7 << GEN9_SF_LINE_WIDTH_SHIFT;
171    } else {
172       dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT;
173    }
174 
175    if (ctx->Line.SmoothFlag) {
176       dw2 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0;
177    }
178 
179    /* _NEW_POINT - Clamp to ARB_point_parameters user limits */
180    point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
181 
182    /* Clamp to the hardware limits and convert to fixed point */
183    dw3 |= U_FIXED(CLAMP(point_size, 0.125f, 255.875f), 3);
184 
185    /* _NEW_PROGRAM | _NEW_POINT, BRW_NEW_VUE_MAP_GEOM_OUT */
186    if (use_state_point_size(brw))
187       dw3 |= GEN6_SF_USE_STATE_POINT_WIDTH;
188 
189    /* _NEW_POINT | _NEW_MULTISAMPLE */
190    if ((ctx->Point.SmoothFlag || _mesa_is_multisample_enabled(ctx)) &&
191        !ctx->Point.PointSprite) {
192       dw3 |= GEN8_SF_SMOOTH_POINT_ENABLE;
193    }
194 
195    dw3 |= GEN6_SF_LINE_AA_MODE_TRUE;
196 
197    /* _NEW_LIGHT */
198    if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) {
199       dw3 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) |
200              (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) |
201              (1 << GEN6_SF_LINE_PROVOKE_SHIFT);
202    } else {
203       dw3 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT);
204    }
205 
206    BEGIN_BATCH(4);
207    OUT_BATCH(_3DSTATE_SF << 16 | (4 - 2));
208    OUT_BATCH(dw1);
209    OUT_BATCH(dw2);
210    OUT_BATCH(dw3);
211    ADVANCE_BATCH();
212 }
213 
214 const struct brw_tracked_state gen8_sf_state = {
215    .dirty = {
216       .mesa  = _NEW_LIGHT |
217                _NEW_PROGRAM |
218                _NEW_LINE |
219                _NEW_MULTISAMPLE |
220                _NEW_POINT,
221       .brw   = BRW_NEW_BLORP |
222                BRW_NEW_CONTEXT |
223                BRW_NEW_VUE_MAP_GEOM_OUT,
224    },
225    .emit = upload_sf,
226 };
227 
228 static void
upload_raster(struct brw_context * brw)229 upload_raster(struct brw_context *brw)
230 {
231    struct gl_context *ctx = &brw->ctx;
232    uint32_t dw1 = 0;
233 
234    /* _NEW_BUFFERS */
235    bool render_to_fbo = _mesa_is_user_fbo(brw->ctx.DrawBuffer);
236 
237    /* _NEW_POLYGON */
238    if (ctx->Polygon._FrontBit == render_to_fbo)
239       dw1 |= GEN8_RASTER_FRONT_WINDING_CCW;
240 
241    if (ctx->Polygon.CullFlag) {
242       switch (ctx->Polygon.CullFaceMode) {
243       case GL_FRONT:
244          dw1 |= GEN8_RASTER_CULL_FRONT;
245          break;
246       case GL_BACK:
247          dw1 |= GEN8_RASTER_CULL_BACK;
248          break;
249       case GL_FRONT_AND_BACK:
250          dw1 |= GEN8_RASTER_CULL_BOTH;
251          break;
252       default:
253          unreachable("not reached");
254       }
255    } else {
256       dw1 |= GEN8_RASTER_CULL_NONE;
257    }
258 
259    /* _NEW_POINT */
260    if (ctx->Point.SmoothFlag)
261       dw1 |= GEN8_RASTER_SMOOTH_POINT_ENABLE;
262 
263    if (_mesa_is_multisample_enabled(ctx))
264       dw1 |= GEN8_RASTER_API_MULTISAMPLE_ENABLE;
265 
266    if (ctx->Polygon.OffsetFill)
267       dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID;
268 
269    if (ctx->Polygon.OffsetLine)
270       dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME;
271 
272    if (ctx->Polygon.OffsetPoint)
273       dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT;
274 
275    switch (ctx->Polygon.FrontMode) {
276    case GL_FILL:
277       dw1 |= GEN6_SF_FRONT_SOLID;
278       break;
279    case GL_LINE:
280       dw1 |= GEN6_SF_FRONT_WIREFRAME;
281       break;
282    case GL_POINT:
283       dw1 |= GEN6_SF_FRONT_POINT;
284       break;
285 
286    default:
287       unreachable("not reached");
288    }
289 
290    switch (ctx->Polygon.BackMode) {
291    case GL_FILL:
292       dw1 |= GEN6_SF_BACK_SOLID;
293       break;
294    case GL_LINE:
295       dw1 |= GEN6_SF_BACK_WIREFRAME;
296       break;
297    case GL_POINT:
298       dw1 |= GEN6_SF_BACK_POINT;
299       break;
300    default:
301       unreachable("not reached");
302    }
303 
304    /* _NEW_LINE */
305    if (ctx->Line.SmoothFlag)
306       dw1 |= GEN8_RASTER_LINE_AA_ENABLE;
307 
308    /* _NEW_SCISSOR */
309    if (ctx->Scissor.EnableFlags)
310       dw1 |= GEN8_RASTER_SCISSOR_ENABLE;
311 
312    /* _NEW_TRANSFORM */
313    if (!ctx->Transform.DepthClamp) {
314       if (brw->gen >= 9) {
315          dw1 |= GEN9_RASTER_VIEWPORT_Z_NEAR_CLIP_TEST_ENABLE |
316                 GEN9_RASTER_VIEWPORT_Z_FAR_CLIP_TEST_ENABLE;
317       } else {
318          dw1 |= GEN8_RASTER_VIEWPORT_Z_CLIP_TEST_ENABLE;
319       }
320    }
321 
322    /* BRW_NEW_CONSERVATIVE_RASTERIZATION */
323    if (ctx->IntelConservativeRasterization) {
324       if (brw->gen >= 9)
325          dw1 |= GEN9_RASTER_CONSERVATIVE_RASTERIZATION_ENABLE;
326    }
327 
328    BEGIN_BATCH(5);
329    OUT_BATCH(_3DSTATE_RASTER << 16 | (5 - 2));
330    OUT_BATCH(dw1);
331    OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant.  copied from gen4 */
332    OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */
333    OUT_BATCH_F(ctx->Polygon.OffsetClamp); /* global depth offset clamp */
334    ADVANCE_BATCH();
335 }
336 
337 const struct brw_tracked_state gen8_raster_state = {
338    .dirty = {
339       .mesa  = _NEW_BUFFERS |
340                _NEW_LINE |
341                _NEW_MULTISAMPLE |
342                _NEW_POINT |
343                _NEW_POLYGON |
344                _NEW_SCISSOR |
345                _NEW_TRANSFORM,
346       .brw   = BRW_NEW_BLORP |
347                BRW_NEW_CONTEXT |
348                BRW_NEW_CONSERVATIVE_RASTERIZATION,
349    },
350    .emit = upload_raster,
351 };
352