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
;
60 struct nv04_screen
*screen
= nv04
->screen
;
61 struct nouveau_channel
*chan
= screen
->base
.channel
;
62 struct nouveau_grobj
*fahrenheit
= screen
->fahrenheit
;
64 BEGIN_RING(chan
, fahrenheit
, NV04_TEXTURED_TRIANGLE_CONTROL
, 1);
65 OUT_RING(chan
, control
);
68 static void nv04_emit_blend(struct nv04_context
* nv04
)
70 struct nv04_screen
*screen
= nv04
->screen
;
71 struct nouveau_channel
*chan
= screen
->base
.channel
;
72 struct nouveau_grobj
*fahrenheit
= screen
->fahrenheit
;
75 blend
=0x4; // texture MODULATE_ALPHA
76 blend
|=0x20; // alpha is MSB
77 blend
|=(2<<6); // flat shading
78 blend
|=(1<<8); // persp correct
79 blend
|=(0<<16); // no fog
80 blend
|=(nv04
->blend
->b_enable
<<20);
81 blend
|=(nv04_blend_func(nv04
->blend
->b_src
)<<24);
82 blend
|=(nv04_blend_func(nv04
->blend
->b_dst
)<<28);
84 BEGIN_RING(chan
, fahrenheit
, NV04_TEXTURED_TRIANGLE_BLEND
, 1);
85 OUT_RING(chan
, blend
);
88 static void nv04_emit_sampler(struct nv04_context
*nv04
, int unit
)
90 struct nv04_miptree
*nv04mt
= nv04
->tex_miptree
[unit
];
91 struct pipe_texture
*pt
= &nv04mt
->base
;
92 struct nv04_screen
*screen
= nv04
->screen
;
93 struct nouveau_channel
*chan
= screen
->base
.channel
;
94 struct nouveau_grobj
*fahrenheit
= screen
->fahrenheit
;
95 struct nouveau_bo
*bo
= nouveau_bo(nv04mt
->buffer
);
97 BEGIN_RING(chan
, fahrenheit
, NV04_TEXTURED_TRIANGLE_OFFSET
, 3);
98 OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
99 OUT_RELOCd(chan
, bo
, (nv04
->fragtex
.format
| nv04
->sampler
[unit
]->format
), NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 1/*VRAM*/,2/*TT*/);
100 OUT_RING(chan
, nv04
->sampler
[unit
]->filter
);
103 static void nv04_state_emit_framebuffer(struct nv04_context
* nv04
)
105 struct pipe_framebuffer_state
* fb
= nv04
->framebuffer
;
106 struct nv04_surface
*rt
, *zeta
;
107 uint32_t rt_format
, w
, h
;
108 int colour_format
= 0, zeta_format
= 0;
109 struct nv04_miptree
*nv04mt
= 0;
110 struct nv04_screen
*screen
= nv04
->screen
;
111 struct nouveau_channel
*chan
= screen
->base
.channel
;
112 struct nouveau_grobj
*context_surfaces_3d
= screen
->context_surfaces_3d
;
113 struct nouveau_bo
*bo
;
115 w
= fb
->cbufs
[0]->width
;
116 h
= fb
->cbufs
[0]->height
;
117 colour_format
= fb
->cbufs
[0]->format
;
118 rt
= (struct nv04_surface
*)fb
->cbufs
[0];
122 assert(w
== fb
->zsbuf
->width
);
123 assert(h
== fb
->zsbuf
->height
);
125 w
= fb
->zsbuf
->width
;
126 h
= fb
->zsbuf
->height
;
129 zeta_format
= fb
->zsbuf
->format
;
130 zeta
= (struct nv04_surface
*)fb
->zsbuf
;
133 switch (colour_format
) {
134 case PIPE_FORMAT_A8R8G8B8_UNORM
:
138 case PIPE_FORMAT_R5G6B5_UNORM
:
145 BEGIN_RING(chan
, context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_FORMAT
, 1);
146 OUT_RING(chan
, rt_format
);
148 nv04mt
= (struct nv04_miptree
*)rt
->base
.texture
;
149 bo
= nouveau_bo(nv04mt
->buffer
);
150 /* FIXME pitches have to be aligned ! */
151 BEGIN_RING(chan
, context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_PITCH
, 2);
152 OUT_RING(chan
, rt
->pitch
|(zeta
->pitch
<<16));
153 OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
155 nv04mt
= (struct nv04_miptree
*)zeta
->base
.texture
;
156 BEGIN_RING(chan
, context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA
, 1);
157 OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
162 nv04_emit_hw_state(struct nv04_context
*nv04
)
164 struct nv04_screen
*screen
= nv04
->screen
;
165 struct nouveau_channel
*chan
= screen
->base
.channel
;
166 struct nouveau_grobj
*fahrenheit
= screen
->fahrenheit
;
167 struct nouveau_grobj
*context_surfaces_3d
= screen
->context_surfaces_3d
;
170 if (nv04
->dirty
& NV04_NEW_VERTPROG
) {
171 //nv04_vertprog_bind(nv04, nv04->vertprog.current);
172 nv04
->dirty
&= ~NV04_NEW_VERTPROG
;
175 if (nv04
->dirty
& NV04_NEW_FRAGPROG
) {
176 nv04_fragprog_bind(nv04
, nv04
->fragprog
.current
);
177 nv04
->dirty
&= ~NV04_NEW_FRAGPROG
;
178 nv04
->dirty_samplers
|= (1<<10);
179 nv04
->dirty_samplers
= 0;
182 if (nv04
->dirty
& NV04_NEW_CONTROL
) {
183 nv04
->dirty
&= ~NV04_NEW_CONTROL
;
185 BEGIN_RING(chan
, fahrenheit
, NV04_TEXTURED_TRIANGLE_CONTROL
, 1);
186 OUT_RING(chan
, nv04
->dsa
->control
);
189 if (nv04
->dirty
& NV04_NEW_BLEND
) {
190 nv04
->dirty
&= ~NV04_NEW_BLEND
;
192 nv04_emit_blend(nv04
);
195 if (nv04
->dirty
& NV04_NEW_VTXARRAYS
) {
196 nv04
->dirty
&= ~NV04_NEW_VTXARRAYS
;
197 nv04_vertex_layout(nv04
);
200 if (nv04
->dirty
& NV04_NEW_SAMPLER
) {
201 nv04
->dirty
&= ~NV04_NEW_SAMPLER
;
203 nv04_emit_sampler(nv04
, 0);
206 if (nv04
->dirty
& NV04_NEW_VIEWPORT
) {
207 nv04
->dirty
&= ~NV04_NEW_VIEWPORT
;
208 // nv04_state_emit_viewport(nv04);
211 if (nv04
->dirty
& NV04_NEW_FRAMEBUFFER
) {
212 nv04
->dirty
&= ~NV04_NEW_FRAMEBUFFER
;
213 nv04_state_emit_framebuffer(nv04
);
216 /* Emit relocs for every referenced buffer.
217 * This is to ensure the bufmgr has an accurate idea of how
218 * the buffer is used. This isn't very efficient, but we don't
219 * seem to take a significant performance hit. Will be improved
220 * at some point. Vertex arrays are emitted by nv04_vbo.c
224 unsigned rt_pitch
= ((struct nv04_surface
*)nv04
->rt
)->pitch
;
225 unsigned zeta_pitch
= ((struct nv04_surface
*)nv04
->zeta
)->pitch
;
227 BEGIN_RING(chan
, context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_PITCH
, 2);
228 OUT_RING(chan
, rt_pitch
|(zeta_pitch
<<16));
229 OUT_RELOCl(chan
, nouveau_bo(nv04
->rt
), 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
231 BEGIN_RING(chan
, context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA
, 1);
232 OUT_RELOCl(chan
, nouveau_bo(nv04
->zeta
), 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
236 for (i
= 0; i
< 1; i
++) {
237 if (!(nv04
->fp_samplers
& (1 << i
)))
239 struct nv04_miptree
*nv04mt
= nv04
->tex_miptree
[i
];
240 struct nouveau_bo
*bo
= nouveau_bo(nv04mt
->buffer
);
241 BEGIN_RING(chan
, fahrenheit
, NV04_TEXTURED_TRIANGLE_OFFSET
, 2);
242 OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
243 OUT_RELOCd(chan
, bo
, (nv04
->fragtex
.format
| nv04
->sampler
[i
]->format
), NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_OR
| NOUVEAU_BO_RD
, 1/*VRAM*/,2/*TT*/);