1 #include "nv20_context.h"
2 #include "nv20_state.h"
3 #include "draw/draw_context.h"
5 static void nv20_state_emit_blend(struct nv20_context
* nv20
)
7 struct nv20_blend_state
*b
= nv20
->blend
;
8 struct nv20_screen
*screen
= nv20
->screen
;
9 struct nouveau_channel
*chan
= screen
->base
.channel
;
10 struct nouveau_grobj
*kelvin
= screen
->kelvin
;
12 BEGIN_RING(chan
, kelvin
, NV20TCL_DITHER_ENABLE
, 1);
13 OUT_RING (chan
, b
->d_enable
);
15 BEGIN_RING(chan
, kelvin
, NV20TCL_BLEND_FUNC_ENABLE
, 1);
16 OUT_RING (chan
, b
->b_enable
);
18 BEGIN_RING(chan
, kelvin
, NV20TCL_BLEND_FUNC_SRC
, 2);
19 OUT_RING (chan
, b
->b_srcfunc
);
20 OUT_RING (chan
, b
->b_dstfunc
);
22 BEGIN_RING(chan
, kelvin
, NV20TCL_COLOR_MASK
, 1);
23 OUT_RING (chan
, b
->c_mask
);
26 static void nv20_state_emit_blend_color(struct nv20_context
* nv20
)
28 struct pipe_blend_color
*c
= nv20
->blend_color
;
29 struct nv20_screen
*screen
= nv20
->screen
;
30 struct nouveau_channel
*chan
= screen
->base
.channel
;
31 struct nouveau_grobj
*kelvin
= screen
->kelvin
;
33 BEGIN_RING(chan
, kelvin
, NV20TCL_BLEND_COLOR
, 1);
35 (float_to_ubyte(c
->color
[3]) << 24)|
36 (float_to_ubyte(c
->color
[0]) << 16)|
37 (float_to_ubyte(c
->color
[1]) << 8) |
38 (float_to_ubyte(c
->color
[2]) << 0));
41 static void nv20_state_emit_rast(struct nv20_context
* nv20
)
43 struct nv20_rasterizer_state
*r
= nv20
->rast
;
44 struct nv20_screen
*screen
= nv20
->screen
;
45 struct nouveau_channel
*chan
= screen
->base
.channel
;
46 struct nouveau_grobj
*kelvin
= screen
->kelvin
;
48 BEGIN_RING(chan
, kelvin
, NV20TCL_SHADE_MODEL
, 2);
49 OUT_RING (chan
, r
->shade_model
);
50 OUT_RING (chan
, r
->line_width
);
53 BEGIN_RING(chan
, kelvin
, NV20TCL_POINT_SIZE
, 1);
54 OUT_RING (chan
, r
->point_size
);
56 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_MODE_FRONT
, 2);
57 OUT_RING (chan
, r
->poly_mode_front
);
58 OUT_RING (chan
, r
->poly_mode_back
);
61 BEGIN_RING(chan
, kelvin
, NV20TCL_CULL_FACE
, 2);
62 OUT_RING (chan
, r
->cull_face
);
63 OUT_RING (chan
, r
->front_face
);
65 BEGIN_RING(chan
, kelvin
, NV20TCL_LINE_SMOOTH_ENABLE
, 2);
66 OUT_RING (chan
, r
->line_smooth_en
);
67 OUT_RING (chan
, r
->poly_smooth_en
);
69 BEGIN_RING(chan
, kelvin
, NV20TCL_CULL_FACE_ENABLE
, 1);
70 OUT_RING (chan
, r
->cull_face_en
);
73 static void nv20_state_emit_dsa(struct nv20_context
* nv20
)
75 struct nv20_depth_stencil_alpha_state
*d
= nv20
->dsa
;
76 struct nv20_screen
*screen
= nv20
->screen
;
77 struct nouveau_channel
*chan
= screen
->base
.channel
;
78 struct nouveau_grobj
*kelvin
= screen
->kelvin
;
80 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_FUNC
, 1);
81 OUT_RING (chan
, d
->depth
.func
);
83 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_WRITE_ENABLE
, 1);
84 OUT_RING (chan
, d
->depth
.write_enable
);
86 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_TEST_ENABLE
, 1);
87 OUT_RING (chan
, d
->depth
.test_enable
);
89 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_UNK17D8
, 1);
93 BEGIN_RING(chan
, kelvin
, NV20TCL_STENCIL_ENABLE
, 1);
94 OUT_RING (chan
, d
->stencil
.enable
);
95 BEGIN_RING(chan
, kelvin
, NV20TCL_STENCIL_MASK
, 7);
96 OUT_RINGp (chan
, (uint32_t *)&(d
->stencil
.wmask
), 7);
99 BEGIN_RING(chan
, kelvin
, NV20TCL_ALPHA_FUNC_ENABLE
, 1);
100 OUT_RING (chan
, d
->alpha
.enabled
);
102 BEGIN_RING(chan
, kelvin
, NV20TCL_ALPHA_FUNC_FUNC
, 1);
103 OUT_RING (chan
, d
->alpha
.func
);
105 BEGIN_RING(chan
, kelvin
, NV20TCL_ALPHA_FUNC_REF
, 1);
106 OUT_RING (chan
, d
->alpha
.ref
);
109 static void nv20_state_emit_viewport(struct nv20_context
* nv20
)
113 static void nv20_state_emit_scissor(struct nv20_context
* nv20
)
115 /* NV20TCL_SCISSOR_* is probably a software method */
116 /* struct pipe_scissor_state *s = nv20->scissor;
117 struct nv20_screen *screen = nv20->screen;
118 struct nouveau_channel *chan = screen->base.channel;
119 struct nouveau_grobj *kelvin = screen->kelvin;
121 BEGIN_RING(chan, kelvin, NV20TCL_SCISSOR_HORIZ, 2);
122 OUT_RING (chan, ((s->maxx - s->minx) << 16) | s->minx);
123 OUT_RING (chan, ((s->maxy - s->miny) << 16) | s->miny);*/
126 static void nv20_state_emit_framebuffer(struct nv20_context
* nv20
)
128 struct pipe_framebuffer_state
* fb
= nv20
->framebuffer
;
129 struct nv04_surface
*rt
, *zeta
= NULL
;
130 uint32_t rt_format
, w
, h
;
131 int colour_format
= 0, zeta_format
= 0;
132 struct nv20_miptree
*nv20mt
= 0;
133 struct nv20_screen
*screen
= nv20
->screen
;
134 struct nouveau_channel
*chan
= screen
->base
.channel
;
135 struct nouveau_grobj
*kelvin
= screen
->kelvin
;
137 w
= fb
->cbufs
[0]->width
;
138 h
= fb
->cbufs
[0]->height
;
139 colour_format
= fb
->cbufs
[0]->format
;
140 rt
= (struct nv04_surface
*)fb
->cbufs
[0];
144 assert(w
== fb
->zsbuf
->width
);
145 assert(h
== fb
->zsbuf
->height
);
147 w
= fb
->zsbuf
->width
;
148 h
= fb
->zsbuf
->height
;
151 zeta_format
= fb
->zsbuf
->format
;
152 zeta
= (struct nv04_surface
*)fb
->zsbuf
;
155 rt_format
= NV20TCL_RT_FORMAT_TYPE_LINEAR
| 0x20;
157 switch (colour_format
) {
158 case PIPE_FORMAT_X8R8G8B8_UNORM
:
159 rt_format
|= NV20TCL_RT_FORMAT_COLOR_X8R8G8B8
;
161 case PIPE_FORMAT_A8R8G8B8_UNORM
:
163 rt_format
|= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8
;
165 case PIPE_FORMAT_R5G6B5_UNORM
:
166 rt_format
|= NV20TCL_RT_FORMAT_COLOR_R5G6B5
;
173 BEGIN_RING(chan
, kelvin
, NV20TCL_RT_PITCH
, 1);
174 OUT_RING (chan
, rt
->pitch
| (zeta
->pitch
<< 16));
176 BEGIN_RING(chan
, kelvin
, NV20TCL_RT_PITCH
, 1);
177 OUT_RING (chan
, rt
->pitch
| (rt
->pitch
<< 16));
180 nv20mt
= (struct nv20_miptree
*)rt
->base
.texture
;
181 nv20
->rt
[0] = nv20mt
->buffer
;
185 nv20mt
= (struct nv20_miptree
*)zeta
->base
.texture
;
186 nv20
->zeta
= nv20mt
->buffer
;
189 BEGIN_RING(chan
, kelvin
, NV20TCL_RT_HORIZ
, 3);
190 OUT_RING (chan
, (w
<< 16) | 0);
191 OUT_RING (chan
, (h
<< 16) | 0); /*NV20TCL_RT_VERT */
192 OUT_RING (chan
, rt_format
); /* NV20TCL_RT_FORMAT */
193 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
194 OUT_RING (chan
, ((w
- 1) << 16) | 0);
195 OUT_RING (chan
, ((h
- 1) << 16) | 0);
198 static void nv20_vertex_layout(struct nv20_context
*nv20
)
200 struct nv20_fragment_program
*fp
= nv20
->fragprog
.current
;
201 struct draw_context
*dc
= nv20
->draw
;
204 struct vertex_info
*vinfo
= &nv20
->vertex_info
;
205 const enum interp_mode colorInterp
= INTERP_LINEAR
;
206 boolean colors
[2] = { FALSE
};
207 boolean generics
[12] = { FALSE
};
210 memset(vinfo
, 0, sizeof(*vinfo
));
213 * Assumed NV20 hardware vertex attribute order:
214 * 0 position, 1 ?, 2 ?, 3 col0,
215 * 4 col1?, 5 ?, 6 ?, 7 ?,
216 * 8 ?, 9 tex0, 10 tex1, 11 tex2,
217 * 12 tex3, 13 ?, 14 ?, 15 ?
218 * unaccounted: wgh, nor, fog
219 * There are total 16 attrs.
220 * vinfo->hwfmt[0] has a used-bit corresponding to each of these.
221 * relation to TGSI_SEMANTIC_*:
222 * - POSITION: position (always used)
223 * - COLOR: col1, col0
224 * - GENERIC: tex3, tex2, tex1, tex0, normal, weight
228 for (i
= 0; i
< fp
->info
.num_inputs
; i
++) {
229 int isn
= fp
->info
.input_semantic_name
[i
];
230 int isi
= fp
->info
.input_semantic_index
[i
];
232 case TGSI_SEMANTIC_POSITION
:
234 case TGSI_SEMANTIC_COLOR
:
238 case TGSI_SEMANTIC_GENERIC
:
240 generics
[isi
] = TRUE
;
242 case TGSI_SEMANTIC_FOG
:
246 assert(0 && "unknown input_semantic_name");
250 /* always do position */ {
251 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_POSITION
, 0);
252 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_LINEAR
, src
);
253 vinfo
->hwfmt
[0] |= (1 << 0);
256 /* two unnamed generics */
257 for (i
= 4; i
< 6; i
++) {
260 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
261 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
262 vinfo
->hwfmt
[0] |= (1 << (i
- 3));
266 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_COLOR
, 0);
267 draw_emit_vertex_attr(vinfo
, EMIT_4F
, colorInterp
, src
);
268 vinfo
->hwfmt
[0] |= (1 << 3);
272 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_COLOR
, 1);
273 draw_emit_vertex_attr(vinfo
, EMIT_4F
, colorInterp
, src
);
274 vinfo
->hwfmt
[0] |= (1 << 4);
277 /* four unnamed generics */
278 for (i
= 6; i
< 10; i
++) {
281 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
282 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
283 vinfo
->hwfmt
[0] |= (1 << (i
- 1));
286 /* tex0, tex1, tex2, tex3 */
287 for (i
= 0; i
< 4; i
++) {
290 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
291 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
292 vinfo
->hwfmt
[0] |= (1 << (i
+ 9));
295 /* two unnamed generics */
296 for (i
= 10; i
< 12; i
++) {
299 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
300 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
301 vinfo
->hwfmt
[0] |= (1 << (i
+ 3));
305 src
= draw_find_shader_output(dc
, TGSI_SEMANTIC_FOG
, 0);
306 draw_emit_vertex_attr(vinfo
, EMIT_1F
, INTERP_PERSPECTIVE
, src
);
307 vinfo
->hwfmt
[0] |= (1 << 15);
310 draw_compute_vertex_size(vinfo
);
314 nv20_emit_hw_state(struct nv20_context
*nv20
)
316 struct nv20_screen
*screen
= nv20
->screen
;
317 struct nouveau_channel
*chan
= screen
->base
.channel
;
318 struct nouveau_grobj
*kelvin
= screen
->kelvin
;
319 struct nouveau_bo
*rt_bo
;
322 if (nv20
->dirty
& NV20_NEW_VERTPROG
) {
323 //nv20_vertprog_bind(nv20, nv20->vertprog.current);
324 nv20
->dirty
&= ~NV20_NEW_VERTPROG
;
327 if (nv20
->dirty
& NV20_NEW_FRAGPROG
) {
328 nv20_fragprog_bind(nv20
, nv20
->fragprog
.current
);
329 /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */
330 nv20
->dirty_samplers
|= (1<<10);
331 nv20
->dirty_samplers
= 0;
334 if (nv20
->dirty_samplers
|| (nv20
->dirty
& NV20_NEW_FRAGPROG
)) {
335 nv20_fragtex_bind(nv20
);
336 nv20
->dirty
&= ~NV20_NEW_FRAGPROG
;
339 if (nv20
->dirty
& NV20_NEW_VTXARRAYS
) {
340 nv20
->dirty
&= ~NV20_NEW_VTXARRAYS
;
341 nv20_vertex_layout(nv20
);
342 nv20_vtxbuf_bind(nv20
);
345 if (nv20
->dirty
& NV20_NEW_BLEND
) {
346 nv20
->dirty
&= ~NV20_NEW_BLEND
;
347 nv20_state_emit_blend(nv20
);
350 if (nv20
->dirty
& NV20_NEW_BLENDCOL
) {
351 nv20
->dirty
&= ~NV20_NEW_BLENDCOL
;
352 nv20_state_emit_blend_color(nv20
);
355 if (nv20
->dirty
& NV20_NEW_RAST
) {
356 nv20
->dirty
&= ~NV20_NEW_RAST
;
357 nv20_state_emit_rast(nv20
);
360 if (nv20
->dirty
& NV20_NEW_DSA
) {
361 nv20
->dirty
&= ~NV20_NEW_DSA
;
362 nv20_state_emit_dsa(nv20
);
365 if (nv20
->dirty
& NV20_NEW_VIEWPORT
) {
366 nv20
->dirty
&= ~NV20_NEW_VIEWPORT
;
367 nv20_state_emit_viewport(nv20
);
370 if (nv20
->dirty
& NV20_NEW_SCISSOR
) {
371 nv20
->dirty
&= ~NV20_NEW_SCISSOR
;
372 nv20_state_emit_scissor(nv20
);
375 if (nv20
->dirty
& NV20_NEW_FRAMEBUFFER
) {
376 nv20
->dirty
&= ~NV20_NEW_FRAMEBUFFER
;
377 nv20_state_emit_framebuffer(nv20
);
380 /* Emit relocs for every referenced buffer.
381 * This is to ensure the bufmgr has an accurate idea of how
382 * the buffer is used. This isn't very efficient, but we don't
383 * seem to take a significant performance hit. Will be improved
384 * at some point. Vertex arrays are emitted by nv20_vbo.c
388 rt_bo
= nouveau_bo(nv20
->rt
[0]);
389 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_COLOR
, 1);
390 OUT_RELOCo(chan
, rt_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
391 BEGIN_RING(chan
, kelvin
, NV20TCL_COLOR_OFFSET
, 1);
392 OUT_RELOCl(chan
, rt_bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
395 struct nouveau_bo
*zeta_bo
= nouveau_bo(nv20
->zeta
);
396 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_ZETA
, 1);
397 OUT_RELOCo(chan
, zeta_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
398 BEGIN_RING(chan
, kelvin
, NV20TCL_ZETA_OFFSET
, 1);
399 OUT_RELOCl(chan
, zeta_bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
400 /* XXX for when we allocate LMA on nv17 */
401 /* BEGIN_RING(chan, kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
402 OUT_RELOCl(chan, nouveau_bo(nv20->zeta + lma_offset));*/
406 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_VTXBUF0
, 1);
407 OUT_RELOCo(chan
, rt_bo
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
408 BEGIN_RING(chan
, kelvin
, NV20TCL_COLOR_OFFSET
, 1);
409 OUT_RELOCl(chan
, rt_bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
412 for (i
= 0; i
< 2; i
++) {
413 if (!(nv20
->fp_samplers
& (1 << i
)))
415 struct nouveau_bo
*bo
= nouveau_bo(nv20
->tex
[i
].buffer
);
416 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_OFFSET(i
), 1);
417 OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
|
418 NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
419 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_FORMAT(i
), 1);
420 OUT_RELOCd(chan
, bo
, nv20
->tex
[i
].format
,
421 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
|
422 NOUVEAU_BO_OR
, NV20TCL_TX_FORMAT_DMA0
,
423 NV20TCL_TX_FORMAT_DMA1
);