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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 #include "util/u_inlines.h"
28 #include "nouveau/nouveau_gldefs.h"
29 #include "nouveau/nv_object.xml.h"
30 #include "nv30-40_3d.xml.h"
31 #include "nv30_context.h"
32 #include "nv30_winsys.h"
34 #define NV40_3D_MRT_BLEND_ENABLE 0x0000036c
37 nv30_blend_state_create(struct pipe_context
*pipe
,
38 const struct pipe_blend_state
*cso
)
40 struct nouveau_object
*eng3d
= nv30_context(pipe
)->screen
->eng3d
;
41 struct nv30_blend_stateobj
*so
;
42 uint32_t blend
[2], cmask
[2];
45 so
= CALLOC_STRUCT(nv30_blend_stateobj
);
50 if (cso
->logicop_enable
) {
51 SB_MTHD30(so
, COLOR_LOGIC_OP_ENABLE
, 2);
53 SB_DATA (so
, nvgl_logicop_func(cso
->logicop_func
));
55 SB_MTHD30(so
, COLOR_LOGIC_OP_ENABLE
, 1);
59 SB_MTHD30(so
, DITHER_ENABLE
, 1);
60 SB_DATA (so
, cso
->dither
);
62 blend
[0] = cso
->rt
[0].blend_enable
;
63 cmask
[0] = !!(cso
->rt
[0].colormask
& PIPE_MASK_A
) << 24 |
64 !!(cso
->rt
[0].colormask
& PIPE_MASK_R
) << 16 |
65 !!(cso
->rt
[0].colormask
& PIPE_MASK_G
) << 8 |
66 !!(cso
->rt
[0].colormask
& PIPE_MASK_B
);
67 if (cso
->independent_blend_enable
) {
70 for (i
= 1; i
< 4; i
++) {
71 blend
[1] |= cso
->rt
[i
].blend_enable
<< i
;
72 cmask
[1] |= !!(cso
->rt
[i
].colormask
& PIPE_MASK_A
) << (0 + (i
* 4)) |
73 !!(cso
->rt
[i
].colormask
& PIPE_MASK_R
) << (1 + (i
* 4)) |
74 !!(cso
->rt
[i
].colormask
& PIPE_MASK_G
) << (2 + (i
* 4)) |
75 !!(cso
->rt
[i
].colormask
& PIPE_MASK_B
) << (3 + (i
* 4));
78 blend
[1] = 0x0000000e * (blend
[0] & 0x00000001);
79 cmask
[1] = 0x00001110 * !!(cmask
[0] & 0x01000000);
80 cmask
[1] |= 0x00002220 * !!(cmask
[0] & 0x00010000);
81 cmask
[1] |= 0x00004440 * !!(cmask
[0] & 0x00000100);
82 cmask
[1] |= 0x00008880 * !!(cmask
[0] & 0x00000001);
85 if (eng3d
->oclass
>= NV40_3D_CLASS
) {
86 SB_MTHD40(so
, MRT_BLEND_ENABLE
, 2);
87 SB_DATA (so
, blend
[1]);
88 SB_DATA (so
, cmask
[1]);
91 if (blend
[0] || blend
[1]) {
92 SB_MTHD30(so
, BLEND_FUNC_ENABLE
, 3);
93 SB_DATA (so
, blend
[0]);
94 SB_DATA (so
, (nvgl_blend_func(cso
->rt
[0].alpha_src_factor
) << 16) |
95 nvgl_blend_func(cso
->rt
[0].rgb_src_factor
));
96 SB_DATA (so
, (nvgl_blend_func(cso
->rt
[0].alpha_dst_factor
) << 16) |
97 nvgl_blend_func(cso
->rt
[0].rgb_dst_factor
));
98 if (eng3d
->oclass
< NV40_3D_CLASS
) {
99 SB_MTHD30(so
, BLEND_EQUATION
, 1);
100 SB_DATA (so
, nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
102 SB_MTHD40(so
, BLEND_EQUATION
, 1);
103 SB_DATA (so
, (nvgl_blend_eqn(cso
->rt
[0].alpha_func
) << 16) |
104 nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
107 SB_MTHD30(so
, BLEND_FUNC_ENABLE
, 1);
108 SB_DATA (so
, blend
[0]);
111 SB_MTHD30(so
, COLOR_MASK
, 1);
112 SB_DATA (so
, cmask
[0]);
117 nv30_blend_state_bind(struct pipe_context
*pipe
, void *hwcso
)
119 struct nv30_context
*nv30
= nv30_context(pipe
);
122 nv30
->dirty
|= NV30_NEW_BLEND
;
126 nv30_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
132 nv30_rasterizer_state_create(struct pipe_context
*pipe
,
133 const struct pipe_rasterizer_state
*cso
)
135 struct nv30_rasterizer_stateobj
*so
;
137 so
= CALLOC_STRUCT(nv30_rasterizer_stateobj
);
142 SB_MTHD30(so
, SHADE_MODEL
, 1);
143 SB_DATA (so
, cso
->flatshade
? NV30_3D_SHADE_MODEL_FLAT
:
144 NV30_3D_SHADE_MODEL_SMOOTH
);
146 SB_MTHD30(so
, POLYGON_MODE_FRONT
, 6);
147 SB_DATA (so
, nvgl_polygon_mode(cso
->fill_front
));
148 SB_DATA (so
, nvgl_polygon_mode(cso
->fill_back
));
149 if (cso
->cull_face
== PIPE_FACE_FRONT_AND_BACK
)
150 SB_DATA (so
, NV30_3D_CULL_FACE_FRONT_AND_BACK
);
152 if (cso
->cull_face
== PIPE_FACE_FRONT
)
153 SB_DATA (so
, NV30_3D_CULL_FACE_FRONT
);
155 SB_DATA (so
, NV30_3D_CULL_FACE_BACK
);
156 SB_DATA (so
, cso
->front_ccw
? NV30_3D_FRONT_FACE_CCW
:
157 NV30_3D_FRONT_FACE_CW
);
158 SB_DATA (so
, cso
->poly_smooth
);
159 SB_DATA (so
, cso
->cull_face
!= PIPE_FACE_NONE
);
161 SB_MTHD30(so
, POLYGON_OFFSET_POINT_ENABLE
, 3);
162 SB_DATA (so
, cso
->offset_point
);
163 SB_DATA (so
, cso
->offset_line
);
164 SB_DATA (so
, cso
->offset_tri
);
165 if (cso
->offset_point
|| cso
->offset_line
|| cso
->offset_tri
) {
166 SB_MTHD30(so
, POLYGON_OFFSET_FACTOR
, 2);
167 SB_DATA (so
, fui(cso
->offset_scale
));
168 SB_DATA (so
, fui(cso
->offset_units
* 2.0));
171 SB_MTHD30(so
, LINE_WIDTH
, 2);
172 SB_DATA (so
, (unsigned char)(cso
->line_width
* 8.0) & 0xff);
173 SB_DATA (so
, cso
->line_smooth
);
174 SB_MTHD30(so
, LINE_STIPPLE_ENABLE
, 2);
175 SB_DATA (so
, cso
->line_stipple_enable
);
176 SB_DATA (so
, (cso
->line_stipple_pattern
<< 16) |
177 cso
->line_stipple_factor
);
179 SB_MTHD30(so
, VERTEX_TWO_SIDE_ENABLE
, 1);
180 SB_DATA (so
, cso
->light_twoside
);
181 SB_MTHD30(so
, POLYGON_STIPPLE_ENABLE
, 1);
182 SB_DATA (so
, cso
->poly_stipple_enable
);
183 SB_MTHD30(so
, POINT_SIZE
, 1);
184 SB_DATA (so
, fui(cso
->point_size
));
185 SB_MTHD30(so
, FLATSHADE_FIRST
, 1);
186 SB_DATA (so
, cso
->flatshade_first
);
188 SB_MTHD30(so
, DEPTH_CONTROL
, 1);
189 SB_DATA (so
, cso
->depth_clip
? 0x00000001 : 0x00000010);
194 nv30_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
196 struct nv30_context
*nv30
= nv30_context(pipe
);
199 nv30
->dirty
|= NV30_NEW_RASTERIZER
;
203 nv30_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
209 nv30_zsa_state_create(struct pipe_context
*pipe
,
210 const struct pipe_depth_stencil_alpha_state
*cso
)
212 struct nv30_zsa_stateobj
*so
;
214 so
= CALLOC_STRUCT(nv30_zsa_stateobj
);
219 SB_MTHD30(so
, DEPTH_FUNC
, 3);
220 SB_DATA (so
, nvgl_comparison_op(cso
->depth
.func
));
221 SB_DATA (so
, cso
->depth
.writemask
);
222 SB_DATA (so
, cso
->depth
.enabled
);
224 if (cso
->stencil
[0].enabled
) {
225 SB_MTHD30(so
, STENCIL_ENABLE(0), 3);
227 SB_DATA (so
, cso
->stencil
[0].writemask
);
228 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[0].func
));
229 SB_MTHD30(so
, STENCIL_FUNC_MASK(0), 4);
230 SB_DATA (so
, cso
->stencil
[0].valuemask
);
231 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
232 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
233 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
235 SB_MTHD30(so
, STENCIL_ENABLE(0), 2);
237 SB_DATA (so
, 0x000000ff);
240 if (cso
->stencil
[1].enabled
) {
241 SB_MTHD30(so
, STENCIL_ENABLE(1), 3);
243 SB_DATA (so
, cso
->stencil
[1].writemask
);
244 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[1].func
));
245 SB_MTHD30(so
, STENCIL_FUNC_MASK(1), 4);
246 SB_DATA (so
, cso
->stencil
[1].valuemask
);
247 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
248 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
249 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
251 SB_MTHD30(so
, STENCIL_ENABLE(1), 1);
255 SB_MTHD30(so
, ALPHA_FUNC_ENABLE
, 3);
256 SB_DATA (so
, cso
->alpha
.enabled
? 1 : 0);
257 SB_DATA (so
, nvgl_comparison_op(cso
->alpha
.func
));
258 SB_DATA (so
, float_to_ubyte(cso
->alpha
.ref_value
));
264 nv30_zsa_state_bind(struct pipe_context
*pipe
, void *hwcso
)
266 struct nv30_context
*nv30
= nv30_context(pipe
);
269 nv30
->dirty
|= NV30_NEW_ZSA
;
273 nv30_zsa_state_delete(struct pipe_context
*pipe
, void *hwcso
)
279 nv30_set_blend_color(struct pipe_context
*pipe
,
280 const struct pipe_blend_color
*bcol
)
282 struct nv30_context
*nv30
= nv30_context(pipe
);
284 nv30
->blend_colour
= *bcol
;
285 nv30
->dirty
|= NV30_NEW_BLEND_COLOUR
;
289 nv30_set_stencil_ref(struct pipe_context
*pipe
,
290 const struct pipe_stencil_ref
*sr
)
292 struct nv30_context
*nv30
= nv30_context(pipe
);
294 nv30
->stencil_ref
= *sr
;
295 nv30
->dirty
|= NV30_NEW_STENCIL_REF
;
299 nv30_set_clip_state(struct pipe_context
*pipe
,
300 const struct pipe_clip_state
*clip
)
302 struct nv30_context
*nv30
= nv30_context(pipe
);
304 memcpy(nv30
->clip
.ucp
, clip
->ucp
, sizeof(clip
->ucp
));
306 nv30
->dirty
|= NV30_NEW_CLIP
;
310 nv30_set_sample_mask(struct pipe_context
*pipe
, unsigned sample_mask
)
312 struct nv30_context
*nv30
= nv30_context(pipe
);
314 nv30
->sample_mask
= sample_mask
;
315 nv30
->dirty
|= NV30_NEW_SAMPLE_MASK
;
319 nv30_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
320 struct pipe_resource
*buf
)
322 struct nv30_context
*nv30
= nv30_context(pipe
);
327 size
= buf
->width0
/ (4 * sizeof(float));
329 if (shader
== PIPE_SHADER_VERTEX
) {
330 pipe_resource_reference(&nv30
->vertprog
.constbuf
, buf
);
331 nv30
->vertprog
.constbuf_nr
= size
;
332 nv30
->dirty
|= NV30_NEW_VERTCONST
;
334 if (shader
== PIPE_SHADER_FRAGMENT
) {
335 pipe_resource_reference(&nv30
->fragprog
.constbuf
, buf
);
336 nv30
->fragprog
.constbuf_nr
= size
;
337 nv30
->dirty
|= NV30_NEW_FRAGCONST
;
342 nv30_set_framebuffer_state(struct pipe_context
*pipe
,
343 const struct pipe_framebuffer_state
*fb
)
345 struct nv30_context
*nv30
= nv30_context(pipe
);
347 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_FB
);
349 nv30
->framebuffer
= *fb
;
350 nv30
->dirty
|= NV30_NEW_FRAMEBUFFER
;
354 nv30_set_polygon_stipple(struct pipe_context
*pipe
,
355 const struct pipe_poly_stipple
*stipple
)
357 struct nv30_context
*nv30
= nv30_context(pipe
);
359 nv30
->stipple
= *stipple
;
360 nv30
->dirty
|= NV30_NEW_STIPPLE
;
364 nv30_set_scissor_state(struct pipe_context
*pipe
,
365 const struct pipe_scissor_state
*scissor
)
367 struct nv30_context
*nv30
= nv30_context(pipe
);
369 nv30
->scissor
= *scissor
;
370 nv30
->dirty
|= NV30_NEW_SCISSOR
;
374 nv30_set_viewport_state(struct pipe_context
*pipe
,
375 const struct pipe_viewport_state
*vpt
)
377 struct nv30_context
*nv30
= nv30_context(pipe
);
379 nv30
->viewport
= *vpt
;
380 nv30
->dirty
|= NV30_NEW_VIEWPORT
;
384 nv30_set_vertex_buffers(struct pipe_context
*pipe
,
386 const struct pipe_vertex_buffer
*vb
)
388 struct nv30_context
*nv30
= nv30_context(pipe
);
391 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_VTXBUF
);
393 for (i
= 0; i
< count
; ++i
)
394 pipe_resource_reference(&nv30
->vtxbuf
[i
].buffer
, vb
[i
].buffer
);
395 for (; i
< nv30
->num_vtxbufs
; ++i
)
396 pipe_resource_reference(&nv30
->vtxbuf
[i
].buffer
, NULL
);
398 memcpy(nv30
->vtxbuf
, vb
, sizeof(*vb
) * count
);
399 nv30
->num_vtxbufs
= count
;
401 nv30
->dirty
|= NV30_NEW_ARRAYS
;
405 nv30_set_index_buffer(struct pipe_context
*pipe
,
406 const struct pipe_index_buffer
*ib
)
408 struct nv30_context
*nv30
= nv30_context(pipe
);
411 pipe_resource_reference(&nv30
->idxbuf
.buffer
, ib
->buffer
);
412 memcpy(&nv30
->idxbuf
, ib
, sizeof(nv30
->idxbuf
));
414 pipe_resource_reference(&nv30
->idxbuf
.buffer
, NULL
);
419 nv30_state_init(struct pipe_context
*pipe
)
421 pipe
->create_blend_state
= nv30_blend_state_create
;
422 pipe
->bind_blend_state
= nv30_blend_state_bind
;
423 pipe
->delete_blend_state
= nv30_blend_state_delete
;
425 pipe
->create_rasterizer_state
= nv30_rasterizer_state_create
;
426 pipe
->bind_rasterizer_state
= nv30_rasterizer_state_bind
;
427 pipe
->delete_rasterizer_state
= nv30_rasterizer_state_delete
;
429 pipe
->create_depth_stencil_alpha_state
= nv30_zsa_state_create
;
430 pipe
->bind_depth_stencil_alpha_state
= nv30_zsa_state_bind
;
431 pipe
->delete_depth_stencil_alpha_state
= nv30_zsa_state_delete
;
433 pipe
->set_blend_color
= nv30_set_blend_color
;
434 pipe
->set_stencil_ref
= nv30_set_stencil_ref
;
435 pipe
->set_clip_state
= nv30_set_clip_state
;
436 pipe
->set_sample_mask
= nv30_set_sample_mask
;
437 pipe
->set_constant_buffer
= nv30_set_constant_buffer
;
438 pipe
->set_framebuffer_state
= nv30_set_framebuffer_state
;
439 pipe
->set_polygon_stipple
= nv30_set_polygon_stipple
;
440 pipe
->set_scissor_state
= nv30_set_scissor_state
;
441 pipe
->set_viewport_state
= nv30_set_viewport_state
;
443 pipe
->set_vertex_buffers
= nv30_set_vertex_buffers
;
444 pipe
->set_index_buffer
= nv30_set_index_buffer
;
446 pipe
->redefine_user_buffer
= u_default_redefine_user_buffer
;