Merge branch 'gallium-nopointsizeminmax'
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_state.c
1 /*
2 * Copyright (C) 2009 Francisco Jerez.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27 #include "nouveau_driver.h"
28 #include "nouveau_context.h"
29 #include "nouveau_texture.h"
30 #include "nouveau_util.h"
31
32 #include "swrast/swrast.h"
33 #include "tnl/tnl.h"
34
35 static void
36 nouveau_alpha_func(GLcontext *ctx, GLenum func, GLfloat ref)
37 {
38 context_dirty(ctx, ALPHA_FUNC);
39 }
40
41 static void
42 nouveau_blend_color(GLcontext *ctx, const GLfloat color[4])
43 {
44 context_dirty(ctx, BLEND_COLOR);
45 }
46
47 static void
48 nouveau_blend_equation_separate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
49 {
50 context_dirty(ctx, BLEND_EQUATION);
51 }
52
53 static void
54 nouveau_blend_func_separate(GLcontext *ctx, GLenum sfactorRGB,
55 GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA)
56 {
57 context_dirty(ctx, BLEND_FUNC);
58 }
59
60 static void
61 nouveau_clip_plane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
62 {
63 context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0);
64 }
65
66 static void
67 nouveau_color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
68 GLboolean bmask, GLboolean amask)
69 {
70 context_dirty(ctx, COLOR_MASK);
71 }
72
73 static void
74 nouveau_color_material(GLcontext *ctx, GLenum face, GLenum mode)
75 {
76 context_dirty(ctx, COLOR_MATERIAL);
77 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
78 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
79 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
80 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
81 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
82 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
83 }
84
85 static void
86 nouveau_cull_face(GLcontext *ctx, GLenum mode)
87 {
88 context_dirty(ctx, CULL_FACE);
89 }
90
91 static void
92 nouveau_front_face(GLcontext *ctx, GLenum mode)
93 {
94 context_dirty(ctx, FRONT_FACE);
95 }
96
97 static void
98 nouveau_depth_func(GLcontext *ctx, GLenum func)
99 {
100 context_dirty(ctx, DEPTH);
101 }
102
103 static void
104 nouveau_depth_mask(GLcontext *ctx, GLboolean flag)
105 {
106 context_dirty(ctx, DEPTH);
107 }
108
109 static void
110 nouveau_depth_range(GLcontext *ctx, GLclampd nearval, GLclampd farval)
111 {
112 context_dirty(ctx, VIEWPORT);
113 }
114
115 static void
116 nouveau_draw_buffer(GLcontext *ctx, GLenum buffer)
117 {
118 context_dirty(ctx, FRAMEBUFFER);
119 }
120
121 static void
122 nouveau_draw_buffers(GLcontext *ctx, GLsizei n, const GLenum *buffers)
123 {
124 context_dirty(ctx, FRAMEBUFFER);
125 }
126
127 static void
128 nouveau_enable(GLcontext *ctx, GLenum cap, GLboolean state)
129 {
130 int i;
131
132 switch (cap) {
133 case GL_ALPHA_TEST:
134 context_dirty(ctx, ALPHA_FUNC);
135 break;
136 case GL_BLEND:
137 context_dirty(ctx, BLEND_EQUATION);
138 break;
139 case GL_COLOR_LOGIC_OP:
140 context_dirty(ctx, LOGIC_OPCODE);
141 break;
142 case GL_COLOR_MATERIAL:
143 context_dirty(ctx, COLOR_MATERIAL);
144 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
145 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
146 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
147 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
148 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
149 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
150 break;
151 case GL_COLOR_SUM_EXT:
152 context_dirty(ctx, FRAG);
153 break;
154 case GL_CULL_FACE:
155 context_dirty(ctx, CULL_FACE);
156 break;
157 case GL_DEPTH_TEST:
158 context_dirty(ctx, DEPTH);
159 break;
160 case GL_DITHER:
161 context_dirty(ctx, DITHER);
162 break;
163 case GL_FOG:
164 context_dirty(ctx, FOG);
165 context_dirty(ctx, FRAG);
166 context_dirty(ctx, MODELVIEW);
167 break;
168 case GL_LIGHT0:
169 case GL_LIGHT1:
170 case GL_LIGHT2:
171 case GL_LIGHT3:
172 case GL_LIGHT4:
173 case GL_LIGHT5:
174 case GL_LIGHT6:
175 case GL_LIGHT7:
176 context_dirty(ctx, MODELVIEW);
177 context_dirty(ctx, LIGHT_ENABLE);
178 context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0);
179 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
180 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
181 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
182 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
183 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
184 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
185 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
186 context_dirty(ctx, MATERIAL_BACK_SHININESS);
187 break;
188 case GL_LIGHTING:
189 context_dirty(ctx, FRAG);
190 context_dirty(ctx, MODELVIEW);
191 context_dirty(ctx, LIGHT_ENABLE);
192
193 for (i = 0; i < MAX_LIGHTS; i++) {
194 if (ctx->Light.Light[i].Enabled)
195 context_dirty_i(ctx, LIGHT_SOURCE, i);
196 }
197
198 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
199 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
200 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
201 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
202 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
203 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
204 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
205 context_dirty(ctx, MATERIAL_BACK_SHININESS);
206 break;
207 case GL_LINE_SMOOTH:
208 context_dirty(ctx, LINE_MODE);
209 break;
210 case GL_NORMALIZE:
211 context_dirty(ctx, LIGHT_ENABLE);
212 break;
213 case GL_POINT_SMOOTH:
214 context_dirty(ctx, POINT_MODE);
215 break;
216 case GL_POLYGON_OFFSET_POINT:
217 case GL_POLYGON_OFFSET_LINE:
218 case GL_POLYGON_OFFSET_FILL:
219 context_dirty(ctx, POLYGON_OFFSET);
220 break;
221 case GL_POLYGON_SMOOTH:
222 context_dirty(ctx, POLYGON_MODE);
223 break;
224 case GL_SCISSOR_TEST:
225 context_dirty(ctx, SCISSOR);
226 break;
227 case GL_STENCIL_TEST:
228 context_dirty(ctx, STENCIL_FUNC);
229 break;
230 case GL_TEXTURE_1D:
231 case GL_TEXTURE_2D:
232 case GL_TEXTURE_3D:
233 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
234 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
235 break;
236 }
237 }
238
239 static void
240 nouveau_fog(GLcontext *ctx, GLenum pname, const GLfloat *params)
241 {
242 context_dirty(ctx, FOG);
243 }
244
245 static void
246 nouveau_index_mask(GLcontext *ctx, GLuint mask)
247 {
248 context_dirty(ctx, INDEX_MASK);
249 }
250
251 static void
252 nouveau_light(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params)
253 {
254 switch (pname) {
255 case GL_AMBIENT:
256 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
257 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
258 break;
259 case GL_DIFFUSE:
260 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
261 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
262 break;
263 case GL_SPECULAR:
264 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
265 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
266 break;
267 case GL_SPOT_CUTOFF:
268 case GL_POSITION:
269 context_dirty(ctx, MODELVIEW);
270 context_dirty(ctx, LIGHT_ENABLE);
271 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
272 break;
273 default:
274 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
275 break;
276 }
277 }
278
279 static void
280 nouveau_light_model(GLcontext *ctx, GLenum pname, const GLfloat *params)
281 {
282 context_dirty(ctx, LIGHT_MODEL);
283 context_dirty(ctx, MODELVIEW);
284 }
285
286 static void
287 nouveau_line_stipple(GLcontext *ctx, GLint factor, GLushort pattern )
288 {
289 context_dirty(ctx, LINE_STIPPLE);
290 }
291
292 static void
293 nouveau_line_width(GLcontext *ctx, GLfloat width)
294 {
295 context_dirty(ctx, LINE_MODE);
296 }
297
298 static void
299 nouveau_logic_opcode(GLcontext *ctx, GLenum opcode)
300 {
301 context_dirty(ctx, LOGIC_OPCODE);
302 }
303
304 static void
305 nouveau_point_parameter(GLcontext *ctx, GLenum pname, const GLfloat *params)
306 {
307 context_dirty(ctx, POINT_PARAMETER);
308 }
309
310 static void
311 nouveau_point_size(GLcontext *ctx, GLfloat size)
312 {
313 context_dirty(ctx, POINT_MODE);
314 }
315
316 static void
317 nouveau_polygon_mode(GLcontext *ctx, GLenum face, GLenum mode)
318 {
319 context_dirty(ctx, POLYGON_MODE);
320 }
321
322 static void
323 nouveau_polygon_offset(GLcontext *ctx, GLfloat factor, GLfloat units)
324 {
325 context_dirty(ctx, POLYGON_OFFSET);
326 }
327
328 static void
329 nouveau_polygon_stipple(GLcontext *ctx, const GLubyte *mask)
330 {
331 context_dirty(ctx, POLYGON_STIPPLE);
332 }
333
334 static void
335 nouveau_render_mode(GLcontext *ctx, GLenum mode)
336 {
337 context_dirty(ctx, RENDER_MODE);
338 }
339
340 static void
341 nouveau_scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
342 {
343 context_dirty(ctx, SCISSOR);
344 }
345
346 static void
347 nouveau_shade_model(GLcontext *ctx, GLenum mode)
348 {
349 context_dirty(ctx, SHADE_MODEL);
350 }
351
352 static void
353 nouveau_stencil_func_separate(GLcontext *ctx, GLenum face, GLenum func,
354 GLint ref, GLuint mask)
355 {
356 context_dirty(ctx, STENCIL_FUNC);
357 }
358
359 static void
360 nouveau_stencil_mask_separate(GLcontext *ctx, GLenum face, GLuint mask)
361 {
362 context_dirty(ctx, STENCIL_MASK);
363 }
364
365 static void
366 nouveau_stencil_op_separate(GLcontext *ctx, GLenum face, GLenum fail,
367 GLenum zfail, GLenum zpass)
368 {
369 context_dirty(ctx, STENCIL_OP);
370 }
371
372 static void
373 nouveau_tex_gen(GLcontext *ctx, GLenum coord, GLenum pname,
374 const GLfloat *params)
375 {
376 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
377 }
378
379 static void
380 nouveau_tex_env(GLcontext *ctx, GLenum target, GLenum pname,
381 const GLfloat *param)
382 {
383 switch (target) {
384 case GL_TEXTURE_FILTER_CONTROL_EXT:
385 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
386 break;
387 default:
388 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
389 break;
390 }
391 }
392
393 static void
394 nouveau_tex_parameter(GLcontext *ctx, GLenum target,
395 struct gl_texture_object *t, GLenum pname,
396 const GLfloat *params)
397 {
398 switch (pname) {
399 case GL_TEXTURE_MIN_FILTER:
400 case GL_TEXTURE_MAG_FILTER:
401 case GL_TEXTURE_WRAP_S:
402 case GL_TEXTURE_WRAP_T:
403 case GL_TEXTURE_WRAP_R:
404 case GL_TEXTURE_MIN_LOD:
405 case GL_TEXTURE_MAX_LOD:
406 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
407 case GL_TEXTURE_LOD_BIAS:
408 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
409 break;
410
411 case GL_TEXTURE_BASE_LEVEL:
412 case GL_TEXTURE_MAX_LEVEL:
413 texture_dirty(t);
414 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
415 break;
416 }
417 }
418
419 static void
420 nouveau_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
421 {
422 context_dirty(ctx, VIEWPORT);
423 }
424
425 void
426 nouveau_emit_nothing(GLcontext *ctx, int emit)
427 {
428 }
429
430 int
431 nouveau_next_dirty_state(GLcontext *ctx)
432 {
433 struct nouveau_context *nctx = to_nouveau_context(ctx);
434 int i = BITSET_FFS(nctx->dirty) - 1;
435
436 if (i < 0 || i >= context_drv(ctx)->num_emit)
437 return -1;
438
439 return i;
440 }
441
442 void
443 nouveau_state_emit(GLcontext *ctx)
444 {
445 struct nouveau_context *nctx = to_nouveau_context(ctx);
446 const struct nouveau_driver *drv = context_drv(ctx);
447 int i;
448
449 while ((i = nouveau_next_dirty_state(ctx)) >= 0) {
450 BITSET_CLEAR(nctx->dirty, i);
451 drv->emit[i](ctx, i);
452 }
453
454 BITSET_ZERO(nctx->dirty);
455
456 nouveau_bo_state_emit(ctx);
457 }
458
459 static void
460 nouveau_update_state(GLcontext *ctx, GLbitfield new_state)
461 {
462 if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW))
463 context_dirty(ctx, PROJECTION);
464
465 if (new_state & _NEW_MODELVIEW)
466 context_dirty(ctx, MODELVIEW);
467
468 if (new_state & _NEW_CURRENT_ATTRIB &&
469 new_state & _NEW_LIGHT) {
470 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
471 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
472 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
473 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
474 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
475 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
476 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
477 context_dirty(ctx, MATERIAL_BACK_SHININESS);
478 }
479
480 _swrast_InvalidateState(ctx, new_state);
481 _tnl_InvalidateState(ctx, new_state);
482
483 nouveau_state_emit(ctx);
484 }
485
486 void
487 nouveau_state_init(GLcontext *ctx)
488 {
489 struct nouveau_context *nctx = to_nouveau_context(ctx);
490
491 ctx->Driver.AlphaFunc = nouveau_alpha_func;
492 ctx->Driver.BlendColor = nouveau_blend_color;
493 ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate;
494 ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate;
495 ctx->Driver.ClipPlane = nouveau_clip_plane;
496 ctx->Driver.ColorMask = nouveau_color_mask;
497 ctx->Driver.ColorMaterial = nouveau_color_material;
498 ctx->Driver.CullFace = nouveau_cull_face;
499 ctx->Driver.FrontFace = nouveau_front_face;
500 ctx->Driver.DepthFunc = nouveau_depth_func;
501 ctx->Driver.DepthMask = nouveau_depth_mask;
502 ctx->Driver.DepthRange = nouveau_depth_range;
503 ctx->Driver.DrawBuffer = nouveau_draw_buffer;
504 ctx->Driver.DrawBuffers = nouveau_draw_buffers;
505 ctx->Driver.Enable = nouveau_enable;
506 ctx->Driver.Fogfv = nouveau_fog;
507 ctx->Driver.IndexMask = nouveau_index_mask;
508 ctx->Driver.Lightfv = nouveau_light;
509 ctx->Driver.LightModelfv = nouveau_light_model;
510 ctx->Driver.LineStipple = nouveau_line_stipple;
511 ctx->Driver.LineWidth = nouveau_line_width;
512 ctx->Driver.LogicOpcode = nouveau_logic_opcode;
513 ctx->Driver.PointParameterfv = nouveau_point_parameter;
514 ctx->Driver.PointSize = nouveau_point_size;
515 ctx->Driver.PolygonMode = nouveau_polygon_mode;
516 ctx->Driver.PolygonOffset = nouveau_polygon_offset;
517 ctx->Driver.PolygonStipple = nouveau_polygon_stipple;
518 ctx->Driver.RenderMode = nouveau_render_mode;
519 ctx->Driver.Scissor = nouveau_scissor;
520 ctx->Driver.ShadeModel = nouveau_shade_model;
521 ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate;
522 ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate;
523 ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate;
524 ctx->Driver.TexGen = nouveau_tex_gen;
525 ctx->Driver.TexEnv = nouveau_tex_env;
526 ctx->Driver.TexParameter = nouveau_tex_parameter;
527 ctx->Driver.Viewport = nouveau_viewport;
528
529 ctx->Driver.UpdateState = nouveau_update_state;
530
531 BITSET_ONES(nctx->dirty);
532 }