2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 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 "util/u_helpers.h"
29 #include "util/u_upload_mgr.h"
31 #include "ilo_context.h"
32 #include "ilo_resource.h"
33 #include "ilo_shader.h"
34 #include "ilo_state.h"
37 finalize_shader_states(struct ilo_context
*ilo
)
41 for (type
= 0; type
< PIPE_SHADER_TYPES
; type
++) {
42 struct ilo_shader_state
*shader
;
46 case PIPE_SHADER_VERTEX
:
50 case PIPE_SHADER_GEOMETRY
:
54 case PIPE_SHADER_FRAGMENT
:
67 /* compile if the shader or the states it depends on changed */
68 if (ilo
->dirty
& state
) {
69 ilo_shader_select_kernel(shader
, ilo
, ILO_DIRTY_ALL
);
71 else if (ilo_shader_select_kernel(shader
, ilo
, ilo
->dirty
)) {
72 /* mark the state dirty if a new kernel is selected */
76 /* need to setup SBE for FS */
77 if (type
== PIPE_SHADER_FRAGMENT
&& ilo
->dirty
&
78 (state
| ILO_DIRTY_GS
| ILO_DIRTY_VS
| ILO_DIRTY_RASTERIZER
)) {
79 if (ilo_shader_select_kernel_routing(shader
,
80 (ilo
->gs
) ? ilo
->gs
: ilo
->vs
, ilo
->rasterizer
))
87 finalize_cbuf_state(struct ilo_context
*ilo
,
88 struct ilo_cbuf_state
*cbuf
,
89 const struct ilo_shader_state
*sh
)
91 uint32_t upload_mask
= cbuf
->enabled_mask
;
93 /* skip CBUF0 if the kernel does not need it */
95 ~ilo_shader_get_kernel_param(sh
, ILO_KERNEL_SKIP_CBUF0_UPLOAD
);
98 const enum pipe_format elem_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
101 i
= u_bit_scan(&upload_mask
);
102 /* no need to upload */
103 if (cbuf
->cso
[i
].resource
)
106 u_upload_data(ilo
->uploader
, 0, cbuf
->cso
[i
].user_buffer_size
,
107 cbuf
->cso
[i
].user_buffer
, &offset
, &cbuf
->cso
[i
].resource
);
109 ilo_gpe_init_view_surface_for_buffer(ilo
->dev
,
110 ilo_buffer(cbuf
->cso
[i
].resource
),
111 offset
, cbuf
->cso
[i
].user_buffer_size
,
112 util_format_get_blocksize(elem_format
), elem_format
,
113 false, false, &cbuf
->cso
[i
].surface
);
115 ilo
->dirty
|= ILO_DIRTY_CBUF
;
120 finalize_constant_buffers(struct ilo_context
*ilo
)
122 if (ilo
->dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_VS
))
123 finalize_cbuf_state(ilo
, &ilo
->cbuf
[PIPE_SHADER_VERTEX
], ilo
->vs
);
125 if (ilo
->dirty
& (ILO_DIRTY_CBUF
| ILO_DIRTY_FS
))
126 finalize_cbuf_state(ilo
, &ilo
->cbuf
[PIPE_SHADER_FRAGMENT
], ilo
->fs
);
130 finalize_index_buffer(struct ilo_context
*ilo
)
132 const bool need_upload
= (ilo
->draw
->indexed
&&
133 (ilo
->ib
.user_buffer
|| ilo
->ib
.offset
% ilo
->ib
.index_size
));
134 struct pipe_resource
*current_hw_res
= NULL
;
136 if (!(ilo
->dirty
& ILO_DIRTY_IB
) && !need_upload
)
139 pipe_resource_reference(¤t_hw_res
, ilo
->ib
.hw_resource
);
142 const unsigned offset
= ilo
->ib
.index_size
* ilo
->draw
->start
;
143 const unsigned size
= ilo
->ib
.index_size
* ilo
->draw
->count
;
146 if (ilo
->ib
.user_buffer
) {
147 u_upload_data(ilo
->uploader
, 0, size
,
148 ilo
->ib
.user_buffer
+ offset
, &hw_offset
, &ilo
->ib
.hw_resource
);
151 u_upload_buffer(ilo
->uploader
, 0, ilo
->ib
.offset
+ offset
, size
,
152 ilo
->ib
.buffer
, &hw_offset
, &ilo
->ib
.hw_resource
);
155 /* the HW offset should be aligned */
156 assert(hw_offset
% ilo
->ib
.index_size
== 0);
157 ilo
->ib
.draw_start_offset
= hw_offset
/ ilo
->ib
.index_size
;
160 * INDEX[ilo->draw->start] in the original buffer is INDEX[0] in the HW
163 ilo
->ib
.draw_start_offset
-= ilo
->draw
->start
;
166 pipe_resource_reference(&ilo
->ib
.hw_resource
, ilo
->ib
.buffer
);
168 /* note that index size may be zero when the draw is not indexed */
169 if (ilo
->draw
->indexed
)
170 ilo
->ib
.draw_start_offset
= ilo
->ib
.offset
/ ilo
->ib
.index_size
;
172 ilo
->ib
.draw_start_offset
= 0;
175 /* treat the IB as clean if the HW states do not change */
176 if (ilo
->ib
.hw_resource
== current_hw_res
&&
177 ilo
->ib
.hw_index_size
== ilo
->ib
.index_size
)
178 ilo
->dirty
&= ~ILO_DIRTY_IB
;
180 ilo
->ib
.hw_index_size
= ilo
->ib
.index_size
;
182 pipe_resource_reference(¤t_hw_res
, NULL
);
186 * Finalize states. Some states depend on other states and are
187 * incomplete/invalid until finalized.
190 ilo_finalize_3d_states(struct ilo_context
*ilo
,
191 const struct pipe_draw_info
*draw
)
195 finalize_shader_states(ilo
);
196 finalize_constant_buffers(ilo
);
197 finalize_index_buffer(ilo
);
199 u_upload_unmap(ilo
->uploader
);
203 ilo_create_blend_state(struct pipe_context
*pipe
,
204 const struct pipe_blend_state
*state
)
206 struct ilo_context
*ilo
= ilo_context(pipe
);
207 struct ilo_blend_state
*blend
;
209 blend
= MALLOC_STRUCT(ilo_blend_state
);
212 ilo_gpe_init_blend(ilo
->dev
, state
, blend
);
218 ilo_bind_blend_state(struct pipe_context
*pipe
, void *state
)
220 struct ilo_context
*ilo
= ilo_context(pipe
);
224 ilo
->dirty
|= ILO_DIRTY_BLEND
;
228 ilo_delete_blend_state(struct pipe_context
*pipe
, void *state
)
234 ilo_create_sampler_state(struct pipe_context
*pipe
,
235 const struct pipe_sampler_state
*state
)
237 struct ilo_context
*ilo
= ilo_context(pipe
);
238 struct ilo_sampler_cso
*sampler
;
240 sampler
= MALLOC_STRUCT(ilo_sampler_cso
);
243 ilo_gpe_init_sampler_cso(ilo
->dev
, state
, sampler
);
249 ilo_bind_sampler_states(struct pipe_context
*pipe
, unsigned shader
,
250 unsigned start
, unsigned count
, void **samplers
)
252 struct ilo_context
*ilo
= ilo_context(pipe
);
253 struct ilo_sampler_state
*dst
= &ilo
->sampler
[shader
];
254 bool changed
= false;
257 assert(start
+ count
<= Elements(dst
->cso
));
260 for (i
= 0; i
< count
; i
++) {
261 if (dst
->cso
[start
+ i
] != samplers
[i
]) {
262 dst
->cso
[start
+ i
] = samplers
[i
];
265 * This function is sometimes called to reduce the number of bound
266 * samplers. Do not consider that as a state change (and create a
267 * new array of SAMPLER_STATE).
275 for (i
= 0; i
< count
; i
++)
276 dst
->cso
[start
+ i
] = NULL
;
279 if (dst
->count
<= start
+ count
) {
285 while (count
> 0 && !dst
->cso
[count
- 1])
293 case PIPE_SHADER_VERTEX
:
294 ilo
->dirty
|= ILO_DIRTY_SAMPLER_VS
;
296 case PIPE_SHADER_GEOMETRY
:
297 ilo
->dirty
|= ILO_DIRTY_SAMPLER_GS
;
299 case PIPE_SHADER_FRAGMENT
:
300 ilo
->dirty
|= ILO_DIRTY_SAMPLER_FS
;
302 case PIPE_SHADER_COMPUTE
:
303 ilo
->dirty
|= ILO_DIRTY_SAMPLER_CS
;
310 ilo_delete_sampler_state(struct pipe_context
*pipe
, void *state
)
316 ilo_create_rasterizer_state(struct pipe_context
*pipe
,
317 const struct pipe_rasterizer_state
*state
)
319 struct ilo_context
*ilo
= ilo_context(pipe
);
320 struct ilo_rasterizer_state
*rast
;
322 rast
= MALLOC_STRUCT(ilo_rasterizer_state
);
325 rast
->state
= *state
;
326 ilo_gpe_init_rasterizer(ilo
->dev
, state
, rast
);
332 ilo_bind_rasterizer_state(struct pipe_context
*pipe
, void *state
)
334 struct ilo_context
*ilo
= ilo_context(pipe
);
336 ilo
->rasterizer
= state
;
338 ilo
->dirty
|= ILO_DIRTY_RASTERIZER
;
342 ilo_delete_rasterizer_state(struct pipe_context
*pipe
, void *state
)
348 ilo_create_depth_stencil_alpha_state(struct pipe_context
*pipe
,
349 const struct pipe_depth_stencil_alpha_state
*state
)
351 struct ilo_context
*ilo
= ilo_context(pipe
);
352 struct ilo_dsa_state
*dsa
;
354 dsa
= MALLOC_STRUCT(ilo_dsa_state
);
357 ilo_gpe_init_dsa(ilo
->dev
, state
, dsa
);
363 ilo_bind_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
365 struct ilo_context
*ilo
= ilo_context(pipe
);
369 ilo
->dirty
|= ILO_DIRTY_DSA
;
373 ilo_delete_depth_stencil_alpha_state(struct pipe_context
*pipe
, void *state
)
379 ilo_create_fs_state(struct pipe_context
*pipe
,
380 const struct pipe_shader_state
*state
)
382 struct ilo_context
*ilo
= ilo_context(pipe
);
383 struct ilo_shader_state
*shader
;
385 shader
= ilo_shader_create_fs(ilo
->dev
, state
, ilo
);
388 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
394 ilo_bind_fs_state(struct pipe_context
*pipe
, void *state
)
396 struct ilo_context
*ilo
= ilo_context(pipe
);
400 ilo
->dirty
|= ILO_DIRTY_FS
;
404 ilo_delete_fs_state(struct pipe_context
*pipe
, void *state
)
406 struct ilo_context
*ilo
= ilo_context(pipe
);
407 struct ilo_shader_state
*fs
= (struct ilo_shader_state
*) state
;
409 ilo_shader_cache_remove(ilo
->shader_cache
, fs
);
410 ilo_shader_destroy(fs
);
414 ilo_create_vs_state(struct pipe_context
*pipe
,
415 const struct pipe_shader_state
*state
)
417 struct ilo_context
*ilo
= ilo_context(pipe
);
418 struct ilo_shader_state
*shader
;
420 shader
= ilo_shader_create_vs(ilo
->dev
, state
, ilo
);
423 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
429 ilo_bind_vs_state(struct pipe_context
*pipe
, void *state
)
431 struct ilo_context
*ilo
= ilo_context(pipe
);
435 ilo
->dirty
|= ILO_DIRTY_VS
;
439 ilo_delete_vs_state(struct pipe_context
*pipe
, void *state
)
441 struct ilo_context
*ilo
= ilo_context(pipe
);
442 struct ilo_shader_state
*vs
= (struct ilo_shader_state
*) state
;
444 ilo_shader_cache_remove(ilo
->shader_cache
, vs
);
445 ilo_shader_destroy(vs
);
449 ilo_create_gs_state(struct pipe_context
*pipe
,
450 const struct pipe_shader_state
*state
)
452 struct ilo_context
*ilo
= ilo_context(pipe
);
453 struct ilo_shader_state
*shader
;
455 shader
= ilo_shader_create_gs(ilo
->dev
, state
, ilo
);
458 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
464 ilo_bind_gs_state(struct pipe_context
*pipe
, void *state
)
466 struct ilo_context
*ilo
= ilo_context(pipe
);
468 /* util_blitter may set this unnecessarily */
469 if (ilo
->gs
== state
)
474 ilo
->dirty
|= ILO_DIRTY_GS
;
478 ilo_delete_gs_state(struct pipe_context
*pipe
, void *state
)
480 struct ilo_context
*ilo
= ilo_context(pipe
);
481 struct ilo_shader_state
*gs
= (struct ilo_shader_state
*) state
;
483 ilo_shader_cache_remove(ilo
->shader_cache
, gs
);
484 ilo_shader_destroy(gs
);
488 ilo_create_vertex_elements_state(struct pipe_context
*pipe
,
489 unsigned num_elements
,
490 const struct pipe_vertex_element
*elements
)
492 struct ilo_context
*ilo
= ilo_context(pipe
);
493 struct ilo_ve_state
*ve
;
495 ve
= MALLOC_STRUCT(ilo_ve_state
);
498 ilo_gpe_init_ve(ilo
->dev
, num_elements
, elements
, ve
);
504 ilo_bind_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
506 struct ilo_context
*ilo
= ilo_context(pipe
);
510 ilo
->dirty
|= ILO_DIRTY_VE
;
514 ilo_delete_vertex_elements_state(struct pipe_context
*pipe
, void *state
)
516 struct ilo_ve_state
*ve
= state
;
522 ilo_set_blend_color(struct pipe_context
*pipe
,
523 const struct pipe_blend_color
*state
)
525 struct ilo_context
*ilo
= ilo_context(pipe
);
527 ilo
->blend_color
= *state
;
529 ilo
->dirty
|= ILO_DIRTY_BLEND_COLOR
;
533 ilo_set_stencil_ref(struct pipe_context
*pipe
,
534 const struct pipe_stencil_ref
*state
)
536 struct ilo_context
*ilo
= ilo_context(pipe
);
538 /* util_blitter may set this unnecessarily */
539 if (!memcmp(&ilo
->stencil_ref
, state
, sizeof(*state
)))
542 ilo
->stencil_ref
= *state
;
544 ilo
->dirty
|= ILO_DIRTY_STENCIL_REF
;
548 ilo_set_sample_mask(struct pipe_context
*pipe
,
549 unsigned sample_mask
)
551 struct ilo_context
*ilo
= ilo_context(pipe
);
553 /* util_blitter may set this unnecessarily */
554 if (ilo
->sample_mask
== sample_mask
)
557 ilo
->sample_mask
= sample_mask
;
559 ilo
->dirty
|= ILO_DIRTY_SAMPLE_MASK
;
563 ilo_set_clip_state(struct pipe_context
*pipe
,
564 const struct pipe_clip_state
*state
)
566 struct ilo_context
*ilo
= ilo_context(pipe
);
570 ilo
->dirty
|= ILO_DIRTY_CLIP
;
574 ilo_set_constant_buffer(struct pipe_context
*pipe
,
575 uint shader
, uint index
,
576 struct pipe_constant_buffer
*buf
)
578 struct ilo_context
*ilo
= ilo_context(pipe
);
579 struct ilo_cbuf_state
*cbuf
= &ilo
->cbuf
[shader
];
580 const unsigned count
= 1;
583 assert(shader
< Elements(ilo
->cbuf
));
584 assert(index
+ count
<= Elements(ilo
->cbuf
[shader
].cso
));
587 for (i
= 0; i
< count
; i
++) {
588 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
590 pipe_resource_reference(&cso
->resource
, buf
[i
].buffer
);
593 const enum pipe_format elem_format
=
594 PIPE_FORMAT_R32G32B32A32_FLOAT
;
596 ilo_gpe_init_view_surface_for_buffer(ilo
->dev
,
597 ilo_buffer(buf
[i
].buffer
),
598 buf
[i
].buffer_offset
, buf
[i
].buffer_size
,
599 util_format_get_blocksize(elem_format
), elem_format
,
600 false, false, &cso
->surface
);
602 cso
->user_buffer
= NULL
;
603 cso
->user_buffer_size
= 0;
605 cbuf
->enabled_mask
|= 1 << (index
+ i
);
607 else if (buf
[i
].user_buffer
) {
608 cso
->surface
.bo
= NULL
;
610 /* buffer_offset does not apply for user buffer */
611 cso
->user_buffer
= buf
[i
].user_buffer
;
612 cso
->user_buffer_size
= buf
[i
].buffer_size
;
614 cbuf
->enabled_mask
|= 1 << (index
+ i
);
617 cso
->surface
.bo
= NULL
;
618 cso
->user_buffer
= NULL
;
619 cso
->user_buffer_size
= 0;
621 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
626 for (i
= 0; i
< count
; i
++) {
627 struct ilo_cbuf_cso
*cso
= &cbuf
->cso
[index
+ i
];
629 pipe_resource_reference(&cso
->resource
, NULL
);
630 cso
->surface
.bo
= NULL
;
631 cso
->user_buffer
= NULL
;
632 cso
->user_buffer_size
= 0;
634 cbuf
->enabled_mask
&= ~(1 << (index
+ i
));
638 ilo
->dirty
|= ILO_DIRTY_CBUF
;
642 ilo_set_framebuffer_state(struct pipe_context
*pipe
,
643 const struct pipe_framebuffer_state
*state
)
645 struct ilo_context
*ilo
= ilo_context(pipe
);
647 ilo_gpe_set_fb(ilo
->dev
, state
, &ilo
->fb
);
649 ilo
->dirty
|= ILO_DIRTY_FB
;
653 ilo_set_polygon_stipple(struct pipe_context
*pipe
,
654 const struct pipe_poly_stipple
*state
)
656 struct ilo_context
*ilo
= ilo_context(pipe
);
658 ilo
->poly_stipple
= *state
;
660 ilo
->dirty
|= ILO_DIRTY_POLY_STIPPLE
;
664 ilo_set_scissor_states(struct pipe_context
*pipe
,
666 unsigned num_scissors
,
667 const struct pipe_scissor_state
*scissors
)
669 struct ilo_context
*ilo
= ilo_context(pipe
);
671 ilo_gpe_set_scissor(ilo
->dev
, start_slot
, num_scissors
,
672 scissors
, &ilo
->scissor
);
674 ilo
->dirty
|= ILO_DIRTY_SCISSOR
;
678 ilo_set_viewport_states(struct pipe_context
*pipe
,
680 unsigned num_viewports
,
681 const struct pipe_viewport_state
*viewports
)
683 struct ilo_context
*ilo
= ilo_context(pipe
);
688 for (i
= 0; i
< num_viewports
; i
++) {
689 ilo_gpe_set_viewport_cso(ilo
->dev
, &viewports
[i
],
690 &ilo
->viewport
.cso
[start_slot
+ i
]);
693 if (ilo
->viewport
.count
< start_slot
+ num_viewports
)
694 ilo
->viewport
.count
= start_slot
+ num_viewports
;
696 /* need to save viewport 0 for util_blitter */
697 if (!start_slot
&& num_viewports
)
698 ilo
->viewport
.viewport0
= viewports
[0];
701 if (ilo
->viewport
.count
<= start_slot
+ num_viewports
&&
702 ilo
->viewport
.count
> start_slot
)
703 ilo
->viewport
.count
= start_slot
;
706 ilo
->dirty
|= ILO_DIRTY_VIEWPORT
;
710 ilo_set_sampler_views(struct pipe_context
*pipe
, unsigned shader
,
711 unsigned start
, unsigned count
,
712 struct pipe_sampler_view
**views
)
714 struct ilo_context
*ilo
= ilo_context(pipe
);
715 struct ilo_view_state
*dst
= &ilo
->view
[shader
];
718 assert(start
+ count
<= Elements(dst
->states
));
721 for (i
= 0; i
< count
; i
++)
722 pipe_sampler_view_reference(&dst
->states
[start
+ i
], views
[i
]);
725 for (i
= 0; i
< count
; i
++)
726 pipe_sampler_view_reference(&dst
->states
[start
+ i
], NULL
);
729 if (dst
->count
<= start
+ count
) {
735 while (count
> 0 && !dst
->states
[count
- 1])
742 case PIPE_SHADER_VERTEX
:
743 ilo
->dirty
|= ILO_DIRTY_VIEW_VS
;
745 case PIPE_SHADER_GEOMETRY
:
746 ilo
->dirty
|= ILO_DIRTY_VIEW_GS
;
748 case PIPE_SHADER_FRAGMENT
:
749 ilo
->dirty
|= ILO_DIRTY_VIEW_FS
;
751 case PIPE_SHADER_COMPUTE
:
752 ilo
->dirty
|= ILO_DIRTY_VIEW_CS
;
758 ilo_set_shader_resources(struct pipe_context
*pipe
,
759 unsigned start
, unsigned count
,
760 struct pipe_surface
**surfaces
)
762 struct ilo_context
*ilo
= ilo_context(pipe
);
763 struct ilo_resource_state
*dst
= &ilo
->resource
;
766 assert(start
+ count
<= Elements(dst
->states
));
769 for (i
= 0; i
< count
; i
++)
770 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
773 for (i
= 0; i
< count
; i
++)
774 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
777 if (dst
->count
<= start
+ count
) {
783 while (count
> 0 && !dst
->states
[count
- 1])
789 ilo
->dirty
|= ILO_DIRTY_RESOURCE
;
793 ilo_set_vertex_buffers(struct pipe_context
*pipe
,
794 unsigned start_slot
, unsigned num_buffers
,
795 const struct pipe_vertex_buffer
*buffers
)
797 struct ilo_context
*ilo
= ilo_context(pipe
);
800 /* no PIPE_CAP_USER_VERTEX_BUFFERS */
802 for (i
= 0; i
< num_buffers
; i
++)
803 assert(!buffers
[i
].user_buffer
);
806 util_set_vertex_buffers_mask(ilo
->vb
.states
,
807 &ilo
->vb
.enabled_mask
, buffers
, start_slot
, num_buffers
);
809 ilo
->dirty
|= ILO_DIRTY_VB
;
813 ilo_set_index_buffer(struct pipe_context
*pipe
,
814 const struct pipe_index_buffer
*state
)
816 struct ilo_context
*ilo
= ilo_context(pipe
);
819 pipe_resource_reference(&ilo
->ib
.buffer
, state
->buffer
);
820 ilo
->ib
.user_buffer
= state
->user_buffer
;
821 ilo
->ib
.offset
= state
->offset
;
822 ilo
->ib
.index_size
= state
->index_size
;
825 pipe_resource_reference(&ilo
->ib
.buffer
, NULL
);
826 ilo
->ib
.user_buffer
= NULL
;
828 ilo
->ib
.index_size
= 0;
831 ilo
->dirty
|= ILO_DIRTY_IB
;
834 static struct pipe_stream_output_target
*
835 ilo_create_stream_output_target(struct pipe_context
*pipe
,
836 struct pipe_resource
*res
,
837 unsigned buffer_offset
,
838 unsigned buffer_size
)
840 struct pipe_stream_output_target
*target
;
842 target
= MALLOC_STRUCT(pipe_stream_output_target
);
845 pipe_reference_init(&target
->reference
, 1);
846 target
->buffer
= NULL
;
847 pipe_resource_reference(&target
->buffer
, res
);
848 target
->context
= pipe
;
849 target
->buffer_offset
= buffer_offset
;
850 target
->buffer_size
= buffer_size
;
856 ilo_set_stream_output_targets(struct pipe_context
*pipe
,
857 unsigned num_targets
,
858 struct pipe_stream_output_target
**targets
,
859 const unsigned *offset
)
861 struct ilo_context
*ilo
= ilo_context(pipe
);
863 unsigned append_bitmask
= 0;
868 /* util_blitter may set this unnecessarily */
869 if (!ilo
->so
.count
&& !num_targets
)
872 for (i
= 0; i
< num_targets
; i
++) {
873 pipe_so_target_reference(&ilo
->so
.states
[i
], targets
[i
]);
874 if (offset
[i
] == (unsigned)-1)
875 append_bitmask
|= 1 << i
;
878 for (; i
< ilo
->so
.count
; i
++)
879 pipe_so_target_reference(&ilo
->so
.states
[i
], NULL
);
881 ilo
->so
.count
= num_targets
;
882 ilo
->so
.append_bitmask
= append_bitmask
;
884 ilo
->so
.enabled
= (ilo
->so
.count
> 0);
886 ilo
->dirty
|= ILO_DIRTY_SO
;
890 ilo_stream_output_target_destroy(struct pipe_context
*pipe
,
891 struct pipe_stream_output_target
*target
)
893 pipe_resource_reference(&target
->buffer
, NULL
);
897 static struct pipe_sampler_view
*
898 ilo_create_sampler_view(struct pipe_context
*pipe
,
899 struct pipe_resource
*res
,
900 const struct pipe_sampler_view
*templ
)
902 struct ilo_context
*ilo
= ilo_context(pipe
);
903 struct ilo_view_cso
*view
;
905 view
= MALLOC_STRUCT(ilo_view_cso
);
909 pipe_reference_init(&view
->base
.reference
, 1);
910 view
->base
.texture
= NULL
;
911 pipe_resource_reference(&view
->base
.texture
, res
);
912 view
->base
.context
= pipe
;
914 if (res
->target
== PIPE_BUFFER
) {
915 const unsigned elem_size
= util_format_get_blocksize(templ
->format
);
916 const unsigned first_elem
= templ
->u
.buf
.first_element
;
917 const unsigned num_elems
= templ
->u
.buf
.last_element
- first_elem
+ 1;
919 ilo_gpe_init_view_surface_for_buffer(ilo
->dev
, ilo_buffer(res
),
920 first_elem
* elem_size
, num_elems
* elem_size
,
921 elem_size
, templ
->format
, false, false, &view
->surface
);
924 struct ilo_texture
*tex
= ilo_texture(res
);
926 /* warn about degraded performance because of a missing binding flag */
927 if (tex
->tiling
== INTEL_TILING_NONE
&&
928 !(tex
->base
.bind
& PIPE_BIND_SAMPLER_VIEW
)) {
929 ilo_warn("creating sampler view for a resource "
930 "not created for sampling\n");
933 ilo_gpe_init_view_surface_for_texture(ilo
->dev
, tex
,
935 templ
->u
.tex
.first_level
,
936 templ
->u
.tex
.last_level
- templ
->u
.tex
.first_level
+ 1,
937 templ
->u
.tex
.first_layer
,
938 templ
->u
.tex
.last_layer
- templ
->u
.tex
.first_layer
+ 1,
939 false, false, &view
->surface
);
946 ilo_sampler_view_destroy(struct pipe_context
*pipe
,
947 struct pipe_sampler_view
*view
)
949 pipe_resource_reference(&view
->texture
, NULL
);
953 static struct pipe_surface
*
954 ilo_create_surface(struct pipe_context
*pipe
,
955 struct pipe_resource
*res
,
956 const struct pipe_surface
*templ
)
958 struct ilo_context
*ilo
= ilo_context(pipe
);
959 struct ilo_surface_cso
*surf
;
961 surf
= MALLOC_STRUCT(ilo_surface_cso
);
965 pipe_reference_init(&surf
->base
.reference
, 1);
966 surf
->base
.texture
= NULL
;
967 pipe_resource_reference(&surf
->base
.texture
, res
);
969 surf
->base
.context
= pipe
;
970 surf
->base
.width
= u_minify(res
->width0
, templ
->u
.tex
.level
);
971 surf
->base
.height
= u_minify(res
->height0
, templ
->u
.tex
.level
);
973 surf
->is_rt
= !util_format_is_depth_or_stencil(templ
->format
);
977 assert(res
->target
!= PIPE_BUFFER
);
980 * classic i965 sets render_cache_rw for constant buffers and sol
981 * surfaces but not render buffers. Why?
983 ilo_gpe_init_view_surface_for_texture(ilo
->dev
, ilo_texture(res
),
984 templ
->format
, templ
->u
.tex
.level
, 1,
985 templ
->u
.tex
.first_layer
,
986 templ
->u
.tex
.last_layer
- templ
->u
.tex
.first_layer
+ 1,
987 true, false, &surf
->u
.rt
);
990 assert(res
->target
!= PIPE_BUFFER
);
992 ilo_gpe_init_zs_surface(ilo
->dev
, ilo_texture(res
),
993 templ
->format
, templ
->u
.tex
.level
,
994 templ
->u
.tex
.first_layer
,
995 templ
->u
.tex
.last_layer
- templ
->u
.tex
.first_layer
+ 1,
1003 ilo_surface_destroy(struct pipe_context
*pipe
,
1004 struct pipe_surface
*surface
)
1006 pipe_resource_reference(&surface
->texture
, NULL
);
1011 ilo_create_compute_state(struct pipe_context
*pipe
,
1012 const struct pipe_compute_state
*state
)
1014 struct ilo_context
*ilo
= ilo_context(pipe
);
1015 struct ilo_shader_state
*shader
;
1017 shader
= ilo_shader_create_cs(ilo
->dev
, state
, ilo
);
1020 ilo_shader_cache_add(ilo
->shader_cache
, shader
);
1026 ilo_bind_compute_state(struct pipe_context
*pipe
, void *state
)
1028 struct ilo_context
*ilo
= ilo_context(pipe
);
1032 ilo
->dirty
|= ILO_DIRTY_CS
;
1036 ilo_delete_compute_state(struct pipe_context
*pipe
, void *state
)
1038 struct ilo_context
*ilo
= ilo_context(pipe
);
1039 struct ilo_shader_state
*cs
= (struct ilo_shader_state
*) state
;
1041 ilo_shader_cache_remove(ilo
->shader_cache
, cs
);
1042 ilo_shader_destroy(cs
);
1046 ilo_set_compute_resources(struct pipe_context
*pipe
,
1047 unsigned start
, unsigned count
,
1048 struct pipe_surface
**surfaces
)
1050 struct ilo_context
*ilo
= ilo_context(pipe
);
1051 struct ilo_resource_state
*dst
= &ilo
->cs_resource
;
1054 assert(start
+ count
<= Elements(dst
->states
));
1057 for (i
= 0; i
< count
; i
++)
1058 pipe_surface_reference(&dst
->states
[start
+ i
], surfaces
[i
]);
1061 for (i
= 0; i
< count
; i
++)
1062 pipe_surface_reference(&dst
->states
[start
+ i
], NULL
);
1065 if (dst
->count
<= start
+ count
) {
1071 while (count
> 0 && !dst
->states
[count
- 1])
1077 ilo
->dirty
|= ILO_DIRTY_CS_RESOURCE
;
1081 ilo_set_global_binding(struct pipe_context
*pipe
,
1082 unsigned start
, unsigned count
,
1083 struct pipe_resource
**resources
,
1086 struct ilo_context
*ilo
= ilo_context(pipe
);
1087 struct ilo_global_binding
*dst
= &ilo
->global_binding
;
1090 assert(start
+ count
<= Elements(dst
->resources
));
1093 for (i
= 0; i
< count
; i
++)
1094 pipe_resource_reference(&dst
->resources
[start
+ i
], resources
[i
]);
1097 for (i
= 0; i
< count
; i
++)
1098 pipe_resource_reference(&dst
->resources
[start
+ i
], NULL
);
1101 if (dst
->count
<= start
+ count
) {
1107 while (count
> 0 && !dst
->resources
[count
- 1])
1113 ilo
->dirty
|= ILO_DIRTY_GLOBAL_BINDING
;
1117 * Initialize state-related functions.
1120 ilo_init_state_functions(struct ilo_context
*ilo
)
1122 STATIC_ASSERT(ILO_STATE_COUNT
<= 32);
1124 ilo
->base
.create_blend_state
= ilo_create_blend_state
;
1125 ilo
->base
.bind_blend_state
= ilo_bind_blend_state
;
1126 ilo
->base
.delete_blend_state
= ilo_delete_blend_state
;
1127 ilo
->base
.create_sampler_state
= ilo_create_sampler_state
;
1128 ilo
->base
.bind_sampler_states
= ilo_bind_sampler_states
;
1129 ilo
->base
.delete_sampler_state
= ilo_delete_sampler_state
;
1130 ilo
->base
.create_rasterizer_state
= ilo_create_rasterizer_state
;
1131 ilo
->base
.bind_rasterizer_state
= ilo_bind_rasterizer_state
;
1132 ilo
->base
.delete_rasterizer_state
= ilo_delete_rasterizer_state
;
1133 ilo
->base
.create_depth_stencil_alpha_state
= ilo_create_depth_stencil_alpha_state
;
1134 ilo
->base
.bind_depth_stencil_alpha_state
= ilo_bind_depth_stencil_alpha_state
;
1135 ilo
->base
.delete_depth_stencil_alpha_state
= ilo_delete_depth_stencil_alpha_state
;
1136 ilo
->base
.create_fs_state
= ilo_create_fs_state
;
1137 ilo
->base
.bind_fs_state
= ilo_bind_fs_state
;
1138 ilo
->base
.delete_fs_state
= ilo_delete_fs_state
;
1139 ilo
->base
.create_vs_state
= ilo_create_vs_state
;
1140 ilo
->base
.bind_vs_state
= ilo_bind_vs_state
;
1141 ilo
->base
.delete_vs_state
= ilo_delete_vs_state
;
1142 ilo
->base
.create_gs_state
= ilo_create_gs_state
;
1143 ilo
->base
.bind_gs_state
= ilo_bind_gs_state
;
1144 ilo
->base
.delete_gs_state
= ilo_delete_gs_state
;
1145 ilo
->base
.create_vertex_elements_state
= ilo_create_vertex_elements_state
;
1146 ilo
->base
.bind_vertex_elements_state
= ilo_bind_vertex_elements_state
;
1147 ilo
->base
.delete_vertex_elements_state
= ilo_delete_vertex_elements_state
;
1149 ilo
->base
.set_blend_color
= ilo_set_blend_color
;
1150 ilo
->base
.set_stencil_ref
= ilo_set_stencil_ref
;
1151 ilo
->base
.set_sample_mask
= ilo_set_sample_mask
;
1152 ilo
->base
.set_clip_state
= ilo_set_clip_state
;
1153 ilo
->base
.set_constant_buffer
= ilo_set_constant_buffer
;
1154 ilo
->base
.set_framebuffer_state
= ilo_set_framebuffer_state
;
1155 ilo
->base
.set_polygon_stipple
= ilo_set_polygon_stipple
;
1156 ilo
->base
.set_scissor_states
= ilo_set_scissor_states
;
1157 ilo
->base
.set_viewport_states
= ilo_set_viewport_states
;
1158 ilo
->base
.set_sampler_views
= ilo_set_sampler_views
;
1159 ilo
->base
.set_shader_resources
= ilo_set_shader_resources
;
1160 ilo
->base
.set_vertex_buffers
= ilo_set_vertex_buffers
;
1161 ilo
->base
.set_index_buffer
= ilo_set_index_buffer
;
1163 ilo
->base
.create_stream_output_target
= ilo_create_stream_output_target
;
1164 ilo
->base
.stream_output_target_destroy
= ilo_stream_output_target_destroy
;
1165 ilo
->base
.set_stream_output_targets
= ilo_set_stream_output_targets
;
1167 ilo
->base
.create_sampler_view
= ilo_create_sampler_view
;
1168 ilo
->base
.sampler_view_destroy
= ilo_sampler_view_destroy
;
1170 ilo
->base
.create_surface
= ilo_create_surface
;
1171 ilo
->base
.surface_destroy
= ilo_surface_destroy
;
1173 ilo
->base
.create_compute_state
= ilo_create_compute_state
;
1174 ilo
->base
.bind_compute_state
= ilo_bind_compute_state
;
1175 ilo
->base
.delete_compute_state
= ilo_delete_compute_state
;
1176 ilo
->base
.set_compute_resources
= ilo_set_compute_resources
;
1177 ilo
->base
.set_global_binding
= ilo_set_global_binding
;
1181 ilo_init_states(struct ilo_context
*ilo
)
1183 ilo_gpe_set_scissor_null(ilo
->dev
, &ilo
->scissor
);
1185 ilo_gpe_init_zs_surface(ilo
->dev
, NULL
, PIPE_FORMAT_NONE
,
1186 0, 0, 1, false, &ilo
->fb
.null_zs
);
1188 ilo
->dirty
= ILO_DIRTY_ALL
;
1192 ilo_cleanup_states(struct ilo_context
*ilo
)
1196 for (i
= 0; i
< Elements(ilo
->vb
.states
); i
++) {
1197 if (ilo
->vb
.enabled_mask
& (1 << i
))
1198 pipe_resource_reference(&ilo
->vb
.states
[i
].buffer
, NULL
);
1201 pipe_resource_reference(&ilo
->ib
.buffer
, NULL
);
1202 pipe_resource_reference(&ilo
->ib
.hw_resource
, NULL
);
1204 for (i
= 0; i
< ilo
->so
.count
; i
++)
1205 pipe_so_target_reference(&ilo
->so
.states
[i
], NULL
);
1207 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
1208 for (i
= 0; i
< ilo
->view
[sh
].count
; i
++) {
1209 struct pipe_sampler_view
*view
= ilo
->view
[sh
].states
[i
];
1210 pipe_sampler_view_reference(&view
, NULL
);
1213 for (i
= 0; i
< Elements(ilo
->cbuf
[sh
].cso
); i
++) {
1214 struct ilo_cbuf_cso
*cbuf
= &ilo
->cbuf
[sh
].cso
[i
];
1215 pipe_resource_reference(&cbuf
->resource
, NULL
);
1219 for (i
= 0; i
< ilo
->resource
.count
; i
++)
1220 pipe_surface_reference(&ilo
->resource
.states
[i
], NULL
);
1222 for (i
= 0; i
< ilo
->fb
.state
.nr_cbufs
; i
++)
1223 pipe_surface_reference(&ilo
->fb
.state
.cbufs
[i
], NULL
);
1225 if (ilo
->fb
.state
.zsbuf
)
1226 pipe_surface_reference(&ilo
->fb
.state
.zsbuf
, NULL
);
1228 for (i
= 0; i
< ilo
->cs_resource
.count
; i
++)
1229 pipe_surface_reference(&ilo
->cs_resource
.states
[i
], NULL
);
1231 for (i
= 0; i
< ilo
->global_binding
.count
; i
++)
1232 pipe_resource_reference(&ilo
->global_binding
.resources
[i
], NULL
);
1236 * Mark all states that have the resource dirty.
1239 ilo_mark_states_with_resource_renamed(struct ilo_context
*ilo
,
1240 struct pipe_resource
*res
)
1242 struct intel_bo
*bo
= ilo_resource_get_bo(res
);
1243 uint32_t states
= 0;
1246 if (res
->target
== PIPE_BUFFER
) {
1247 uint32_t vb_mask
= ilo
->vb
.enabled_mask
;
1250 const unsigned idx
= u_bit_scan(&vb_mask
);
1252 if (ilo
->vb
.states
[idx
].buffer
== res
) {
1253 states
|= ILO_DIRTY_VB
;
1258 if (ilo
->ib
.buffer
== res
) {
1259 states
|= ILO_DIRTY_IB
;
1262 * finalize_index_buffer() has an optimization that clears
1263 * ILO_DIRTY_IB when the HW states do not change. However, it fails
1264 * to flush the VF cache when the HW states do not change, but the
1265 * contents of the IB has changed. Here, we set the index size to an
1266 * invalid value to avoid the optimization.
1268 ilo
->ib
.hw_index_size
= 0;
1271 for (i
= 0; i
< ilo
->so
.count
; i
++) {
1272 if (ilo
->so
.states
[i
]->buffer
== res
) {
1273 states
|= ILO_DIRTY_SO
;
1279 for (sh
= 0; sh
< PIPE_SHADER_TYPES
; sh
++) {
1280 for (i
= 0; i
< ilo
->view
[sh
].count
; i
++) {
1281 struct ilo_view_cso
*cso
= (struct ilo_view_cso
*) ilo
->view
[sh
].states
[i
];
1283 if (cso
->base
.texture
== res
) {
1284 static const unsigned view_dirty_bits
[PIPE_SHADER_TYPES
] = {
1285 [PIPE_SHADER_VERTEX
] = ILO_DIRTY_VIEW_VS
,
1286 [PIPE_SHADER_FRAGMENT
] = ILO_DIRTY_VIEW_FS
,
1287 [PIPE_SHADER_GEOMETRY
] = ILO_DIRTY_VIEW_GS
,
1288 [PIPE_SHADER_COMPUTE
] = ILO_DIRTY_VIEW_CS
,
1290 cso
->surface
.bo
= bo
;
1292 states
|= view_dirty_bits
[sh
];
1297 if (res
->target
== PIPE_BUFFER
) {
1298 for (i
= 0; i
< Elements(ilo
->cbuf
[sh
].cso
); i
++) {
1299 struct ilo_cbuf_cso
*cbuf
= &ilo
->cbuf
[sh
].cso
[i
];
1301 if (cbuf
->resource
== res
) {
1302 cbuf
->surface
.bo
= bo
;
1303 states
|= ILO_DIRTY_CBUF
;
1310 for (i
= 0; i
< ilo
->resource
.count
; i
++) {
1311 struct ilo_surface_cso
*cso
=
1312 (struct ilo_surface_cso
*) ilo
->resource
.states
[i
];
1314 if (cso
->base
.texture
== res
) {
1316 states
|= ILO_DIRTY_RESOURCE
;
1322 if (res
->target
!= PIPE_BUFFER
) {
1323 for (i
= 0; i
< ilo
->fb
.state
.nr_cbufs
; i
++) {
1324 struct ilo_surface_cso
*cso
=
1325 (struct ilo_surface_cso
*) ilo
->fb
.state
.cbufs
[i
];
1326 if (cso
&& cso
->base
.texture
== res
) {
1328 states
|= ILO_DIRTY_FB
;
1333 if (ilo
->fb
.state
.zsbuf
&& ilo
->fb
.state
.zsbuf
->texture
== res
) {
1334 struct ilo_surface_cso
*cso
=
1335 (struct ilo_surface_cso
*) ilo
->fb
.state
.zsbuf
;
1338 states
|= ILO_DIRTY_FB
;
1342 for (i
= 0; i
< ilo
->cs_resource
.count
; i
++) {
1343 struct ilo_surface_cso
*cso
=
1344 (struct ilo_surface_cso
*) ilo
->cs_resource
.states
[i
];
1345 if (cso
->base
.texture
== res
) {
1347 states
|= ILO_DIRTY_CS_RESOURCE
;
1352 for (i
= 0; i
< ilo
->global_binding
.count
; i
++) {
1353 if (ilo
->global_binding
.resources
[i
] == res
) {
1354 states
|= ILO_DIRTY_GLOBAL_BINDING
;
1359 ilo
->dirty
|= states
;
1363 ilo_dump_dirty_flags(uint32_t dirty
)
1365 static const char *state_names
[ILO_STATE_COUNT
] = {
1366 [ILO_STATE_VB
] = "VB",
1367 [ILO_STATE_VE
] = "VE",
1368 [ILO_STATE_IB
] = "IB",
1369 [ILO_STATE_VS
] = "VS",
1370 [ILO_STATE_GS
] = "GS",
1371 [ILO_STATE_SO
] = "SO",
1372 [ILO_STATE_CLIP
] = "CLIP",
1373 [ILO_STATE_VIEWPORT
] = "VIEWPORT",
1374 [ILO_STATE_SCISSOR
] = "SCISSOR",
1375 [ILO_STATE_RASTERIZER
] = "RASTERIZER",
1376 [ILO_STATE_POLY_STIPPLE
] = "POLY_STIPPLE",
1377 [ILO_STATE_SAMPLE_MASK
] = "SAMPLE_MASK",
1378 [ILO_STATE_FS
] = "FS",
1379 [ILO_STATE_DSA
] = "DSA",
1380 [ILO_STATE_STENCIL_REF
] = "STENCIL_REF",
1381 [ILO_STATE_BLEND
] = "BLEND",
1382 [ILO_STATE_BLEND_COLOR
] = "BLEND_COLOR",
1383 [ILO_STATE_FB
] = "FB",
1384 [ILO_STATE_SAMPLER_VS
] = "SAMPLER_VS",
1385 [ILO_STATE_SAMPLER_GS
] = "SAMPLER_GS",
1386 [ILO_STATE_SAMPLER_FS
] = "SAMPLER_FS",
1387 [ILO_STATE_SAMPLER_CS
] = "SAMPLER_CS",
1388 [ILO_STATE_VIEW_VS
] = "VIEW_VS",
1389 [ILO_STATE_VIEW_GS
] = "VIEW_GS",
1390 [ILO_STATE_VIEW_FS
] = "VIEW_FS",
1391 [ILO_STATE_VIEW_CS
] = "VIEW_CS",
1392 [ILO_STATE_CBUF
] = "CBUF",
1393 [ILO_STATE_RESOURCE
] = "RESOURCE",
1394 [ILO_STATE_CS
] = "CS",
1395 [ILO_STATE_CS_RESOURCE
] = "CS_RESOURCE",
1396 [ILO_STATE_GLOBAL_BINDING
] = "GLOBAL_BINDING",
1400 ilo_printf("no state is dirty\n");
1404 dirty
&= (1U << ILO_STATE_COUNT
) - 1;
1406 ilo_printf("%2d states are dirty:", util_bitcount(dirty
));
1408 const enum ilo_state state
= u_bit_scan(&dirty
);
1409 ilo_printf(" %s", state_names
[state
]);