Merge branch 'nouveau-import'
[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 nouveau_renderbuffer *nrb;
63 const GLfloat *v = ctx->Viewport._WindowMap.m;
64 GLfloat *m = nmesa->viewport.m;
65 GLfloat xoffset, yoffset;
66 GLint h = 0;
67
68 nrb = nouveau_current_draw_buffer(ctx);
69 nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
70
71 if (nrb && nrb->map) {
72 /* Window */
73 xoffset = nrb->dPriv->x;
74 yoffset = nrb->dPriv->y;
75 } else {
76 /* Offscreen or back buffer */
77 xoffset = 0.0;
78 yoffset = 0.0;
79 }
80
81 m[MAT_SX] = v[MAT_SX];
82 m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X;
83 m[MAT_SY] = - v[MAT_SY];
84 m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y;
85 m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale;
86 m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale;
87
88 nmesa->hw_func.WindowMoved(nmesa);
89 }
90
91 static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
92 {
93 /*
94 * Need to send (at least on an nv35 the following:
95 * cons = 4 (this may be bytes per pixel)
96 *
97 * The viewport:
98 * 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ?
99 * 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons
100 * 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons
101 * 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons
102 * 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons
103 * 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS
104 * 44b 0x04000000 <-- (Width_from_glViewport << 16) | x
105 * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y)
106 *
107 */
108
109 nouveauCalcViewport(ctx);
110 }
111
112 static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
113 {
114 nouveauCalcViewport(ctx);
115 }
116
117 static void nouveauDDUpdateHWState(GLcontext *ctx)
118 {
119 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
120 int new_state = nmesa->new_state;
121
122 if ( new_state || nmesa->new_render_state & _NEW_TEXTURE )
123 {
124 nmesa->new_state = 0;
125
126 /* Update the various parts of the context's state.
127 */
128 /*
129 if ( new_state & NOUVEAU_NEW_ALPHA )
130 nouveauUpdateAlphaMode( ctx );
131
132 if ( new_state & NOUVEAU_NEW_DEPTH )
133 nouveauUpdateZMode( ctx );
134
135 if ( new_state & NOUVEAU_NEW_FOG )
136 nouveauUpdateFogAttrib( ctx );
137
138 if ( new_state & NOUVEAU_NEW_CLIP )
139 nouveauUpdateClipping( ctx );
140
141 if ( new_state & NOUVEAU_NEW_CULL )
142 nouveauUpdateCull( ctx );
143
144 if ( new_state & NOUVEAU_NEW_MASKS )
145 nouveauUpdateMasks( ctx );
146
147 if ( new_state & NOUVEAU_NEW_WINDOW )
148 nouveauUpdateWindow( ctx );
149
150 if ( nmesa->new_render_state & _NEW_TEXTURE ) {
151 nouveauUpdateTextureState( ctx );
152 }*/
153 }
154 }
155
156 static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
157 {
158 _swrast_InvalidateState( ctx, new_state );
159 _swsetup_InvalidateState( ctx, new_state );
160 _ac_InvalidateState( ctx, new_state );
161 _tnl_InvalidateState( ctx, new_state );
162 NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state;
163 }
164
165 /* Initialize the context's hardware state. */
166 void nouveauDDInitState(nouveauContextPtr nmesa)
167 {
168 uint32_t type = nmesa->screen->card->type;
169 switch(type)
170 {
171 case NV_03:
172 case NV_04:
173 case NV_05:
174 /* No TCL engines for these ones */
175 break;
176 case NV_10:
177 nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
178 break;
179 case NV_20:
180 nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
181 break;
182 case NV_30:
183 case NV_40:
184 case NV_44:
185 case NV_50:
186 nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
187 break;
188 default:
189 break;
190 }
191 nouveau_state_cache_init(nmesa);
192 }
193
194 /* Initialize the driver's state functions */
195 void nouveauDDInitStateFuncs(GLcontext *ctx)
196 {
197 ctx->Driver.UpdateState = nouveauDDInvalidateState;
198
199 ctx->Driver.ClearIndex = NULL;
200 ctx->Driver.ClearColor = NULL; //nouveauDDClearColor;
201 ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil;
202 ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer;
203 ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer;
204
205 ctx->Driver.IndexMask = NULL;
206 ctx->Driver.ColorMask = NULL; //nouveauDDColorMask;
207 ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc;
208 ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate;
209 ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate;
210 ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth;
211 ctx->Driver.CullFace = NULL; //nouveauDDCullFace;
212 ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace;
213 ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc;
214 ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask;
215 ctx->Driver.Enable = NULL; //nouveauDDEnable;
216 ctx->Driver.Fogfv = NULL; //nouveauDDFogfv;
217 ctx->Driver.Hint = NULL;
218 ctx->Driver.Lightfv = NULL;
219 ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv;
220 ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode;
221 ctx->Driver.PolygonMode = NULL;
222 ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple;
223 ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode;
224 ctx->Driver.Scissor = NULL; //nouveauDDScissor;
225 ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel;
226 ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate;
227 ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate;
228 ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate;
229
230 ctx->Driver.DepthRange = nouveauDepthRange;
231 ctx->Driver.Viewport = nouveauViewport;
232
233 /* Pixel path fallbacks.
234 */
235 ctx->Driver.Accum = _swrast_Accum;
236 ctx->Driver.Bitmap = _swrast_Bitmap;
237 ctx->Driver.CopyPixels = _swrast_CopyPixels;
238 ctx->Driver.DrawPixels = _swrast_DrawPixels;
239 ctx->Driver.ReadPixels = _swrast_ReadPixels;
240
241 /* Swrast hooks for imaging extensions:
242 */
243 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
244 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
245 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
246 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
247 }
248
249 #define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a
250
251 void nouveauInitState(GLcontext *ctx)
252 {
253 /*
254 * Mesa should do this for us:
255 */
256
257 STATE_INIT(AlphaFunc)( ctx,
258 ctx->Color.AlphaFunc,
259 ctx->Color.AlphaRef);
260
261 STATE_INIT(BlendColor)( ctx,
262 ctx->Color.BlendColor );
263
264 STATE_INIT(BlendEquationSeparate)( ctx,
265 ctx->Color.BlendEquationRGB,
266 ctx->Color.BlendEquationA);
267
268 STATE_INIT(BlendFuncSeparate)( ctx,
269 ctx->Color.BlendSrcRGB,
270 ctx->Color.BlendDstRGB,
271 ctx->Color.BlendSrcA,
272 ctx->Color.BlendDstA);
273
274 STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor);
275 STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear);
276 STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear);
277
278 STATE_INIT(ColorMask)( ctx,
279 ctx->Color.ColorMask[RCOMP],
280 ctx->Color.ColorMask[GCOMP],
281 ctx->Color.ColorMask[BCOMP],
282 ctx->Color.ColorMask[ACOMP]);
283
284 STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode );
285 STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func );
286 STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask );
287
288 STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
289 STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled );
290 STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
291 STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
292 STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
293 STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
294 STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag );
295 STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled );
296 STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
297 STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
298 STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
299 STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
300 STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
301 STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
302 STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
303 STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
304 STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
305 STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
306 STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
307 STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE );
308 STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE );
309 STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
310 STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE );
311 STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
312
313 STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
314 STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 );
315 STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
316 STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start );
317 STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End );
318
319 STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace );
320
321 {
322 GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
323 STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
324 }
325
326 STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern );
327 STATE_INIT(LineWidth)( ctx, ctx->Line.Width );
328 STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp );
329 STATE_INIT(PointSize)( ctx, ctx->Point.Size );
330 STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode );
331 STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode );
332 STATE_INIT(PolygonOffset)( ctx,
333 ctx->Polygon.OffsetFactor,
334 ctx->Polygon.OffsetUnits );
335 STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
336 STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
337 STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
338 ctx->Stencil.Function[0],
339 ctx->Stencil.Ref[0],
340 ctx->Stencil.ValueMask[0] );
341 STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK,
342 ctx->Stencil.Function[1],
343 ctx->Stencil.Ref[1],
344 ctx->Stencil.ValueMask[1] );
345 STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
346 STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
347 STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT,
348 ctx->Stencil.FailFunc[0],
349 ctx->Stencil.ZFailFunc[0],
350 ctx->Stencil.ZPassFunc[0]);
351 STATE_INIT(StencilOpSeparate)( ctx, GL_BACK,
352 ctx->Stencil.FailFunc[1],
353 ctx->Stencil.ZFailFunc[1],
354 ctx->Stencil.ZPassFunc[1]);
355 }