nouveau: add nv04 state support, and small nv04 fixes.
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_state.c
1 /**************************************************************************
2
3 Copyright 2006 Jeremy Kolb
4 All Rights Reserved.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 on the rights to use, copy, modify, merge, publish, distribute, sub
10 license, and/or sell copies of the Software, and to permit persons to whom
11 the Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice (including the next
14 paragraph) shall be included in all copies or substantial portions of the
15 Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
21 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 **************************************************************************/
26
27 #include "nouveau_context.h"
28 #include "nouveau_state.h"
29 #include "nouveau_swtcl.h"
30 #include "nouveau_fifo.h"
31
32 #include "swrast/swrast.h"
33 #include "array_cache/acache.h"
34 #include "tnl/tnl.h"
35 #include "swrast_setup/swrast_setup.h"
36
37 #include "tnl/t_pipeline.h"
38
39 #include "mtypes.h"
40 #include "colormac.h"
41
42 static __inline__ GLuint nouveauPackColor(GLuint format,
43 GLubyte r, GLubyte g,
44 GLubyte b, GLubyte a)
45 {
46 switch (format) {
47 case 2:
48 return PACK_COLOR_565( r, g, b );
49 case 4:
50 return PACK_COLOR_8888( r, g, b, a);
51 default:
52 fprintf(stderr, "unknown format %d\n", (int)format);
53 return 0;
54 }
55 }
56
57 static void nouveauCalcViewport(GLcontext *ctx)
58 {
59 /* Calculate the Viewport Matrix */
60
61 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
62 const GLfloat *v = ctx->Viewport._WindowMap.m;
63 GLfloat *m = nmesa->viewport.m;
64 GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY;
65
66 nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
67
68 m[MAT_SX] = v[MAT_SX];
69 m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X;
70 m[MAT_SY] = - v[MAT_SY];
71 m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y;
72 m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale;
73 m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale;
74
75 nmesa->hw_func.WindowMoved(nmesa);
76 }
77
78 static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
79 {
80 /*
81 * Need to send (at least on an nv35 the following:
82 * cons = 4 (this may be bytes per pixel)
83 *
84 * The viewport:
85 * 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ?
86 * 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons
87 * 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons
88 * 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons
89 * 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons
90 * 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS
91 * 44b 0x04000000 <-- (Width_from_glViewport << 16) | x
92 * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y)
93 *
94 */
95
96 nouveauCalcViewport(ctx);
97 }
98
99 static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
100 {
101 nouveauCalcViewport(ctx);
102 }
103
104 static void nouveauDDUpdateHWState(GLcontext *ctx)
105 {
106 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
107 int new_state = nmesa->new_state;
108
109 if ( new_state || nmesa->new_render_state & _NEW_TEXTURE )
110 {
111 nmesa->new_state = 0;
112
113 /* Update the various parts of the context's state.
114 */
115 /*
116 if ( new_state & NOUVEAU_NEW_ALPHA )
117 nouveauUpdateAlphaMode( ctx );
118
119 if ( new_state & NOUVEAU_NEW_DEPTH )
120 nouveauUpdateZMode( ctx );
121
122 if ( new_state & NOUVEAU_NEW_FOG )
123 nouveauUpdateFogAttrib( ctx );
124
125 if ( new_state & NOUVEAU_NEW_CLIP )
126 nouveauUpdateClipping( ctx );
127
128 if ( new_state & NOUVEAU_NEW_CULL )
129 nouveauUpdateCull( ctx );
130
131 if ( new_state & NOUVEAU_NEW_MASKS )
132 nouveauUpdateMasks( ctx );
133
134 if ( new_state & NOUVEAU_NEW_WINDOW )
135 nouveauUpdateWindow( ctx );
136
137 if ( nmesa->new_render_state & _NEW_TEXTURE ) {
138 nouveauUpdateTextureState( ctx );
139 }*/
140 }
141 }
142
143 static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
144 {
145 _swrast_InvalidateState( ctx, new_state );
146 _swsetup_InvalidateState( ctx, new_state );
147 _ac_InvalidateState( ctx, new_state );
148 _tnl_InvalidateState( ctx, new_state );
149 NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state;
150 }
151
152 /* Initialize the context's hardware state. */
153 void nouveauDDInitState(nouveauContextPtr nmesa)
154 {
155 uint32_t type = nmesa->screen->card->type;
156 switch(type)
157 {
158 case NV_03:
159 /* Unimplemented */
160 break;
161 case NV_04:
162 case NV_05:
163 nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
164 break;
165 case NV_10:
166 nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
167 break;
168 case NV_20:
169 nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
170 break;
171 case NV_30:
172 case NV_40:
173 case NV_44:
174 case NV_50:
175 nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
176 break;
177 default:
178 break;
179 }
180 nouveau_state_cache_init(nmesa);
181 }
182
183 /* Initialize the driver's state functions */
184 void nouveauDDInitStateFuncs(GLcontext *ctx)
185 {
186 ctx->Driver.UpdateState = nouveauDDInvalidateState;
187
188 ctx->Driver.ClearIndex = NULL;
189 ctx->Driver.ClearColor = NULL; //nouveauDDClearColor;
190 ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil;
191 ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer;
192 ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer;
193
194 ctx->Driver.IndexMask = NULL;
195 ctx->Driver.ColorMask = NULL; //nouveauDDColorMask;
196 ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc;
197 ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate;
198 ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate;
199 ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth;
200 ctx->Driver.CullFace = NULL; //nouveauDDCullFace;
201 ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace;
202 ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc;
203 ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask;
204 ctx->Driver.Enable = NULL; //nouveauDDEnable;
205 ctx->Driver.Fogfv = NULL; //nouveauDDFogfv;
206 ctx->Driver.Hint = NULL;
207 ctx->Driver.Lightfv = NULL;
208 ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv;
209 ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode;
210 ctx->Driver.PolygonMode = NULL;
211 ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple;
212 ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode;
213 ctx->Driver.Scissor = NULL; //nouveauDDScissor;
214 ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel;
215 ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate;
216 ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate;
217 ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate;
218
219 ctx->Driver.DepthRange = nouveauDepthRange;
220 ctx->Driver.Viewport = nouveauViewport;
221
222 /* Pixel path fallbacks.
223 */
224 ctx->Driver.Accum = _swrast_Accum;
225 ctx->Driver.Bitmap = _swrast_Bitmap;
226 ctx->Driver.CopyPixels = _swrast_CopyPixels;
227 ctx->Driver.DrawPixels = _swrast_DrawPixels;
228 ctx->Driver.ReadPixels = _swrast_ReadPixels;
229
230 /* Swrast hooks for imaging extensions:
231 */
232 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
233 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
234 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
235 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
236 }
237
238 #define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a
239
240 void nouveauInitState(GLcontext *ctx)
241 {
242 /*
243 * Mesa should do this for us:
244 */
245
246 STATE_INIT(AlphaFunc)( ctx,
247 ctx->Color.AlphaFunc,
248 ctx->Color.AlphaRef);
249
250 STATE_INIT(BlendColor)( ctx,
251 ctx->Color.BlendColor );
252
253 STATE_INIT(BlendEquationSeparate)( ctx,
254 ctx->Color.BlendEquationRGB,
255 ctx->Color.BlendEquationA);
256
257 STATE_INIT(BlendFuncSeparate)( ctx,
258 ctx->Color.BlendSrcRGB,
259 ctx->Color.BlendDstRGB,
260 ctx->Color.BlendSrcA,
261 ctx->Color.BlendDstA);
262
263 STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor);
264 STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear);
265 STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear);
266
267 STATE_INIT(ColorMask)( ctx,
268 ctx->Color.ColorMask[RCOMP],
269 ctx->Color.ColorMask[GCOMP],
270 ctx->Color.ColorMask[BCOMP],
271 ctx->Color.ColorMask[ACOMP]);
272
273 STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode );
274 STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func );
275 STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask );
276
277 STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
278 STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled );
279 STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
280 STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
281 STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
282 STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
283 STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag );
284 STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled );
285 STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
286 STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
287 STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
288 STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
289 STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
290 STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
291 STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
292 STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
293 STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
294 STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
295 STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
296 STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE );
297 STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE );
298 STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
299 STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE );
300 STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
301
302 STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
303 STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 );
304 STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
305 STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start );
306 STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End );
307
308 STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace );
309
310 {
311 GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
312 STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
313 }
314
315 STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern );
316 STATE_INIT(LineWidth)( ctx, ctx->Line.Width );
317 STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp );
318 STATE_INIT(PointSize)( ctx, ctx->Point.Size );
319 STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode );
320 STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode );
321 STATE_INIT(PolygonOffset)( ctx,
322 ctx->Polygon.OffsetFactor,
323 ctx->Polygon.OffsetUnits );
324 STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
325 STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
326 STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
327 ctx->Stencil.Function[0],
328 ctx->Stencil.Ref[0],
329 ctx->Stencil.ValueMask[0] );
330 STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK,
331 ctx->Stencil.Function[1],
332 ctx->Stencil.Ref[1],
333 ctx->Stencil.ValueMask[1] );
334 STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
335 STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
336 STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT,
337 ctx->Stencil.FailFunc[0],
338 ctx->Stencil.ZFailFunc[0],
339 ctx->Stencil.ZPassFunc[0]);
340 STATE_INIT(StencilOpSeparate)( ctx, GL_BACK,
341 ctx->Stencil.FailFunc[1],
342 ctx->Stencil.ZFailFunc[1],
343 ctx->Stencil.ZPassFunc[1]);
344 }