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
;
9 BEGIN_RING(kelvin
, NV20TCL_DITHER_ENABLE
, 1);
10 OUT_RING (b
->d_enable
);
12 BEGIN_RING(kelvin
, NV20TCL_BLEND_FUNC_ENABLE
, 1);
13 OUT_RING (b
->b_enable
);
15 BEGIN_RING(kelvin
, NV20TCL_BLEND_FUNC_SRC
, 2);
16 OUT_RING (b
->b_srcfunc
);
17 OUT_RING (b
->b_dstfunc
);
19 BEGIN_RING(kelvin
, NV20TCL_COLOR_MASK
, 1);
23 static void nv20_state_emit_blend_color(struct nv20_context
* nv20
)
25 struct pipe_blend_color
*c
= nv20
->blend_color
;
27 BEGIN_RING(kelvin
, NV20TCL_BLEND_COLOR
, 1);
28 OUT_RING ((float_to_ubyte(c
->color
[3]) << 24)|
29 (float_to_ubyte(c
->color
[0]) << 16)|
30 (float_to_ubyte(c
->color
[1]) << 8) |
31 (float_to_ubyte(c
->color
[2]) << 0));
34 static void nv20_state_emit_rast(struct nv20_context
* nv20
)
36 struct nv20_rasterizer_state
*r
= nv20
->rast
;
38 BEGIN_RING(kelvin
, NV20TCL_SHADE_MODEL
, 2);
39 OUT_RING (r
->shade_model
);
40 OUT_RING (r
->line_width
);
43 BEGIN_RING(kelvin
, NV20TCL_POINT_SIZE
, 1);
44 OUT_RING (r
->point_size
);
46 BEGIN_RING(kelvin
, NV20TCL_POLYGON_MODE_FRONT
, 2);
47 OUT_RING (r
->poly_mode_front
);
48 OUT_RING (r
->poly_mode_back
);
51 BEGIN_RING(kelvin
, NV20TCL_CULL_FACE
, 2);
52 OUT_RING (r
->cull_face
);
53 OUT_RING (r
->front_face
);
55 BEGIN_RING(kelvin
, NV20TCL_LINE_SMOOTH_ENABLE
, 2);
56 OUT_RING (r
->line_smooth_en
);
57 OUT_RING (r
->poly_smooth_en
);
59 BEGIN_RING(kelvin
, NV20TCL_CULL_FACE_ENABLE
, 1);
60 OUT_RING (r
->cull_face_en
);
63 static void nv20_state_emit_dsa(struct nv20_context
* nv20
)
65 struct nv20_depth_stencil_alpha_state
*d
= nv20
->dsa
;
67 BEGIN_RING(kelvin
, NV20TCL_DEPTH_FUNC
, 1);
68 OUT_RING (d
->depth
.func
);
70 BEGIN_RING(kelvin
, NV20TCL_DEPTH_WRITE_ENABLE
, 1);
71 OUT_RING (d
->depth
.write_enable
);
73 BEGIN_RING(kelvin
, NV20TCL_DEPTH_TEST_ENABLE
, 1);
74 OUT_RING (d
->depth
.test_enable
);
76 BEGIN_RING(kelvin
, NV20TCL_DEPTH_UNK17D8
, 1);
80 BEGIN_RING(kelvin
, NV20TCL_STENCIL_ENABLE
, 1);
81 OUT_RING (d
->stencil
.enable
);
82 BEGIN_RING(kelvin
, NV20TCL_STENCIL_MASK
, 7);
83 OUT_RINGp ((uint32_t *)&(d
->stencil
.wmask
), 7);
86 BEGIN_RING(kelvin
, NV20TCL_ALPHA_FUNC_ENABLE
, 1);
87 OUT_RING (d
->alpha
.enabled
);
89 BEGIN_RING(kelvin
, NV20TCL_ALPHA_FUNC_FUNC
, 1);
90 OUT_RING (d
->alpha
.func
);
92 BEGIN_RING(kelvin
, NV20TCL_ALPHA_FUNC_REF
, 1);
93 OUT_RING (d
->alpha
.ref
);
96 static void nv20_state_emit_viewport(struct nv20_context
* nv20
)
100 static void nv20_state_emit_scissor(struct nv20_context
* nv20
)
102 /* NV20TCL_SCISSOR_* is probably a software method */
103 /* struct pipe_scissor_state *s = nv20->scissor;
104 BEGIN_RING(kelvin, NV20TCL_SCISSOR_HORIZ, 2);
105 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
106 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
109 static void nv20_state_emit_framebuffer(struct nv20_context
* nv20
)
111 struct pipe_framebuffer_state
* fb
= nv20
->framebuffer
;
112 struct pipe_surface
*rt
, *zeta
= NULL
;
113 uint32_t rt_format
, w
, h
;
114 int colour_format
= 0, zeta_format
= 0;
115 struct nv20_miptree
*nv20mt
= 0;
117 w
= fb
->cbufs
[0]->width
;
118 h
= fb
->cbufs
[0]->height
;
119 colour_format
= fb
->cbufs
[0]->format
;
124 assert(w
== fb
->zsbuf
->width
);
125 assert(h
== fb
->zsbuf
->height
);
127 w
= fb
->zsbuf
->width
;
128 h
= fb
->zsbuf
->height
;
131 zeta_format
= fb
->zsbuf
->format
;
135 rt_format
= NV20TCL_RT_FORMAT_TYPE_LINEAR
| 0x20;
137 switch (colour_format
) {
138 case PIPE_FORMAT_A8R8G8B8_UNORM
:
140 rt_format
|= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8
;
142 case PIPE_FORMAT_R5G6B5_UNORM
:
143 rt_format
|= NV20TCL_RT_FORMAT_COLOR_R5G6B5
;
150 BEGIN_RING(kelvin
, NV20TCL_RT_PITCH
, 1);
151 OUT_RING (rt
->stride
| (zeta
->stride
<< 16));
153 BEGIN_RING(kelvin
, NV20TCL_RT_PITCH
, 1);
154 OUT_RING (rt
->stride
| (rt
->stride
<< 16));
157 nv20mt
= (struct nv20_miptree
*)rt
->texture
;
158 nv20
->rt
[0] = nv20mt
->buffer
;
162 nv20mt
= (struct nv20_miptree
*)zeta
->texture
;
163 nv20
->zeta
= nv20mt
->buffer
;
166 BEGIN_RING(kelvin
, NV20TCL_RT_HORIZ
, 3);
167 OUT_RING ((w
<< 16) | 0);
168 OUT_RING ((h
<< 16) | 0); /*NV20TCL_RT_VERT */
169 OUT_RING (rt_format
); /* NV20TCL_RT_FORMAT */
170 BEGIN_RING(kelvin
, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
171 OUT_RING (((w
- 1) << 16) | 0);
172 OUT_RING (((h
- 1) << 16) | 0);
175 static void nv20_vertex_layout(struct nv20_context
*nv20
)
177 struct nv20_fragment_program
*fp
= nv20
->fragprog
.current
;
178 struct draw_context
*dc
= nv20
->draw
;
181 struct vertex_info
*vinfo
= &nv20
->vertex_info
;
182 const enum interp_mode colorInterp
= INTERP_LINEAR
;
183 boolean colors
[2] = { FALSE
};
184 boolean generics
[12] = { FALSE
};
187 memset(vinfo
, 0, sizeof(*vinfo
));
190 * Assumed NV20 hardware vertex attribute order:
191 * 0 position, 1 ?, 2 ?, 3 col0,
192 * 4 col1?, 5 ?, 6 ?, 7 ?,
193 * 8 ?, 9 tex0, 10 tex1, 11 tex2,
194 * 12 tex3, 13 ?, 14 ?, 15 ?
195 * unaccounted: wgh, nor, fog
196 * There are total 16 attrs.
197 * vinfo->hwfmt[0] has a used-bit corresponding to each of these.
198 * relation to TGSI_SEMANTIC_*:
199 * - POSITION: position (always used)
200 * - COLOR: col1, col0
201 * - GENERIC: tex3, tex2, tex1, tex0, normal, weight
205 for (i
= 0; i
< fp
->info
.num_inputs
; i
++) {
206 int isn
= fp
->info
.input_semantic_name
[i
];
207 int isi
= fp
->info
.input_semantic_index
[i
];
209 case TGSI_SEMANTIC_POSITION
:
211 case TGSI_SEMANTIC_COLOR
:
215 case TGSI_SEMANTIC_GENERIC
:
217 generics
[isi
] = TRUE
;
219 case TGSI_SEMANTIC_FOG
:
223 assert(0 && "unknown input_semantic_name");
227 /* always do position */ {
228 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_POSITION
, 0);
229 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_LINEAR
, src
);
230 vinfo
->hwfmt
[0] |= (1 << 0);
233 /* two unnamed generics */
234 for (i
= 4; i
< 6; i
++) {
237 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
238 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
239 vinfo
->hwfmt
[0] |= (1 << (i
- 3));
243 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_COLOR
, 0);
244 draw_emit_vertex_attr(vinfo
, EMIT_4F
, colorInterp
, src
);
245 vinfo
->hwfmt
[0] |= (1 << 3);
249 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_COLOR
, 1);
250 draw_emit_vertex_attr(vinfo
, EMIT_4F
, colorInterp
, src
);
251 vinfo
->hwfmt
[0] |= (1 << 4);
254 /* four unnamed generics */
255 for (i
= 6; i
< 10; i
++) {
258 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
259 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
260 vinfo
->hwfmt
[0] |= (1 << (i
- 1));
263 /* tex0, tex1, tex2, tex3 */
264 for (i
= 0; i
< 4; i
++) {
267 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
268 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
269 vinfo
->hwfmt
[0] |= (1 << (i
+ 9));
272 /* two unnamed generics */
273 for (i
= 10; i
< 12; i
++) {
276 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
277 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
278 vinfo
->hwfmt
[0] |= (1 << (i
+ 3));
282 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_FOG
, 0);
283 draw_emit_vertex_attr(vinfo
, EMIT_1F
, INTERP_PERSPECTIVE
, src
);
284 vinfo
->hwfmt
[0] |= (1 << 15);
287 draw_compute_vertex_size(vinfo
);
291 nv20_emit_hw_state(struct nv20_context
*nv20
)
295 if (nv20
->dirty
& NV20_NEW_VERTPROG
) {
296 //nv20_vertprog_bind(nv20, nv20->vertprog.current);
297 nv20
->dirty
&= ~NV20_NEW_VERTPROG
;
300 if (nv20
->dirty
& NV20_NEW_FRAGPROG
) {
301 nv20_fragprog_bind(nv20
, nv20
->fragprog
.current
);
302 /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */
303 nv20
->dirty_samplers
|= (1<<10);
304 nv20
->dirty_samplers
= 0;
307 if (nv20
->dirty_samplers
|| (nv20
->dirty
& NV20_NEW_FRAGPROG
)) {
308 nv20_fragtex_bind(nv20
);
309 nv20
->dirty
&= ~NV20_NEW_FRAGPROG
;
312 if (nv20
->dirty
& NV20_NEW_VTXARRAYS
) {
313 nv20
->dirty
&= ~NV20_NEW_VTXARRAYS
;
314 nv20_vertex_layout(nv20
);
315 nv20_vtxbuf_bind(nv20
);
318 if (nv20
->dirty
& NV20_NEW_BLEND
) {
319 nv20
->dirty
&= ~NV20_NEW_BLEND
;
320 nv20_state_emit_blend(nv20
);
323 if (nv20
->dirty
& NV20_NEW_BLENDCOL
) {
324 nv20
->dirty
&= ~NV20_NEW_BLENDCOL
;
325 nv20_state_emit_blend_color(nv20
);
328 if (nv20
->dirty
& NV20_NEW_RAST
) {
329 nv20
->dirty
&= ~NV20_NEW_RAST
;
330 nv20_state_emit_rast(nv20
);
333 if (nv20
->dirty
& NV20_NEW_DSA
) {
334 nv20
->dirty
&= ~NV20_NEW_DSA
;
335 nv20_state_emit_dsa(nv20
);
338 if (nv20
->dirty
& NV20_NEW_VIEWPORT
) {
339 nv20
->dirty
&= ~NV20_NEW_VIEWPORT
;
340 nv20_state_emit_viewport(nv20
);
343 if (nv20
->dirty
& NV20_NEW_SCISSOR
) {
344 nv20
->dirty
&= ~NV20_NEW_SCISSOR
;
345 nv20_state_emit_scissor(nv20
);
348 if (nv20
->dirty
& NV20_NEW_FRAMEBUFFER
) {
349 nv20
->dirty
&= ~NV20_NEW_FRAMEBUFFER
;
350 nv20_state_emit_framebuffer(nv20
);
353 /* Emit relocs for every referenced buffer.
354 * This is to ensure the bufmgr has an accurate idea of how
355 * the buffer is used. This isn't very efficient, but we don't
356 * seem to take a significant performance hit. Will be improved
357 * at some point. Vertex arrays are emitted by nv20_vbo.c
361 BEGIN_RING(kelvin
, NV20TCL_DMA_COLOR
, 1);
362 OUT_RELOCo(nv20
->rt
[0], NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
363 BEGIN_RING(kelvin
, NV20TCL_COLOR_OFFSET
, 1);
364 OUT_RELOCl(nv20
->rt
[0], 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
367 BEGIN_RING(kelvin
, NV20TCL_DMA_ZETA
, 1);
368 OUT_RELOCo(nv20
->zeta
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
369 BEGIN_RING(kelvin
, NV20TCL_ZETA_OFFSET
, 1);
370 OUT_RELOCl(nv20
->zeta
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
371 /* XXX for when we allocate LMA on nv17 */
372 /* BEGIN_RING(kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
373 OUT_RELOCl(nv20->zeta + lma_offset);*/
377 BEGIN_RING(kelvin
, NV20TCL_DMA_VTXBUF0
, 1);
378 OUT_RELOCo(nv20
->rt
[0], NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
379 BEGIN_RING(kelvin
, NV20TCL_COLOR_OFFSET
, 1);
380 OUT_RELOCl(nv20
->rt
[0], 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
383 for (i
= 0; i
< 2; i
++) {
384 if (!(nv20
->fp_samplers
& (1 << i
)))
386 BEGIN_RING(kelvin
, NV20TCL_TX_OFFSET(i
), 1);
387 OUT_RELOCl(nv20
->tex
[i
].buffer
, 0, NOUVEAU_BO_VRAM
|
388 NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
389 BEGIN_RING(kelvin
, NV20TCL_TX_FORMAT(i
), 1);
390 OUT_RELOCd(nv20
->tex
[i
].buffer
, nv20
->tex
[i
].format
,
391 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
|
392 NOUVEAU_BO_OR
, NV20TCL_TX_FORMAT_DMA0
,
393 NV20TCL_TX_FORMAT_DMA1
);