summaryrefslogtreecommitdiff
path: root/src/mesa/swrast/s_context.c
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2000-11-05 18:24:40 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2000-11-05 18:24:40 +0000
commitcd03ed4f54444d96e4e47cdb118a3dfd94d92bb0 (patch)
tree57d9620635286b4ee4b8adf950014113d5961017 /src/mesa/swrast/s_context.c
parent7c20642b1091df1aab7d9076a3fe2fb11c6f011c (diff)
Reorganized software rasterizer as a module which manages its own state,
with tighter interfaces with the rest of the world. Proper documentation to come.
Diffstat (limited to 'src/mesa/swrast/s_context.c')
-rw-r--r--src/mesa/swrast/s_context.c353
1 files changed, 345 insertions, 8 deletions
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 87a2001849..b17b6052db 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -1,4 +1,4 @@
-/* $Id: s_context.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */
+/* $Id: s_context.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -22,28 +22,365 @@
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Whitwell <keithw@valinux.com>
*/
-
#include "glheader.h"
+#include "types.h"
+#include "mem.h"
#include "s_pb.h"
+#include "s_points.h"
+#include "s_lines.h"
+#include "s_triangle.h"
+#include "s_quads.h"
+#include "s_blend.h"
+#include "s_context.h"
+#include "s_texture.h"
-GLboolean
-_swrast_create_context( GLcontext *ctx )
+
+
+
+/*
+ * Recompute the value of swrast->_RasterMask, etc. according to
+ * the current context.
+ */
+static void
+_swrast_update_rasterflags( GLcontext *ctx )
{
- ctx->PB = gl_alloc_pb();
- if (!ctx->PB) return GL_FALSE;
+ GLuint RasterMask = 0;
- return GL_TRUE;
+ if (ctx->Color.AlphaEnabled) RasterMask |= ALPHATEST_BIT;
+ if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT;
+ if (ctx->Depth.Test) RasterMask |= DEPTH_BIT;
+ if (ctx->Fog.Enabled) RasterMask |= FOG_BIT;
+ if (ctx->Scissor.Enabled) RasterMask |= SCISSOR_BIT;
+ if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT;
+ if (ctx->Visual.RGBAflag) {
+ const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+ if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT;
+ if (ctx->Color.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT;
+ if (ctx->Texture._ReallyEnabled) RasterMask |= TEXTURE_BIT;
+ }
+ else {
+ if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT;
+ if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT;
+ }
+
+ if (ctx->DrawBuffer->UseSoftwareAlphaBuffers
+ && ctx->Color.ColorMask[ACOMP]
+ && ctx->Color.DrawBuffer != GL_NONE)
+ RasterMask |= ALPHABUF_BIT;
+
+ if ( ctx->Viewport.X < 0
+ || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
+ || ctx->Viewport.Y < 0
+ || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
+ RasterMask |= WINCLIP_BIT;
+ }
+
+ if (ctx->Depth.OcclusionTest)
+ RasterMask |= OCCLUSION_BIT;
+
+
+ /* If we're not drawing to exactly one color buffer set the
+ * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
+ * buffers or the RGBA or CI mask disables all writes.
+ */
+ if (ctx->Color.MultiDrawBuffer) {
+ RasterMask |= MULTI_DRAW_BIT;
+ }
+ else if (ctx->Color.DrawBuffer==GL_NONE) {
+ RasterMask |= MULTI_DRAW_BIT;
+ }
+ else if (ctx->Visual.RGBAflag && *((GLuint *) ctx->Color.ColorMask) == 0) {
+ RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
+ }
+ else if (!ctx->Visual.RGBAflag && ctx->Color.IndexMask==0) {
+ RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
+ }
+
+ if ( ctx->Viewport.X<0
+ || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
+ || ctx->Viewport.Y<0
+ || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
+ RasterMask |= WINCLIP_BIT;
+ }
+
+ SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask;
+}
+
+
+
+#define _SWRAST_NEW_TRIANGLE (_NEW_RENDERMODE| \
+ _NEW_POLYGON| \
+ _NEW_DEPTH| \
+ _NEW_STENCIL| \
+ _NEW_COLOR| \
+ _NEW_TEXTURE| \
+ _NEW_HINT| \
+ _SWRAST_NEW_RASTERMASK| \
+ _NEW_LIGHT| \
+ _NEW_FOG)
+
+#define _SWRAST_NEW_LINE (_NEW_RENDERMODE| \
+ _NEW_LINE| \
+ _NEW_TEXTURE| \
+ _NEW_LIGHT| \
+ _NEW_FOG| \
+ _NEW_DEPTH)
+
+#define _SWRAST_NEW_POINT (_NEW_RENDERMODE | \
+ _NEW_POINT | \
+ _NEW_TEXTURE | \
+ _NEW_LIGHT | \
+ _NEW_FOG)
+
+#define _SWRAST_NEW_QUAD 0
+
+#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
+
+#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
+
+
+
+/* Stub for swrast->Triangle to select a true triangle function
+ * after a state change.
+ */
+static void
+_swrast_validate_quad( GLcontext *ctx,
+ SWvertex *v0, SWvertex *v1, SWvertex *v2, SWvertex *v3 )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ _swrast_validate_derived( ctx );
+ swrast->choose_quad( ctx );
+
+ swrast->Quad( ctx, v0, v1, v2, v3 );
+}
+
+static void
+_swrast_validate_triangle( GLcontext *ctx,
+ SWvertex *v0, SWvertex *v1, SWvertex *v2 )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ _swrast_validate_derived( ctx );
+ swrast->choose_triangle( ctx );
+
+ swrast->Triangle( ctx, v0, v1, v2 );
}
+static void
+_swrast_validate_line( GLcontext *ctx, SWvertex *v0, SWvertex *v1 )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ _swrast_validate_derived( ctx );
+ swrast->choose_line( ctx );
+
+ swrast->Line( ctx, v0, v1 );
+}
+
+static void
+_swrast_validate_point( GLcontext *ctx, SWvertex *v0 )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ _swrast_validate_derived( ctx );
+ swrast->choose_point( ctx );
+
+ swrast->Point( ctx, v0 );
+}
+
+void
+_swrast_validate_blend_func( GLcontext *ctx, GLuint n,
+ const GLubyte mask[],
+ GLchan src[][4],
+ CONST GLchan dst[][4] )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ _swrast_validate_derived( ctx );
+ _swrast_choose_blend_func( ctx );
+
+ swrast->BlendFunc( ctx, n, mask, src, dst );
+}
+
+
+void
+_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj,
+ GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ _swrast_validate_derived( ctx );
+ _swrast_choose_texture_sample_func( ctx, texUnit, tObj );
+
+ swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, s, t, u,
+ lambda, rgba );
+}
+
+
+static void
+_swrast_sleep( GLcontext *ctx, GLuint new_state )
+{
+}
+
+
+static void
+_swrast_invalidate_state( GLcontext *ctx, GLuint new_state )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLuint i;
+
+ swrast->NewState |= new_state;
+
+ /* After 10 statechanges without any swrast functions being called,
+ * put the module to sleep.
+ */
+ if (++swrast->StateChanges > 10) {
+ swrast->InvalidateState = _swrast_sleep;
+ swrast->NewState = ~0;
+ new_state = ~0;
+ }
+
+ if (new_state & swrast->invalidate_triangle)
+ swrast->Triangle = _swrast_validate_triangle;
+
+ if (new_state & swrast->invalidate_line)
+ swrast->Line = _swrast_validate_line;
+
+ if (new_state & swrast->invalidate_point)
+ swrast->Point = _swrast_validate_point;
+
+ if (new_state & swrast->invalidate_quad)
+ swrast->Quad = _swrast_validate_quad;
+
+ if (new_state & _SWRAST_NEW_BLEND_FUNC)
+ swrast->BlendFunc = _swrast_validate_blend_func;
+
+ if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC)
+ for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
+ swrast->TextureSample[i] = _swrast_validate_texture_sample;
+}
+
+
+
void
-_swrast_destroy_context( GLcontext *ctx )
+_swrast_validate_derived( GLcontext *ctx )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ if (swrast->NewState)
+ {
+ if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
+ _swrast_update_rasterflags( ctx );
+
+ swrast->NewState = 0;
+ swrast->StateChanges = 0;
+ swrast->InvalidateState = _swrast_invalidate_state;
+ }
}
+/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc.
+ */
+void
+_swrast_Quad( GLcontext *ctx,
+ SWvertex *v0, SWvertex *v1, SWvertex *v2, SWvertex *v3 )
+{
+ SWRAST_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 );
+}
+
+void
+_swrast_Triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )
+{
+ SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 );
+}
+
+void
+_swrast_Line( GLcontext *ctx, SWvertex *v0, SWvertex *v1 )
+{
+ SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 );
+}
+
+void
+_swrast_Point( GLcontext *ctx, SWvertex *v0 )
+{
+ SWRAST_CONTEXT(ctx)->Point( ctx, v0 );
+}
+
+void
+_swrast_InvalidateState( GLcontext *ctx, GLuint new_state )
+{
+ SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state );
+}
+
+
+GLuint *
+_swrast_get_stipple_counter_ref( GLcontext *ctx )
+{
+ return &SWRAST_CONTEXT(ctx)->StippleCounter;
+}
+
+
+GLboolean
+_swrast_CreateContext( GLcontext *ctx )
+{
+ GLuint i;
+ SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext));
+ if (!swrast)
+ return GL_FALSE;
+
+ swrast->PB = gl_alloc_pb();
+ if (!swrast->PB) {
+ FREE(swrast);
+ return GL_FALSE;
+ }
+
+ swrast->NewState = ~0;
+
+ swrast->choose_point = _swrast_choose_point;
+ swrast->choose_line = _swrast_choose_line;
+ swrast->choose_triangle = _swrast_choose_triangle;
+ swrast->choose_quad = _swrast_choose_quad;
+
+ swrast->invalidate_point = _SWRAST_NEW_POINT;
+ swrast->invalidate_line = _SWRAST_NEW_LINE;
+ swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE;
+ swrast->invalidate_quad = _SWRAST_NEW_QUAD;
+
+ swrast->Point = _swrast_validate_point;
+ swrast->Line = _swrast_validate_line;
+ swrast->Triangle = _swrast_validate_triangle;
+ swrast->Quad = _swrast_validate_quad;
+ swrast->InvalidateState = _swrast_sleep;
+ swrast->BlendFunc = _swrast_validate_blend_func;
+
+ for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
+ swrast->TextureSample[i] = _swrast_validate_texture_sample;
+
+ ctx->swrast_context = swrast;
+ return GL_TRUE;
+}
+
+void
+_swrast_DestroyContext( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ FREE( swrast->PB );
+ FREE( swrast );
+
+ ctx->swrast_context = 0;
+}