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_resource.h"
33 #include "ilo_shader.h"
34 #include "ilo_state.h"
35 #include "ilo_render_gen.h"
37 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
39 static inline uint32_t
40 gen6_so_SURFACE_STATE(struct ilo_builder
*builder
,
41 const struct pipe_stream_output_target
*so
,
42 const struct pipe_stream_output_info
*so_info
,
45 struct ilo_state_surface_buffer_info info
;
46 struct ilo_state_surface surf
;
48 ILO_DEV_ASSERT(builder
->dev
, 6, 6);
50 memset(&info
, 0, sizeof(info
));
52 info
.vma
= ilo_resource_get_vma(so
->buffer
);
53 info
.offset
= so
->buffer_offset
+ so_info
->output
[so_index
].dst_offset
* 4;
54 info
.size
= so
->buffer_size
- so_info
->output
[so_index
].dst_offset
* 4;
56 info
.access
= ILO_STATE_SURFACE_ACCESS_DP_SVB
;
58 switch (so_info
->output
[so_index
].num_components
) {
60 info
.format
= GEN6_FORMAT_R32_FLOAT
;
64 info
.format
= GEN6_FORMAT_R32G32_FLOAT
;
68 info
.format
= GEN6_FORMAT_R32G32B32_FLOAT
;
69 info
.format_size
= 12;
72 info
.format
= GEN6_FORMAT_R32G32B32A32_FLOAT
;
73 info
.format_size
= 16;
76 assert(!"unexpected SO components length");
77 info
.format
= GEN6_FORMAT_R32_FLOAT
;
83 so_info
->stride
[so_info
->output
[so_index
].output_buffer
] * 4;
85 memset(&surf
, 0, sizeof(surf
));
86 ilo_state_surface_init_for_buffer(&surf
, builder
->dev
, &info
);
88 return gen6_SURFACE_STATE(builder
, &surf
);
92 gen6_emit_draw_surface_rt(struct ilo_render
*r
,
93 const struct ilo_state_vector
*vec
,
94 struct ilo_render_draw_session
*session
)
96 const struct ilo_shader_state
*fs
= vec
->fs
;
97 const struct ilo_fb_state
*fb
= &vec
->fb
;
98 uint32_t *surface_state
;
101 ILO_DEV_ASSERT(r
->dev
, 6, 8);
103 if (!DIRTY(FS
) && !DIRTY(FB
))
108 session
->binding_table_fs_changed
= true;
110 base
= ilo_shader_get_kernel_param(fs
, ILO_KERNEL_FS_SURFACE_RT_BASE
);
111 count
= ilo_shader_get_kernel_param(fs
, ILO_KERNEL_FS_SURFACE_RT_COUNT
);
113 /* SURFACE_STATEs for render targets */
114 surface_state
= &r
->state
.wm
.SURFACE_STATE
[base
];
115 for (i
= 0; i
< count
; i
++) {
116 if (i
< fb
->state
.nr_cbufs
&& fb
->state
.cbufs
[i
]) {
117 const struct ilo_surface_cso
*surface
=
118 (const struct ilo_surface_cso
*) fb
->state
.cbufs
[i
];
120 assert(surface
->is_rt
);
121 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
, &surface
->u
.rt
);
123 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
, &fb
->null_rt
);
129 gen6_emit_draw_surface_so(struct ilo_render
*r
,
130 const struct ilo_state_vector
*vec
,
131 struct ilo_render_draw_session
*session
)
133 const struct ilo_shader_state
*vs
= vec
->vs
;
134 const struct ilo_shader_state
*gs
= vec
->gs
;
135 const struct ilo_so_state
*so
= &vec
->so
;
136 const struct pipe_stream_output_info
*so_info
;
137 uint32_t *surface_state
;
140 ILO_DEV_ASSERT(r
->dev
, 6, 6);
142 if (!DIRTY(VS
) && !DIRTY(GS
) && !DIRTY(SO
))
146 so_info
= ilo_shader_get_kernel_so_info(gs
);
147 base
= ilo_shader_get_kernel_param(gs
,
148 ILO_KERNEL_GS_GEN6_SURFACE_SO_BASE
);
149 count
= ilo_shader_get_kernel_param(gs
,
150 ILO_KERNEL_GS_GEN6_SURFACE_SO_COUNT
);
152 so_info
= ilo_shader_get_kernel_so_info(vs
);
154 count
= ilo_shader_get_kernel_param(vs
,
155 ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT
);
160 session
->binding_table_gs_changed
= true;
162 /* SURFACE_STATEs for stream output targets */
163 surface_state
= &r
->state
.gs
.SURFACE_STATE
[base
];
164 for (i
= 0; i
< count
; i
++) {
165 if (so_info
&& i
< so_info
->num_outputs
&&
166 so_info
->output
[i
].output_buffer
< so
->count
&&
167 so
->states
[so_info
->output
[i
].output_buffer
]) {
168 const struct pipe_stream_output_target
*so_target
=
169 so
->states
[so_info
->output
[i
].output_buffer
];
171 surface_state
[i
] = gen6_so_SURFACE_STATE(r
->builder
,
172 so_target
, so_info
, i
);
174 surface_state
[i
] = 0;
180 gen6_emit_draw_surface_view(struct ilo_render
*r
,
181 const struct ilo_state_vector
*vec
,
183 struct ilo_render_draw_session
*session
)
185 const struct ilo_view_state
*view
= &vec
->view
[shader_type
];
186 const struct ilo_shader_state
*sh
;
187 uint32_t *surface_state
;
190 ILO_DEV_ASSERT(r
->dev
, 6, 8);
192 switch (shader_type
) {
193 case PIPE_SHADER_VERTEX
:
194 if (!DIRTY(VS
) && !DIRTY(VIEW_VS
))
200 surface_state
= r
->state
.vs
.SURFACE_STATE
;
201 session
->binding_table_vs_changed
= true;
203 case PIPE_SHADER_FRAGMENT
:
204 if (!DIRTY(FS
) && !DIRTY(VIEW_FS
))
210 surface_state
= r
->state
.wm
.SURFACE_STATE
;
211 session
->binding_table_fs_changed
= true;
218 base
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_TEX_BASE
);
219 count
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_TEX_COUNT
);
221 /* SURFACE_STATEs for sampler views */
222 surface_state
+= base
;
223 for (i
= 0; i
< count
; i
++) {
224 if (i
< view
->count
&& view
->states
[i
]) {
225 const struct ilo_view_cso
*cso
=
226 (const struct ilo_view_cso
*) view
->states
[i
];
228 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
, &cso
->surface
);
230 surface_state
[i
] = 0;
236 gen6_emit_draw_surface_const(struct ilo_render
*r
,
237 const struct ilo_state_vector
*vec
,
239 struct ilo_render_draw_session
*session
)
241 const struct ilo_cbuf_state
*cbuf
= &vec
->cbuf
[shader_type
];
242 const struct ilo_shader_state
*sh
;
243 uint32_t *surface_state
;
246 ILO_DEV_ASSERT(r
->dev
, 6, 8);
248 switch (shader_type
) {
249 case PIPE_SHADER_VERTEX
:
250 if (!DIRTY(VS
) && !DIRTY(CBUF
))
256 surface_state
= r
->state
.vs
.SURFACE_STATE
;
257 session
->binding_table_vs_changed
= true;
259 case PIPE_SHADER_FRAGMENT
:
260 if (!DIRTY(FS
) && !DIRTY(CBUF
))
266 surface_state
= r
->state
.wm
.SURFACE_STATE
;
267 session
->binding_table_fs_changed
= true;
274 base
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_CONST_BASE
);
275 count
= ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SURFACE_CONST_COUNT
);
277 /* SURFACE_STATEs for constant buffers */
278 surface_state
+= base
;
279 for (i
= 0; i
< count
; i
++) {
280 const struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[i
];
283 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
, &cso
->surface
);
285 surface_state
[i
] = 0;
290 gen6_emit_draw_surface_binding_tables(struct ilo_render
*r
,
291 const struct ilo_state_vector
*vec
,
293 struct ilo_render_draw_session
*session
)
297 ILO_DEV_ASSERT(r
->dev
, 6, 8);
299 /* BINDING_TABLE_STATE */
300 switch (shader_type
) {
301 case PIPE_SHADER_VERTEX
:
302 if (!session
->binding_table_vs_changed
)
307 count
= ilo_shader_get_kernel_param(vec
->vs
,
308 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
310 r
->state
.vs
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
311 r
->state
.vs
.SURFACE_STATE
, count
);
313 case PIPE_SHADER_GEOMETRY
:
314 if (!session
->binding_table_gs_changed
)
317 count
= ilo_shader_get_kernel_param(vec
->gs
,
318 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
319 } else if (ilo_dev_gen(r
->dev
) == ILO_GEN(6) && vec
->vs
) {
320 count
= ilo_shader_get_kernel_param(vec
->vs
,
321 ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT
);
326 r
->state
.gs
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
327 r
->state
.gs
.SURFACE_STATE
, count
);
329 case PIPE_SHADER_FRAGMENT
:
330 if (!session
->binding_table_fs_changed
)
335 count
= ilo_shader_get_kernel_param(vec
->fs
,
336 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
338 r
->state
.wm
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
339 r
->state
.wm
.SURFACE_STATE
, count
);
349 ilo_render_get_draw_surface_states_len(const struct ilo_render
*render
,
350 const struct ilo_state_vector
*vec
)
354 ILO_DEV_ASSERT(render
->dev
, 6, 8);
358 for (sh_type
= 0; sh_type
< PIPE_SHADER_TYPES
; sh_type
++) {
359 const int alignment
=
360 (ilo_dev_gen(render
->dev
) >= ILO_GEN(8) ? 64 : 32) / 4;
361 int num_surfaces
= 0;
364 case PIPE_SHADER_VERTEX
:
366 num_surfaces
= ilo_shader_get_kernel_param(vec
->vs
,
367 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
369 if (ilo_dev_gen(render
->dev
) == ILO_GEN(6)) {
370 num_surfaces
+= ilo_shader_get_kernel_param(vec
->vs
,
371 ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT
);
375 case PIPE_SHADER_GEOMETRY
:
377 num_surfaces
= ilo_shader_get_kernel_param(vec
->gs
,
378 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
381 case PIPE_SHADER_FRAGMENT
:
383 num_surfaces
= ilo_shader_get_kernel_param(vec
->fs
,
384 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
391 /* BINDING_TABLE_STATE and SURFACE_STATEs */
393 len
+= align(num_surfaces
, alignment
) +
394 align(GEN6_SURFACE_STATE__SIZE
, alignment
) * num_surfaces
;
402 ilo_render_emit_draw_surface_states(struct ilo_render
*render
,
403 const struct ilo_state_vector
*vec
,
404 struct ilo_render_draw_session
*session
)
406 const unsigned surface_used
= ilo_builder_surface_used(render
->builder
);
409 ILO_DEV_ASSERT(render
->dev
, 6, 8);
412 * upload all SURAFCE_STATEs together so that we know there are minimal
416 gen6_emit_draw_surface_rt(render
, vec
, session
);
418 if (ilo_dev_gen(render
->dev
) == ILO_GEN(6))
419 gen6_emit_draw_surface_so(render
, vec
, session
);
421 for (shader_type
= 0; shader_type
< PIPE_SHADER_TYPES
; shader_type
++) {
422 gen6_emit_draw_surface_view(render
, vec
, shader_type
, session
);
423 gen6_emit_draw_surface_const(render
, vec
, shader_type
, session
);
426 /* this must be called after all SURFACE_STATEs have been uploaded */
427 for (shader_type
= 0; shader_type
< PIPE_SHADER_TYPES
; shader_type
++) {
428 gen6_emit_draw_surface_binding_tables(render
, vec
,
429 shader_type
, session
);
432 assert(ilo_builder_surface_used(render
->builder
) <= surface_used
+
433 ilo_render_get_draw_surface_states_len(render
, vec
));
437 gen6_emit_launch_grid_surface_view(struct ilo_render
*r
,
438 const struct ilo_state_vector
*vec
,
439 struct ilo_render_launch_grid_session
*session
)
441 const struct ilo_shader_state
*cs
= vec
->cs
;
442 const struct ilo_view_state
*view
= &vec
->view
[PIPE_SHADER_COMPUTE
];
443 uint32_t *surface_state
= r
->state
.cs
.SURFACE_STATE
;
446 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
448 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_TEX_BASE
);
449 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_TEX_COUNT
);
451 /* SURFACE_STATEs for sampler views */
452 surface_state
+= base
;
453 for (i
= 0; i
< count
; i
++) {
454 if (i
< view
->count
&& view
->states
[i
]) {
455 const struct ilo_view_cso
*cso
=
456 (const struct ilo_view_cso
*) view
->states
[i
];
458 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
, &cso
->surface
);
460 surface_state
[i
] = 0;
466 gen6_emit_launch_grid_surface_const(struct ilo_render
*r
,
467 const struct ilo_state_vector
*vec
,
468 struct ilo_render_launch_grid_session
*session
)
470 const struct ilo_shader_state
*cs
= vec
->cs
;
471 uint32_t *surface_state
= r
->state
.cs
.SURFACE_STATE
;
472 struct ilo_state_surface_buffer_info info
;
473 struct ilo_state_surface surf
;
476 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
478 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_CONST_BASE
);
479 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_CONST_COUNT
);
484 memset(&info
, 0, sizeof(info
));
486 info
.vma
= ilo_resource_get_vma(session
->input
->buffer
);
487 info
.offset
= session
->input
->buffer_offset
;
488 info
.size
= session
->input
->buffer_size
;
490 info
.access
= ILO_STATE_SURFACE_ACCESS_DP_UNTYPED
;
491 info
.format
= GEN6_FORMAT_RAW
;
492 info
.format_size
= 1;
493 info
.struct_size
= 1;
494 info
.readonly
= true;
496 memset(&surf
, 0, sizeof(surf
));
497 ilo_state_surface_init_for_buffer(&surf
, r
->dev
, &info
);
499 assert(count
== 1 && session
->input
->buffer
);
500 surface_state
[base
] = gen6_SURFACE_STATE(r
->builder
, &surf
);
504 gen6_emit_launch_grid_surface_cs_resource(struct ilo_render
*r
,
505 const struct ilo_state_vector
*vec
,
506 struct ilo_render_launch_grid_session
*session
)
508 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
511 assert(!vec
->cs_resource
.count
);
515 gen6_emit_launch_grid_surface_global(struct ilo_render
*r
,
516 const struct ilo_state_vector
*vec
,
517 struct ilo_render_launch_grid_session
*session
)
519 const struct ilo_shader_state
*cs
= vec
->cs
;
520 const struct ilo_global_binding_cso
*bindings
=
521 util_dynarray_begin(&vec
->global_binding
.bindings
);
522 uint32_t *surface_state
= r
->state
.cs
.SURFACE_STATE
;
525 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
527 base
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE
);
528 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT
);
533 if (base
+ count
> Elements(r
->state
.cs
.SURFACE_STATE
)) {
534 ilo_warn("too many global bindings\n");
535 count
= Elements(r
->state
.cs
.SURFACE_STATE
) - base
;
538 /* SURFACE_STATEs for global bindings */
539 surface_state
+= base
;
540 for (i
= 0; i
< count
; i
++) {
541 if (i
< vec
->global_binding
.count
&& bindings
[i
].resource
) {
542 struct ilo_state_surface_buffer_info info
;
543 struct ilo_state_surface surf
;
545 assert(bindings
[i
].resource
->target
== PIPE_BUFFER
);
547 memset(&info
, 0, sizeof(info
));
549 info
.vma
= ilo_resource_get_vma(bindings
[i
].resource
);
550 info
.size
= info
.vma
->vm_size
;
552 info
.access
= ILO_STATE_SURFACE_ACCESS_DP_UNTYPED
;
553 info
.format
= GEN6_FORMAT_RAW
;
554 info
.format_size
= 1;
555 info
.struct_size
= 1;
557 memset(&surf
, 0, sizeof(surf
));
558 ilo_state_surface_init_for_buffer(&surf
, r
->dev
, &info
);
560 surface_state
[i
] = gen6_SURFACE_STATE(r
->builder
, &surf
);
562 surface_state
[i
] = 0;
568 gen6_emit_launch_grid_surface_binding_table(struct ilo_render
*r
,
569 const struct ilo_state_vector
*vec
,
570 struct ilo_render_launch_grid_session
*session
)
572 const struct ilo_shader_state
*cs
= vec
->cs
;
575 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
577 count
= ilo_shader_get_kernel_param(cs
, ILO_KERNEL_SURFACE_TOTAL_COUNT
);
579 r
->state
.cs
.BINDING_TABLE_STATE
= gen6_BINDING_TABLE_STATE(r
->builder
,
580 r
->state
.cs
.SURFACE_STATE
, count
);
585 ilo_render_get_launch_grid_surface_states_len(const struct ilo_render
*render
,
586 const struct ilo_state_vector
*vec
)
588 const int alignment
= 32 / 4;
592 ILO_DEV_ASSERT(render
->dev
, 7, 7.5);
594 num_surfaces
= ilo_shader_get_kernel_param(vec
->cs
,
595 ILO_KERNEL_SURFACE_TOTAL_COUNT
);
597 /* BINDING_TABLE_STATE and SURFACE_STATEs */
599 len
+= align(num_surfaces
, alignment
) +
600 align(GEN6_SURFACE_STATE__SIZE
, alignment
) * num_surfaces
;
607 ilo_render_emit_launch_grid_surface_states(struct ilo_render
*render
,
608 const struct ilo_state_vector
*vec
,
609 struct ilo_render_launch_grid_session
*session
)
611 const unsigned surface_used
= ilo_builder_surface_used(render
->builder
);
613 ILO_DEV_ASSERT(render
->dev
, 7, 7.5);
615 /* idrt depends on the binding table */
616 assert(!session
->idrt_size
);
618 gen6_emit_launch_grid_surface_view(render
, vec
, session
);
619 gen6_emit_launch_grid_surface_const(render
, vec
, session
);
620 gen6_emit_launch_grid_surface_cs_resource(render
, vec
, session
);
621 gen6_emit_launch_grid_surface_global(render
, vec
, session
);
622 gen6_emit_launch_grid_surface_binding_table(render
, vec
, session
);
624 assert(ilo_builder_surface_used(render
->builder
) <= surface_used
+
625 ilo_render_get_launch_grid_surface_states_len(render
, vec
));