• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2013 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 "genhw/genhw.h"
29 #include "core/ilo_builder_3d.h"
30 #include "core/ilo_builder_render.h"
31 
32 #include "ilo_blitter.h"
33 #include "ilo_resource.h"
34 #include "ilo_shader.h"
35 #include "ilo_state.h"
36 #include "ilo_render_gen.h"
37 
38 static void
gen8_wa_pre_depth(struct ilo_render * r)39 gen8_wa_pre_depth(struct ilo_render *r)
40 {
41    ILO_DEV_ASSERT(r->dev, 8, 8);
42 
43    /*
44     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
45     *
46     *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
47     *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
48     *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
49     *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
50     *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
51     *      Depth Flush Bit set, followed by another pipelined depth stall
52     *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
53     *      guarantee that the pipeline from WM onwards is already flushed
54     *      (e.g., via a preceding MI_FLUSH)."
55     */
56    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
57    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
58    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
59 }
60 
61 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
62 
63 static void
gen8_draw_sf(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)64 gen8_draw_sf(struct ilo_render *r,
65              const struct ilo_state_vector *vec,
66              struct ilo_render_draw_session *session)
67 {
68    /* 3DSTATE_RASTER */
69    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_RASTER)
70       gen8_3DSTATE_RASTER(r->builder, &vec->rasterizer->rs);
71 
72    /* 3DSTATE_SBE and 3DSTATE_SBE_SWIZ */
73    if (DIRTY(FS)) {
74       const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
75 
76       gen8_3DSTATE_SBE(r->builder, sbe);
77       gen8_3DSTATE_SBE_SWIZ(r->builder, sbe);
78    }
79 
80    /* 3DSTATE_SF */
81    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF)
82       gen7_3DSTATE_SF(r->builder, &vec->rasterizer->rs);
83 }
84 
85 static void
gen8_draw_wm(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)86 gen8_draw_wm(struct ilo_render *r,
87              const struct ilo_state_vector *vec,
88              struct ilo_render_draw_session *session)
89 {
90    const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
91    const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
92 
93    /* 3DSTATE_WM */
94    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM)
95       gen8_3DSTATE_WM(r->builder, &vec->rasterizer->rs);
96 
97    if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL)
98       gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, &vec->blend->cc);
99 
100    /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */
101    if (r->hw_ctx_changed) {
102       gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
103       gen8_3DSTATE_WM_CHROMAKEY(r->builder);
104    }
105 
106    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
107    if (session->binding_table_fs_changed) {
108       gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(r->builder,
109             r->state.wm.BINDING_TABLE_STATE);
110    }
111 
112    /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
113    if (session->sampler_fs_changed) {
114       gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(r->builder,
115             r->state.wm.SAMPLER_STATE);
116    }
117 
118    /* 3DSTATE_CONSTANT_PS */
119    if (session->pcb_fs_changed) {
120       gen7_3DSTATE_CONSTANT_PS(r->builder,
121             &r->state.wm.PUSH_CONSTANT_BUFFER,
122             &r->state.wm.PUSH_CONSTANT_BUFFER_size,
123             1);
124    }
125 
126    /* 3DSTATE_PS */
127    if (DIRTY(FS) || r->instruction_bo_changed)
128       gen8_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, r->fs_scratch.bo);
129 
130    /* 3DSTATE_PS_EXTRA */
131    if (DIRTY(FS))
132       gen8_3DSTATE_PS_EXTRA(r->builder, &cso->ps);
133 
134    /* 3DSTATE_PS_BLEND */
135    if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_PS_BLEND)
136       gen8_3DSTATE_PS_BLEND(r->builder, &vec->blend->cc);
137 
138    /* 3DSTATE_SCISSOR_STATE_POINTERS */
139    if (session->scissor_changed) {
140       gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
141             r->state.SCISSOR_RECT);
142    }
143 
144    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
145    if (DIRTY(FB) || r->batch_bo_changed) {
146       const struct ilo_state_zs *zs;
147       uint32_t clear_params;
148 
149       if (vec->fb.state.zsbuf) {
150          const struct ilo_surface_cso *surface =
151             (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
152          const struct ilo_texture_slice *slice =
153             ilo_texture_get_slice(ilo_texture(surface->base.texture),
154                   surface->base.u.tex.level, surface->base.u.tex.first_layer);
155 
156          assert(!surface->is_rt);
157          zs = &surface->u.zs;
158          clear_params = slice->clear_value;
159       }
160       else {
161          zs = &vec->fb.null_zs;
162          clear_params = 0;
163       }
164 
165       gen8_wa_pre_depth(r);
166 
167       gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
168       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
169       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
170       gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
171    }
172 }
173 
174 static void
gen8_draw_wm_sample_pattern(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)175 gen8_draw_wm_sample_pattern(struct ilo_render *r,
176                             const struct ilo_state_vector *vec,
177                             struct ilo_render_draw_session *session)
178 {
179    /* 3DSTATE_SAMPLE_PATTERN */
180    if (r->hw_ctx_changed)
181       gen8_3DSTATE_SAMPLE_PATTERN(r->builder, &r->sample_pattern);
182 }
183 
184 static void
gen8_draw_wm_multisample(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)185 gen8_draw_wm_multisample(struct ilo_render *r,
186                          const struct ilo_state_vector *vec,
187                          struct ilo_render_draw_session *session)
188 {
189    /* 3DSTATE_MULTISAMPLE */
190    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)
191       gen8_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs);
192 
193    /* 3DSTATE_SAMPLE_MASK */
194    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
195       gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
196 }
197 
198 static void
gen8_draw_vf(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)199 gen8_draw_vf(struct ilo_render *r,
200              const struct ilo_state_vector *vec,
201              struct ilo_render_draw_session *session)
202 {
203    /* 3DSTATE_INDEX_BUFFER */
204    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
205        DIRTY(IB) || r->batch_bo_changed)
206       gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
207 
208    /* 3DSTATE_VF */
209    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF)
210       gen75_3DSTATE_VF(r->builder, &vec->ve->vf);
211 
212    /* 3DSTATE_VERTEX_BUFFERS */
213    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
214        DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
215       gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
216             vec->vb.vb, vec->ve->vb_count);
217    }
218 
219    /* 3DSTATE_VERTEX_ELEMENTS */
220    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS)
221       gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf);
222 
223    gen8_3DSTATE_VF_TOPOLOGY(r->builder, vec->draw_info.topology);
224 
225    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_INSTANCING) {
226       const uint8_t attr_count = ilo_state_vf_get_attr_count(&vec->ve->vf);
227       uint8_t i;
228 
229       for (i = 0; i < attr_count; i++)
230          gen8_3DSTATE_VF_INSTANCING(r->builder, &vec->ve->vf, i);
231    }
232 
233    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_SGVS)
234       gen8_3DSTATE_VF_SGVS(r->builder, &vec->ve->vf);
235 }
236 
237 void
ilo_render_emit_draw_commands_gen8(struct ilo_render * render,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)238 ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
239                                    const struct ilo_state_vector *vec,
240                                    struct ilo_render_draw_session *session)
241 {
242    ILO_DEV_ASSERT(render->dev, 8, 8);
243 
244    /*
245     * We try to keep the order of the commands match, as closely as possible,
246     * that of the classic i965 driver.  It allows us to compare the command
247     * streams easily.
248     */
249    gen6_draw_common_select(render, vec, session);
250    gen6_draw_common_sip(render, vec, session);
251    gen6_draw_vf_statistics(render, vec, session);
252    gen8_draw_wm_sample_pattern(render, vec, session);
253    gen6_draw_common_base_address(render, vec, session);
254    gen7_draw_common_pointers_1(render, vec, session);
255    gen7_draw_common_pcb_alloc(render, vec, session);
256    gen7_draw_common_urb(render, vec, session);
257    gen7_draw_common_pointers_2(render, vec, session);
258    gen8_draw_wm_multisample(render, vec, session);
259    gen7_draw_gs(render, vec, session);
260    gen7_draw_hs(render, vec, session);
261    gen7_draw_te(render, vec, session);
262    gen7_draw_ds(render, vec, session);
263    gen7_draw_vs(render, vec, session);
264    gen7_draw_sol(render, vec, session);
265    gen6_draw_clip(render, vec, session);
266    gen8_draw_sf(render, vec, session);
267    gen8_draw_wm(render, vec, session);
268    gen6_draw_wm_raster(render, vec, session);
269    gen6_draw_sf_rect(render, vec, session);
270    gen8_draw_vf(render, vec, session);
271 
272    ilo_render_3dprimitive(render, &vec->draw_info);
273 }
274 
275 int
ilo_render_get_draw_commands_len_gen8(const struct ilo_render * render,const struct ilo_state_vector * vec)276 ilo_render_get_draw_commands_len_gen8(const struct ilo_render *render,
277                                       const struct ilo_state_vector *vec)
278 {
279    static int len;
280 
281    ILO_DEV_ASSERT(render->dev, 8, 8);
282 
283    if (!len) {
284       len += GEN7_3DSTATE_URB_ANY__SIZE * 4;
285       len += GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_ANY__SIZE * 5;
286       len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 5;
287       len += GEN7_3DSTATE_POINTERS_ANY__SIZE * (5 + 5 + 4);
288       len += GEN7_3DSTATE_SO_BUFFER__SIZE * 4;
289       len += GEN6_PIPE_CONTROL__SIZE * 5;
290 
291       len +=
292          GEN6_STATE_BASE_ADDRESS__SIZE +
293          GEN6_STATE_SIP__SIZE +
294          GEN6_3DSTATE_VF_STATISTICS__SIZE +
295          GEN6_PIPELINE_SELECT__SIZE +
296          GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
297          GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
298          GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
299          GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
300          GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
301          GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
302          GEN6_3DSTATE_INDEX_BUFFER__SIZE +
303          GEN75_3DSTATE_VF__SIZE +
304          GEN6_3DSTATE_VS__SIZE +
305          GEN6_3DSTATE_GS__SIZE +
306          GEN6_3DSTATE_CLIP__SIZE +
307          GEN6_3DSTATE_SF__SIZE +
308          GEN6_3DSTATE_WM__SIZE +
309          GEN6_3DSTATE_SAMPLE_MASK__SIZE +
310          GEN7_3DSTATE_HS__SIZE +
311          GEN7_3DSTATE_TE__SIZE +
312          GEN7_3DSTATE_DS__SIZE +
313          GEN7_3DSTATE_STREAMOUT__SIZE +
314          GEN7_3DSTATE_SBE__SIZE +
315          GEN7_3DSTATE_PS__SIZE +
316          GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
317          GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
318          GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
319          GEN6_3DSTATE_LINE_STIPPLE__SIZE +
320          GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
321          GEN6_3DSTATE_MULTISAMPLE__SIZE +
322          GEN7_3DSTATE_SO_DECL_LIST__SIZE +
323          GEN6_3DPRIMITIVE__SIZE;
324 
325       len +=
326          GEN8_3DSTATE_VF_INSTANCING__SIZE * 33 +
327          GEN8_3DSTATE_VF_SGVS__SIZE +
328          GEN8_3DSTATE_VF_TOPOLOGY__SIZE +
329          GEN8_3DSTATE_SBE_SWIZ__SIZE +
330          GEN8_3DSTATE_RASTER__SIZE +
331          GEN8_3DSTATE_WM_CHROMAKEY__SIZE +
332          GEN8_3DSTATE_WM_DEPTH_STENCIL__SIZE +
333          GEN8_3DSTATE_WM_HZ_OP__SIZE +
334          GEN8_3DSTATE_PS_EXTRA__SIZE +
335          GEN8_3DSTATE_PS_BLEND__SIZE +
336          GEN8_3DSTATE_SAMPLE_PATTERN__SIZE;
337    }
338 
339    return len;
340 }
341 
342 int
ilo_render_get_rectlist_commands_len_gen8(const struct ilo_render * render,const struct ilo_blitter * blitter)343 ilo_render_get_rectlist_commands_len_gen8(const struct ilo_render *render,
344                                           const struct ilo_blitter *blitter)
345 {
346    ILO_DEV_ASSERT(render->dev, 8, 8);
347 
348    return 96;
349 }
350 
351 void
ilo_render_emit_rectlist_commands_gen8(struct ilo_render * r,const struct ilo_blitter * blitter,const struct ilo_render_rectlist_session * session)352 ilo_render_emit_rectlist_commands_gen8(struct ilo_render *r,
353                                        const struct ilo_blitter *blitter,
354                                        const struct ilo_render_rectlist_session *session)
355 {
356    ILO_DEV_ASSERT(r->dev, 8, 8);
357 
358    gen8_wa_pre_depth(r);
359 
360    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
361                         ILO_BLITTER_USE_FB_STENCIL))
362       gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
363 
364    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
365       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
366             &blitter->fb.dst.u.zs);
367    }
368 
369    if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) {
370       gen6_3DSTATE_STENCIL_BUFFER(r->builder,
371             &blitter->fb.dst.u.zs);
372    }
373 
374    gen7_3DSTATE_CLEAR_PARAMS(r->builder,
375          blitter->depth_clear_value);
376 
377    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
378          blitter->fb.width, blitter->fb.height);
379 
380    gen8_3DSTATE_WM_HZ_OP(r->builder, &blitter->fb.rs,
381          blitter->fb.width, blitter->fb.height);
382 
383    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_WRITE_IMM);
384 
385    gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
386 }
387