1 #include "nv04_context.h"
2 #include "nv04_state.h"
4 static void nv04_vertex_layout(struct pipe_context
* pipe
)
6 struct nv04_context
*nv04
= nv04_context(pipe
);
7 struct nv04_fragment_program
*fp
= nv04
->fragprog
.current
;
10 struct vertex_info vinfo
;
12 memset(&vinfo
, 0, sizeof(vinfo
));
14 for (i
= 0; i
< fp
->info
.num_inputs
; i
++) {
15 int isn
= fp
->info
.input_semantic_name
[i
];
16 int isi
= fp
->info
.input_semantic_index
[i
];
18 case TGSI_SEMANTIC_POSITION
:
19 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_LINEAR
, src
++);
21 case TGSI_SEMANTIC_COLOR
:
22 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_LINEAR
, src
++);
25 case TGSI_SEMANTIC_GENERIC
:
26 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
++);
28 case TGSI_SEMANTIC_FOG
:
29 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
++);
34 printf("%d vertex input\n",fp
->info
.num_inputs
);
35 draw_compute_vertex_size(&vinfo
);
38 static uint32_t nv04_blend_func(uint32_t f
)
41 case PIPE_BLENDFACTOR_ZERO
: return 0x1;
42 case PIPE_BLENDFACTOR_ONE
: return 0x2;
43 case PIPE_BLENDFACTOR_SRC_COLOR
: return 0x3;
44 case PIPE_BLENDFACTOR_INV_SRC_COLOR
: return 0x4;
45 case PIPE_BLENDFACTOR_SRC_ALPHA
: return 0x5;
46 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
: return 0x6;
47 case PIPE_BLENDFACTOR_DST_ALPHA
: return 0x7;
48 case PIPE_BLENDFACTOR_INV_DST_ALPHA
: return 0x8;
49 case PIPE_BLENDFACTOR_DST_COLOR
: return 0x9;
50 case PIPE_BLENDFACTOR_INV_DST_COLOR
: return 0xA;
51 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
: return 0xB;
53 NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f
);
57 static void nv04_emit_control(struct nv04_context
* nv04
)
59 uint32_t control
= nv04
->dsa
->control
;
61 BEGIN_RING(fahrenheit
, NV04_DX5_TEXTURED_TRIANGLE_CONTROL
, 1);
65 static void nv04_emit_blend(struct nv04_context
* nv04
)
69 blend
=0x4; // texture MODULATE_ALPHA
70 blend
|=0x20; // alpha is MSB
71 blend
|=(2<<6); // flat shading
72 blend
|=(1<<8); // persp correct
73 blend
|=(0<<16); // no fog
74 blend
|=(nv04
->blend
->b_enable
<<20);
75 blend
|=(nv04_blend_func(nv04
->blend
->b_src
)<<24);
76 blend
|=(nv04_blend_func(nv04
->blend
->b_dst
)<<28);
78 BEGIN_RING(fahrenheit
, NV04_DX5_TEXTURED_TRIANGLE_BLEND
, 1);
82 static void nv04_emit_sampler(struct nv04_context
*nv04
, int unit
)
84 struct nv04_miptree
*nv04mt
= nv04
->tex_miptree
[unit
];
85 struct pipe_texture
*pt
= &nv04mt
->base
;
87 BEGIN_RING(fahrenheit
, NV04_DX5_TEXTURED_TRIANGLE_OFFSET
, 3);
88 OUT_RELOCl(nv04mt
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
89 OUT_RELOCd(nv04mt
->buffer
, (nv04
->fragtex
.format
| nv04
->sampler
[unit
]->format
), NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 1/*VRAM*/,2/*TT*/);
90 OUT_RING(nv04
->sampler
[unit
]->filter
);
93 static void nv04_state_emit_framebuffer(struct nv04_context
* nv04
)
95 struct pipe_framebuffer_state
* fb
= nv04
->framebuffer
;
96 struct nv04_surface
*rt
, *zeta
;
97 uint32_t rt_format
, w
, h
;
98 int colour_format
= 0, zeta_format
= 0;
99 struct nv04_miptree
*nv04mt
= 0;
101 w
= fb
->cbufs
[0]->width
;
102 h
= fb
->cbufs
[0]->height
;
103 colour_format
= fb
->cbufs
[0]->format
;
104 rt
= (struct nv04_surface
*)fb
->cbufs
[0];
108 assert(w
== fb
->zsbuf
->width
);
109 assert(h
== fb
->zsbuf
->height
);
111 w
= fb
->zsbuf
->width
;
112 h
= fb
->zsbuf
->height
;
115 zeta_format
= fb
->zsbuf
->format
;
116 zeta
= (struct nv04_surface
*)fb
->zsbuf
;
119 switch (colour_format
) {
120 case PIPE_FORMAT_A8R8G8B8_UNORM
:
124 case PIPE_FORMAT_R5G6B5_UNORM
:
131 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_FORMAT
, 1);
134 nv04mt
= (struct nv04_miptree
*)rt
->base
.texture
;
135 /* FIXME pitches have to be aligned ! */
136 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_PITCH
, 2);
137 OUT_RING(rt
->pitch
|(zeta
->pitch
<<16));
138 OUT_RELOCl(nv04mt
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
140 nv04mt
= (struct nv04_miptree
*)zeta
->base
.texture
;
141 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA
, 1);
142 OUT_RELOCl(nv04mt
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
147 nv04_emit_hw_state(struct nv04_context
*nv04
)
151 if (nv04
->dirty
& NV04_NEW_VERTPROG
) {
152 //nv04_vertprog_bind(nv04, nv04->vertprog.current);
153 nv04
->dirty
&= ~NV04_NEW_VERTPROG
;
156 if (nv04
->dirty
& NV04_NEW_FRAGPROG
) {
157 nv04_fragprog_bind(nv04
, nv04
->fragprog
.current
);
158 nv04
->dirty
&= ~NV04_NEW_FRAGPROG
;
159 nv04
->dirty_samplers
|= (1<<10);
160 nv04
->dirty_samplers
= 0;
163 if (nv04
->dirty
& NV04_NEW_CONTROL
) {
164 nv04
->dirty
&= ~NV04_NEW_CONTROL
;
166 BEGIN_RING(fahrenheit
, NV04_DX5_TEXTURED_TRIANGLE_CONTROL
, 1);
167 OUT_RING(nv04
->dsa
->control
);
170 if (nv04
->dirty
& NV04_NEW_BLEND
) {
171 nv04
->dirty
&= ~NV04_NEW_BLEND
;
173 nv04_emit_blend(nv04
);
176 if (nv04
->dirty
& NV04_NEW_VTXARRAYS
) {
177 nv04
->dirty
&= ~NV04_NEW_VTXARRAYS
;
178 nv04_vertex_layout(nv04
);
181 if (nv04
->dirty
& NV04_NEW_SAMPLER
) {
182 nv04
->dirty
&= ~NV04_NEW_SAMPLER
;
184 nv04_emit_sampler(nv04
, 0);
187 if (nv04
->dirty
& NV04_NEW_VIEWPORT
) {
188 nv04
->dirty
&= ~NV04_NEW_VIEWPORT
;
189 // nv04_state_emit_viewport(nv04);
192 if (nv04
->dirty
& NV04_NEW_FRAMEBUFFER
) {
193 nv04
->dirty
&= ~NV04_NEW_FRAMEBUFFER
;
194 nv04_state_emit_framebuffer(nv04
);
197 /* Emit relocs for every referenced buffer.
198 * This is to ensure the bufmgr has an accurate idea of how
199 * the buffer is used. This isn't very efficient, but we don't
200 * seem to take a significant performance hit. Will be improved
201 * at some point. Vertex arrays are emitted by nv04_vbo.c
205 unsigned rt_pitch
= ((struct nv04_surface
*)nv04
->rt
)->pitch
;
206 unsigned zeta_pitch
= ((struct nv04_surface
*)nv04
->zeta
)->pitch
;
208 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_PITCH
, 2);
209 OUT_RING(rt_pitch
|(zeta_pitch
<<16));
210 OUT_RELOCl(nv04
->rt
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
212 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA
, 1);
213 OUT_RELOCl(nv04
->zeta
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
217 for (i
= 0; i
< 1; i
++) {
218 if (!(nv04
->fp_samplers
& (1 << i
)))
220 struct nv04_miptree
*nv04mt
= nv04
->tex_miptree
[i
];
221 BEGIN_RING(fahrenheit
, NV04_DX5_TEXTURED_TRIANGLE_OFFSET
, 2);
222 OUT_RELOCl(nv04mt
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
223 OUT_RELOCd(nv04mt
->buffer
, (nv04
->fragtex
.format
| nv04
->sampler
[i
]->format
), NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 1/*VRAM*/,2/*TT*/);