Tizen 2.0 Release
[profile/ivi/osmesa.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(struct gl_context *ctx, GLenum func, GLfloat ref)
37 {
38         context_dirty(ctx, ALPHA_FUNC);
39 }
40
41 static void
42 nouveau_blend_color(struct gl_context *ctx, const GLfloat color[4])
43 {
44         context_dirty(ctx, BLEND_COLOR);
45 }
46
47 static void
48 nouveau_blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA)
49 {
50         context_dirty(ctx, BLEND_EQUATION);
51 }
52
53 static void
54 nouveau_blend_func_separate(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *ctx, GLenum mode)
87 {
88         context_dirty(ctx, CULL_FACE);
89 }
90
91 static void
92 nouveau_front_face(struct gl_context *ctx, GLenum mode)
93 {
94         context_dirty(ctx, FRONT_FACE);
95 }
96
97 static void
98 nouveau_depth_func(struct gl_context *ctx, GLenum func)
99 {
100         context_dirty(ctx, DEPTH);
101 }
102
103 static void
104 nouveau_depth_mask(struct gl_context *ctx, GLboolean flag)
105 {
106         context_dirty(ctx, DEPTH);
107 }
108
109 static void
110 nouveau_depth_range(struct gl_context *ctx, GLclampd nearval, GLclampd farval)
111 {
112         context_dirty(ctx, VIEWPORT);
113 }
114
115 static void
116 nouveau_read_buffer(struct gl_context *ctx, GLenum buffer)
117 {
118         nouveau_validate_framebuffer(ctx);
119 }
120
121 static void
122 nouveau_draw_buffers(struct gl_context *ctx, GLsizei n, const GLenum *buffers)
123 {
124         nouveau_validate_framebuffer(ctx);
125         context_dirty(ctx, FRAMEBUFFER);
126 }
127
128 static void
129 nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
130 {
131         int i;
132
133         switch (cap) {
134         case GL_ALPHA_TEST:
135                 context_dirty(ctx, ALPHA_FUNC);
136                 break;
137         case GL_BLEND:
138                 context_dirty(ctx, BLEND_EQUATION);
139                 break;
140         case GL_COLOR_LOGIC_OP:
141                 context_dirty(ctx, LOGIC_OPCODE);
142                 break;
143         case GL_COLOR_MATERIAL:
144                 context_dirty(ctx, COLOR_MATERIAL);
145                 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
146                 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
147                 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
148                 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
149                 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
150                 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
151                 break;
152         case GL_COLOR_SUM_EXT:
153                 context_dirty(ctx, FRAG);
154                 context_dirty(ctx, LIGHT_MODEL);
155                 break;
156         case GL_CULL_FACE:
157                 context_dirty(ctx, CULL_FACE);
158                 break;
159         case GL_DEPTH_TEST:
160                 context_dirty(ctx, DEPTH);
161                 break;
162         case GL_DITHER:
163                 context_dirty(ctx, DITHER);
164                 break;
165         case GL_FOG:
166                 context_dirty(ctx, FOG);
167                 context_dirty(ctx, FRAG);
168                 context_dirty(ctx, MODELVIEW);
169                 break;
170         case GL_LIGHT0:
171         case GL_LIGHT1:
172         case GL_LIGHT2:
173         case GL_LIGHT3:
174         case GL_LIGHT4:
175         case GL_LIGHT5:
176         case GL_LIGHT6:
177         case GL_LIGHT7:
178                 context_dirty(ctx, MODELVIEW);
179                 context_dirty(ctx, LIGHT_ENABLE);
180                 context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0);
181                 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
182                 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
183                 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
184                 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
185                 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
186                 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
187                 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
188                 context_dirty(ctx, MATERIAL_BACK_SHININESS);
189                 break;
190         case GL_LIGHTING:
191                 context_dirty(ctx, FRAG);
192                 context_dirty(ctx, MODELVIEW);
193                 context_dirty(ctx, LIGHT_MODEL);
194                 context_dirty(ctx, LIGHT_ENABLE);
195
196                 for (i = 0; i < MAX_LIGHTS; i++) {
197                         if (ctx->Light.Light[i].Enabled)
198                                 context_dirty_i(ctx, LIGHT_SOURCE, i);
199                 }
200
201                 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
202                 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
203                 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
204                 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
205                 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
206                 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
207                 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
208                 context_dirty(ctx, MATERIAL_BACK_SHININESS);
209                 break;
210         case GL_LINE_SMOOTH:
211                 context_dirty(ctx, LINE_MODE);
212                 break;
213         case GL_NORMALIZE:
214                 context_dirty(ctx, LIGHT_ENABLE);
215                 break;
216         case GL_POINT_SMOOTH:
217                 context_dirty(ctx, POINT_MODE);
218                 break;
219         case GL_POLYGON_OFFSET_POINT:
220         case GL_POLYGON_OFFSET_LINE:
221         case GL_POLYGON_OFFSET_FILL:
222                 context_dirty(ctx, POLYGON_OFFSET);
223                 break;
224         case GL_POLYGON_SMOOTH:
225                 context_dirty(ctx, POLYGON_MODE);
226                 break;
227         case GL_SCISSOR_TEST:
228                 context_dirty(ctx, SCISSOR);
229                 break;
230         case GL_STENCIL_TEST:
231                 context_dirty(ctx, STENCIL_FUNC);
232                 break;
233         case GL_TEXTURE_1D:
234         case GL_TEXTURE_2D:
235         case GL_TEXTURE_3D:
236         case GL_TEXTURE_RECTANGLE:
237                 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
238                 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
239                 break;
240         case GL_TEXTURE_GEN_S:
241         case GL_TEXTURE_GEN_T:
242         case GL_TEXTURE_GEN_R:
243         case GL_TEXTURE_GEN_Q:
244                 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
245                 context_dirty(ctx, MODELVIEW);
246                 break;
247         }
248 }
249
250 static void
251 nouveau_fog(struct gl_context *ctx, GLenum pname, const GLfloat *params)
252 {
253         context_dirty(ctx, FOG);
254 }
255
256 static void
257 nouveau_light(struct gl_context *ctx, GLenum light, GLenum pname, const GLfloat *params)
258 {
259         switch (pname) {
260         case GL_AMBIENT:
261                 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
262                 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
263                 break;
264         case GL_DIFFUSE:
265                 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
266                 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
267                 break;
268         case GL_SPECULAR:
269                 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
270                 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
271                 break;
272         case GL_SPOT_CUTOFF:
273         case GL_POSITION:
274                 context_dirty(ctx, MODELVIEW);
275                 context_dirty(ctx, LIGHT_ENABLE);
276                 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
277                 break;
278         default:
279                 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
280                 break;
281         }
282 }
283
284 static void
285 nouveau_light_model(struct gl_context *ctx, GLenum pname, const GLfloat *params)
286 {
287         context_dirty(ctx, LIGHT_MODEL);
288         context_dirty(ctx, MODELVIEW);
289 }
290
291 static void
292 nouveau_line_stipple(struct gl_context *ctx, GLint factor, GLushort pattern )
293 {
294         context_dirty(ctx, LINE_STIPPLE);
295 }
296
297 static void
298 nouveau_line_width(struct gl_context *ctx, GLfloat width)
299 {
300         context_dirty(ctx, LINE_MODE);
301 }
302
303 static void
304 nouveau_logic_opcode(struct gl_context *ctx, GLenum opcode)
305 {
306         context_dirty(ctx, LOGIC_OPCODE);
307 }
308
309 static void
310 nouveau_point_parameter(struct gl_context *ctx, GLenum pname, const GLfloat *params)
311 {
312         context_dirty(ctx, POINT_PARAMETER);
313 }
314
315 static void
316 nouveau_point_size(struct gl_context *ctx, GLfloat size)
317 {
318         context_dirty(ctx, POINT_MODE);
319 }
320
321 static void
322 nouveau_polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode)
323 {
324         context_dirty(ctx, POLYGON_MODE);
325 }
326
327 static void
328 nouveau_polygon_offset(struct gl_context *ctx, GLfloat factor, GLfloat units)
329 {
330         context_dirty(ctx, POLYGON_OFFSET);
331 }
332
333 static void
334 nouveau_polygon_stipple(struct gl_context *ctx, const GLubyte *mask)
335 {
336         context_dirty(ctx, POLYGON_STIPPLE);
337 }
338
339 static void
340 nouveau_render_mode(struct gl_context *ctx, GLenum mode)
341 {
342         context_dirty(ctx, RENDER_MODE);
343 }
344
345 static void
346 nouveau_scissor(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
347 {
348         context_dirty(ctx, SCISSOR);
349 }
350
351 static void
352 nouveau_shade_model(struct gl_context *ctx, GLenum mode)
353 {
354         context_dirty(ctx, SHADE_MODEL);
355 }
356
357 static void
358 nouveau_stencil_func_separate(struct gl_context *ctx, GLenum face, GLenum func,
359                               GLint ref, GLuint mask)
360 {
361         context_dirty(ctx, STENCIL_FUNC);
362 }
363
364 static void
365 nouveau_stencil_mask_separate(struct gl_context *ctx, GLenum face, GLuint mask)
366 {
367         context_dirty(ctx, STENCIL_MASK);
368 }
369
370 static void
371 nouveau_stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum fail,
372                             GLenum zfail, GLenum zpass)
373 {
374         context_dirty(ctx, STENCIL_OP);
375 }
376
377 static void
378 nouveau_tex_gen(struct gl_context *ctx, GLenum coord, GLenum pname,
379                 const GLfloat *params)
380 {
381         switch (pname) {
382         case GL_TEXTURE_GEN_MODE:
383                 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
384                 context_dirty(ctx, MODELVIEW);
385                 break;
386         default:
387                 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
388                 break;
389         }
390 }
391
392 static void
393 nouveau_tex_env(struct gl_context *ctx, GLenum target, GLenum pname,
394                 const GLfloat *param)
395 {
396         switch (target) {
397         case GL_TEXTURE_FILTER_CONTROL_EXT:
398                 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
399                 break;
400         default:
401                 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
402                 break;
403         }
404 }
405
406 static void
407 nouveau_tex_parameter(struct gl_context *ctx, GLenum target,
408                       struct gl_texture_object *t, GLenum pname,
409                       const GLfloat *params)
410 {
411         switch (pname) {
412         case GL_TEXTURE_MAG_FILTER:
413         case GL_TEXTURE_WRAP_S:
414         case GL_TEXTURE_WRAP_T:
415         case GL_TEXTURE_WRAP_R:
416         case GL_TEXTURE_MIN_LOD:
417         case GL_TEXTURE_MAX_LOD:
418         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
419         case GL_TEXTURE_LOD_BIAS:
420                 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
421                 break;
422
423         case GL_TEXTURE_MIN_FILTER:
424         case GL_TEXTURE_BASE_LEVEL:
425         case GL_TEXTURE_MAX_LEVEL:
426                 nouveau_texture_reallocate(ctx, t);
427                 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
428                 break;
429         }
430 }
431
432 static void
433 nouveau_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
434 {
435         context_dirty(ctx, VIEWPORT);
436 }
437
438 void
439 nouveau_emit_nothing(struct gl_context *ctx, int emit)
440 {
441 }
442
443 int
444 nouveau_next_dirty_state(struct gl_context *ctx)
445 {
446         struct nouveau_context *nctx = to_nouveau_context(ctx);
447         int i = BITSET_FFS(nctx->dirty) - 1;
448
449         if (i < 0 || i >= context_drv(ctx)->num_emit)
450                 return -1;
451
452         return i;
453 }
454
455 void
456 nouveau_state_emit(struct gl_context *ctx)
457 {
458         struct nouveau_context *nctx = to_nouveau_context(ctx);
459         const struct nouveau_driver *drv = context_drv(ctx);
460         int i;
461
462         while ((i = nouveau_next_dirty_state(ctx)) >= 0) {
463                 BITSET_CLEAR(nctx->dirty, i);
464                 drv->emit[i](ctx, i);
465         }
466
467         BITSET_ZERO(nctx->dirty);
468 }
469
470 static void
471 nouveau_update_state(struct gl_context *ctx, GLbitfield new_state)
472 {
473         int i;
474
475         if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW))
476                 context_dirty(ctx, PROJECTION);
477
478         if (new_state & _NEW_MODELVIEW)
479                 context_dirty(ctx, MODELVIEW);
480
481         if (new_state & _NEW_TEXTURE_MATRIX) {
482                 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
483                         context_dirty_i(ctx, TEX_MAT, i);
484         }
485
486         if (new_state & _NEW_CURRENT_ATTRIB &&
487             new_state & _NEW_LIGHT) {
488                 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
489                 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
490                 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
491                 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
492                 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
493                 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
494                 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
495                 context_dirty(ctx, MATERIAL_BACK_SHININESS);
496         }
497
498         _swrast_InvalidateState(ctx, new_state);
499         _tnl_InvalidateState(ctx, new_state);
500
501         nouveau_state_emit(ctx);
502 }
503
504 void
505 nouveau_state_init(struct gl_context *ctx)
506 {
507         struct nouveau_context *nctx = to_nouveau_context(ctx);
508
509         ctx->Driver.AlphaFunc = nouveau_alpha_func;
510         ctx->Driver.BlendColor = nouveau_blend_color;
511         ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate;
512         ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate;
513         ctx->Driver.ClipPlane = nouveau_clip_plane;
514         ctx->Driver.ColorMask = nouveau_color_mask;
515         ctx->Driver.ColorMaterial = nouveau_color_material;
516         ctx->Driver.CullFace = nouveau_cull_face;
517         ctx->Driver.FrontFace = nouveau_front_face;
518         ctx->Driver.DepthFunc = nouveau_depth_func;
519         ctx->Driver.DepthMask = nouveau_depth_mask;
520         ctx->Driver.DepthRange = nouveau_depth_range;
521         ctx->Driver.ReadBuffer = nouveau_read_buffer;
522         ctx->Driver.DrawBuffers = nouveau_draw_buffers;
523         ctx->Driver.Enable = nouveau_enable;
524         ctx->Driver.Fogfv = nouveau_fog;
525         ctx->Driver.Lightfv = nouveau_light;
526         ctx->Driver.LightModelfv = nouveau_light_model;
527         ctx->Driver.LineStipple = nouveau_line_stipple;
528         ctx->Driver.LineWidth = nouveau_line_width;
529         ctx->Driver.LogicOpcode = nouveau_logic_opcode;
530         ctx->Driver.PointParameterfv = nouveau_point_parameter;
531         ctx->Driver.PointSize = nouveau_point_size;
532         ctx->Driver.PolygonMode = nouveau_polygon_mode;
533         ctx->Driver.PolygonOffset = nouveau_polygon_offset;
534         ctx->Driver.PolygonStipple = nouveau_polygon_stipple;
535         ctx->Driver.RenderMode = nouveau_render_mode;
536         ctx->Driver.Scissor = nouveau_scissor;
537         ctx->Driver.ShadeModel = nouveau_shade_model;
538         ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate;
539         ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate;
540         ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate;
541         ctx->Driver.TexGen = nouveau_tex_gen;
542         ctx->Driver.TexEnv = nouveau_tex_env;
543         ctx->Driver.TexParameter = nouveau_tex_parameter;
544         ctx->Driver.Viewport = nouveau_viewport;
545
546         ctx->Driver.UpdateState = nouveau_update_state;
547
548         BITSET_ONES(nctx->dirty);
549 }