2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2014 LunarG, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "core/ilo_builder_3d.h"
30 #include "ilo_common.h"
31 #include "ilo_blitter.h"
32 #include "ilo_state.h"
33 #include "ilo_render_gen.h"
35 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
38 gen6_emit_draw_surface_rt(struct ilo_render
*r
,
39 const struct ilo_state_vector
*vec
,
40 struct ilo_render_draw_session
*session
)
42 const struct ilo_shader_state
*fs
= vec
->fs
;
43 const struct ilo_fb_state
*fb
= &vec
->fb
;
44 uint32_t *surface_state
;
47 ILO_DEV_ASSERT(r
->dev
, 6, 8);
49 if (!DIRTY(FS
) && !DIRTY(FB
))
54 session
->binding_table_fs_changed
= true;
56 base
= ilo_shader_get_kernel_param(fs
, ILO_KERNEL_FS_SURFACE_RT_BASE
);
57 count
= ilo_shader_get_kernel_param(fs
, ILO_KERNEL_FS_SURFACE_RT_COUNT
);
59 /* SURFACE_STATEs for render targets */
60 surface_state
= &r
->state
.wm
.SURFACE_STATE
[base
];
61 for (i
= 0; i
< count
; i
++) {
62 if (i
< fb
->state
.nr_cbufs
&& fb
->state
.cbufs
[i
]) {
63 const struct ilo_surface_cso
*surface
=
64 (const struct ilo_surface_cso
*) fb
->state
.cbufs
[i
];
66 assert(surface
->is_rt
);
68 gen6_SURFACE_STATE(r
->builder
, &surface
->u
.rt
, true);
71 gen6_SURFACE_STATE(r
->builder
, &fb
->null_rt
, true);
77 gen6_emit_draw_surface_so(struct ilo_render
*r
,
78 const struct ilo_state_vector
*vec
,
79 struct ilo_render_draw_session
*session
)
81 const struct ilo_shader_state
*vs
= vec
->vs
;
82 const struct ilo_shader_state
*gs
= vec
->gs
;
83 const struct ilo_so_state
*so
= &vec
->so
;
84 const struct pipe_stream_output_info
*so_info
;
85 uint32_t *surface_state
;
88 ILO_DEV_ASSERT(r
->dev
, 6, 6);
90 if (!DIRTY(VS
) && !DIRTY(GS
) && !DIRTY(SO
))
94 so_info
= ilo_shader_get_kernel_so_info(gs
);
95 base
= ilo_shader_get_kernel_param(gs
,
96 ILO_KERNEL_GS_GEN6_SURFACE_SO_BASE
);
97 count
= ilo_shader_get_kernel_param(gs
,
98 ILO_KERNEL_GS_GEN6_SURFACE_SO_COUNT
);
100 so_info
= ilo_shader_get_kernel_so_info(vs
);
102 count
= ilo_shader_get_kernel_param(vs
,
103 ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT
);
108 session
->binding_table_gs_changed
= true;
110 /* SURFACE_STATEs for stream output targets */
111 surface_state
= &r
->state
.gs
.SURFACE_STATE
[base
];
112 for (i
= 0; i
< count
; i
++) {
113 if (so_info
&& i
< so_info
->num_outputs
&&
114 so_info
->output
[i
].output_buffer
< so
->count
&&
115 so
->states
[so_info
->output
[i
].output_buffer
]) {
116 const struct pipe_stream_output_target
*so_target
=
117 so
->states
[so_info
->output
[i
].output_buffer
];
119 surface_state
[i
] = gen6_so_SURFACE_STATE(r
->builder
,
120 so_target
, so_info
, i
);
122 surface_state
[i
] = 0;
128 gen6_emit_draw_surface_view(struct ilo_render
*r
,
129 const struct ilo_state_vector
*vec
,
131 struct ilo_render_draw_session
*session
)
133 const struct ilo_view_state
*view
= &vec
->view
[shader_type
];
134 const struct ilo_shader_state
*sh
;
135 uint32_t *surface_state
;
138 ILO_DEV_ASSERT(r
->dev
, 6, 8);
140 switch (shader_type
) {
141 case PIPE_SHADER_VERTEX
:
142 if (!DIRTY(VS
) && !DIRTY(VIEW_VS
))
148 surface_state
= r
->state
.vs
.SURFACE_STATE
;
149 session
->binding_table_vs_changed
= true;
151 case PIPE_SHADER_FRAGMENT
:
152 if (!DIRTY(FS
) && !DIRTY(VIEW_FS
))
158 surface_state
= r
->state
.wm
.SURFACE_STATE
;
159 session
->binding_table_fs_changed
= true;
166 base
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_TEX_BASE
);
167 count
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_TEX_COUNT
);
169 /* SURFACE_STATEs for sampler views */
170 surface_state
+= base
;
171 for (i
= 0; i
< count
; i
++) {
172 if (i
< view
->count
&& view
->states
[i
]) {
173 const struct ilo_view_cso
*cso
=
174 (const struct ilo_view_cso
*) view
->states
[i
];
177 gen6_SURFACE_STATE(r
->builder
, &cso
->surface
, false);
179 surface_state
[i
] = 0;
185 gen6_emit_draw_surface_const(struct ilo_render
*r
,
186 const struct ilo_state_vector
*vec
,
188 struct ilo_render_draw_session
*session
)
190 const struct ilo_cbuf_state
*cbuf
= &vec
->cbuf
[shader_type
];
191 const struct ilo_shader_state
*sh
;
192 uint32_t *surface_state
;
195 ILO_DEV_ASSERT(r
->dev
, 6, 8);
197 switch (shader_type
) {
198 case PIPE_SHADER_VERTEX
:
199 if (!DIRTY(VS
) && !DIRTY(CBUF
))
205 surface_state
= r
->state
.vs
.SURFACE_STATE
;
206 session
->binding_table_vs_changed
= true;
208 case PIPE_SHADER_FRAGMENT
:
209 if (!DIRTY(FS
) && !DIRTY(CBUF
))
215 surface_state
= r
->state
.wm
.SURFACE_STATE
;
216 session
->binding_table_fs_changed
= true;
223 base
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_CONST_BASE
);
224 count
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_CONST_COUNT
);
226 /* SURFACE_STATEs for constant buffers */
227 surface_state
+= base
;
228 for (i
= 0; i
< count
; i
++) {
229 const struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[i
];
232 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
,
233 &cso
->surface
, false);
235 surface_state
[i
] = 0;
241 gen6_emit_draw_surface_binding_tables(struct ilo_render
*r
,
242 const struct ilo_state_vector
*vec
,
244 struct ilo_render_draw_session
*session
)
248 ILO_DEV_ASSERT(r
->dev
, 6, 8);
250 /* BINDING_TABLE_STATE */
251 switch (shader_type
) {
252 case PIPE_SHADER_VERTEX
:
253 if (!session
->binding_table_vs_changed
)
258 count
= ilo_shader_get_kernel_param(vec
->vs
,
259 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
261 r
->state
.vs
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
262 r
->state
.vs
.SURFACE_STATE
, count
);
264 case PIPE_SHADER_GEOMETRY
:
265 if (!session
->binding_table_gs_changed
)
268 count
= ilo_shader_get_kernel_param(vec
->gs
,
269 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
270 } else if (ilo_dev_gen(r
->dev
) == ILO_GEN(6) && vec
->vs
) {
271 count
= ilo_shader_get_kernel_param(vec
->vs
,
272 ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT
);
277 r
->state
.gs
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
278 r
->state
.gs
.SURFACE_STATE
, count
);
280 case PIPE_SHADER_FRAGMENT
:
281 if (!session
->binding_table_fs_changed
)
286 count
= ilo_shader_get_kernel_param(vec
->fs
,
287 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
289 r
->state
.wm
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
290 r
->state
.wm
.SURFACE_STATE
, count
);
300 ilo_render_get_draw_surface_states_len(const struct ilo_render
*render
,
301 const struct ilo_state_vector
*vec
)
305 ILO_DEV_ASSERT(render
->dev
, 6, 8);
309 for (sh_type
= 0; sh_type
< PIPE_SHADER_TYPES
; sh_type
++) {
310 const int alignment
=
311 (ilo_dev_gen(render
->dev
) >= ILO_GEN(8) ? 64 : 32) / 4;
312 int num_surfaces
= 0;
315 case PIPE_SHADER_VERTEX
:
317 num_surfaces
= ilo_shader_get_kernel_param(vec
->vs
,
318 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
320 if (ilo_dev_gen(render
->dev
) == ILO_GEN(6)) {
321 num_surfaces
+= ilo_shader_get_kernel_param(vec
->vs
,
322 ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT
);
326 case PIPE_SHADER_GEOMETRY
:
328 num_surfaces
= ilo_shader_get_kernel_param(vec
->gs
,
329 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
332 case PIPE_SHADER_FRAGMENT
:
334 num_surfaces
= ilo_shader_get_kernel_param(vec
->fs
,
335 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
342 /* BINDING_TABLE_STATE and SURFACE_STATEs */
344 len
+= align(num_surfaces
, alignment
) +
345 align(GEN6_SURFACE_STATE__SIZE
, alignment
) * num_surfaces
;
353 ilo_render_emit_draw_surface_states(struct ilo_render
*render
,
354 const struct ilo_state_vector
*vec
,
355 struct ilo_render_draw_session
*session
)
357 const unsigned surface_used
= ilo_builder_surface_used(render
->builder
);
360 ILO_DEV_ASSERT(render
->dev
, 6, 8);
363 * upload all SURAFCE_STATEs together so that we know there are minimal
367 gen6_emit_draw_surface_rt(render
, vec
, session
);
369 if (ilo_dev_gen(render
->dev
) == ILO_GEN(6))
370 gen6_emit_draw_surface_so(render
, vec
, session
);
372 for (shader_type
= 0; shader_type
< PIPE_SHADER_TYPES
; shader_type
++) {
373 gen6_emit_draw_surface_view(render
, vec
, shader_type
, session
);
374 gen6_emit_draw_surface_const(render
, vec
, shader_type
, session
);
377 /* this must be called after all SURFACE_STATEs have been uploaded */
378 for (shader_type
= 0; shader_type
< PIPE_SHADER_TYPES
; shader_type
++) {
379 gen6_emit_draw_surface_binding_tables(render
, vec
,
380 shader_type
, session
);
383 assert(ilo_builder_surface_used(render
->builder
) <= surface_used
+
384 ilo_render_get_draw_surface_states_len(render
, vec
));
388 gen6_emit_launch_grid_surface_view(struct ilo_render
*r
,
389 const struct ilo_state_vector
*vec
,
390 struct ilo_render_launch_grid_session
*session
)
392 const struct ilo_shader_state
*cs
= vec
->cs
;
393 const struct ilo_view_state
*view
= &vec
->view
[PIPE_SHADER_COMPUTE
];
394 uint32_t *surface_state
= r
->state
.cs
.SURFACE_STATE
;
397 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
399 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_TEX_BASE
);
400 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_TEX_COUNT
);
402 /* SURFACE_STATEs for sampler views */
403 surface_state
+= base
;
404 for (i
= 0; i
< count
; i
++) {
405 if (i
< view
->count
&& view
->states
[i
]) {
406 const struct ilo_view_cso
*cso
=
407 (const struct ilo_view_cso
*) view
->states
[i
];
410 gen6_SURFACE_STATE(r
->builder
, &cso
->surface
, false);
412 surface_state
[i
] = 0;
418 gen6_emit_launch_grid_surface_const(struct ilo_render
*r
,
419 const struct ilo_state_vector
*vec
,
420 struct ilo_render_launch_grid_session
*session
)
422 const struct ilo_shader_state
*cs
= vec
->cs
;
423 uint32_t *surface_state
= r
->state
.cs
.SURFACE_STATE
;
424 struct ilo_view_surface view
;
427 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
429 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_CONST_BASE
);
430 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_CONST_COUNT
);
435 ilo_gpe_init_view_surface_for_buffer(r
->dev
,
436 ilo_buffer(session
->input
->buffer
),
437 session
->input
->buffer_offset
,
438 session
->input
->buffer_size
,
440 false, false, &view
);
442 assert(count
== 1 && session
->input
->buffer
);
443 surface_state
[base
] = gen6_SURFACE_STATE(r
->builder
, &view
, false);
447 gen6_emit_launch_grid_surface_cs_resource(struct ilo_render
*r
,
448 const struct ilo_state_vector
*vec
,
449 struct ilo_render_launch_grid_session
*session
)
451 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
454 assert(!vec
->cs_resource
.count
);
458 gen6_emit_launch_grid_surface_global(struct ilo_render
*r
,
459 const struct ilo_state_vector
*vec
,
460 struct ilo_render_launch_grid_session
*session
)
462 const struct ilo_shader_state
*cs
= vec
->cs
;
463 const struct ilo_global_binding_cso
*bindings
=
464 util_dynarray_begin(&vec
->global_binding
.bindings
);
465 uint32_t *surface_state
= r
->state
.cs
.SURFACE_STATE
;
468 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
470 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE
);
471 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT
);
476 if (base
+ count
> Elements(r
->state
.cs
.SURFACE_STATE
)) {
477 ilo_warn("too many global bindings\n");
478 count
= Elements(r
->state
.cs
.SURFACE_STATE
) - base
;
481 /* SURFACE_STATEs for global bindings */
482 surface_state
+= base
;
483 for (i
= 0; i
< count
; i
++) {
484 if (i
< vec
->global_binding
.count
&& bindings
[i
].resource
) {
485 const struct ilo_buffer
*buf
= ilo_buffer(bindings
[i
].resource
);
486 struct ilo_view_surface view
;
488 assert(bindings
[i
].resource
->target
== PIPE_BUFFER
);
490 ilo_gpe_init_view_surface_for_buffer(r
->dev
, buf
, 0, buf
->bo_size
,
491 1, PIPE_FORMAT_NONE
, true, true, &view
);
493 gen6_SURFACE_STATE(r
->builder
, &view
, true);
495 surface_state
[i
] = 0;
501 gen6_emit_launch_grid_surface_binding_table(struct ilo_render
*r
,
502 const struct ilo_state_vector
*vec
,
503 struct ilo_render_launch_grid_session
*session
)
505 const struct ilo_shader_state
*cs
= vec
->cs
;
508 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
510 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_TOTAL_COUNT
);
512 r
->state
.cs
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
513 r
->state
.cs
.SURFACE_STATE
, count
);
518 ilo_render_get_launch_grid_surface_states_len(const struct ilo_render
*render
,
519 const struct ilo_state_vector
*vec
)
521 const int alignment
= 32 / 4;
525 ILO_DEV_ASSERT(render
->dev
, 7, 7.5);
527 num_surfaces
= ilo_shader_get_kernel_param(vec
->cs
,
528 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
530 /* BINDING_TABLE_STATE and SURFACE_STATEs */
532 len
+= align(num_surfaces
, alignment
) +
533 align(GEN6_SURFACE_STATE__SIZE
, alignment
) * num_surfaces
;
540 ilo_render_emit_launch_grid_surface_states(struct ilo_render
*render
,
541 const struct ilo_state_vector
*vec
,
542 struct ilo_render_launch_grid_session
*session
)
544 const unsigned surface_used
= ilo_builder_surface_used(render
->builder
);
546 ILO_DEV_ASSERT(render
->dev
, 7, 7.5);
548 /* idrt depends on the binding table */
549 assert(!session
->idrt_size
);
551 gen6_emit_launch_grid_surface_view(render
, vec
, session
);
552 gen6_emit_launch_grid_surface_const(render
, vec
, session
);
553 gen6_emit_launch_grid_surface_cs_resource(render
, vec
, session
);
554 gen6_emit_launch_grid_surface_global(render
, vec
, session
);
555 gen6_emit_launch_grid_surface_binding_table(render
, vec
, session
);
557 assert(ilo_builder_surface_used(render
->builder
) <= surface_used
+
558 ilo_render_get_launch_grid_surface_states_len(render
, vec
));