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
, NV10TCL_DITHER_ENABLE
, 1);
10 OUT_RING (b
->d_enable
);
12 BEGIN_RING(kelvin
, NV10TCL_BLEND_FUNC_ENABLE
, 3);
13 OUT_RING (b
->b_enable
);
14 OUT_RING (b
->b_srcfunc
);
15 OUT_RING (b
->b_dstfunc
);
17 BEGIN_RING(kelvin
, NV10TCL_COLOR_MASK
, 1);
21 static void nv20_state_emit_blend_color(struct nv20_context
* nv20
)
23 struct pipe_blend_color
*c
= nv20
->blend_color
;
25 BEGIN_RING(kelvin
, NV10TCL_BLEND_COLOR
, 1);
26 OUT_RING ((float_to_ubyte(c
->color
[3]) << 24)|
27 (float_to_ubyte(c
->color
[0]) << 16)|
28 (float_to_ubyte(c
->color
[1]) << 8) |
29 (float_to_ubyte(c
->color
[2]) << 0));
32 static void nv20_state_emit_rast(struct nv20_context
* nv20
)
34 struct nv20_rasterizer_state
*r
= nv20
->rast
;
36 BEGIN_RING(kelvin
, NV10TCL_SHADE_MODEL
, 2);
37 OUT_RING (r
->shade_model
);
38 OUT_RING (r
->line_width
);
41 BEGIN_RING(kelvin
, NV10TCL_POINT_SIZE
, 1);
42 OUT_RING (r
->point_size
);
44 BEGIN_RING(kelvin
, NV10TCL_POLYGON_MODE_FRONT
, 2);
45 OUT_RING (r
->poly_mode_front
);
46 OUT_RING (r
->poly_mode_back
);
49 BEGIN_RING(kelvin
, NV10TCL_CULL_FACE
, 2);
50 OUT_RING (r
->cull_face
);
51 OUT_RING (r
->front_face
);
53 BEGIN_RING(kelvin
, NV10TCL_LINE_SMOOTH_ENABLE
, 2);
54 OUT_RING (r
->line_smooth_en
);
55 OUT_RING (r
->poly_smooth_en
);
57 BEGIN_RING(kelvin
, NV10TCL_CULL_FACE_ENABLE
, 1);
58 OUT_RING (r
->cull_face_en
);
61 static void nv20_state_emit_dsa(struct nv20_context
* nv20
)
63 struct nv20_depth_stencil_alpha_state
*d
= nv20
->dsa
;
65 BEGIN_RING(kelvin
, NV10TCL_DEPTH_FUNC
, 1);
66 OUT_RING (d
->depth
.func
);
68 BEGIN_RING(kelvin
, NV10TCL_DEPTH_WRITE_ENABLE
, 1);
69 OUT_RING (d
->depth
.write_enable
);
71 BEGIN_RING(kelvin
, NV10TCL_DEPTH_TEST_ENABLE
, 1);
72 OUT_RING (d
->depth
.test_enable
);
75 BEGIN_RING(kelvin
, NV10TCL_STENCIL_ENABLE
, 1);
76 OUT_RING (d
->stencil
.enable
);
77 BEGIN_RING(kelvin
, NV10TCL_STENCIL_MASK
, 7);
78 OUT_RINGp ((uint32_t *)&(d
->stencil
.wmask
), 7);
81 BEGIN_RING(kelvin
, NV10TCL_ALPHA_FUNC_ENABLE
, 1);
82 OUT_RING (d
->alpha
.enabled
);
84 BEGIN_RING(kelvin
, NV10TCL_ALPHA_FUNC_FUNC
, 1);
85 OUT_RING (d
->alpha
.func
);
87 BEGIN_RING(kelvin
, NV10TCL_ALPHA_FUNC_REF
, 1);
88 OUT_RING (d
->alpha
.ref
);
91 static void nv20_state_emit_viewport(struct nv20_context
* nv20
)
95 static void nv20_state_emit_scissor(struct nv20_context
* nv20
)
97 // XXX this is so not working
98 /* struct pipe_scissor_state *s = nv20->scissor;
99 BEGIN_RING(kelvin, NV10TCL_SCISSOR_HORIZ, 2);
100 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
101 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
104 static void nv20_state_emit_framebuffer(struct nv20_context
* nv20
)
106 struct pipe_framebuffer_state
* fb
= nv20
->framebuffer
;
107 struct pipe_surface
*rt
, *zeta
= NULL
;
108 uint32_t rt_format
, w
, h
;
109 int colour_format
= 0, zeta_format
= 0;
111 w
= fb
->cbufs
[0]->width
;
112 h
= fb
->cbufs
[0]->height
;
113 colour_format
= fb
->cbufs
[0]->format
;
118 assert(w
== fb
->zsbuf
->width
);
119 assert(h
== fb
->zsbuf
->height
);
121 w
= fb
->zsbuf
->width
;
122 h
= fb
->zsbuf
->height
;
125 zeta_format
= fb
->zsbuf
->format
;
129 rt_format
= NV10TCL_RT_FORMAT_TYPE_LINEAR
;
131 switch (colour_format
) {
132 case PIPE_FORMAT_A8R8G8B8_UNORM
:
134 rt_format
|= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8
;
136 case PIPE_FORMAT_R5G6B5_UNORM
:
137 rt_format
|= NV10TCL_RT_FORMAT_COLOR_R5G6B5
;
144 BEGIN_RING(kelvin
, NV10TCL_RT_PITCH
, 1);
145 OUT_RING (rt
->stride
| (zeta
->stride
<< 16));
147 BEGIN_RING(kelvin
, NV10TCL_RT_PITCH
, 1);
148 OUT_RING (rt
->stride
| (rt
->stride
<< 16));
151 nv20
->rt
[0] = rt
->buffer
;
155 nv20
->zeta
= zeta
->buffer
;
158 BEGIN_RING(kelvin
, NV10TCL_RT_HORIZ
, 3);
159 OUT_RING ((w
<< 16) | 0);
160 OUT_RING ((h
<< 16) | 0);
161 OUT_RING (rt_format
);
162 BEGIN_RING(kelvin
, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
163 OUT_RING (((w
- 1) << 16) | 0 | 0x08000800);
164 OUT_RING (((h
- 1) << 16) | 0 | 0x08000800);
167 static void nv20_vertex_layout(struct nv20_context
*nv20
)
169 struct nv20_fragment_program
*fp
= nv20
->fragprog
.current
;
170 struct draw_context
*dc
= nv20
->draw
;
173 struct vertex_info
*vinfo
= &nv20
->vertex_info
;
174 const enum interp_mode colorInterp
= INTERP_LINEAR
;
175 boolean colors
[2] = { FALSE
};
176 boolean generics
[4] = { FALSE
};
179 memset(vinfo
, 0, sizeof(*vinfo
));
182 * NV10 hardware vertex attribute order:
183 * fog, weight, normal, tex1, tex0, 2nd color, color, position
184 * vinfo->hwfmt[0] has a used-bit corresponding to each of these.
185 * relation to TGSI_SEMANTIC_*:
186 * - POSITION: position (always used)
187 * - COLOR: 2nd color, color
188 * - GENERIC: weight, normal, tex1, tex0
192 for (i
= 0; i
< fp
->info
.num_inputs
; i
++) {
193 int isn
= fp
->info
.input_semantic_name
[i
];
194 int isi
= fp
->info
.input_semantic_index
[i
];
196 case TGSI_SEMANTIC_POSITION
:
198 case TGSI_SEMANTIC_COLOR
:
202 case TGSI_SEMANTIC_GENERIC
:
204 generics
[isi
] = TRUE
;
206 case TGSI_SEMANTIC_FOG
:
210 assert(0 && "unknown input_semantic_name");
215 int src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_FOG
, 0);
216 draw_emit_vertex_attr(vinfo
, EMIT_1F
, INTERP_PERSPECTIVE
, src
);
217 vinfo
->hwfmt
[0] |= (1 << 7);
220 for (i
= 3; i
>= 0; i
--) {
224 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_GENERIC
, i
);
225 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
);
226 vinfo
->hwfmt
[0] |= (1 << (i
+ 3));
230 int src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_COLOR
, 1);
231 draw_emit_vertex_attr(vinfo
, EMIT_4F
, colorInterp
, src
);
232 vinfo
->hwfmt
[0] |= (1 << 2);
236 int src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_COLOR
, 0);
237 draw_emit_vertex_attr(vinfo
, EMIT_4F
, colorInterp
, src
);
238 vinfo
->hwfmt
[0] |= (1 << 1);
241 /* always do position */
242 src
= draw_find_vs_output(dc
, TGSI_SEMANTIC_POSITION
, 0);
243 draw_emit_vertex_attr(vinfo
, EMIT_4F
, INTERP_LINEAR
, src
);
244 vinfo
->hwfmt
[0] |= (1 << 0);
246 draw_compute_vertex_size(vinfo
);
250 nv20_emit_hw_state(struct nv20_context
*nv20
)
254 if (nv20
->dirty
& NV20_NEW_VERTPROG
) {
255 //nv20_vertprog_bind(nv20, nv20->vertprog.current);
256 nv20
->dirty
&= ~NV20_NEW_VERTPROG
;
259 if (nv20
->dirty
& NV20_NEW_FRAGPROG
) {
260 nv20_fragprog_bind(nv20
, nv20
->fragprog
.current
);
261 /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */
262 nv20
->dirty_samplers
|= (1<<10);
263 nv20
->dirty_samplers
= 0;
266 if (nv20
->dirty_samplers
|| (nv20
->dirty
& NV20_NEW_FRAGPROG
)) {
267 nv20_fragtex_bind(nv20
);
268 nv20
->dirty
&= ~NV20_NEW_FRAGPROG
;
271 if (nv20
->dirty
& NV20_NEW_VTXARRAYS
) {
272 nv20
->dirty
&= ~NV20_NEW_VTXARRAYS
;
273 nv20_vertex_layout(nv20
);
274 nv20_vtxbuf_bind(nv20
);
277 if (nv20
->dirty
& NV20_NEW_BLEND
) {
278 nv20
->dirty
&= ~NV20_NEW_BLEND
;
279 nv20_state_emit_blend(nv20
);
282 if (nv20
->dirty
& NV20_NEW_BLENDCOL
) {
283 nv20
->dirty
&= ~NV20_NEW_BLENDCOL
;
284 nv20_state_emit_blend_color(nv20
);
287 if (nv20
->dirty
& NV20_NEW_RAST
) {
288 nv20
->dirty
&= ~NV20_NEW_RAST
;
289 nv20_state_emit_rast(nv20
);
292 if (nv20
->dirty
& NV20_NEW_DSA
) {
293 nv20
->dirty
&= ~NV20_NEW_DSA
;
294 nv20_state_emit_dsa(nv20
);
297 if (nv20
->dirty
& NV20_NEW_VIEWPORT
) {
298 nv20
->dirty
&= ~NV20_NEW_VIEWPORT
;
299 nv20_state_emit_viewport(nv20
);
302 if (nv20
->dirty
& NV20_NEW_SCISSOR
) {
303 nv20
->dirty
&= ~NV20_NEW_SCISSOR
;
304 nv20_state_emit_scissor(nv20
);
307 if (nv20
->dirty
& NV20_NEW_FRAMEBUFFER
) {
308 nv20
->dirty
&= ~NV20_NEW_FRAMEBUFFER
;
309 nv20_state_emit_framebuffer(nv20
);
312 /* Emit relocs for every referenced buffer.
313 * This is to ensure the bufmgr has an accurate idea of how
314 * the buffer is used. This isn't very efficient, but we don't
315 * seem to take a significant performance hit. Will be improved
316 * at some point. Vertex arrays are emitted by nv20_vbo.c
320 // XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
321 // BEGIN_RING(kelvin, NV10TCL_DMA_COLOR0, 1);
322 // OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
323 BEGIN_RING(kelvin
, NV10TCL_COLOR_OFFSET
, 1);
324 OUT_RELOCl(nv20
->rt
[0], 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
328 // BEGIN_RING(kelvin, NV10TCL_DMA_ZETA, 1);
329 // OUT_RELOCo(nv20->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
330 BEGIN_RING(kelvin
, NV10TCL_ZETA_OFFSET
, 1);
331 OUT_RELOCl(nv20
->zeta
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
332 /* XXX for when we allocate LMA on nv17 */
333 /* BEGIN_RING(kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
334 OUT_RELOCl(nv20->zeta + lma_offset);*/
338 BEGIN_RING(kelvin
, NV10TCL_DMA_VTXBUF0
, 1);
339 OUT_RELOCo(nv20
->rt
[0], NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
340 BEGIN_RING(kelvin
, NV10TCL_COLOR_OFFSET
, 1);
341 OUT_RELOCl(nv20
->rt
[0], 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
344 for (i
= 0; i
< 2; i
++) {
345 if (!(nv20
->fp_samplers
& (1 << i
)))
347 BEGIN_RING(kelvin
, NV10TCL_TX_OFFSET(i
), 1);
348 OUT_RELOCl(nv20
->tex
[i
].buffer
, 0, NOUVEAU_BO_VRAM
|
349 NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
350 BEGIN_RING(kelvin
, NV10TCL_TX_FORMAT(i
), 1);
351 OUT_RELOCd(nv20
->tex
[i
].buffer
, nv20
->tex
[i
].format
,
352 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
|
353 NOUVEAU_BO_OR
, NV10TCL_TX_FORMAT_DMA0
,
354 NV10TCL_TX_FORMAT_DMA1
);