2 * Copyright 2012 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include "util/u_format.h"
27 #include "util/u_helpers.h"
28 #include "util/u_inlines.h"
30 #include "nouveau_gldefs.h"
31 #include "nv_object.xml.h"
32 #include "nv30/nv30-40_3d.xml.h"
33 #include "nv30/nv30_context.h"
34 #include "nv30/nv30_winsys.h"
36 #define NV40_3D_MRT_BLEND_ENABLE 0x0000036c
39 nv30_blend_state_create(struct pipe_context
*pipe
,
40 const struct pipe_blend_state
*cso
)
42 struct nouveau_object
*eng3d
= nv30_context(pipe
)->screen
->eng3d
;
43 struct nv30_blend_stateobj
*so
;
44 uint32_t blend
[2], cmask
[2];
47 so
= CALLOC_STRUCT(nv30_blend_stateobj
);
52 if (cso
->logicop_enable
) {
53 SB_MTHD30(so
, COLOR_LOGIC_OP_ENABLE
, 2);
55 SB_DATA (so
, nvgl_logicop_func(cso
->logicop_func
));
57 SB_MTHD30(so
, COLOR_LOGIC_OP_ENABLE
, 1);
61 SB_MTHD30(so
, DITHER_ENABLE
, 1);
62 SB_DATA (so
, cso
->dither
);
64 blend
[0] = cso
->rt
[0].blend_enable
;
65 cmask
[0] = !!(cso
->rt
[0].colormask
& PIPE_MASK_A
) << 24 |
66 !!(cso
->rt
[0].colormask
& PIPE_MASK_R
) << 16 |
67 !!(cso
->rt
[0].colormask
& PIPE_MASK_G
) << 8 |
68 !!(cso
->rt
[0].colormask
& PIPE_MASK_B
);
69 if (cso
->independent_blend_enable
) {
72 for (i
= 1; i
< 4; i
++) {
73 blend
[1] |= cso
->rt
[i
].blend_enable
<< i
;
74 cmask
[1] |= !!(cso
->rt
[i
].colormask
& PIPE_MASK_A
) << (0 + (i
* 4)) |
75 !!(cso
->rt
[i
].colormask
& PIPE_MASK_R
) << (1 + (i
* 4)) |
76 !!(cso
->rt
[i
].colormask
& PIPE_MASK_G
) << (2 + (i
* 4)) |
77 !!(cso
->rt
[i
].colormask
& PIPE_MASK_B
) << (3 + (i
* 4));
80 blend
[1] = 0x0000000e * (blend
[0] & 0x00000001);
81 cmask
[1] = 0x00001110 * !!(cmask
[0] & 0x01000000);
82 cmask
[1] |= 0x00002220 * !!(cmask
[0] & 0x00010000);
83 cmask
[1] |= 0x00004440 * !!(cmask
[0] & 0x00000100);
84 cmask
[1] |= 0x00008880 * !!(cmask
[0] & 0x00000001);
87 if (eng3d
->oclass
>= NV40_3D_CLASS
) {
88 SB_MTHD40(so
, MRT_BLEND_ENABLE
, 2);
89 SB_DATA (so
, blend
[1]);
90 SB_DATA (so
, cmask
[1]);
93 if (blend
[0] || blend
[1]) {
94 SB_MTHD30(so
, BLEND_FUNC_ENABLE
, 3);
95 SB_DATA (so
, blend
[0]);
96 SB_DATA (so
, (nvgl_blend_func(cso
->rt
[0].alpha_src_factor
) << 16) |
97 nvgl_blend_func(cso
->rt
[0].rgb_src_factor
));
98 SB_DATA (so
, (nvgl_blend_func(cso
->rt
[0].alpha_dst_factor
) << 16) |
99 nvgl_blend_func(cso
->rt
[0].rgb_dst_factor
));
100 if (eng3d
->oclass
< NV40_3D_CLASS
) {
101 SB_MTHD30(so
, BLEND_EQUATION
, 1);
102 SB_DATA (so
, nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
104 SB_MTHD40(so
, BLEND_EQUATION
, 1);
105 SB_DATA (so
, (nvgl_blend_eqn(cso
->rt
[0].alpha_func
) << 16) |
106 nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
109 SB_MTHD30(so
, BLEND_FUNC_ENABLE
, 1);
110 SB_DATA (so
, blend
[0]);
113 SB_MTHD30(so
, COLOR_MASK
, 1);
114 SB_DATA (so
, cmask
[0]);
119 nv30_blend_state_bind(struct pipe_context
*pipe
, void *hwcso
)
121 struct nv30_context
*nv30
= nv30_context(pipe
);
124 nv30
->dirty
|= NV30_NEW_BLEND
;
128 nv30_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
134 nv30_rasterizer_state_create(struct pipe_context
*pipe
,
135 const struct pipe_rasterizer_state
*cso
)
137 struct nv30_rasterizer_stateobj
*so
;
139 so
= CALLOC_STRUCT(nv30_rasterizer_stateobj
);
144 SB_MTHD30(so
, SHADE_MODEL
, 1);
145 SB_DATA (so
, cso
->flatshade
? NV30_3D_SHADE_MODEL_FLAT
:
146 NV30_3D_SHADE_MODEL_SMOOTH
);
148 SB_MTHD30(so
, POLYGON_MODE_FRONT
, 6);
149 SB_DATA (so
, nvgl_polygon_mode(cso
->fill_front
));
150 SB_DATA (so
, nvgl_polygon_mode(cso
->fill_back
));
151 if (cso
->cull_face
== PIPE_FACE_FRONT_AND_BACK
)
152 SB_DATA (so
, NV30_3D_CULL_FACE_FRONT_AND_BACK
);
154 if (cso
->cull_face
== PIPE_FACE_FRONT
)
155 SB_DATA (so
, NV30_3D_CULL_FACE_FRONT
);
157 SB_DATA (so
, NV30_3D_CULL_FACE_BACK
);
158 SB_DATA (so
, cso
->front_ccw
? NV30_3D_FRONT_FACE_CCW
:
159 NV30_3D_FRONT_FACE_CW
);
160 SB_DATA (so
, cso
->poly_smooth
);
161 SB_DATA (so
, cso
->cull_face
!= PIPE_FACE_NONE
);
163 SB_MTHD30(so
, POLYGON_OFFSET_POINT_ENABLE
, 3);
164 SB_DATA (so
, cso
->offset_point
);
165 SB_DATA (so
, cso
->offset_line
);
166 SB_DATA (so
, cso
->offset_tri
);
167 if (cso
->offset_point
|| cso
->offset_line
|| cso
->offset_tri
) {
168 SB_MTHD30(so
, POLYGON_OFFSET_FACTOR
, 2);
169 SB_DATA (so
, fui(cso
->offset_scale
));
170 SB_DATA (so
, fui(cso
->offset_units
* 2.0));
173 SB_MTHD30(so
, LINE_WIDTH
, 2);
174 SB_DATA (so
, (unsigned char)(cso
->line_width
* 8.0) & 0xff);
175 SB_DATA (so
, cso
->line_smooth
);
176 SB_MTHD30(so
, LINE_STIPPLE_ENABLE
, 2);
177 SB_DATA (so
, cso
->line_stipple_enable
);
178 SB_DATA (so
, (cso
->line_stipple_pattern
<< 16) |
179 cso
->line_stipple_factor
);
181 SB_MTHD30(so
, VERTEX_TWO_SIDE_ENABLE
, 1);
182 SB_DATA (so
, cso
->light_twoside
);
183 SB_MTHD30(so
, POLYGON_STIPPLE_ENABLE
, 1);
184 SB_DATA (so
, cso
->poly_stipple_enable
);
185 SB_MTHD30(so
, POINT_SIZE
, 1);
186 SB_DATA (so
, fui(cso
->point_size
));
187 SB_MTHD30(so
, FLATSHADE_FIRST
, 1);
188 SB_DATA (so
, cso
->flatshade_first
);
190 SB_MTHD30(so
, DEPTH_CONTROL
, 1);
191 SB_DATA (so
, cso
->depth_clip
? 0x00000001 : 0x00000010);
196 nv30_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
198 struct nv30_context
*nv30
= nv30_context(pipe
);
201 nv30
->dirty
|= NV30_NEW_RASTERIZER
;
205 nv30_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
211 nv30_zsa_state_create(struct pipe_context
*pipe
,
212 const struct pipe_depth_stencil_alpha_state
*cso
)
214 struct nv30_zsa_stateobj
*so
;
216 so
= CALLOC_STRUCT(nv30_zsa_stateobj
);
221 SB_MTHD30(so
, DEPTH_FUNC
, 3);
222 SB_DATA (so
, nvgl_comparison_op(cso
->depth
.func
));
223 SB_DATA (so
, cso
->depth
.writemask
);
224 SB_DATA (so
, cso
->depth
.enabled
);
226 if (cso
->stencil
[0].enabled
) {
227 SB_MTHD30(so
, STENCIL_ENABLE(0), 3);
229 SB_DATA (so
, cso
->stencil
[0].writemask
);
230 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[0].func
));
231 SB_MTHD30(so
, STENCIL_FUNC_MASK(0), 4);
232 SB_DATA (so
, cso
->stencil
[0].valuemask
);
233 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
234 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
235 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
237 SB_MTHD30(so
, STENCIL_ENABLE(0), 2);
239 SB_DATA (so
, 0x000000ff);
242 if (cso
->stencil
[1].enabled
) {
243 SB_MTHD30(so
, STENCIL_ENABLE(1), 3);
245 SB_DATA (so
, cso
->stencil
[1].writemask
);
246 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[1].func
));
247 SB_MTHD30(so
, STENCIL_FUNC_MASK(1), 4);
248 SB_DATA (so
, cso
->stencil
[1].valuemask
);
249 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
250 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
251 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
253 SB_MTHD30(so
, STENCIL_ENABLE(1), 1);
257 SB_MTHD30(so
, ALPHA_FUNC_ENABLE
, 3);
258 SB_DATA (so
, cso
->alpha
.enabled
? 1 : 0);
259 SB_DATA (so
, nvgl_comparison_op(cso
->alpha
.func
));
260 SB_DATA (so
, float_to_ubyte(cso
->alpha
.ref_value
));
266 nv30_zsa_state_bind(struct pipe_context
*pipe
, void *hwcso
)
268 struct nv30_context
*nv30
= nv30_context(pipe
);
271 nv30
->dirty
|= NV30_NEW_ZSA
;
275 nv30_zsa_state_delete(struct pipe_context
*pipe
, void *hwcso
)
281 nv30_set_blend_color(struct pipe_context
*pipe
,
282 const struct pipe_blend_color
*bcol
)
284 struct nv30_context
*nv30
= nv30_context(pipe
);
286 nv30
->blend_colour
= *bcol
;
287 nv30
->dirty
|= NV30_NEW_BLEND_COLOUR
;
291 nv30_set_stencil_ref(struct pipe_context
*pipe
,
292 const struct pipe_stencil_ref
*sr
)
294 struct nv30_context
*nv30
= nv30_context(pipe
);
296 nv30
->stencil_ref
= *sr
;
297 nv30
->dirty
|= NV30_NEW_STENCIL_REF
;
301 nv30_set_clip_state(struct pipe_context
*pipe
,
302 const struct pipe_clip_state
*clip
)
304 struct nv30_context
*nv30
= nv30_context(pipe
);
306 memcpy(nv30
->clip
.ucp
, clip
->ucp
, sizeof(clip
->ucp
));
308 nv30
->dirty
|= NV30_NEW_CLIP
;
312 nv30_set_sample_mask(struct pipe_context
*pipe
, unsigned sample_mask
)
314 struct nv30_context
*nv30
= nv30_context(pipe
);
316 nv30
->sample_mask
= sample_mask
;
317 nv30
->dirty
|= NV30_NEW_SAMPLE_MASK
;
321 nv30_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
322 struct pipe_constant_buffer
*cb
)
324 struct nv30_context
*nv30
= nv30_context(pipe
);
325 struct pipe_resource
*buf
= cb
? cb
->buffer
: NULL
;
328 if (cb
&& cb
->user_buffer
) {
329 buf
= nouveau_user_buffer_create(pipe
->screen
, (void*)cb
->user_buffer
,
331 PIPE_BIND_CONSTANT_BUFFER
);
336 size
= buf
->width0
/ (4 * sizeof(float));
338 if (shader
== PIPE_SHADER_VERTEX
) {
339 pipe_resource_reference(&nv30
->vertprog
.constbuf
, buf
);
340 nv30
->vertprog
.constbuf_nr
= size
;
341 nv30
->dirty
|= NV30_NEW_VERTCONST
;
343 if (shader
== PIPE_SHADER_FRAGMENT
) {
344 pipe_resource_reference(&nv30
->fragprog
.constbuf
, buf
);
345 nv30
->fragprog
.constbuf_nr
= size
;
346 nv30
->dirty
|= NV30_NEW_FRAGCONST
;
349 if (cb
&& cb
->user_buffer
) {
350 pipe_resource_reference(&buf
, NULL
);
355 nv30_set_framebuffer_state(struct pipe_context
*pipe
,
356 const struct pipe_framebuffer_state
*fb
)
358 struct nv30_context
*nv30
= nv30_context(pipe
);
360 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_FB
);
362 nv30
->framebuffer
= *fb
;
363 nv30
->dirty
|= NV30_NEW_FRAMEBUFFER
;
365 /* Hardware can't handle different swizzled-ness or different blocksizes
366 * for zs and cbufs. If both are supplied and something doesn't match,
367 * blank out the zs for now so that at least *some* rendering can occur.
369 if (fb
->nr_cbufs
> 0 && fb
->zsbuf
) {
370 struct nv30_miptree
*color_mt
= nv30_miptree(fb
->cbufs
[0]->texture
);
371 struct nv30_miptree
*zeta_mt
= nv30_miptree(fb
->zsbuf
->texture
);
373 if (color_mt
->swizzled
!= zeta_mt
->swizzled
||
374 (util_format_get_blocksize(fb
->zsbuf
->format
) > 2) !=
375 (util_format_get_blocksize(fb
->cbufs
[0]->format
) > 2)) {
376 nv30
->framebuffer
.zsbuf
= NULL
;
377 debug_printf("Mismatched color and zeta formats, ignoring zeta.\n");
383 nv30_set_polygon_stipple(struct pipe_context
*pipe
,
384 const struct pipe_poly_stipple
*stipple
)
386 struct nv30_context
*nv30
= nv30_context(pipe
);
388 nv30
->stipple
= *stipple
;
389 nv30
->dirty
|= NV30_NEW_STIPPLE
;
393 nv30_set_scissor_states(struct pipe_context
*pipe
,
395 unsigned num_viewports
,
396 const struct pipe_scissor_state
*scissor
)
398 struct nv30_context
*nv30
= nv30_context(pipe
);
400 nv30
->scissor
= *scissor
;
401 nv30
->dirty
|= NV30_NEW_SCISSOR
;
405 nv30_set_viewport_states(struct pipe_context
*pipe
,
407 unsigned num_viewports
,
408 const struct pipe_viewport_state
*vpt
)
410 struct nv30_context
*nv30
= nv30_context(pipe
);
412 nv30
->viewport
= *vpt
;
413 nv30
->dirty
|= NV30_NEW_VIEWPORT
;
417 nv30_set_vertex_buffers(struct pipe_context
*pipe
,
418 unsigned start_slot
, unsigned count
,
419 const struct pipe_vertex_buffer
*vb
)
421 struct nv30_context
*nv30
= nv30_context(pipe
);
423 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_VTXBUF
);
425 util_set_vertex_buffers_count(nv30
->vtxbuf
, &nv30
->num_vtxbufs
,
426 vb
, start_slot
, count
);
428 nv30
->dirty
|= NV30_NEW_ARRAYS
;
432 nv30_set_index_buffer(struct pipe_context
*pipe
,
433 const struct pipe_index_buffer
*ib
)
435 struct nv30_context
*nv30
= nv30_context(pipe
);
438 pipe_resource_reference(&nv30
->idxbuf
.buffer
, ib
->buffer
);
439 nv30
->idxbuf
.index_size
= ib
->index_size
;
440 nv30
->idxbuf
.offset
= ib
->offset
;
441 nv30
->idxbuf
.user_buffer
= ib
->user_buffer
;
443 pipe_resource_reference(&nv30
->idxbuf
.buffer
, NULL
);
444 nv30
->idxbuf
.user_buffer
= NULL
;
449 nv30_state_init(struct pipe_context
*pipe
)
451 pipe
->create_blend_state
= nv30_blend_state_create
;
452 pipe
->bind_blend_state
= nv30_blend_state_bind
;
453 pipe
->delete_blend_state
= nv30_blend_state_delete
;
455 pipe
->create_rasterizer_state
= nv30_rasterizer_state_create
;
456 pipe
->bind_rasterizer_state
= nv30_rasterizer_state_bind
;
457 pipe
->delete_rasterizer_state
= nv30_rasterizer_state_delete
;
459 pipe
->create_depth_stencil_alpha_state
= nv30_zsa_state_create
;
460 pipe
->bind_depth_stencil_alpha_state
= nv30_zsa_state_bind
;
461 pipe
->delete_depth_stencil_alpha_state
= nv30_zsa_state_delete
;
463 pipe
->set_blend_color
= nv30_set_blend_color
;
464 pipe
->set_stencil_ref
= nv30_set_stencil_ref
;
465 pipe
->set_clip_state
= nv30_set_clip_state
;
466 pipe
->set_sample_mask
= nv30_set_sample_mask
;
467 pipe
->set_constant_buffer
= nv30_set_constant_buffer
;
468 pipe
->set_framebuffer_state
= nv30_set_framebuffer_state
;
469 pipe
->set_polygon_stipple
= nv30_set_polygon_stipple
;
470 pipe
->set_scissor_states
= nv30_set_scissor_states
;
471 pipe
->set_viewport_states
= nv30_set_viewport_states
;
473 pipe
->set_vertex_buffers
= nv30_set_vertex_buffers
;
474 pipe
->set_index_buffer
= nv30_set_index_buffer
;