2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keith@tungstengraphics.com>
30 #include "bufferobj.h"
34 #include "prog_statevars.h"
38 #include "s_context.h"
42 #include "s_triangle.h"
43 #include "s_texfilter.h"
47 * Recompute the value of swrast->_RasterMask, etc. according to
48 * the current context. The _RasterMask field can be easily tested by
49 * drivers to determine certain basic GL state (does the primitive need
50 * stenciling, logic-op, fog, etc?).
53 _swrast_update_rasterflags( GLcontext
*ctx
)
55 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
56 GLbitfield rasterMask
= 0;
58 if (ctx
->Color
.AlphaEnabled
) rasterMask
|= ALPHATEST_BIT
;
59 if (ctx
->Color
.BlendEnabled
) rasterMask
|= BLEND_BIT
;
60 if (ctx
->Depth
.Test
) rasterMask
|= DEPTH_BIT
;
61 if (swrast
->_FogEnabled
) rasterMask
|= FOG_BIT
;
62 if (ctx
->Scissor
.Enabled
) rasterMask
|= CLIP_BIT
;
63 if (ctx
->Stencil
.Enabled
) rasterMask
|= STENCIL_BIT
;
64 if (ctx
->Visual
.rgbMode
) {
65 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
66 if (colorMask
!= 0xffffffff) rasterMask
|= MASKING_BIT
;
67 if (ctx
->Color
._LogicOpEnabled
) rasterMask
|= LOGIC_OP_BIT
;
68 if (ctx
->Texture
._EnabledUnits
) rasterMask
|= TEXTURE_BIT
;
71 if (ctx
->Color
.IndexMask
!= 0xffffffff) rasterMask
|= MASKING_BIT
;
72 if (ctx
->Color
.IndexLogicOpEnabled
) rasterMask
|= LOGIC_OP_BIT
;
75 if ( ctx
->Viewport
.X
< 0
76 || ctx
->Viewport
.X
+ ctx
->Viewport
.Width
> (GLint
) ctx
->DrawBuffer
->Width
77 || ctx
->Viewport
.Y
< 0
78 || ctx
->Viewport
.Y
+ ctx
->Viewport
.Height
> (GLint
) ctx
->DrawBuffer
->Height
) {
79 rasterMask
|= CLIP_BIT
;
82 if (ctx
->Query
.CurrentOcclusionObject
)
83 rasterMask
|= OCCLUSION_BIT
;
86 /* If we're not drawing to exactly one color buffer set the
87 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
88 * buffers or the RGBA or CI mask disables all writes.
90 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
[0] != 1) {
91 /* more than one color buffer designated for writing (or zero buffers) */
92 rasterMask
|= MULTI_DRAW_BIT
;
94 else if (ctx
->Visual
.rgbMode
&& *((GLuint
*) ctx
->Color
.ColorMask
) == 0) {
95 rasterMask
|= MULTI_DRAW_BIT
; /* all RGBA channels disabled */
97 else if (!ctx
->Visual
.rgbMode
&& ctx
->Color
.IndexMask
==0) {
98 rasterMask
|= MULTI_DRAW_BIT
; /* all color index bits disabled */
101 if (ctx
->FragmentProgram
._Current
) {
102 rasterMask
|= FRAGPROG_BIT
;
105 if (ctx
->ATIFragmentShader
._Enabled
) {
106 rasterMask
|= ATIFRAGSHADER_BIT
;
109 #if CHAN_TYPE == GL_FLOAT
110 if (ctx
->Color
.ClampFragmentColor
== GL_TRUE
) {
111 rasterMask
|= CLAMPING_BIT
;
115 SWRAST_CONTEXT(ctx
)->_RasterMask
= rasterMask
;
120 * Examine polycon culls tate to compute the _BackfaceSign field.
121 * _BackfaceSign will be 0 if no culling, -1 if culling back-faces,
122 * and 1 if culling front-faces. The Polygon FrontFace state also
126 _swrast_update_polygon( GLcontext
*ctx
)
128 GLfloat backface_sign
;
130 if (ctx
->Polygon
.CullFlag
) {
132 switch (ctx
->Polygon
.CullFaceMode
) {
134 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
135 backface_sign
= -1.0;
138 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
139 backface_sign
= -1.0;
141 case GL_FRONT_AND_BACK
:
152 SWRAST_CONTEXT(ctx
)->_BackfaceSign
= backface_sign
;
157 * Update the _PreferPixelFog field to indicate if we need to compute
158 * fog blend factors (from the fog coords) per-fragment.
161 _swrast_update_fog_hint( GLcontext
*ctx
)
163 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
164 swrast
->_PreferPixelFog
= (!swrast
->AllowVertexFog
||
165 ctx
->FragmentProgram
._Current
||
166 (ctx
->Hint
.Fog
== GL_NICEST
&&
167 swrast
->AllowPixelFog
));
173 * Update the swrast->_AnyTextureCombine flag.
176 _swrast_update_texture_env( GLcontext
*ctx
)
178 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
180 swrast
->_AnyTextureCombine
= GL_FALSE
;
181 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
182 if (ctx
->Texture
.Unit
[i
].EnvMode
== GL_COMBINE_EXT
||
183 ctx
->Texture
.Unit
[i
].EnvMode
== GL_COMBINE4_NV
) {
184 swrast
->_AnyTextureCombine
= GL_TRUE
;
192 * Update swrast->_FogColor and swrast->_FogEnable values.
195 _swrast_update_fog_state( GLcontext
*ctx
)
197 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
198 const struct gl_fragment_program
*fp
= ctx
->FragmentProgram
._Current
;
200 /* determine if fog is needed, and if so, which fog mode */
201 swrast
->_FogEnabled
= GL_FALSE
;
202 if (fp
&& fp
->Base
.Target
== GL_FRAGMENT_PROGRAM_ARB
) {
203 if (fp
->FogOption
!= GL_NONE
) {
204 swrast
->_FogEnabled
= GL_TRUE
;
205 swrast
->_FogMode
= fp
->FogOption
;
208 else if (ctx
->Fog
.Enabled
) {
209 swrast
->_FogEnabled
= GL_TRUE
;
210 swrast
->_FogMode
= ctx
->Fog
.Mode
;
216 * Update state for running fragment programs. Basically, load the
217 * program parameters with current state values.
220 _swrast_update_fragment_program(GLcontext
*ctx
, GLbitfield newState
)
222 const struct gl_fragment_program
*fp
= ctx
->FragmentProgram
._Current
;
225 /* XXX Need a way to trigger the initial loading of parameters
226 * even when there's no recent state changes.
228 if (fp
->Base
.Parameters
->StateFlags
& newState
)
230 _mesa_load_state_parameters(ctx
, fp
->Base
.Parameters
);
236 #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \
241 /* State referenced by _swrast_choose_triangle, _swrast_choose_line.
243 #define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \
250 _SWRAST_NEW_RASTERMASK| \
253 _DD_NEW_SEPARATE_SPECULAR)
255 #define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \
262 _DD_NEW_SEPARATE_SPECULAR)
264 #define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \
270 _DD_NEW_SEPARATE_SPECULAR)
272 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
274 #define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
276 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
281 * Stub for swrast->Triangle to select a true triangle function
282 * after a state change.
285 _swrast_validate_triangle( GLcontext
*ctx
,
290 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
292 _swrast_validate_derived( ctx
);
293 swrast
->choose_triangle( ctx
);
294 ASSERT(swrast
->Triangle
);
296 if (ctx
->Texture
._EnabledUnits
== 0
297 && NEED_SECONDARY_COLOR(ctx
)
298 && !ctx
->FragmentProgram
._Current
) {
299 /* separate specular color, but no texture */
300 swrast
->SpecTriangle
= swrast
->Triangle
;
301 swrast
->Triangle
= _swrast_add_spec_terms_triangle
;
304 swrast
->Triangle( ctx
, v0
, v1
, v2
);
308 * Called via swrast->Line. Examine current GL state and choose a software
309 * line routine. Then call it.
312 _swrast_validate_line( GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
314 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
316 _swrast_validate_derived( ctx
);
317 swrast
->choose_line( ctx
);
318 ASSERT(swrast
->Line
);
320 if (ctx
->Texture
._EnabledUnits
== 0
321 && NEED_SECONDARY_COLOR(ctx
)
322 && !ctx
->FragmentProgram
._Current
) {
323 swrast
->SpecLine
= swrast
->Line
;
324 swrast
->Line
= _swrast_add_spec_terms_line
;
328 swrast
->Line( ctx
, v0
, v1
);
332 * Called via swrast->Point. Examine current GL state and choose a software
333 * point routine. Then call it.
336 _swrast_validate_point( GLcontext
*ctx
, const SWvertex
*v0
)
338 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
340 _swrast_validate_derived( ctx
);
341 swrast
->choose_point( ctx
);
343 if (ctx
->Texture
._EnabledUnits
== 0
344 && NEED_SECONDARY_COLOR(ctx
)
345 && !ctx
->FragmentProgram
._Current
) {
346 swrast
->SpecPoint
= swrast
->Point
;
347 swrast
->Point
= _swrast_add_spec_terms_point
;
350 swrast
->Point( ctx
, v0
);
355 * Called via swrast->BlendFunc. Examine GL state to choose a blending
356 * function, then call it.
359 _swrast_validate_blend_func(GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
360 GLvoid
*src
, const GLvoid
*dst
,
363 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
365 _swrast_validate_derived( ctx
); /* why is this needed? */
366 _swrast_choose_blend_func( ctx
, chanType
);
368 swrast
->BlendFunc( ctx
, n
, mask
, src
, dst
, chanType
);
373 * Make sure we have texture image data for all the textures we may need
374 * for subsequent rendering.
377 _swrast_validate_texture_images(GLcontext
*ctx
)
379 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
382 if (!swrast
->ValidateTextureImage
|| !ctx
->Texture
._EnabledUnits
) {
383 /* no textures enabled, or no way to validate images! */
387 for (u
= 0; u
< ctx
->Const
.MaxTextureImageUnits
; u
++) {
388 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
389 struct gl_texture_object
*texObj
= ctx
->Texture
.Unit
[u
]._Current
;
392 GLuint numFaces
= (texObj
->Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
394 for (face
= 0; face
< numFaces
; face
++) {
396 for (lvl
= texObj
->BaseLevel
; lvl
<= texObj
->_MaxLevel
; lvl
++) {
397 struct gl_texture_image
*texImg
= texObj
->Image
[face
][lvl
];
398 if (texImg
&& !texImg
->Data
) {
399 swrast
->ValidateTextureImage(ctx
, texObj
, face
, lvl
);
400 ASSERT(texObj
->Image
[face
][lvl
]->Data
);
411 * Free the texture image data attached to all currently enabled
412 * textures. Meant to be called by device drivers when transitioning
413 * from software to hardware rendering.
416 _swrast_eject_texture_images(GLcontext
*ctx
)
420 if (!ctx
->Texture
._EnabledUnits
) {
421 /* no textures enabled */
425 for (u
= 0; u
< ctx
->Const
.MaxTextureImageUnits
; u
++) {
426 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
427 struct gl_texture_object
*texObj
= ctx
->Texture
.Unit
[u
]._Current
;
430 GLuint numFaces
= (texObj
->Target
== GL_TEXTURE_CUBE_MAP
) ? 6 : 1;
432 for (face
= 0; face
< numFaces
; face
++) {
434 for (lvl
= texObj
->BaseLevel
; lvl
<= texObj
->_MaxLevel
; lvl
++) {
435 struct gl_texture_image
*texImg
= texObj
->Image
[face
][lvl
];
436 if (texImg
&& texImg
->Data
) {
437 _mesa_free_texmemory(texImg
->Data
);
450 _swrast_sleep( GLcontext
*ctx
, GLbitfield new_state
)
452 (void) ctx
; (void) new_state
;
457 _swrast_invalidate_state( GLcontext
*ctx
, GLbitfield new_state
)
459 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
462 swrast
->NewState
|= new_state
;
464 /* After 10 statechanges without any swrast functions being called,
465 * put the module to sleep.
467 if (++swrast
->StateChanges
> 10) {
468 swrast
->InvalidateState
= _swrast_sleep
;
469 swrast
->NewState
= ~0;
473 if (new_state
& swrast
->InvalidateTriangleMask
)
474 swrast
->Triangle
= _swrast_validate_triangle
;
476 if (new_state
& swrast
->InvalidateLineMask
)
477 swrast
->Line
= _swrast_validate_line
;
479 if (new_state
& swrast
->InvalidatePointMask
)
480 swrast
->Point
= _swrast_validate_point
;
482 if (new_state
& _SWRAST_NEW_BLEND_FUNC
)
483 swrast
->BlendFunc
= _swrast_validate_blend_func
;
485 if (new_state
& _SWRAST_NEW_TEXTURE_SAMPLE_FUNC
)
486 for (i
= 0 ; i
< ctx
->Const
.MaxTextureImageUnits
; i
++)
487 swrast
->TextureSample
[i
] = NULL
;
492 _swrast_update_texture_samplers(GLcontext
*ctx
)
494 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
497 for (u
= 0; u
< ctx
->Const
.MaxTextureImageUnits
; u
++) {
498 const struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[u
]._Current
;
499 /* Note: If tObj is NULL, the sample function will be a simple
500 * function that just returns opaque black (0,0,0,1).
502 swrast
->TextureSample
[u
] = _swrast_choose_texture_sample_func(ctx
, tObj
);
508 * Update swrast->_ActiveAttribs and swrast->_NumActiveAttribs
511 _swrast_update_fragment_attribs(GLcontext
*ctx
)
513 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
516 if (ctx
->FragmentProgram
._Current
) {
517 attribsMask
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
525 attribsMask
|= FRAG_BIT_WPOS
;
526 if (NEED_SECONDARY_COLOR(ctx
))
527 attribsMask
|= FRAG_BIT_COL1
;
529 if (swrast
->_FogEnabled
)
530 attribsMask
|= FRAG_BIT_FOGC
;
532 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
533 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
534 attribsMask
|= FRAG_BIT_TEX(u
);
539 /* don't want to interpolate these generic attribs just yet */
541 attribsMask
&= ~(FRAG_BIT_WPOS
|
546 /* Update _ActiveAttribs[] list */
549 for (i
= 0; i
< FRAG_ATTRIB_MAX
; i
++) {
550 if (attribsMask
& (1 << i
))
551 swrast
->_ActiveAttribs
[num
++] = i
;
553 swrast
->_NumActiveAttribs
= num
;
559 * Update the swrast->_ColorOutputsMask which indicates which color
560 * renderbuffers (aka rendertargets) are being written to by the current
562 * We also take glDrawBuffers() into account to skip outputs that are
566 _swrast_update_color_outputs(GLcontext
*ctx
)
568 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
569 const struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
571 swrast
->_ColorOutputsMask
= 0;
572 swrast
->_NumColorOutputs
= 0;
574 if (ctx
->FragmentProgram
._Current
) {
575 const GLbitfield outputsWritten
576 = ctx
->FragmentProgram
._Current
->Base
.OutputsWritten
;
578 for (output
= 0; output
< ctx
->Const
.MaxDrawBuffers
; output
++) {
579 if ((outputsWritten
& (1 << (FRAG_RESULT_DATA0
+ output
)))
580 && (fb
->_NumColorDrawBuffers
[output
] > 0)) {
581 swrast
->_ColorOutputsMask
|= (1 << output
);
582 swrast
->_NumColorOutputs
= output
+ 1;
586 if (swrast
->_ColorOutputsMask
== 0x0) {
587 /* no fragment program, or frag prog didn't write to gl_FragData[] */
588 if (fb
->_NumColorDrawBuffers
[0] > 0) {
589 swrast
->_ColorOutputsMask
= 0x1;
590 swrast
->_NumColorOutputs
= 1;
597 _swrast_validate_derived( GLcontext
*ctx
)
599 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
601 if (swrast
->NewState
) {
602 if (swrast
->NewState
& _NEW_POLYGON
)
603 _swrast_update_polygon( ctx
);
605 if (swrast
->NewState
& (_NEW_HINT
| _NEW_PROGRAM
))
606 _swrast_update_fog_hint( ctx
);
608 if (swrast
->NewState
& _SWRAST_NEW_TEXTURE_ENV_MODE
)
609 _swrast_update_texture_env( ctx
);
611 if (swrast
->NewState
& (_NEW_FOG
| _NEW_PROGRAM
))
612 _swrast_update_fog_state( ctx
);
614 if (swrast
->NewState
& (_NEW_MODELVIEW
|
616 _NEW_TEXTURE_MATRIX
|
625 _swrast_update_fragment_program( ctx
, swrast
->NewState
);
627 if (swrast
->NewState
& (_NEW_TEXTURE
| _NEW_PROGRAM
))
628 _swrast_update_texture_samplers( ctx
);
630 if (swrast
->NewState
& (_NEW_TEXTURE
| _NEW_PROGRAM
))
631 _swrast_validate_texture_images( ctx
);
633 if (swrast
->NewState
& _SWRAST_NEW_RASTERMASK
)
634 _swrast_update_rasterflags( ctx
);
636 if (swrast
->NewState
& (_NEW_DEPTH
|
640 _swrast_update_fragment_attribs(ctx
);
642 if (swrast
->NewState
& (_NEW_PROGRAM
| _NEW_BUFFERS
))
643 _swrast_update_color_outputs(ctx
);
645 swrast
->NewState
= 0;
646 swrast
->StateChanges
= 0;
647 swrast
->InvalidateState
= _swrast_invalidate_state
;
651 #define SWRAST_DEBUG 0
653 /* Public entrypoints: See also s_accum.c, s_bitmap.c, etc.
656 _swrast_Quad( GLcontext
*ctx
,
657 const SWvertex
*v0
, const SWvertex
*v1
,
658 const SWvertex
*v2
, const SWvertex
*v3
)
661 _mesa_debug(ctx
, "_swrast_Quad\n");
662 _swrast_print_vertex( ctx
, v0
);
663 _swrast_print_vertex( ctx
, v1
);
664 _swrast_print_vertex( ctx
, v2
);
665 _swrast_print_vertex( ctx
, v3
);
667 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v3
);
668 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v1
, v2
, v3
);
672 _swrast_Triangle( GLcontext
*ctx
, const SWvertex
*v0
,
673 const SWvertex
*v1
, const SWvertex
*v2
)
676 _mesa_debug(ctx
, "_swrast_Triangle\n");
677 _swrast_print_vertex( ctx
, v0
);
678 _swrast_print_vertex( ctx
, v1
);
679 _swrast_print_vertex( ctx
, v2
);
681 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v2
);
685 _swrast_Line( GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
688 _mesa_debug(ctx
, "_swrast_Line\n");
689 _swrast_print_vertex( ctx
, v0
);
690 _swrast_print_vertex( ctx
, v1
);
692 SWRAST_CONTEXT(ctx
)->Line( ctx
, v0
, v1
);
696 _swrast_Point( GLcontext
*ctx
, const SWvertex
*v0
)
699 _mesa_debug(ctx
, "_swrast_Point\n");
700 _swrast_print_vertex( ctx
, v0
);
702 SWRAST_CONTEXT(ctx
)->Point( ctx
, v0
);
706 _swrast_InvalidateState( GLcontext
*ctx
, GLbitfield new_state
)
709 _mesa_debug(ctx
, "_swrast_InvalidateState\n");
711 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, new_state
);
715 _swrast_ResetLineStipple( GLcontext
*ctx
)
718 _mesa_debug(ctx
, "_swrast_ResetLineStipple\n");
720 SWRAST_CONTEXT(ctx
)->StippleCounter
= 0;
724 _swrast_allow_vertex_fog( GLcontext
*ctx
, GLboolean value
)
727 _mesa_debug(ctx
, "_swrast_allow_vertex_fog %d\n", value
);
729 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
730 SWRAST_CONTEXT(ctx
)->AllowVertexFog
= value
;
734 _swrast_allow_pixel_fog( GLcontext
*ctx
, GLboolean value
)
737 _mesa_debug(ctx
, "_swrast_allow_pixel_fog %d\n", value
);
739 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
740 SWRAST_CONTEXT(ctx
)->AllowPixelFog
= value
;
745 _swrast_CreateContext( GLcontext
*ctx
)
748 SWcontext
*swrast
= (SWcontext
*)CALLOC(sizeof(SWcontext
));
751 _mesa_debug(ctx
, "_swrast_CreateContext\n");
757 swrast
->NewState
= ~0;
759 swrast
->choose_point
= _swrast_choose_point
;
760 swrast
->choose_line
= _swrast_choose_line
;
761 swrast
->choose_triangle
= _swrast_choose_triangle
;
763 swrast
->InvalidatePointMask
= _SWRAST_NEW_POINT
;
764 swrast
->InvalidateLineMask
= _SWRAST_NEW_LINE
;
765 swrast
->InvalidateTriangleMask
= _SWRAST_NEW_TRIANGLE
;
767 swrast
->Point
= _swrast_validate_point
;
768 swrast
->Line
= _swrast_validate_line
;
769 swrast
->Triangle
= _swrast_validate_triangle
;
770 swrast
->InvalidateState
= _swrast_sleep
;
771 swrast
->BlendFunc
= _swrast_validate_blend_func
;
773 swrast
->AllowVertexFog
= GL_TRUE
;
774 swrast
->AllowPixelFog
= GL_TRUE
;
776 /* Optimized Accum buffer */
777 swrast
->_IntegerAccumMode
= GL_FALSE
;
778 swrast
->_IntegerAccumScaler
= 0.0;
780 for (i
= 0; i
< MAX_TEXTURE_IMAGE_UNITS
; i
++)
781 swrast
->TextureSample
[i
] = NULL
;
783 swrast
->SpanArrays
= MALLOC_STRUCT(sw_span_arrays
);
784 if (!swrast
->SpanArrays
) {
788 swrast
->SpanArrays
->ChanType
= CHAN_TYPE
;
789 #if CHAN_TYPE == GL_UNSIGNED_BYTE
790 swrast
->SpanArrays
->rgba
= swrast
->SpanArrays
->color
.sz1
.rgba
;
791 swrast
->SpanArrays
->spec
= swrast
->SpanArrays
->color
.sz1
.spec
;
792 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
793 swrast
->SpanArrays
->rgba
= swrast
->SpanArrays
->color
.sz2
.rgba
;
794 swrast
->SpanArrays
->spec
= swrast
->SpanArrays
->color
.sz2
.spec
;
796 swrast
->SpanArrays
->rgba
= swrast
->SpanArrays
->attribs
[FRAG_ATTRIB_COL0
];
797 swrast
->SpanArrays
->spec
= swrast
->SpanArrays
->attribs
[FRAG_ATTRIB_COL1
];
800 /* init point span buffer */
801 swrast
->PointSpan
.primitive
= GL_POINT
;
802 swrast
->PointSpan
.end
= 0;
803 swrast
->PointSpan
.facing
= 0;
804 swrast
->PointSpan
.array
= swrast
->SpanArrays
;
806 swrast
->TexelBuffer
= (GLchan
*) MALLOC(ctx
->Const
.MaxTextureImageUnits
*
807 MAX_WIDTH
* 4 * sizeof(GLchan
));
808 if (!swrast
->TexelBuffer
) {
809 FREE(swrast
->SpanArrays
);
814 ctx
->swrast_context
= swrast
;
820 _swrast_DestroyContext( GLcontext
*ctx
)
822 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
825 _mesa_debug(ctx
, "_swrast_DestroyContext\n");
828 FREE( swrast
->SpanArrays
);
829 FREE( swrast
->TexelBuffer
);
832 ctx
->swrast_context
= 0;
836 struct swrast_device_driver
*
837 _swrast_GetDeviceDriverReference( GLcontext
*ctx
)
839 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
840 return &swrast
->Driver
;
844 _swrast_flush( GLcontext
*ctx
)
846 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
847 /* flush any pending fragments from rendering points */
848 if (swrast
->PointSpan
.end
> 0) {
849 if (ctx
->Visual
.rgbMode
) {
850 _swrast_write_rgba_span(ctx
, &(swrast
->PointSpan
));
853 _swrast_write_index_span(ctx
, &(swrast
->PointSpan
));
855 swrast
->PointSpan
.end
= 0;
860 _swrast_render_primitive( GLcontext
*ctx
, GLenum prim
)
862 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
863 if (swrast
->Primitive
== GL_POINTS
&& prim
!= GL_POINTS
) {
866 swrast
->Primitive
= prim
;
871 _swrast_render_start( GLcontext
*ctx
)
873 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
874 if (swrast
->Driver
.SpanRenderStart
)
875 swrast
->Driver
.SpanRenderStart( ctx
);
876 swrast
->PointSpan
.end
= 0;
880 _swrast_render_finish( GLcontext
*ctx
)
882 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
883 if (swrast
->Driver
.SpanRenderFinish
)
884 swrast
->Driver
.SpanRenderFinish( ctx
);
890 #define SWRAST_DEBUG_VERTICES 0
893 _swrast_print_vertex( GLcontext
*ctx
, const SWvertex
*v
)
897 if (SWRAST_DEBUG_VERTICES
) {
898 _mesa_debug(ctx
, "win %f %f %f %f\n",
899 v
->win
[0], v
->win
[1], v
->win
[2], v
->win
[3]);
901 for (i
= 0 ; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++)
902 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
903 _mesa_debug(ctx
, "texcoord[%d] %f %f %f %f\n", i
,
904 v
->attrib
[FRAG_ATTRIB_TEX0
+ i
][0],
905 v
->attrib
[FRAG_ATTRIB_TEX0
+ i
][1],
906 v
->attrib
[FRAG_ATTRIB_TEX0
+ i
][2],
907 v
->attrib
[FRAG_ATTRIB_TEX0
+ i
][3]);
909 #if CHAN_TYPE == GL_FLOAT
910 _mesa_debug(ctx
, "color %f %f %f %f\n",
911 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
912 _mesa_debug(ctx
, "spec %f %f %f %f\n",
913 v
->specular
[0], v
->specular
[1],
914 v
->specular
[2], v
->specular
[3]);
916 _mesa_debug(ctx
, "color %d %d %d %d\n",
917 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
918 _mesa_debug(ctx
, "spec %d %d %d %d\n",
919 v
->specular
[0], v
->specular
[1],
920 v
->specular
[2], v
->specular
[3]);
922 _mesa_debug(ctx
, "fog %f\n", v
->attrib
[FRAG_ATTRIB_FOGC
][0]);
923 _mesa_debug(ctx
, "index %d\n", v
->index
);
924 _mesa_debug(ctx
, "pointsize %f\n", v
->pointSize
);
925 _mesa_debug(ctx
, "\n");