2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keithw@vmware.com> Brian Paul
28 #include "main/errors.h"
29 #include "util/imports.h"
30 #include "main/bufferobj.h"
31 #include "main/mtypes.h"
32 #include "main/samplerobj.h"
33 #include "main/state.h"
34 #include "main/stencil.h"
35 #include "main/teximage.h"
36 #include "program/prog_parameter.h"
37 #include "program/prog_statevars.h"
40 #include "s_context.h"
44 #include "s_texfetch.h"
45 #include "s_triangle.h"
46 #include "s_texfilter.h"
50 * Recompute the value of swrast->_RasterMask, etc. according to
51 * the current context. The _RasterMask field can be easily tested by
52 * drivers to determine certain basic GL state (does the primitive need
53 * stenciling, logic-op, fog, etc?).
56 _swrast_update_rasterflags( struct gl_context
*ctx
)
58 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
59 GLbitfield rasterMask
= 0;
62 if (ctx
->Color
.AlphaEnabled
) rasterMask
|= ALPHATEST_BIT
;
63 if (ctx
->Color
.BlendEnabled
) rasterMask
|= BLEND_BIT
;
64 if (ctx
->Depth
.Test
) rasterMask
|= DEPTH_BIT
;
65 if (swrast
->_FogEnabled
) rasterMask
|= FOG_BIT
;
66 if (ctx
->Scissor
.EnableFlags
) rasterMask
|= CLIP_BIT
;
67 if (_mesa_stencil_is_enabled(ctx
)) rasterMask
|= STENCIL_BIT
;
68 for (i
= 0; i
< ctx
->Const
.MaxDrawBuffers
; i
++) {
69 if (GET_COLORMASK(ctx
->Color
.ColorMask
, i
) != 0xf) {
70 rasterMask
|= MASKING_BIT
;
74 if (ctx
->Color
.ColorLogicOpEnabled
) rasterMask
|= LOGIC_OP_BIT
;
75 if (ctx
->Texture
._MaxEnabledTexImageUnit
>= 0) rasterMask
|= TEXTURE_BIT
;
76 if ( ctx
->ViewportArray
[0].X
< 0
77 || ctx
->ViewportArray
[0].X
+ ctx
->ViewportArray
[0].Width
> (GLfloat
) ctx
->DrawBuffer
->Width
78 || ctx
->ViewportArray
[0].Y
< 0
79 || ctx
->ViewportArray
[0].Y
+ ctx
->ViewportArray
[0].Height
> (GLfloat
) ctx
->DrawBuffer
->Height
) {
80 rasterMask
|= CLIP_BIT
;
83 if (ctx
->Query
.CurrentOcclusionObject
)
84 rasterMask
|= OCCLUSION_BIT
;
87 /* If we're not drawing to exactly one color buffer set the
88 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
89 * buffers or the RGBA or CI mask disables all writes.
91 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
!= 1) {
92 /* more than one color buffer designated for writing (or zero buffers) */
93 rasterMask
|= MULTI_DRAW_BIT
;
96 for (i
= 0; i
< ctx
->Const
.MaxDrawBuffers
; i
++) {
97 if (GET_COLORMASK(ctx
->Color
.ColorMask
, i
) == 0) {
98 rasterMask
|= MULTI_DRAW_BIT
; /* all RGBA channels disabled */
104 if (_swrast_use_fragment_program(ctx
)) {
105 rasterMask
|= FRAGPROG_BIT
;
108 if (_mesa_ati_fragment_shader_enabled(ctx
)) {
109 rasterMask
|= ATIFRAGSHADER_BIT
;
112 #if CHAN_TYPE == GL_FLOAT
113 if (ctx
->Color
.ClampFragmentColor
== GL_TRUE
) {
114 rasterMask
|= CLAMPING_BIT
;
118 SWRAST_CONTEXT(ctx
)->_RasterMask
= rasterMask
;
123 * Examine polygon cull state to compute the _BackfaceCullSign field.
124 * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces,
125 * and 1 if culling front-faces. The Polygon FrontFace state also
129 _swrast_update_polygon( struct gl_context
*ctx
)
131 GLfloat backface_sign
;
133 if (ctx
->Polygon
.CullFlag
) {
134 switch (ctx
->Polygon
.CullFaceMode
) {
136 backface_sign
= -1.0F
;
139 backface_sign
= 1.0F
;
141 case GL_FRONT_AND_BACK
:
144 backface_sign
= 0.0F
;
148 backface_sign
= 0.0F
;
151 SWRAST_CONTEXT(ctx
)->_BackfaceCullSign
= backface_sign
;
153 /* This is for front/back-face determination, but not for culling */
154 SWRAST_CONTEXT(ctx
)->_BackfaceSign
155 = (ctx
->Polygon
.FrontFace
== GL_CW
) ? -1.0F
: 1.0F
;
161 * Update the _PreferPixelFog field to indicate if we need to compute
162 * fog blend factors (from the fog coords) per-fragment.
165 _swrast_update_fog_hint( struct gl_context
*ctx
)
167 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
168 swrast
->_PreferPixelFog
= (!swrast
->AllowVertexFog
||
169 _swrast_use_fragment_program(ctx
) ||
170 (ctx
->Hint
.Fog
== GL_NICEST
&&
171 swrast
->AllowPixelFog
));
177 * Update the swrast->_TextureCombinePrimary flag.
180 _swrast_update_texture_env( struct gl_context
*ctx
)
182 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
185 swrast
->_TextureCombinePrimary
= GL_FALSE
;
187 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
188 const struct gl_tex_env_combine_state
*combine
=
189 ctx
->Texture
.FixedFuncUnit
[i
]._CurrentCombine
;
191 for (term
= 0; term
< combine
->_NumArgsRGB
; term
++) {
192 if (combine
->SourceRGB
[term
] == GL_PRIMARY_COLOR
) {
193 swrast
->_TextureCombinePrimary
= GL_TRUE
;
196 if (combine
->SourceA
[term
] == GL_PRIMARY_COLOR
) {
197 swrast
->_TextureCombinePrimary
= GL_TRUE
;
206 * Determine if we can defer texturing/shading until after Z/stencil
207 * testing. This potentially allows us to skip texturing/shading for
211 _swrast_update_deferred_texture(struct gl_context
*ctx
)
213 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
214 if (ctx
->Color
.AlphaEnabled
) {
215 /* alpha test depends on post-texture/shader colors */
216 swrast
->_DeferredTexture
= GL_FALSE
;
219 GLboolean use_fprog
= _swrast_use_fragment_program(ctx
);
220 const struct gl_program
*fprog
= ctx
->FragmentProgram
._Current
;
222 (fprog
->info
.outputs_written
& (1 << FRAG_RESULT_DEPTH
))) {
223 /* Z comes from fragment program/shader */
224 swrast
->_DeferredTexture
= GL_FALSE
;
226 else if (use_fprog
&& fprog
->info
.fs
.uses_discard
) {
227 swrast
->_DeferredTexture
= GL_FALSE
;
229 else if (ctx
->Query
.CurrentOcclusionObject
) {
230 /* occlusion query depends on shader discard/kill results */
231 swrast
->_DeferredTexture
= GL_FALSE
;
234 swrast
->_DeferredTexture
= GL_TRUE
;
241 * Update swrast->_FogColor and swrast->_FogEnable values.
244 _swrast_update_fog_state( struct gl_context
*ctx
)
246 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
247 const struct gl_program
*fp
= ctx
->FragmentProgram
._Current
;
249 assert(fp
== NULL
|| fp
->Target
== GL_FRAGMENT_PROGRAM_ARB
);
250 (void) fp
; /* silence unused var warning */
252 /* determine if fog is needed, and if so, which fog mode */
253 swrast
->_FogEnabled
= (!_swrast_use_fragment_program(ctx
) &&
259 * Update state for running fragment programs. Basically, load the
260 * program parameters with current state values.
263 _swrast_update_fragment_program(struct gl_context
*ctx
, GLbitfield newState
)
265 if (!_swrast_use_fragment_program(ctx
))
268 _mesa_load_state_parameters(ctx
,
269 ctx
->FragmentProgram
._Current
->Parameters
);
274 * See if we can do early diffuse+specular (primary+secondary) color
275 * add per vertex instead of per-fragment.
278 _swrast_update_specular_vertex_add(struct gl_context
*ctx
)
280 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
281 GLboolean separateSpecular
= ctx
->Fog
.ColorSumEnabled
||
282 (ctx
->Light
.Enabled
&&
283 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
);
285 swrast
->SpecularVertexAdd
= (separateSpecular
286 && ctx
->Texture
._MaxEnabledTexImageUnit
== -1
287 && !_swrast_use_fragment_program(ctx
)
288 && !_mesa_ati_fragment_shader_enabled(ctx
));
292 #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \
293 _NEW_PROGRAM_CONSTANTS | \
298 /* State referenced by _swrast_choose_triangle, _swrast_choose_line.
300 #define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \
307 _SWRAST_NEW_RASTERMASK| \
310 _MESA_NEW_SEPARATE_SPECULAR)
312 #define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \
319 _MESA_NEW_SEPARATE_SPECULAR)
321 #define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \
327 _MESA_NEW_SEPARATE_SPECULAR)
329 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
331 #define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
333 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
338 * Stub for swrast->Triangle to select a true triangle function
339 * after a state change.
342 _swrast_validate_triangle( struct gl_context
*ctx
,
347 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
349 _swrast_validate_derived( ctx
);
350 swrast
->choose_triangle( ctx
);
351 assert(swrast
->Triangle
);
353 if (swrast
->SpecularVertexAdd
) {
354 /* separate specular color, but no texture */
355 swrast
->SpecTriangle
= swrast
->Triangle
;
356 swrast
->Triangle
= _swrast_add_spec_terms_triangle
;
359 swrast
->Triangle( ctx
, v0
, v1
, v2
);
363 * Called via swrast->Line. Examine current GL state and choose a software
364 * line routine. Then call it.
367 _swrast_validate_line( struct gl_context
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
369 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
371 _swrast_validate_derived( ctx
);
372 swrast
->choose_line( ctx
);
373 assert(swrast
->Line
);
375 if (swrast
->SpecularVertexAdd
) {
376 swrast
->SpecLine
= swrast
->Line
;
377 swrast
->Line
= _swrast_add_spec_terms_line
;
380 swrast
->Line( ctx
, v0
, v1
);
384 * Called via swrast->Point. Examine current GL state and choose a software
385 * point routine. Then call it.
388 _swrast_validate_point( struct gl_context
*ctx
, const SWvertex
*v0
)
390 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
392 _swrast_validate_derived( ctx
);
393 swrast
->choose_point( ctx
);
395 if (swrast
->SpecularVertexAdd
) {
396 swrast
->SpecPoint
= swrast
->Point
;
397 swrast
->Point
= _swrast_add_spec_terms_point
;
400 swrast
->Point( ctx
, v0
);
405 * Called via swrast->BlendFunc. Examine GL state to choose a blending
406 * function, then call it.
409 _swrast_validate_blend_func(struct gl_context
*ctx
, GLuint n
, const GLubyte mask
[],
410 GLvoid
*src
, const GLvoid
*dst
,
413 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
415 _swrast_validate_derived( ctx
); /* why is this needed? */
416 _swrast_choose_blend_func( ctx
, chanType
);
418 swrast
->BlendFunc( ctx
, n
, mask
, src
, dst
, chanType
);
422 _swrast_sleep( struct gl_context
*ctx
, GLbitfield new_state
)
424 (void) ctx
; (void) new_state
;
429 _swrast_invalidate_state( struct gl_context
*ctx
, GLbitfield new_state
)
431 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
434 swrast
->NewState
|= new_state
;
436 /* After 10 statechanges without any swrast functions being called,
437 * put the module to sleep.
439 if (++swrast
->StateChanges
> 10) {
440 swrast
->InvalidateState
= _swrast_sleep
;
441 swrast
->NewState
= ~0;
445 if (new_state
& swrast
->InvalidateTriangleMask
)
446 swrast
->Triangle
= _swrast_validate_triangle
;
448 if (new_state
& swrast
->InvalidateLineMask
)
449 swrast
->Line
= _swrast_validate_line
;
451 if (new_state
& swrast
->InvalidatePointMask
)
452 swrast
->Point
= _swrast_validate_point
;
454 if (new_state
& _SWRAST_NEW_BLEND_FUNC
)
455 swrast
->BlendFunc
= _swrast_validate_blend_func
;
457 if (new_state
& _SWRAST_NEW_TEXTURE_SAMPLE_FUNC
)
458 for (i
= 0 ; i
< ARRAY_SIZE(swrast
->TextureSample
); i
++)
459 swrast
->TextureSample
[i
] = NULL
;
464 _swrast_update_texture_samplers(struct gl_context
*ctx
)
466 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
470 return; /* pipe hack */
472 for (u
= 0; u
< ARRAY_SIZE(swrast
->TextureSample
); u
++) {
473 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[u
]._Current
;
474 /* Note: If tObj is NULL, the sample function will be a simple
475 * function that just returns opaque black (0,0,0,1).
477 _mesa_update_fetch_functions(ctx
, u
);
478 swrast
->TextureSample
[u
] =
479 _swrast_choose_texture_sample_func(ctx
, tObj
,
480 _mesa_get_samplerobj(ctx
, u
));
486 * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
487 * swrast->_ActiveAtttribMask.
490 _swrast_update_active_attribs(struct gl_context
*ctx
)
492 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
493 GLbitfield64 attribsMask
;
496 * Compute _ActiveAttribsMask = which fragment attributes are needed.
498 if (_swrast_use_fragment_program(ctx
)) {
499 /* fragment program/shader */
500 attribsMask
= ctx
->FragmentProgram
._Current
->info
.inputs_read
;
501 attribsMask
&= ~VARYING_BIT_POS
; /* WPOS is always handled specially */
503 else if (_mesa_ati_fragment_shader_enabled(ctx
)) {
504 attribsMask
= VARYING_BIT_COL0
| VARYING_BIT_COL1
|
505 VARYING_BIT_FOGC
| VARYING_BITS_TEX_ANY
;
511 #if CHAN_TYPE == GL_FLOAT
512 attribsMask
|= VARYING_BIT_COL0
;
515 if (ctx
->Fog
.ColorSumEnabled
||
516 (ctx
->Light
.Enabled
&&
517 ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
)) {
518 attribsMask
|= VARYING_BIT_COL1
;
521 if (swrast
->_FogEnabled
)
522 attribsMask
|= VARYING_BIT_FOGC
;
524 attribsMask
|= (ctx
->Texture
._EnabledCoordUnits
<< VARYING_SLOT_TEX0
);
527 swrast
->_ActiveAttribMask
= attribsMask
;
529 /* Update _ActiveAttribs[] list */
532 for (i
= 0; i
< VARYING_SLOT_MAX
; i
++) {
533 if (attribsMask
& BITFIELD64_BIT(i
)) {
534 swrast
->_ActiveAttribs
[num
++] = i
;
535 /* how should this attribute be interpolated? */
536 if (i
== VARYING_SLOT_COL0
|| i
== VARYING_SLOT_COL1
)
537 swrast
->_InterpMode
[i
] = ctx
->Light
.ShadeModel
;
539 swrast
->_InterpMode
[i
] = GL_SMOOTH
;
542 swrast
->_NumActiveAttribs
= num
;
548 _swrast_validate_derived( struct gl_context
*ctx
)
550 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
552 if (swrast
->NewState
) {
553 if (swrast
->NewState
& _NEW_POLYGON
)
554 _swrast_update_polygon( ctx
);
556 if (swrast
->NewState
& (_NEW_HINT
| _NEW_PROGRAM
))
557 _swrast_update_fog_hint( ctx
);
559 if (swrast
->NewState
& _SWRAST_NEW_TEXTURE_ENV_MODE
)
560 _swrast_update_texture_env( ctx
);
562 if (swrast
->NewState
& (_NEW_FOG
| _NEW_PROGRAM
))
563 _swrast_update_fog_state( ctx
);
565 if (swrast
->NewState
& (_NEW_PROGRAM_CONSTANTS
| _NEW_PROGRAM
))
566 _swrast_update_fragment_program( ctx
, swrast
->NewState
);
568 if (swrast
->NewState
& (_NEW_TEXTURE
| _NEW_PROGRAM
)) {
569 _swrast_update_texture_samplers( ctx
);
572 if (swrast
->NewState
& (_NEW_COLOR
| _NEW_PROGRAM
))
573 _swrast_update_deferred_texture(ctx
);
575 if (swrast
->NewState
& _SWRAST_NEW_RASTERMASK
)
576 _swrast_update_rasterflags( ctx
);
578 if (swrast
->NewState
& (_NEW_DEPTH
|
583 _swrast_update_active_attribs(ctx
);
585 if (swrast
->NewState
& (_NEW_FOG
|
589 _swrast_update_specular_vertex_add(ctx
);
591 swrast
->NewState
= 0;
592 swrast
->StateChanges
= 0;
593 swrast
->InvalidateState
= _swrast_invalidate_state
;
597 #define SWRAST_DEBUG 0
599 /* Public entrypoints: See also s_bitmap.c, etc.
602 _swrast_Quad( struct gl_context
*ctx
,
603 const SWvertex
*v0
, const SWvertex
*v1
,
604 const SWvertex
*v2
, const SWvertex
*v3
)
607 _mesa_debug(ctx
, "_swrast_Quad\n");
608 _swrast_print_vertex( ctx
, v0
);
609 _swrast_print_vertex( ctx
, v1
);
610 _swrast_print_vertex( ctx
, v2
);
611 _swrast_print_vertex( ctx
, v3
);
613 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v3
);
614 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v1
, v2
, v3
);
618 _swrast_Triangle( struct gl_context
*ctx
, const SWvertex
*v0
,
619 const SWvertex
*v1
, const SWvertex
*v2
)
622 _mesa_debug(ctx
, "_swrast_Triangle\n");
623 _swrast_print_vertex( ctx
, v0
);
624 _swrast_print_vertex( ctx
, v1
);
625 _swrast_print_vertex( ctx
, v2
);
627 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v2
);
631 _swrast_Line( struct gl_context
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
634 _mesa_debug(ctx
, "_swrast_Line\n");
635 _swrast_print_vertex( ctx
, v0
);
636 _swrast_print_vertex( ctx
, v1
);
638 SWRAST_CONTEXT(ctx
)->Line( ctx
, v0
, v1
);
642 _swrast_Point( struct gl_context
*ctx
, const SWvertex
*v0
)
645 _mesa_debug(ctx
, "_swrast_Point\n");
646 _swrast_print_vertex( ctx
, v0
);
648 SWRAST_CONTEXT(ctx
)->Point( ctx
, v0
);
652 _swrast_InvalidateState( struct gl_context
*ctx
, GLbitfield new_state
)
655 _mesa_debug(ctx
, "_swrast_InvalidateState\n");
657 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, new_state
);
661 _swrast_ResetLineStipple( struct gl_context
*ctx
)
664 _mesa_debug(ctx
, "_swrast_ResetLineStipple\n");
666 SWRAST_CONTEXT(ctx
)->StippleCounter
= 0;
670 _swrast_SetFacing(struct gl_context
*ctx
, GLuint facing
)
672 SWRAST_CONTEXT(ctx
)->PointLineFacing
= facing
;
676 _swrast_allow_vertex_fog( struct gl_context
*ctx
, GLboolean value
)
679 _mesa_debug(ctx
, "_swrast_allow_vertex_fog %d\n", value
);
681 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
682 SWRAST_CONTEXT(ctx
)->AllowVertexFog
= value
;
686 _swrast_allow_pixel_fog( struct gl_context
*ctx
, GLboolean value
)
689 _mesa_debug(ctx
, "_swrast_allow_pixel_fog %d\n", value
);
691 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
692 SWRAST_CONTEXT(ctx
)->AllowPixelFog
= value
;
697 * Initialize native program limits by copying the logical limits.
698 * See comments in init_program_limits() in context.c
701 init_program_native_limits(struct gl_program_constants
*prog
)
703 prog
->MaxNativeInstructions
= prog
->MaxInstructions
;
704 prog
->MaxNativeAluInstructions
= prog
->MaxAluInstructions
;
705 prog
->MaxNativeTexInstructions
= prog
->MaxTexInstructions
;
706 prog
->MaxNativeTexIndirections
= prog
->MaxTexIndirections
;
707 prog
->MaxNativeAttribs
= prog
->MaxAttribs
;
708 prog
->MaxNativeTemps
= prog
->MaxTemps
;
709 prog
->MaxNativeAddressRegs
= prog
->MaxAddressRegs
;
710 prog
->MaxNativeParameters
= prog
->MaxParameters
;
715 _swrast_CreateContext( struct gl_context
*ctx
)
718 SWcontext
*swrast
= calloc(1, sizeof(SWcontext
));
720 const GLuint maxThreads
= omp_get_max_threads();
722 const GLuint maxThreads
= 1;
725 assert(ctx
->Const
.MaxViewportWidth
<= SWRAST_MAX_WIDTH
);
726 assert(ctx
->Const
.MaxViewportHeight
<= SWRAST_MAX_WIDTH
);
728 assert(ctx
->Const
.MaxRenderbufferSize
<= SWRAST_MAX_WIDTH
);
730 /* make sure largest texture image is <= SWRAST_MAX_WIDTH in size */
731 assert(ctx
->Const
.MaxTextureSize
<= SWRAST_MAX_WIDTH
);
732 assert((1 << (ctx
->Const
.MaxCubeTextureLevels
- 1)) <= SWRAST_MAX_WIDTH
);
733 assert((1 << (ctx
->Const
.Max3DTextureLevels
- 1)) <= SWRAST_MAX_WIDTH
);
735 assert(PROG_MAX_WIDTH
== SWRAST_MAX_WIDTH
);
738 _mesa_debug(ctx
, "_swrast_CreateContext\n");
744 swrast
->NewState
= ~0;
746 swrast
->choose_point
= _swrast_choose_point
;
747 swrast
->choose_line
= _swrast_choose_line
;
748 swrast
->choose_triangle
= _swrast_choose_triangle
;
750 swrast
->InvalidatePointMask
= _SWRAST_NEW_POINT
;
751 swrast
->InvalidateLineMask
= _SWRAST_NEW_LINE
;
752 swrast
->InvalidateTriangleMask
= _SWRAST_NEW_TRIANGLE
;
754 swrast
->Point
= _swrast_validate_point
;
755 swrast
->Line
= _swrast_validate_line
;
756 swrast
->Triangle
= _swrast_validate_triangle
;
757 swrast
->InvalidateState
= _swrast_sleep
;
758 swrast
->BlendFunc
= _swrast_validate_blend_func
;
760 swrast
->AllowVertexFog
= GL_TRUE
;
761 swrast
->AllowPixelFog
= GL_TRUE
;
763 swrast
->Driver
.SpanRenderStart
= _swrast_span_render_start
;
764 swrast
->Driver
.SpanRenderFinish
= _swrast_span_render_finish
;
766 for (i
= 0; i
< ARRAY_SIZE(swrast
->TextureSample
); i
++)
767 swrast
->TextureSample
[i
] = NULL
;
769 /* SpanArrays is global and shared by all SWspan instances. However, when
770 * using multiple threads, it is necessary to have one SpanArrays instance
773 swrast
->SpanArrays
= malloc(maxThreads
* sizeof(SWspanarrays
));
774 if (!swrast
->SpanArrays
) {
778 for(i
= 0; i
< maxThreads
; i
++) {
779 swrast
->SpanArrays
[i
].ChanType
= CHAN_TYPE
;
780 #if CHAN_TYPE == GL_UNSIGNED_BYTE
781 swrast
->SpanArrays
[i
].rgba
= swrast
->SpanArrays
[i
].rgba8
;
782 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
783 swrast
->SpanArrays
[i
].rgba
= swrast
->SpanArrays
[i
].rgba16
;
785 swrast
->SpanArrays
[i
].rgba
= swrast
->SpanArrays
[i
].attribs
[VARYING_SLOT_COL0
];
789 /* init point span buffer */
790 swrast
->PointSpan
.primitive
= GL_POINT
;
791 swrast
->PointSpan
.end
= 0;
792 swrast
->PointSpan
.facing
= 0;
793 swrast
->PointSpan
.array
= swrast
->SpanArrays
;
795 init_program_native_limits(&ctx
->Const
.Program
[MESA_SHADER_VERTEX
]);
796 init_program_native_limits(&ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
]);
797 init_program_native_limits(&ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
]);
799 ctx
->swrast_context
= swrast
;
801 swrast
->stencil_temp
.buf1
= malloc(SWRAST_MAX_WIDTH
* sizeof(GLubyte
));
802 swrast
->stencil_temp
.buf2
= malloc(SWRAST_MAX_WIDTH
* sizeof(GLubyte
));
803 swrast
->stencil_temp
.buf3
= malloc(SWRAST_MAX_WIDTH
* sizeof(GLubyte
));
804 swrast
->stencil_temp
.buf4
= malloc(SWRAST_MAX_WIDTH
* sizeof(GLubyte
));
806 if (!swrast
->stencil_temp
.buf1
||
807 !swrast
->stencil_temp
.buf2
||
808 !swrast
->stencil_temp
.buf3
||
809 !swrast
->stencil_temp
.buf4
) {
810 _swrast_DestroyContext(ctx
);
818 _swrast_DestroyContext( struct gl_context
*ctx
)
820 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
823 _mesa_debug(ctx
, "_swrast_DestroyContext\n");
826 free( swrast
->SpanArrays
);
827 free( swrast
->ZoomedArrays
);
828 free( swrast
->TexelBuffer
);
830 free(swrast
->stencil_temp
.buf1
);
831 free(swrast
->stencil_temp
.buf2
);
832 free(swrast
->stencil_temp
.buf3
);
833 free(swrast
->stencil_temp
.buf4
);
837 ctx
->swrast_context
= 0;
841 struct swrast_device_driver
*
842 _swrast_GetDeviceDriverReference( struct gl_context
*ctx
)
844 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
845 return &swrast
->Driver
;
849 _swrast_flush( struct gl_context
*ctx
)
851 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
852 /* flush any pending fragments from rendering points */
853 if (swrast
->PointSpan
.end
> 0) {
854 _swrast_write_rgba_span(ctx
, &(swrast
->PointSpan
));
855 swrast
->PointSpan
.end
= 0;
860 _swrast_render_primitive( struct gl_context
*ctx
, GLenum prim
)
862 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
863 if (swrast
->Primitive
== GL_POINTS
&& prim
!= GL_POINTS
) {
866 swrast
->Primitive
= prim
;
870 /** called via swrast->Driver.SpanRenderStart() */
872 _swrast_span_render_start(struct gl_context
*ctx
)
874 _swrast_map_textures(ctx
);
875 _swrast_map_renderbuffers(ctx
);
879 /** called via swrast->Driver.SpanRenderFinish() */
881 _swrast_span_render_finish(struct gl_context
*ctx
)
883 _swrast_unmap_textures(ctx
);
884 _swrast_unmap_renderbuffers(ctx
);
889 _swrast_render_start( struct gl_context
*ctx
)
891 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
892 if (swrast
->Driver
.SpanRenderStart
)
893 swrast
->Driver
.SpanRenderStart( ctx
);
894 swrast
->PointSpan
.end
= 0;
898 _swrast_render_finish( struct gl_context
*ctx
)
900 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
901 struct gl_query_object
*query
= ctx
->Query
.CurrentOcclusionObject
;
905 if (swrast
->Driver
.SpanRenderFinish
)
906 swrast
->Driver
.SpanRenderFinish( ctx
);
908 if (query
&& (query
->Target
== GL_ANY_SAMPLES_PASSED
||
909 query
->Target
== GL_ANY_SAMPLES_PASSED_CONSERVATIVE
))
910 query
->Result
= !!query
->Result
;
914 #define SWRAST_DEBUG_VERTICES 0
917 _swrast_print_vertex( struct gl_context
*ctx
, const SWvertex
*v
)
921 if (SWRAST_DEBUG_VERTICES
) {
922 _mesa_debug(ctx
, "win %f %f %f %f\n",
923 v
->attrib
[VARYING_SLOT_POS
][0],
924 v
->attrib
[VARYING_SLOT_POS
][1],
925 v
->attrib
[VARYING_SLOT_POS
][2],
926 v
->attrib
[VARYING_SLOT_POS
][3]);
928 for (i
= 0 ; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++)
929 if (ctx
->Texture
.Unit
[i
]._Current
)
930 _mesa_debug(ctx
, "texcoord[%d] %f %f %f %f\n", i
,
931 v
->attrib
[VARYING_SLOT_TEX0
+ i
][0],
932 v
->attrib
[VARYING_SLOT_TEX0
+ i
][1],
933 v
->attrib
[VARYING_SLOT_TEX0
+ i
][2],
934 v
->attrib
[VARYING_SLOT_TEX0
+ i
][3]);
936 #if CHAN_TYPE == GL_FLOAT
937 _mesa_debug(ctx
, "color %f %f %f %f\n",
938 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
940 _mesa_debug(ctx
, "color %d %d %d %d\n",
941 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
943 _mesa_debug(ctx
, "spec %g %g %g %g\n",
944 v
->attrib
[VARYING_SLOT_COL1
][0],
945 v
->attrib
[VARYING_SLOT_COL1
][1],
946 v
->attrib
[VARYING_SLOT_COL1
][2],
947 v
->attrib
[VARYING_SLOT_COL1
][3]);
948 _mesa_debug(ctx
, "fog %f\n", v
->attrib
[VARYING_SLOT_FOGC
][0]);
949 _mesa_debug(ctx
, "index %f\n", v
->attrib
[VARYING_SLOT_CI
][0]);
950 _mesa_debug(ctx
, "pointsize %f\n", v
->pointSize
);
951 _mesa_debug(ctx
, "\n");