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_helpers.h"
27 #include "util/u_inlines.h"
29 #include "nouveau/nouveau_gldefs.h"
30 #include "nouveau/nv_object.xml.h"
31 #include "nv30-40_3d.xml.h"
32 #include "nv30_context.h"
33 #include "nv30_winsys.h"
35 #define NV40_3D_MRT_BLEND_ENABLE 0x0000036c
38 nv30_blend_state_create(struct pipe_context
*pipe
,
39 const struct pipe_blend_state
*cso
)
41 struct nouveau_object
*eng3d
= nv30_context(pipe
)->screen
->eng3d
;
42 struct nv30_blend_stateobj
*so
;
43 uint32_t blend
[2], cmask
[2];
46 so
= CALLOC_STRUCT(nv30_blend_stateobj
);
51 if (cso
->logicop_enable
) {
52 SB_MTHD30(so
, COLOR_LOGIC_OP_ENABLE
, 2);
54 SB_DATA (so
, nvgl_logicop_func(cso
->logicop_func
));
56 SB_MTHD30(so
, COLOR_LOGIC_OP_ENABLE
, 1);
60 SB_MTHD30(so
, DITHER_ENABLE
, 1);
61 SB_DATA (so
, cso
->dither
);
63 blend
[0] = cso
->rt
[0].blend_enable
;
64 cmask
[0] = !!(cso
->rt
[0].colormask
& PIPE_MASK_A
) << 24 |
65 !!(cso
->rt
[0].colormask
& PIPE_MASK_R
) << 16 |
66 !!(cso
->rt
[0].colormask
& PIPE_MASK_G
) << 8 |
67 !!(cso
->rt
[0].colormask
& PIPE_MASK_B
);
68 if (cso
->independent_blend_enable
) {
71 for (i
= 1; i
< 4; i
++) {
72 blend
[1] |= cso
->rt
[i
].blend_enable
<< i
;
73 cmask
[1] |= !!(cso
->rt
[i
].colormask
& PIPE_MASK_A
) << (0 + (i
* 4)) |
74 !!(cso
->rt
[i
].colormask
& PIPE_MASK_R
) << (1 + (i
* 4)) |
75 !!(cso
->rt
[i
].colormask
& PIPE_MASK_G
) << (2 + (i
* 4)) |
76 !!(cso
->rt
[i
].colormask
& PIPE_MASK_B
) << (3 + (i
* 4));
79 blend
[1] = 0x0000000e * (blend
[0] & 0x00000001);
80 cmask
[1] = 0x00001110 * !!(cmask
[0] & 0x01000000);
81 cmask
[1] |= 0x00002220 * !!(cmask
[0] & 0x00010000);
82 cmask
[1] |= 0x00004440 * !!(cmask
[0] & 0x00000100);
83 cmask
[1] |= 0x00008880 * !!(cmask
[0] & 0x00000001);
86 if (eng3d
->oclass
>= NV40_3D_CLASS
) {
87 SB_MTHD40(so
, MRT_BLEND_ENABLE
, 2);
88 SB_DATA (so
, blend
[1]);
89 SB_DATA (so
, cmask
[1]);
92 if (blend
[0] || blend
[1]) {
93 SB_MTHD30(so
, BLEND_FUNC_ENABLE
, 3);
94 SB_DATA (so
, blend
[0]);
95 SB_DATA (so
, (nvgl_blend_func(cso
->rt
[0].alpha_src_factor
) << 16) |
96 nvgl_blend_func(cso
->rt
[0].rgb_src_factor
));
97 SB_DATA (so
, (nvgl_blend_func(cso
->rt
[0].alpha_dst_factor
) << 16) |
98 nvgl_blend_func(cso
->rt
[0].rgb_dst_factor
));
99 if (eng3d
->oclass
< NV40_3D_CLASS
) {
100 SB_MTHD30(so
, BLEND_EQUATION
, 1);
101 SB_DATA (so
, nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
103 SB_MTHD40(so
, BLEND_EQUATION
, 1);
104 SB_DATA (so
, (nvgl_blend_eqn(cso
->rt
[0].alpha_func
) << 16) |
105 nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
108 SB_MTHD30(so
, BLEND_FUNC_ENABLE
, 1);
109 SB_DATA (so
, blend
[0]);
112 SB_MTHD30(so
, COLOR_MASK
, 1);
113 SB_DATA (so
, cmask
[0]);
118 nv30_blend_state_bind(struct pipe_context
*pipe
, void *hwcso
)
120 struct nv30_context
*nv30
= nv30_context(pipe
);
123 nv30
->dirty
|= NV30_NEW_BLEND
;
127 nv30_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
133 nv30_rasterizer_state_create(struct pipe_context
*pipe
,
134 const struct pipe_rasterizer_state
*cso
)
136 struct nv30_rasterizer_stateobj
*so
;
138 so
= CALLOC_STRUCT(nv30_rasterizer_stateobj
);
143 SB_MTHD30(so
, SHADE_MODEL
, 1);
144 SB_DATA (so
, cso
->flatshade
? NV30_3D_SHADE_MODEL_FLAT
:
145 NV30_3D_SHADE_MODEL_SMOOTH
);
147 SB_MTHD30(so
, POLYGON_MODE_FRONT
, 6);
148 SB_DATA (so
, nvgl_polygon_mode(cso
->fill_front
));
149 SB_DATA (so
, nvgl_polygon_mode(cso
->fill_back
));
150 if (cso
->cull_face
== PIPE_FACE_FRONT_AND_BACK
)
151 SB_DATA (so
, NV30_3D_CULL_FACE_FRONT_AND_BACK
);
153 if (cso
->cull_face
== PIPE_FACE_FRONT
)
154 SB_DATA (so
, NV30_3D_CULL_FACE_FRONT
);
156 SB_DATA (so
, NV30_3D_CULL_FACE_BACK
);
157 SB_DATA (so
, cso
->front_ccw
? NV30_3D_FRONT_FACE_CCW
:
158 NV30_3D_FRONT_FACE_CW
);
159 SB_DATA (so
, cso
->poly_smooth
);
160 SB_DATA (so
, cso
->cull_face
!= PIPE_FACE_NONE
);
162 SB_MTHD30(so
, POLYGON_OFFSET_POINT_ENABLE
, 3);
163 SB_DATA (so
, cso
->offset_point
);
164 SB_DATA (so
, cso
->offset_line
);
165 SB_DATA (so
, cso
->offset_tri
);
166 if (cso
->offset_point
|| cso
->offset_line
|| cso
->offset_tri
) {
167 SB_MTHD30(so
, POLYGON_OFFSET_FACTOR
, 2);
168 SB_DATA (so
, fui(cso
->offset_scale
));
169 SB_DATA (so
, fui(cso
->offset_units
* 2.0));
172 SB_MTHD30(so
, LINE_WIDTH
, 2);
173 SB_DATA (so
, (unsigned char)(cso
->line_width
* 8.0) & 0xff);
174 SB_DATA (so
, cso
->line_smooth
);
175 SB_MTHD30(so
, LINE_STIPPLE_ENABLE
, 2);
176 SB_DATA (so
, cso
->line_stipple_enable
);
177 SB_DATA (so
, (cso
->line_stipple_pattern
<< 16) |
178 cso
->line_stipple_factor
);
180 SB_MTHD30(so
, VERTEX_TWO_SIDE_ENABLE
, 1);
181 SB_DATA (so
, cso
->light_twoside
);
182 SB_MTHD30(so
, POLYGON_STIPPLE_ENABLE
, 1);
183 SB_DATA (so
, cso
->poly_stipple_enable
);
184 SB_MTHD30(so
, POINT_SIZE
, 1);
185 SB_DATA (so
, fui(cso
->point_size
));
186 SB_MTHD30(so
, FLATSHADE_FIRST
, 1);
187 SB_DATA (so
, cso
->flatshade_first
);
189 SB_MTHD30(so
, DEPTH_CONTROL
, 1);
190 SB_DATA (so
, cso
->depth_clip
? 0x00000001 : 0x00000010);
195 nv30_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
197 struct nv30_context
*nv30
= nv30_context(pipe
);
200 nv30
->dirty
|= NV30_NEW_RASTERIZER
;
204 nv30_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
210 nv30_zsa_state_create(struct pipe_context
*pipe
,
211 const struct pipe_depth_stencil_alpha_state
*cso
)
213 struct nv30_zsa_stateobj
*so
;
215 so
= CALLOC_STRUCT(nv30_zsa_stateobj
);
220 SB_MTHD30(so
, DEPTH_FUNC
, 3);
221 SB_DATA (so
, nvgl_comparison_op(cso
->depth
.func
));
222 SB_DATA (so
, cso
->depth
.writemask
);
223 SB_DATA (so
, cso
->depth
.enabled
);
225 if (cso
->stencil
[0].enabled
) {
226 SB_MTHD30(so
, STENCIL_ENABLE(0), 3);
228 SB_DATA (so
, cso
->stencil
[0].writemask
);
229 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[0].func
));
230 SB_MTHD30(so
, STENCIL_FUNC_MASK(0), 4);
231 SB_DATA (so
, cso
->stencil
[0].valuemask
);
232 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
233 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
234 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
236 SB_MTHD30(so
, STENCIL_ENABLE(0), 2);
238 SB_DATA (so
, 0x000000ff);
241 if (cso
->stencil
[1].enabled
) {
242 SB_MTHD30(so
, STENCIL_ENABLE(1), 3);
244 SB_DATA (so
, cso
->stencil
[1].writemask
);
245 SB_DATA (so
, nvgl_comparison_op(cso
->stencil
[1].func
));
246 SB_MTHD30(so
, STENCIL_FUNC_MASK(1), 4);
247 SB_DATA (so
, cso
->stencil
[1].valuemask
);
248 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
249 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
250 SB_DATA (so
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
252 SB_MTHD30(so
, STENCIL_ENABLE(1), 1);
256 SB_MTHD30(so
, ALPHA_FUNC_ENABLE
, 3);
257 SB_DATA (so
, cso
->alpha
.enabled
? 1 : 0);
258 SB_DATA (so
, nvgl_comparison_op(cso
->alpha
.func
));
259 SB_DATA (so
, float_to_ubyte(cso
->alpha
.ref_value
));
265 nv30_zsa_state_bind(struct pipe_context
*pipe
, void *hwcso
)
267 struct nv30_context
*nv30
= nv30_context(pipe
);
270 nv30
->dirty
|= NV30_NEW_ZSA
;
274 nv30_zsa_state_delete(struct pipe_context
*pipe
, void *hwcso
)
280 nv30_set_blend_color(struct pipe_context
*pipe
,
281 const struct pipe_blend_color
*bcol
)
283 struct nv30_context
*nv30
= nv30_context(pipe
);
285 nv30
->blend_colour
= *bcol
;
286 nv30
->dirty
|= NV30_NEW_BLEND_COLOUR
;
290 nv30_set_stencil_ref(struct pipe_context
*pipe
,
291 const struct pipe_stencil_ref
*sr
)
293 struct nv30_context
*nv30
= nv30_context(pipe
);
295 nv30
->stencil_ref
= *sr
;
296 nv30
->dirty
|= NV30_NEW_STENCIL_REF
;
300 nv30_set_clip_state(struct pipe_context
*pipe
,
301 const struct pipe_clip_state
*clip
)
303 struct nv30_context
*nv30
= nv30_context(pipe
);
305 memcpy(nv30
->clip
.ucp
, clip
->ucp
, sizeof(clip
->ucp
));
307 nv30
->dirty
|= NV30_NEW_CLIP
;
311 nv30_set_sample_mask(struct pipe_context
*pipe
, unsigned sample_mask
)
313 struct nv30_context
*nv30
= nv30_context(pipe
);
315 nv30
->sample_mask
= sample_mask
;
316 nv30
->dirty
|= NV30_NEW_SAMPLE_MASK
;
320 nv30_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
321 struct pipe_constant_buffer
*cb
)
323 struct nv30_context
*nv30
= nv30_context(pipe
);
324 struct pipe_resource
*buf
= cb
? cb
->buffer
: NULL
;
327 if (cb
&& cb
->user_buffer
) {
328 buf
= nouveau_user_buffer_create(pipe
->screen
, (void*)cb
->user_buffer
,
330 PIPE_BIND_CONSTANT_BUFFER
);
335 size
= buf
->width0
/ (4 * sizeof(float));
337 if (shader
== PIPE_SHADER_VERTEX
) {
338 pipe_resource_reference(&nv30
->vertprog
.constbuf
, buf
);
339 nv30
->vertprog
.constbuf_nr
= size
;
340 nv30
->dirty
|= NV30_NEW_VERTCONST
;
342 if (shader
== PIPE_SHADER_FRAGMENT
) {
343 pipe_resource_reference(&nv30
->fragprog
.constbuf
, buf
);
344 nv30
->fragprog
.constbuf_nr
= size
;
345 nv30
->dirty
|= NV30_NEW_FRAGCONST
;
348 if (cb
&& cb
->user_buffer
) {
349 pipe_resource_reference(&buf
, NULL
);
354 nv30_set_framebuffer_state(struct pipe_context
*pipe
,
355 const struct pipe_framebuffer_state
*fb
)
357 struct nv30_context
*nv30
= nv30_context(pipe
);
359 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_FB
);
361 nv30
->framebuffer
= *fb
;
362 nv30
->dirty
|= NV30_NEW_FRAMEBUFFER
;
366 nv30_set_polygon_stipple(struct pipe_context
*pipe
,
367 const struct pipe_poly_stipple
*stipple
)
369 struct nv30_context
*nv30
= nv30_context(pipe
);
371 nv30
->stipple
= *stipple
;
372 nv30
->dirty
|= NV30_NEW_STIPPLE
;
376 nv30_set_scissor_state(struct pipe_context
*pipe
,
377 const struct pipe_scissor_state
*scissor
)
379 struct nv30_context
*nv30
= nv30_context(pipe
);
381 nv30
->scissor
= *scissor
;
382 nv30
->dirty
|= NV30_NEW_SCISSOR
;
386 nv30_set_viewport_state(struct pipe_context
*pipe
,
387 const struct pipe_viewport_state
*vpt
)
389 struct nv30_context
*nv30
= nv30_context(pipe
);
391 nv30
->viewport
= *vpt
;
392 nv30
->dirty
|= NV30_NEW_VIEWPORT
;
396 nv30_set_vertex_buffers(struct pipe_context
*pipe
,
397 unsigned start_slot
, unsigned count
,
398 const struct pipe_vertex_buffer
*vb
)
400 struct nv30_context
*nv30
= nv30_context(pipe
);
402 nouveau_bufctx_reset(nv30
->bufctx
, BUFCTX_VTXBUF
);
404 util_set_vertex_buffers_count(nv30
->vtxbuf
, &nv30
->num_vtxbufs
,
405 vb
, start_slot
, count
);
407 nv30
->dirty
|= NV30_NEW_ARRAYS
;
411 nv30_set_index_buffer(struct pipe_context
*pipe
,
412 const struct pipe_index_buffer
*ib
)
414 struct nv30_context
*nv30
= nv30_context(pipe
);
417 pipe_resource_reference(&nv30
->idxbuf
.buffer
, ib
->buffer
);
418 nv30
->idxbuf
.index_size
= ib
->index_size
;
419 nv30
->idxbuf
.offset
= ib
->offset
;
420 nv30
->idxbuf
.user_buffer
= ib
->user_buffer
;
422 pipe_resource_reference(&nv30
->idxbuf
.buffer
, NULL
);
423 nv30
->idxbuf
.user_buffer
= NULL
;
428 nv30_state_init(struct pipe_context
*pipe
)
430 pipe
->create_blend_state
= nv30_blend_state_create
;
431 pipe
->bind_blend_state
= nv30_blend_state_bind
;
432 pipe
->delete_blend_state
= nv30_blend_state_delete
;
434 pipe
->create_rasterizer_state
= nv30_rasterizer_state_create
;
435 pipe
->bind_rasterizer_state
= nv30_rasterizer_state_bind
;
436 pipe
->delete_rasterizer_state
= nv30_rasterizer_state_delete
;
438 pipe
->create_depth_stencil_alpha_state
= nv30_zsa_state_create
;
439 pipe
->bind_depth_stencil_alpha_state
= nv30_zsa_state_bind
;
440 pipe
->delete_depth_stencil_alpha_state
= nv30_zsa_state_delete
;
442 pipe
->set_blend_color
= nv30_set_blend_color
;
443 pipe
->set_stencil_ref
= nv30_set_stencil_ref
;
444 pipe
->set_clip_state
= nv30_set_clip_state
;
445 pipe
->set_sample_mask
= nv30_set_sample_mask
;
446 pipe
->set_constant_buffer
= nv30_set_constant_buffer
;
447 pipe
->set_framebuffer_state
= nv30_set_framebuffer_state
;
448 pipe
->set_polygon_stipple
= nv30_set_polygon_stipple
;
449 pipe
->set_scissor_state
= nv30_set_scissor_state
;
450 pipe
->set_viewport_state
= nv30_set_viewport_state
;
452 pipe
->set_vertex_buffers
= nv30_set_vertex_buffers
;
453 pipe
->set_index_buffer
= nv30_set_index_buffer
;