Added few more stubs so that control reaches to DestroyDevice().
[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 #include "util/bitscan.h"
35 #include "main/framebuffer.h"
36
37 static void
38 nouveau_alpha_func(struct gl_context *ctx, GLenum func, GLfloat ref)
39 {
40 context_dirty(ctx, ALPHA_FUNC);
41 }
42
43 static void
44 nouveau_blend_color(struct gl_context *ctx, const GLfloat color[4])
45 {
46 context_dirty(ctx, BLEND_COLOR);
47 }
48
49 static void
50 nouveau_blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA)
51 {
52 context_dirty(ctx, BLEND_EQUATION);
53 }
54
55 static void
56 nouveau_blend_func_separate(struct gl_context *ctx, GLenum sfactorRGB,
57 GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA)
58 {
59 context_dirty(ctx, BLEND_FUNC);
60 }
61
62 static void
63 nouveau_clip_plane(struct gl_context *ctx, GLenum plane, const GLfloat *equation)
64 {
65 context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0);
66 }
67
68 static void
69 nouveau_color_mask(struct gl_context *ctx, GLboolean rmask, GLboolean gmask,
70 GLboolean bmask, GLboolean amask)
71 {
72 context_dirty(ctx, COLOR_MASK);
73 }
74
75 static void
76 nouveau_color_material(struct gl_context *ctx, GLenum face, GLenum mode)
77 {
78 context_dirty(ctx, COLOR_MATERIAL);
79 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
80 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
81 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
82 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
83 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
84 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
85 }
86
87 static void
88 nouveau_cull_face(struct gl_context *ctx, GLenum mode)
89 {
90 context_dirty(ctx, CULL_FACE);
91 }
92
93 static void
94 nouveau_front_face(struct gl_context *ctx, GLenum mode)
95 {
96 context_dirty(ctx, FRONT_FACE);
97 }
98
99 static void
100 nouveau_depth_func(struct gl_context *ctx, GLenum func)
101 {
102 context_dirty(ctx, DEPTH);
103 }
104
105 static void
106 nouveau_depth_mask(struct gl_context *ctx, GLboolean flag)
107 {
108 context_dirty(ctx, DEPTH);
109 }
110
111 static void
112 nouveau_read_buffer(struct gl_context *ctx, GLenum buffer)
113 {
114 nouveau_validate_framebuffer(ctx);
115 }
116
117 static void
118 nouveau_draw_buffer(struct gl_context *ctx)
119 {
120 nouveau_validate_framebuffer(ctx);
121 context_dirty(ctx, FRAMEBUFFER);
122 }
123
124 static void
125 nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
126 {
127 GLbitfield mask;
128
129 switch (cap) {
130 case GL_ALPHA_TEST:
131 context_dirty(ctx, ALPHA_FUNC);
132 break;
133 case GL_BLEND:
134 context_dirty(ctx, BLEND_EQUATION);
135 break;
136 case GL_COLOR_LOGIC_OP:
137 context_dirty(ctx, LOGIC_OPCODE);
138 break;
139 case GL_COLOR_MATERIAL:
140 context_dirty(ctx, COLOR_MATERIAL);
141 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
142 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
143 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
144 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
145 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
146 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
147 break;
148 case GL_COLOR_SUM_EXT:
149 context_dirty(ctx, FRAG);
150 context_dirty(ctx, LIGHT_MODEL);
151 break;
152 case GL_CULL_FACE:
153 context_dirty(ctx, CULL_FACE);
154 break;
155 case GL_DEPTH_TEST:
156 context_dirty(ctx, DEPTH);
157 break;
158 case GL_DITHER:
159 context_dirty(ctx, DITHER);
160 break;
161 case GL_FOG:
162 context_dirty(ctx, FOG);
163 context_dirty(ctx, FRAG);
164 context_dirty(ctx, MODELVIEW);
165 break;
166 case GL_LIGHT0:
167 case GL_LIGHT1:
168 case GL_LIGHT2:
169 case GL_LIGHT3:
170 case GL_LIGHT4:
171 case GL_LIGHT5:
172 case GL_LIGHT6:
173 case GL_LIGHT7:
174 context_dirty(ctx, MODELVIEW);
175 context_dirty(ctx, LIGHT_ENABLE);
176 context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0);
177 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
178 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
179 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
180 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
181 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
182 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
183 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
184 context_dirty(ctx, MATERIAL_BACK_SHININESS);
185 break;
186 case GL_LIGHTING:
187 context_dirty(ctx, FRAG);
188 context_dirty(ctx, MODELVIEW);
189 context_dirty(ctx, LIGHT_MODEL);
190 context_dirty(ctx, LIGHT_ENABLE);
191
192 mask = ctx->Light._EnabledLights;
193 while (mask) {
194 const int i = u_bit_scan(&mask);
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 case GL_TEXTURE_RECTANGLE:
234 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
235 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
236 break;
237 case GL_TEXTURE_GEN_S:
238 case GL_TEXTURE_GEN_T:
239 case GL_TEXTURE_GEN_R:
240 case GL_TEXTURE_GEN_Q:
241 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
242 context_dirty(ctx, MODELVIEW);
243 break;
244 }
245 }
246
247 static void
248 nouveau_fog(struct gl_context *ctx, GLenum pname, const GLfloat *params)
249 {
250 context_dirty(ctx, FOG);
251 }
252
253 static void
254 nouveau_light(struct gl_context *ctx, GLenum light, GLenum pname, const GLfloat *params)
255 {
256 switch (pname) {
257 case GL_AMBIENT:
258 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
259 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
260 break;
261 case GL_DIFFUSE:
262 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
263 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
264 break;
265 case GL_SPECULAR:
266 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
267 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
268 break;
269 case GL_SPOT_CUTOFF:
270 case GL_POSITION:
271 context_dirty(ctx, MODELVIEW);
272 context_dirty(ctx, LIGHT_ENABLE);
273 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
274 break;
275 default:
276 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
277 break;
278 }
279 }
280
281 static void
282 nouveau_light_model(struct gl_context *ctx, GLenum pname, const GLfloat *params)
283 {
284 context_dirty(ctx, LIGHT_MODEL);
285 context_dirty(ctx, MODELVIEW);
286 }
287
288 static void
289 nouveau_line_stipple(struct gl_context *ctx, GLint factor, GLushort pattern )
290 {
291 context_dirty(ctx, LINE_STIPPLE);
292 }
293
294 static void
295 nouveau_line_width(struct gl_context *ctx, GLfloat width)
296 {
297 context_dirty(ctx, LINE_MODE);
298 }
299
300 static void
301 nouveau_logic_opcode(struct gl_context *ctx, UNUSED enum gl_logicop_mode opcode)
302 {
303 context_dirty(ctx, LOGIC_OPCODE);
304 }
305
306 static void
307 nouveau_point_parameter(struct gl_context *ctx, GLenum pname, const GLfloat *params)
308 {
309 context_dirty(ctx, POINT_PARAMETER);
310 }
311
312 static void
313 nouveau_point_size(struct gl_context *ctx, GLfloat size)
314 {
315 context_dirty(ctx, POINT_MODE);
316 }
317
318 static void
319 nouveau_polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode)
320 {
321 context_dirty(ctx, POLYGON_MODE);
322 }
323
324 static void
325 nouveau_polygon_offset(struct gl_context *ctx, GLfloat factor, GLfloat units, GLfloat clamp)
326 {
327 context_dirty(ctx, POLYGON_OFFSET);
328 }
329
330 static void
331 nouveau_polygon_stipple(struct gl_context *ctx, const GLubyte *mask)
332 {
333 context_dirty(ctx, POLYGON_STIPPLE);
334 }
335
336 static void
337 nouveau_render_mode(struct gl_context *ctx, GLenum mode)
338 {
339 context_dirty(ctx, RENDER_MODE);
340 }
341
342 static void
343 nouveau_shade_model(struct gl_context *ctx, GLenum mode)
344 {
345 context_dirty(ctx, SHADE_MODEL);
346 }
347
348 static void
349 nouveau_stencil_func_separate(struct gl_context *ctx, GLenum face, GLenum func,
350 GLint ref, GLuint mask)
351 {
352 context_dirty(ctx, STENCIL_FUNC);
353 }
354
355 static void
356 nouveau_stencil_mask_separate(struct gl_context *ctx, GLenum face, GLuint mask)
357 {
358 context_dirty(ctx, STENCIL_MASK);
359 }
360
361 static void
362 nouveau_stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum fail,
363 GLenum zfail, GLenum zpass)
364 {
365 context_dirty(ctx, STENCIL_OP);
366 }
367
368 static void
369 nouveau_tex_gen(struct gl_context *ctx, GLenum coord, GLenum pname,
370 const GLfloat *params)
371 {
372 switch (pname) {
373 case GL_TEXTURE_GEN_MODE:
374 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
375 context_dirty(ctx, MODELVIEW);
376 break;
377 default:
378 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
379 break;
380 }
381 }
382
383 static void
384 nouveau_tex_env(struct gl_context *ctx, GLenum target, GLenum pname,
385 const GLfloat *param)
386 {
387 switch (target) {
388 case GL_TEXTURE_FILTER_CONTROL_EXT:
389 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
390 break;
391 default:
392 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
393 break;
394 }
395 }
396
397 static void
398 nouveau_tex_parameter(struct gl_context *ctx,
399 struct gl_texture_object *t, GLenum pname)
400 {
401 switch (pname) {
402 case GL_TEXTURE_MAG_FILTER:
403 case GL_TEXTURE_WRAP_S:
404 case GL_TEXTURE_WRAP_T:
405 case GL_TEXTURE_WRAP_R:
406 case GL_TEXTURE_MIN_LOD:
407 case GL_TEXTURE_MAX_LOD:
408 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
409 case GL_TEXTURE_LOD_BIAS:
410 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
411 break;
412
413 case GL_TEXTURE_MIN_FILTER:
414 case GL_TEXTURE_BASE_LEVEL:
415 case GL_TEXTURE_MAX_LEVEL:
416 nouveau_texture_reallocate(ctx, t);
417 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
418 break;
419 }
420 }
421
422 void
423 nouveau_emit_nothing(struct gl_context *ctx, int emit)
424 {
425 }
426
427 int
428 nouveau_next_dirty_state(struct gl_context *ctx)
429 {
430 struct nouveau_context *nctx = to_nouveau_context(ctx);
431 int i = BITSET_FFS(nctx->dirty) - 1;
432
433 if (i < 0 || i >= context_drv(ctx)->num_emit)
434 return -1;
435
436 return i;
437 }
438
439 void
440 nouveau_state_emit(struct gl_context *ctx)
441 {
442 struct nouveau_context *nctx = to_nouveau_context(ctx);
443 const struct nouveau_driver *drv = context_drv(ctx);
444 int i;
445
446 while ((i = nouveau_next_dirty_state(ctx)) >= 0) {
447 BITSET_CLEAR(nctx->dirty, i);
448 drv->emit[i](ctx, i);
449 }
450
451 BITSET_ZERO(nctx->dirty);
452 }
453
454 static void
455 nouveau_update_state(struct gl_context *ctx)
456 {
457 GLbitfield new_state = ctx->NewState;
458 int i;
459
460 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
461 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
462
463 if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW))
464 context_dirty(ctx, PROJECTION);
465
466 if (new_state & _NEW_MODELVIEW)
467 context_dirty(ctx, MODELVIEW);
468
469 if (new_state & _NEW_TEXTURE_MATRIX) {
470 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
471 context_dirty_i(ctx, TEX_MAT, i);
472 }
473
474 if (new_state & _NEW_SCISSOR)
475 context_dirty(ctx, SCISSOR);
476
477 if (new_state & _NEW_VIEWPORT)
478 context_dirty(ctx, VIEWPORT);
479
480 if (new_state & _NEW_CURRENT_ATTRIB &&
481 new_state & _NEW_LIGHT) {
482 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
483 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
484 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
485 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
486 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
487 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
488 context_dirty(ctx, MATERIAL_FRONT_SHININESS);
489 context_dirty(ctx, MATERIAL_BACK_SHININESS);
490 }
491
492 if (new_state & _NEW_TEXTURE) {
493 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
494 if (ctx->Texture.Unit[i].Sampler)
495 context_dirty_i(ctx, TEX_OBJ, i);
496 }
497 }
498
499 _swrast_InvalidateState(ctx, new_state);
500 _tnl_InvalidateState(ctx, new_state);
501
502 nouveau_state_emit(ctx);
503 }
504
505 void
506 nouveau_state_init(struct gl_context *ctx)
507 {
508 struct nouveau_context *nctx = to_nouveau_context(ctx);
509
510 ctx->Driver.AlphaFunc = nouveau_alpha_func;
511 ctx->Driver.BlendColor = nouveau_blend_color;
512 ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate;
513 ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate;
514 ctx->Driver.ClipPlane = nouveau_clip_plane;
515 ctx->Driver.ColorMask = nouveau_color_mask;
516 ctx->Driver.ColorMaterial = nouveau_color_material;
517 ctx->Driver.CullFace = nouveau_cull_face;
518 ctx->Driver.FrontFace = nouveau_front_face;
519 ctx->Driver.DepthFunc = nouveau_depth_func;
520 ctx->Driver.DepthMask = nouveau_depth_mask;
521 ctx->Driver.ReadBuffer = nouveau_read_buffer;
522 ctx->Driver.DrawBuffer = nouveau_draw_buffer;
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.ShadeModel = nouveau_shade_model;
537 ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate;
538 ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate;
539 ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate;
540 ctx->Driver.TexGen = nouveau_tex_gen;
541 ctx->Driver.TexEnv = nouveau_tex_env;
542 ctx->Driver.TexParameter = nouveau_tex_parameter;
543
544 ctx->Driver.UpdateState = nouveau_update_state;
545
546 BITSET_ONES(nctx->dirty);
547 }