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 nouveau_object
*eng3d
= nv30_context(pipe
)->screen
->eng3d
;
215 struct nv30_zsa_stateobj
*so
;
217 so
= CALLOC_STRUCT(nv30_zsa_stateobj
);
222 SB_MTHD30(so
, DEPTH_FUNC
, 3);
223 SB_DATA (so
, nvgl_comparison_op(cso
->depth
.func
));
224 SB_DATA (so
, cso
->depth
.writemask
);
225 SB_DATA (so
, cso
->depth
.enabled
);
227 if (eng3d
->oclass
== NV35_3D_CLASS
|| eng3d
->oclass
>= NV40_3D_CLASS
) {
228 SB_MTHD35(so
, DEPTH_BOUNDS_TEST_ENABLE
, 3);
229 SB_DATA (so
, cso
->depth
.bounds_test
);
230 SB_DATA (so
, fui(cso
->depth
.bounds_min
));
231 SB_DATA (so
, fui(cso
->depth
.bounds_max
));
234 if (cso
->stencil
[0].enabled
) {
235 SB_MTHD30(so
, STENCIL_ENABLE(0), 3);
237 SB_DATA (so
, cso
->stencil
[0].writemask
);
238 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[0].func
));
239 SB_MTHD30(so
, STENCIL_FUNC_MASK(0), 4);
240 SB_DATA (so
, cso
->stencil
[0].valuemask
);
241 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
242 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
243 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
245 SB_MTHD30(so
, STENCIL_ENABLE(0), 2);
247 SB_DATA (so
, 0x000000ff);
250 if (cso
->stencil
[1].enabled
) {
251 SB_MTHD30(so
, STENCIL_ENABLE(1), 3);
253 SB_DATA (so
, cso
->stencil
[1].writemask
);
254 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[1].func
));
255 SB_MTHD30(so
, STENCIL_FUNC_MASK(1), 4);
256 SB_DATA (so
, cso
->stencil
[1].valuemask
);
257 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
258 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
259 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
261 SB_MTHD30(so
, STENCIL_ENABLE(1), 1);
265 SB_MTHD30(so
, ALPHA_FUNC_ENABLE
, 3);
266 SB_DATA (so
, cso
->alpha
.enabled
? 1 : 0);
267 SB_DATA (so
, nvgl_comparison_op(cso
->alpha
.func
));
268 SB_DATA (so
, float_to_ubyte(cso
->alpha
.ref_value
));
274 nv30_zsa_state_bind(struct pipe_context
*pipe
, void *hwcso
)
276 struct nv30_context
*nv30
= nv30_context(pipe
);
279 nv30
->dirty
|= NV30_NEW_ZSA
;
283 nv30_zsa_state_delete(struct pipe_context
*pipe
, void *hwcso
)
289 nv30_set_blend_color(struct pipe_context
*pipe
,
290 const struct pipe_blend_color
*bcol
)
292 struct nv30_context
*nv30
= nv30_context(pipe
);
294 nv30
->blend_colour
= *bcol
;
295 nv30
->dirty
|= NV30_NEW_BLEND_COLOUR
;
299 nv30_set_stencil_ref(struct pipe_context
*pipe
,
300 const struct pipe_stencil_ref
*sr
)
302 struct nv30_context
*nv30
= nv30_context(pipe
);
304 nv30
->stencil_ref
= *sr
;
305 nv30
->dirty
|= NV30_NEW_STENCIL_REF
;
309 nv30_set_clip_state(struct pipe_context
*pipe
,
310 const struct pipe_clip_state
*clip
)
312 struct nv30_context
*nv30
= nv30_context(pipe
);
314 memcpy(nv30
->clip
.ucp
, clip
->ucp
, sizeof(clip
->ucp
));
316 nv30
->dirty
|= NV30_NEW_CLIP
;
320 nv30_set_sample_mask(struct pipe_context
*pipe
, unsigned sample_mask
)
322 struct nv30_context
*nv30
= nv30_context(pipe
);
324 nv30
->sample_mask
= sample_mask
;
325 nv30
->dirty
|= NV30_NEW_SAMPLE_MASK
;
329 nv30_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
330 struct pipe_constant_buffer
*cb
)
332 struct nv30_context
*nv30
= nv30_context(pipe
);
333 struct pipe_resource
*buf
= cb
? cb
->buffer
: NULL
;
336 if (cb
&& cb
->user_buffer
) {
337 buf
= nouveau_user_buffer_create(pipe
->screen
, (void*)cb
->user_buffer
,
339 PIPE_BIND_CONSTANT_BUFFER
);
344 size
= buf
->width0
/ (4 * sizeof(float));
346 if (shader
== PIPE_SHADER_VERTEX
) {
347 pipe_resource_reference(&nv30
->vertprog
.constbuf
, buf
);
348 nv30
->vertprog
.constbuf_nr
= size
;
349 nv30
->dirty
|= NV30_NEW_VERTCONST
;
351 if (shader
== PIPE_SHADER_FRAGMENT
) {
352 pipe_resource_reference(&nv30
->fragprog
.constbuf
, buf
);
353 nv30
->fragprog
.constbuf_nr
= size
;
354 nv30
->dirty
|= NV30_NEW_FRAGCONST
;
357 if (cb
&& cb
->user_buffer
) {
358 pipe_resource_reference(&buf
, NULL
);
363 nv30_set_framebuffer_state(struct pipe_context
*pipe
,
364 const struct pipe_framebuffer_state
*fb
)
366 struct nv30_context
*nv30
= nv30_context(pipe
);
368 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_FB
);
370 nv30
->framebuffer
= *fb
;
371 nv30
->dirty
|= NV30_NEW_FRAMEBUFFER
;
373 /* Hardware can't handle different swizzled-ness or different blocksizes
374 * for zs and cbufs. If both are supplied and something doesn't match,
375 * blank out the zs for now so that at least *some* rendering can occur.
377 if (fb
->nr_cbufs
> 0 && fb
->zsbuf
) {
378 struct nv30_miptree
*color_mt
= nv30_miptree(fb
->cbufs
[0]->texture
);
379 struct nv30_miptree
*zeta_mt
= nv30_miptree(fb
->zsbuf
->texture
);
381 if (color_mt
->swizzled
!= zeta_mt
->swizzled
||
382 (util_format_get_blocksize(fb
->zsbuf
->format
) > 2) !=
383 (util_format_get_blocksize(fb
->cbufs
[0]->format
) > 2)) {
384 nv30
->framebuffer
.zsbuf
= NULL
;
385 debug_printf("Mismatched color and zeta formats, ignoring zeta.\n");
391 nv30_set_polygon_stipple(struct pipe_context
*pipe
,
392 const struct pipe_poly_stipple
*stipple
)
394 struct nv30_context
*nv30
= nv30_context(pipe
);
396 nv30
->stipple
= *stipple
;
397 nv30
->dirty
|= NV30_NEW_STIPPLE
;
401 nv30_set_scissor_states(struct pipe_context
*pipe
,
403 unsigned num_viewports
,
404 const struct pipe_scissor_state
*scissor
)
406 struct nv30_context
*nv30
= nv30_context(pipe
);
408 nv30
->scissor
= *scissor
;
409 nv30
->dirty
|= NV30_NEW_SCISSOR
;
413 nv30_set_viewport_states(struct pipe_context
*pipe
,
415 unsigned num_viewports
,
416 const struct pipe_viewport_state
*vpt
)
418 struct nv30_context
*nv30
= nv30_context(pipe
);
420 nv30
->viewport
= *vpt
;
421 nv30
->dirty
|= NV30_NEW_VIEWPORT
;
425 nv30_set_vertex_buffers(struct pipe_context
*pipe
,
426 unsigned start_slot
, unsigned count
,
427 const struct pipe_vertex_buffer
*vb
)
429 struct nv30_context
*nv30
= nv30_context(pipe
);
431 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_VTXBUF
);
433 util_set_vertex_buffers_count(nv30
->vtxbuf
, &nv30
->num_vtxbufs
,
434 vb
, start_slot
, count
);
436 nv30
->dirty
|= NV30_NEW_ARRAYS
;
440 nv30_set_index_buffer(struct pipe_context
*pipe
,
441 const struct pipe_index_buffer
*ib
)
443 struct nv30_context
*nv30
= nv30_context(pipe
);
446 pipe_resource_reference(&nv30
->idxbuf
.buffer
, ib
->buffer
);
447 nv30
->idxbuf
.index_size
= ib
->index_size
;
448 nv30
->idxbuf
.offset
= ib
->offset
;
449 nv30
->idxbuf
.user_buffer
= ib
->user_buffer
;
451 pipe_resource_reference(&nv30
->idxbuf
.buffer
, NULL
);
452 nv30
->idxbuf
.user_buffer
= NULL
;
457 nv30_state_init(struct pipe_context
*pipe
)
459 pipe
->create_blend_state
= nv30_blend_state_create
;
460 pipe
->bind_blend_state
= nv30_blend_state_bind
;
461 pipe
->delete_blend_state
= nv30_blend_state_delete
;
463 pipe
->create_rasterizer_state
= nv30_rasterizer_state_create
;
464 pipe
->bind_rasterizer_state
= nv30_rasterizer_state_bind
;
465 pipe
->delete_rasterizer_state
= nv30_rasterizer_state_delete
;
467 pipe
->create_depth_stencil_alpha_state
= nv30_zsa_state_create
;
468 pipe
->bind_depth_stencil_alpha_state
= nv30_zsa_state_bind
;
469 pipe
->delete_depth_stencil_alpha_state
= nv30_zsa_state_delete
;
471 pipe
->set_blend_color
= nv30_set_blend_color
;
472 pipe
->set_stencil_ref
= nv30_set_stencil_ref
;
473 pipe
->set_clip_state
= nv30_set_clip_state
;
474 pipe
->set_sample_mask
= nv30_set_sample_mask
;
475 pipe
->set_constant_buffer
= nv30_set_constant_buffer
;
476 pipe
->set_framebuffer_state
= nv30_set_framebuffer_state
;
477 pipe
->set_polygon_stipple
= nv30_set_polygon_stipple
;
478 pipe
->set_scissor_states
= nv30_set_scissor_states
;
479 pipe
->set_viewport_states
= nv30_set_viewport_states
;
481 pipe
->set_vertex_buffers
= nv30_set_vertex_buffers
;
482 pipe
->set_index_buffer
= nv30_set_index_buffer
;