2 * Copyright (C) 2009 Francisco Jerez.
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:
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.
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.
27 #include "nouveau_driver.h"
28 #include "nouveau_context.h"
29 #include "nouveau_texture.h"
30 #include "nouveau_util.h"
32 #include "swrast/swrast.h"
36 nouveau_alpha_func(struct gl_context *ctx, GLenum func, GLfloat ref)
38 context_dirty(ctx, ALPHA_FUNC);
42 nouveau_blend_color(struct gl_context *ctx, const GLfloat color[4])
44 context_dirty(ctx, BLEND_COLOR);
48 nouveau_blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA)
50 context_dirty(ctx, BLEND_EQUATION);
54 nouveau_blend_func_separate(struct gl_context *ctx, GLenum sfactorRGB,
55 GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA)
57 context_dirty(ctx, BLEND_FUNC);
61 nouveau_clip_plane(struct gl_context *ctx, GLenum plane, const GLfloat *equation)
63 context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0);
67 nouveau_color_mask(struct gl_context *ctx, GLboolean rmask, GLboolean gmask,
68 GLboolean bmask, GLboolean amask)
70 context_dirty(ctx, COLOR_MASK);
74 nouveau_color_material(struct gl_context *ctx, GLenum face, GLenum mode)
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);
86 nouveau_cull_face(struct gl_context *ctx, GLenum mode)
88 context_dirty(ctx, CULL_FACE);
92 nouveau_front_face(struct gl_context *ctx, GLenum mode)
94 context_dirty(ctx, FRONT_FACE);
98 nouveau_depth_func(struct gl_context *ctx, GLenum func)
100 context_dirty(ctx, DEPTH);
104 nouveau_depth_mask(struct gl_context *ctx, GLboolean flag)
106 context_dirty(ctx, DEPTH);
110 nouveau_depth_range(struct gl_context *ctx, GLclampd nearval, GLclampd farval)
112 context_dirty(ctx, VIEWPORT);
116 nouveau_read_buffer(struct gl_context *ctx, GLenum buffer)
118 nouveau_validate_framebuffer(ctx);
122 nouveau_draw_buffers(struct gl_context *ctx, GLsizei n, const GLenum *buffers)
124 nouveau_validate_framebuffer(ctx);
125 context_dirty(ctx, FRAMEBUFFER);
129 nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
135 context_dirty(ctx, ALPHA_FUNC);
138 context_dirty(ctx, BLEND_EQUATION);
140 case GL_COLOR_LOGIC_OP:
141 context_dirty(ctx, LOGIC_OPCODE);
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);
152 case GL_COLOR_SUM_EXT:
153 context_dirty(ctx, FRAG);
154 context_dirty(ctx, LIGHT_MODEL);
157 context_dirty(ctx, CULL_FACE);
160 context_dirty(ctx, DEPTH);
163 context_dirty(ctx, DITHER);
166 context_dirty(ctx, FOG);
167 context_dirty(ctx, FRAG);
168 context_dirty(ctx, MODELVIEW);
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);
191 context_dirty(ctx, FRAG);
192 context_dirty(ctx, MODELVIEW);
193 context_dirty(ctx, LIGHT_MODEL);
194 context_dirty(ctx, LIGHT_ENABLE);
196 for (i = 0; i < MAX_LIGHTS; i++) {
197 if (ctx->Light.Light[i].Enabled)
198 context_dirty_i(ctx, LIGHT_SOURCE, i);
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);
211 context_dirty(ctx, LINE_MODE);
214 context_dirty(ctx, LIGHT_ENABLE);
216 case GL_POINT_SMOOTH:
217 context_dirty(ctx, POINT_MODE);
219 case GL_POLYGON_OFFSET_POINT:
220 case GL_POLYGON_OFFSET_LINE:
221 case GL_POLYGON_OFFSET_FILL:
222 context_dirty(ctx, POLYGON_OFFSET);
224 case GL_POLYGON_SMOOTH:
225 context_dirty(ctx, POLYGON_MODE);
227 case GL_SCISSOR_TEST:
228 context_dirty(ctx, SCISSOR);
230 case GL_STENCIL_TEST:
231 context_dirty(ctx, STENCIL_FUNC);
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);
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);
251 nouveau_fog(struct gl_context *ctx, GLenum pname, const GLfloat *params)
253 context_dirty(ctx, FOG);
257 nouveau_light(struct gl_context *ctx, GLenum light, GLenum pname, const GLfloat *params)
261 context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
262 context_dirty(ctx, MATERIAL_BACK_AMBIENT);
265 context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
266 context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
269 context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
270 context_dirty(ctx, MATERIAL_BACK_SPECULAR);
274 context_dirty(ctx, MODELVIEW);
275 context_dirty(ctx, LIGHT_ENABLE);
276 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
279 context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
285 nouveau_light_model(struct gl_context *ctx, GLenum pname, const GLfloat *params)
287 context_dirty(ctx, LIGHT_MODEL);
288 context_dirty(ctx, MODELVIEW);
292 nouveau_line_stipple(struct gl_context *ctx, GLint factor, GLushort pattern )
294 context_dirty(ctx, LINE_STIPPLE);
298 nouveau_line_width(struct gl_context *ctx, GLfloat width)
300 context_dirty(ctx, LINE_MODE);
304 nouveau_logic_opcode(struct gl_context *ctx, GLenum opcode)
306 context_dirty(ctx, LOGIC_OPCODE);
310 nouveau_point_parameter(struct gl_context *ctx, GLenum pname, const GLfloat *params)
312 context_dirty(ctx, POINT_PARAMETER);
316 nouveau_point_size(struct gl_context *ctx, GLfloat size)
318 context_dirty(ctx, POINT_MODE);
322 nouveau_polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode)
324 context_dirty(ctx, POLYGON_MODE);
328 nouveau_polygon_offset(struct gl_context *ctx, GLfloat factor, GLfloat units)
330 context_dirty(ctx, POLYGON_OFFSET);
334 nouveau_polygon_stipple(struct gl_context *ctx, const GLubyte *mask)
336 context_dirty(ctx, POLYGON_STIPPLE);
340 nouveau_render_mode(struct gl_context *ctx, GLenum mode)
342 context_dirty(ctx, RENDER_MODE);
346 nouveau_scissor(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
348 context_dirty(ctx, SCISSOR);
352 nouveau_shade_model(struct gl_context *ctx, GLenum mode)
354 context_dirty(ctx, SHADE_MODEL);
358 nouveau_stencil_func_separate(struct gl_context *ctx, GLenum face, GLenum func,
359 GLint ref, GLuint mask)
361 context_dirty(ctx, STENCIL_FUNC);
365 nouveau_stencil_mask_separate(struct gl_context *ctx, GLenum face, GLuint mask)
367 context_dirty(ctx, STENCIL_MASK);
371 nouveau_stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum fail,
372 GLenum zfail, GLenum zpass)
374 context_dirty(ctx, STENCIL_OP);
378 nouveau_tex_gen(struct gl_context *ctx, GLenum coord, GLenum pname,
379 const GLfloat *params)
382 case GL_TEXTURE_GEN_MODE:
383 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
384 context_dirty(ctx, MODELVIEW);
387 context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
393 nouveau_tex_env(struct gl_context *ctx, GLenum target, GLenum pname,
394 const GLfloat *param)
397 case GL_TEXTURE_FILTER_CONTROL_EXT:
398 context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
401 context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
407 nouveau_tex_parameter(struct gl_context *ctx, GLenum target,
408 struct gl_texture_object *t, GLenum pname,
409 const GLfloat *params)
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);
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);
433 nouveau_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
435 context_dirty(ctx, VIEWPORT);
439 nouveau_emit_nothing(struct gl_context *ctx, int emit)
444 nouveau_next_dirty_state(struct gl_context *ctx)
446 struct nouveau_context *nctx = to_nouveau_context(ctx);
447 int i = BITSET_FFS(nctx->dirty) - 1;
449 if (i < 0 || i >= context_drv(ctx)->num_emit)
456 nouveau_state_emit(struct gl_context *ctx)
458 struct nouveau_context *nctx = to_nouveau_context(ctx);
459 const struct nouveau_driver *drv = context_drv(ctx);
462 while ((i = nouveau_next_dirty_state(ctx)) >= 0) {
463 BITSET_CLEAR(nctx->dirty, i);
464 drv->emit[i](ctx, i);
467 BITSET_ZERO(nctx->dirty);
471 nouveau_update_state(struct gl_context *ctx, GLbitfield new_state)
475 if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW))
476 context_dirty(ctx, PROJECTION);
478 if (new_state & _NEW_MODELVIEW)
479 context_dirty(ctx, MODELVIEW);
481 if (new_state & _NEW_TEXTURE_MATRIX) {
482 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
483 context_dirty_i(ctx, TEX_MAT, i);
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);
498 _swrast_InvalidateState(ctx, new_state);
499 _tnl_InvalidateState(ctx, new_state);
501 nouveau_state_emit(ctx);
505 nouveau_state_init(struct gl_context *ctx)
507 struct nouveau_context *nctx = to_nouveau_context(ctx);
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;
546 ctx->Driver.UpdateState = nouveau_update_state;
548 BITSET_ONES(nctx->dirty);