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 if (new_state
& _NEW_TEXTURE
) {
499 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
500 if (ctx
->Texture
.Unit
[i
].Sampler
)
501 context_dirty_i(ctx
, TEX_OBJ
, i
);
505 _swrast_InvalidateState(ctx
, new_state
);
506 _tnl_InvalidateState(ctx
, new_state
);
508 nouveau_state_emit(ctx
);
512 nouveau_state_init(struct gl_context
*ctx
)
514 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
516 ctx
->Driver
.AlphaFunc
= nouveau_alpha_func
;
517 ctx
->Driver
.BlendColor
= nouveau_blend_color
;
518 ctx
->Driver
.BlendEquationSeparate
= nouveau_blend_equation_separate
;
519 ctx
->Driver
.BlendFuncSeparate
= nouveau_blend_func_separate
;
520 ctx
->Driver
.ClipPlane
= nouveau_clip_plane
;
521 ctx
->Driver
.ColorMask
= nouveau_color_mask
;
522 ctx
->Driver
.ColorMaterial
= nouveau_color_material
;
523 ctx
->Driver
.CullFace
= nouveau_cull_face
;
524 ctx
->Driver
.FrontFace
= nouveau_front_face
;
525 ctx
->Driver
.DepthFunc
= nouveau_depth_func
;
526 ctx
->Driver
.DepthMask
= nouveau_depth_mask
;
527 ctx
->Driver
.DepthRange
= nouveau_depth_range
;
528 ctx
->Driver
.ReadBuffer
= nouveau_read_buffer
;
529 ctx
->Driver
.DrawBuffers
= nouveau_draw_buffers
;
530 ctx
->Driver
.Enable
= nouveau_enable
;
531 ctx
->Driver
.Fogfv
= nouveau_fog
;
532 ctx
->Driver
.Lightfv
= nouveau_light
;
533 ctx
->Driver
.LightModelfv
= nouveau_light_model
;
534 ctx
->Driver
.LineStipple
= nouveau_line_stipple
;
535 ctx
->Driver
.LineWidth
= nouveau_line_width
;
536 ctx
->Driver
.LogicOpcode
= nouveau_logic_opcode
;
537 ctx
->Driver
.PointParameterfv
= nouveau_point_parameter
;
538 ctx
->Driver
.PointSize
= nouveau_point_size
;
539 ctx
->Driver
.PolygonMode
= nouveau_polygon_mode
;
540 ctx
->Driver
.PolygonOffset
= nouveau_polygon_offset
;
541 ctx
->Driver
.PolygonStipple
= nouveau_polygon_stipple
;
542 ctx
->Driver
.RenderMode
= nouveau_render_mode
;
543 ctx
->Driver
.Scissor
= nouveau_scissor
;
544 ctx
->Driver
.ShadeModel
= nouveau_shade_model
;
545 ctx
->Driver
.StencilFuncSeparate
= nouveau_stencil_func_separate
;
546 ctx
->Driver
.StencilMaskSeparate
= nouveau_stencil_mask_separate
;
547 ctx
->Driver
.StencilOpSeparate
= nouveau_stencil_op_separate
;
548 ctx
->Driver
.TexGen
= nouveau_tex_gen
;
549 ctx
->Driver
.TexEnv
= nouveau_tex_env
;
550 ctx
->Driver
.TexParameter
= nouveau_tex_parameter
;
551 ctx
->Driver
.Viewport
= nouveau_viewport
;
553 ctx
->Driver
.UpdateState
= nouveau_update_state
;
555 BITSET_ONES(nctx
->dirty
);