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 "ilo_common.h"
29 #include "ilo_blitter.h"
30 #include "ilo_builder_3d.h"
31 #include "ilo_state.h"
32 #include "ilo_render_gen.h"
34 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
37 gen6_emit_draw_dynamic_viewports(struct ilo_render
*r
,
38 const struct ilo_state_vector
*vec
,
39 struct gen6_draw_session
*session
)
41 ILO_DEV_ASSERT(r
->dev
, 6, 6);
43 /* SF_VIEWPORT, CLIP_VIEWPORT, and CC_VIEWPORT */
44 if (DIRTY(VIEWPORT
)) {
45 r
->state
.CLIP_VIEWPORT
= gen6_CLIP_VIEWPORT(r
->builder
,
46 vec
->viewport
.cso
, vec
->viewport
.count
);
48 r
->state
.SF_VIEWPORT
= gen6_SF_VIEWPORT(r
->builder
,
49 vec
->viewport
.cso
, vec
->viewport
.count
);
51 r
->state
.CC_VIEWPORT
= gen6_CC_VIEWPORT(r
->builder
,
52 vec
->viewport
.cso
, vec
->viewport
.count
);
54 session
->viewport_changed
= true;
59 gen7_emit_draw_dynamic_viewports(struct ilo_render
*r
,
60 const struct ilo_state_vector
*vec
,
61 struct gen6_draw_session
*session
)
63 ILO_DEV_ASSERT(r
->dev
, 7, 7.5);
65 /* SF_CLIP_VIEWPORT and CC_VIEWPORT */
66 if (DIRTY(VIEWPORT
)) {
67 r
->state
.SF_CLIP_VIEWPORT
= gen7_SF_CLIP_VIEWPORT(r
->builder
,
68 vec
->viewport
.cso
, vec
->viewport
.count
);
70 r
->state
.CC_VIEWPORT
= gen6_CC_VIEWPORT(r
->builder
,
71 vec
->viewport
.cso
, vec
->viewport
.count
);
73 session
->viewport_changed
= true;
78 gen6_emit_draw_dynamic_scissors(struct ilo_render
*r
,
79 const struct ilo_state_vector
*vec
,
80 struct gen6_draw_session
*session
)
82 ILO_DEV_ASSERT(r
->dev
, 6, 7.5);
85 if (DIRTY(SCISSOR
) || DIRTY(VIEWPORT
)) {
86 /* there should be as many scissors as there are viewports */
87 r
->state
.SCISSOR_RECT
= gen6_SCISSOR_RECT(r
->builder
,
88 &vec
->scissor
, vec
->viewport
.count
);
90 session
->scissor_changed
= true;
95 gen6_emit_draw_dynamic_cc(struct ilo_render
*r
,
96 const struct ilo_state_vector
*vec
,
97 struct gen6_draw_session
*session
)
99 ILO_DEV_ASSERT(r
->dev
, 6, 7.5);
102 if (DIRTY(BLEND
) || DIRTY(FB
) || DIRTY(DSA
)) {
103 r
->state
.BLEND_STATE
= gen6_BLEND_STATE(r
->builder
,
104 vec
->blend
, &vec
->fb
, vec
->dsa
);
106 session
->blend_changed
= true;
109 /* COLOR_CALC_STATE */
110 if (DIRTY(DSA
) || DIRTY(STENCIL_REF
) || DIRTY(BLEND_COLOR
)) {
111 r
->state
.COLOR_CALC_STATE
=
112 gen6_COLOR_CALC_STATE(r
->builder
, &vec
->stencil_ref
,
113 vec
->dsa
->alpha_ref
, &vec
->blend_color
);
115 session
->cc_changed
= true;
118 /* DEPTH_STENCIL_STATE */
120 r
->state
.DEPTH_STENCIL_STATE
=
121 gen6_DEPTH_STENCIL_STATE(r
->builder
, vec
->dsa
);
123 session
->dsa_changed
= true;
128 gen6_emit_draw_dynamic_samplers(struct ilo_render
*r
,
129 const struct ilo_state_vector
*vec
,
131 struct gen6_draw_session
*session
)
133 const struct ilo_sampler_cso
* const *samplers
=
134 vec
->sampler
[shader_type
].cso
;
135 const struct pipe_sampler_view
* const *views
=
136 (const struct pipe_sampler_view
**) vec
->view
[shader_type
].states
;
137 const int num_samplers
= vec
->sampler
[shader_type
].count
;
138 const int num_views
= vec
->view
[shader_type
].count
;
139 uint32_t *sampler_state
, *border_color_state
;
140 bool emit_border_color
= false;
143 ILO_DEV_ASSERT(r
->dev
, 6, 7.5);
145 /* SAMPLER_BORDER_COLOR_STATE and SAMPLER_STATE */
146 switch (shader_type
) {
147 case PIPE_SHADER_VERTEX
:
148 if (DIRTY(SAMPLER_VS
) || DIRTY(VIEW_VS
)) {
149 sampler_state
= &r
->state
.vs
.SAMPLER_STATE
;
150 border_color_state
= r
->state
.vs
.SAMPLER_BORDER_COLOR_STATE
;
152 if (DIRTY(SAMPLER_VS
))
153 emit_border_color
= true;
155 session
->sampler_vs_changed
= true;
160 case PIPE_SHADER_FRAGMENT
:
161 if (DIRTY(SAMPLER_FS
) || DIRTY(VIEW_FS
)) {
162 sampler_state
= &r
->state
.wm
.SAMPLER_STATE
;
163 border_color_state
= r
->state
.wm
.SAMPLER_BORDER_COLOR_STATE
;
165 if (DIRTY(SAMPLER_FS
))
166 emit_border_color
= true;
168 session
->sampler_fs_changed
= true;
181 if (emit_border_color
) {
184 for (i
= 0; i
< num_samplers
; i
++) {
185 border_color_state
[i
] = (samplers
[i
]) ?
186 gen6_SAMPLER_BORDER_COLOR_STATE(r
->builder
, samplers
[i
]) : 0;
190 /* should we take the minimum of num_samplers and num_views? */
191 *sampler_state
= gen6_SAMPLER_STATE(r
->builder
,
194 MIN2(num_samplers
, num_views
));
198 gen6_emit_draw_dynamic_pcb(struct ilo_render
*r
,
199 const struct ilo_state_vector
*vec
,
200 struct gen6_draw_session
*session
)
202 ILO_DEV_ASSERT(r
->dev
, 6, 7.5);
204 /* push constant buffer for VS */
205 if (DIRTY(VS
) || DIRTY(CBUF
) || DIRTY(CLIP
)) {
206 const int cbuf0_size
= (vec
->vs
) ?
207 ilo_shader_get_kernel_param(vec
->vs
,
208 ILO_KERNEL_PCB_CBUF0_SIZE
) : 0;
209 const int clip_state_size
= (vec
->vs
) ?
210 ilo_shader_get_kernel_param(vec
->vs
,
211 ILO_KERNEL_VS_PCB_UCP_SIZE
) : 0;
212 const int total_size
= cbuf0_size
+ clip_state_size
;
217 r
->state
.vs
.PUSH_CONSTANT_BUFFER
=
218 gen6_push_constant_buffer(r
->builder
, total_size
, &pcb
);
219 r
->state
.vs
.PUSH_CONSTANT_BUFFER_size
= total_size
;
222 const struct ilo_cbuf_state
*cbuf
=
223 &vec
->cbuf
[PIPE_SHADER_VERTEX
];
225 if (cbuf0_size
<= cbuf
->cso
[0].user_buffer_size
) {
226 memcpy(pcb
, cbuf
->cso
[0].user_buffer
, cbuf0_size
);
228 memcpy(pcb
, cbuf
->cso
[0].user_buffer
,
229 cbuf
->cso
[0].user_buffer_size
);
230 memset(pcb
+ cbuf
->cso
[0].user_buffer_size
, 0,
231 cbuf0_size
- cbuf
->cso
[0].user_buffer_size
);
238 memcpy(pcb
, &vec
->clip
, clip_state_size
);
240 session
->pcb_vs_changed
= true;
241 } else if (r
->state
.vs
.PUSH_CONSTANT_BUFFER_size
) {
242 r
->state
.vs
.PUSH_CONSTANT_BUFFER
= 0;
243 r
->state
.vs
.PUSH_CONSTANT_BUFFER_size
= 0;
245 session
->pcb_vs_changed
= true;
249 /* push constant buffer for FS */
250 if (DIRTY(FS
) || DIRTY(CBUF
)) {
251 const int cbuf0_size
= (vec
->fs
) ?
252 ilo_shader_get_kernel_param(vec
->fs
, ILO_KERNEL_PCB_CBUF0_SIZE
) : 0;
255 const struct ilo_cbuf_state
*cbuf
= &vec
->cbuf
[PIPE_SHADER_FRAGMENT
];
258 r
->state
.wm
.PUSH_CONSTANT_BUFFER
=
259 gen6_push_constant_buffer(r
->builder
, cbuf0_size
, &pcb
);
260 r
->state
.wm
.PUSH_CONSTANT_BUFFER_size
= cbuf0_size
;
262 if (cbuf0_size
<= cbuf
->cso
[0].user_buffer_size
) {
263 memcpy(pcb
, cbuf
->cso
[0].user_buffer
, cbuf0_size
);
265 memcpy(pcb
, cbuf
->cso
[0].user_buffer
,
266 cbuf
->cso
[0].user_buffer_size
);
267 memset(pcb
+ cbuf
->cso
[0].user_buffer_size
, 0,
268 cbuf0_size
- cbuf
->cso
[0].user_buffer_size
);
271 session
->pcb_fs_changed
= true;
272 } else if (r
->state
.wm
.PUSH_CONSTANT_BUFFER_size
) {
273 r
->state
.wm
.PUSH_CONSTANT_BUFFER
= 0;
274 r
->state
.wm
.PUSH_CONSTANT_BUFFER_size
= 0;
276 session
->pcb_fs_changed
= true;
284 ilo_render_get_draw_dynamic_states_len(const struct ilo_render
*render
,
285 const struct ilo_state_vector
*vec
)
287 static int static_len
;
290 ILO_DEV_ASSERT(render
->dev
, 6, 7.5);
293 /* 64 bytes, or 16 dwords */
294 const int alignment
= 64 / 4;
300 len
+= align(GEN6_BLEND_STATE__SIZE
* ILO_MAX_DRAW_BUFFERS
, alignment
);
301 len
+= align(GEN6_DEPTH_STENCIL_STATE__SIZE
, alignment
);
302 len
+= align(GEN6_COLOR_CALC_STATE__SIZE
, alignment
);
304 /* viewport arrays */
305 if (ilo_dev_gen(render
->dev
) >= ILO_GEN(7)) {
306 len
+= 15 + /* pad first */
307 align(GEN7_SF_CLIP_VIEWPORT__SIZE
* ILO_MAX_VIEWPORTS
, 16) +
308 align(GEN6_CC_VIEWPORT__SIZE
* ILO_MAX_VIEWPORTS
, 8) +
309 align(GEN6_SCISSOR_RECT__SIZE
* ILO_MAX_VIEWPORTS
, 8);
311 len
+= 7 + /* pad first */
312 align(GEN6_SF_VIEWPORT__SIZE
* ILO_MAX_VIEWPORTS
, 8) +
313 align(GEN6_CLIP_VIEWPORT__SIZE
* ILO_MAX_VIEWPORTS
, 8) +
314 align(GEN6_CC_VIEWPORT__SIZE
* ILO_MAX_VIEWPORTS
, 8) +
315 align(GEN6_SCISSOR_RECT__SIZE
* ILO_MAX_VIEWPORTS
, 8);
323 for (sh_type
= 0; sh_type
< PIPE_SHADER_TYPES
; sh_type
++) {
324 const int alignment
= 32 / 4;
325 int num_samplers
, pcb_len
;
327 num_samplers
= vec
->sampler
[sh_type
].count
;
331 case PIPE_SHADER_VERTEX
:
333 pcb_len
= ilo_shader_get_kernel_param(vec
->vs
,
334 ILO_KERNEL_PCB_CBUF0_SIZE
);
335 pcb_len
+= ilo_shader_get_kernel_param(vec
->vs
,
336 ILO_KERNEL_VS_PCB_UCP_SIZE
);
339 case PIPE_SHADER_GEOMETRY
:
341 case PIPE_SHADER_FRAGMENT
:
343 pcb_len
= ilo_shader_get_kernel_param(vec
->fs
,
344 ILO_KERNEL_PCB_CBUF0_SIZE
);
351 /* SAMPLER_STATE array and SAMPLER_BORDER_COLORs */
353 len
+= align(GEN6_SAMPLER_STATE__SIZE
* num_samplers
, alignment
) +
354 align(GEN6_SAMPLER_BORDER_COLOR__SIZE
, alignment
) * num_samplers
;
359 len
+= align(pcb_len
, alignment
);
366 ilo_render_emit_draw_dynamic_states(struct ilo_render
*render
,
367 const struct ilo_state_vector
*vec
,
368 struct gen6_draw_session
*session
)
370 const unsigned dynamic_used
= ilo_builder_dynamic_used(render
->builder
);
372 ILO_DEV_ASSERT(render
->dev
, 6, 7.5);
374 if (ilo_dev_gen(render
->dev
) >= ILO_GEN(7))
375 gen7_emit_draw_dynamic_viewports(render
, vec
, session
);
377 gen6_emit_draw_dynamic_viewports(render
, vec
, session
);
379 gen6_emit_draw_dynamic_cc(render
, vec
, session
);
380 gen6_emit_draw_dynamic_scissors(render
, vec
, session
);
381 gen6_emit_draw_dynamic_pcb(render
, vec
, session
);
383 gen6_emit_draw_dynamic_samplers(render
, vec
,
384 PIPE_SHADER_VERTEX
, session
);
385 gen6_emit_draw_dynamic_samplers(render
, vec
,
386 PIPE_SHADER_FRAGMENT
, session
);
388 assert(ilo_builder_dynamic_used(render
->builder
) <= dynamic_used
+
389 ilo_render_get_draw_dynamic_states_len(render
, vec
));
393 ilo_render_get_rectlist_dynamic_states_len(const struct ilo_render
*render
,
394 const struct ilo_blitter
*blitter
)
396 ILO_DEV_ASSERT(render
->dev
, 6, 7.5);
402 ilo_render_emit_rectlist_dynamic_states(struct ilo_render
*render
,
403 const struct ilo_blitter
*blitter
)
405 const unsigned dynamic_used
= ilo_builder_dynamic_used(render
->builder
);
407 ILO_DEV_ASSERT(render
->dev
, 6, 7.5);
409 if (blitter
->uses
& ILO_BLITTER_USE_DSA
) {
410 render
->state
.DEPTH_STENCIL_STATE
=
411 gen6_DEPTH_STENCIL_STATE(render
->builder
, &blitter
->dsa
);
414 if (blitter
->uses
& ILO_BLITTER_USE_CC
) {
415 render
->state
.COLOR_CALC_STATE
=
416 gen6_COLOR_CALC_STATE(render
->builder
, &blitter
->cc
.stencil_ref
,
417 blitter
->cc
.alpha_ref
, &blitter
->cc
.blend_color
);
420 if (blitter
->uses
& ILO_BLITTER_USE_VIEWPORT
) {
421 render
->state
.CC_VIEWPORT
=
422 gen6_CC_VIEWPORT(render
->builder
, &blitter
->viewport
, 1);
425 assert(ilo_builder_dynamic_used(render
->builder
) <= dynamic_used
+
426 ilo_render_get_rectlist_dynamic_states_len(render
, blitter
));