diff options
Diffstat (limited to 'src/mesa/swrast/s_logic.c')
-rw-r--r-- | src/mesa/swrast/s_logic.c | 588 |
1 files changed, 168 insertions, 420 deletions
diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c index ad27cb7b625..aabe18d9c9a 100644 --- a/src/mesa/swrast/s_logic.c +++ b/src/mesa/swrast/s_logic.c @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,133 +28,151 @@ #include "imports.h" #include "macros.h" -#include "s_alphabuf.h" #include "s_context.h" #include "s_logic.h" #include "s_span.h" +#define LOGIC_OP_LOOP(MODE) \ +do { \ + GLuint i; \ + switch (MODE) { \ + case GL_CLEAR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = 0; \ + } \ + } \ + break; \ + case GL_SET: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~0; \ + } \ + } \ + break; \ + case GL_COPY: \ + /* do nothing */ \ + break; \ + case GL_COPY_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~src[i]; \ + } \ + } \ + break; \ + case GL_NOOP: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = dest[i]; \ + } \ + } \ + break; \ + case GL_INVERT: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~dest[i]; \ + } \ + } \ + break; \ + case GL_AND: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] &= dest[i]; \ + } \ + } \ + break; \ + case GL_NAND: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~(src[i] & dest[i]); \ + } \ + } \ + break; \ + case GL_OR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] |= dest[i]; \ + } \ + } \ + break; \ + case GL_NOR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~(src[i] | dest[i]); \ + } \ + } \ + break; \ + case GL_XOR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] ^= dest[i]; \ + } \ + } \ + break; \ + case GL_EQUIV: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~(src[i] ^ dest[i]); \ + } \ + } \ + break; \ + case GL_AND_REVERSE: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = src[i] & ~dest[i]; \ + } \ + } \ + break; \ + case GL_AND_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~src[i] & dest[i]; \ + } \ + } \ + break; \ + case GL_OR_REVERSE: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = src[i] | ~dest[i]; \ + } \ + } \ + break; \ + case GL_OR_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~src[i] | dest[i]; \ + } \ + } \ + break; \ + default: \ + _mesa_problem(ctx, "bad logicop mode");\ + } \ +} while (0) + + -/* - * Apply logic op to array of CI pixels. - */ static void -index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[], - const GLubyte mask[] ) +logicop_ubyte(GLcontext *ctx, GLuint n, GLubyte src[], const GLubyte dest[], + const GLubyte mask[]) { - GLuint i; - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = 0; - } - } - break; - case GL_SET: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~0; - } - } - break; - case GL_COPY: - /* do nothing */ - break; - case GL_COPY_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~index[i]; - } - } - break; - case GL_NOOP: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = dest[i]; - } - } - break; - case GL_INVERT: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~dest[i]; - } - } - break; - case GL_AND: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] &= dest[i]; - } - } - break; - case GL_NAND: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~(index[i] & dest[i]); - } - } - break; - case GL_OR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] |= dest[i]; - } - } - break; - case GL_NOR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~(index[i] | dest[i]); - } - } - break; - case GL_XOR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] ^= dest[i]; - } - } - break; - case GL_EQUIV: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~(index[i] ^ dest[i]); - } - } - break; - case GL_AND_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = index[i] & ~dest[i]; - } - } - break; - case GL_AND_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~index[i] & dest[i]; - } - } - break; - case GL_OR_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = index[i] | ~dest[i]; - } - } - break; - case GL_OR_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~index[i] | dest[i]; - } - } - break; - default: - _mesa_problem(ctx, "bad mode in index_logic()"); - } + LOGIC_OP_LOOP(ctx->Color.LogicOp); +} + + +static void +logicop_ushort(GLcontext *ctx, GLuint n, GLushort src[], const GLushort dest[], + const GLubyte mask[]) +{ + LOGIC_OP_LOOP(ctx->Color.LogicOp); +} + + +static void +logicop_uint(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[], + const GLubyte mask[]) +{ + LOGIC_OP_LOOP(ctx->Color.LogicOp); } @@ -165,305 +182,35 @@ index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[], * used if the device driver can't do logic ops. */ void -_swrast_logicop_ci_span( GLcontext *ctx, const struct sw_span *span, - GLuint index[] ) +_swrast_logicop_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLuint index[]) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint dest[MAX_WIDTH]; ASSERT(span->end < MAX_WIDTH); /* Read dest values from frame buffer */ if (span->arrayMask & SPAN_XY) { - (*swrast->Driver.ReadCI32Pixels)( ctx, span->end, - span->array->x, span->array->y, - dest, span->array->mask ); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, dest); } else { - (*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest ); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, span->end, span->x, span->y, dest); } - index_logicop( ctx, span->end, index, dest, span->array->mask ); + logicop_uint(ctx, span->end, index, dest, span->array->mask); } - -/* - * Apply logic operator to rgba pixels. - * Input: ctx - the context - * n - number of pixels - * mask - pixel mask array - * In/Out: src - incoming pixels which will be modified - * Input: dest - frame buffer values - * - * Note: Since the R, G, B, and A channels are all treated the same we - * process them as 4-byte GLuints instead of four GLubytes. - */ -static void -rgba_logicop_ui( const GLcontext *ctx, GLuint n, const GLubyte mask[], - GLuint src[], const GLuint dest[] ) -{ - GLuint i; - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = 0; - } - } - break; - case GL_SET: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~0; - } - } - break; - case GL_COPY: - /* do nothing */ - break; - case GL_COPY_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i]; - } - } - break; - case GL_NOOP: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = dest[i]; - } - } - break; - case GL_INVERT: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~dest[i]; - } - } - break; - case GL_AND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] &= dest[i]; - } - } - break; - case GL_NAND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] & dest[i]); - } - } - break; - case GL_OR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i]|= dest[i]; - } - } - break; - case GL_NOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] | dest[i]); - } - } - break; - case GL_XOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] ^= dest[i]; - } - } - break; - case GL_EQUIV: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] ^ dest[i]); - } - } - break; - case GL_AND_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] & ~dest[i]; - } - } - break; - case GL_AND_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] & dest[i]; - } - } - break; - case GL_OR_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] | ~dest[i]; - } - } - break; - case GL_OR_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] | dest[i]; - } - } - break; - default: - /* should never happen */ - _mesa_problem(ctx, "Bad function in rgba_logicop"); - } -} - - -/* - * As above, but operate on GLchan values - * Note: need to pass n = numPixels * 4. - */ -static void -rgba_logicop_chan( const GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan srcPtr[], const GLchan destPtr[] ) -{ -#if CHAN_TYPE == GL_FLOAT - GLuint *src = (GLuint *) srcPtr; - const GLuint *dest = (const GLuint *) destPtr; - GLuint i; - ASSERT(sizeof(GLfloat) == sizeof(GLuint)); -#else - GLchan *src = srcPtr; - const GLchan *dest = destPtr; - GLuint i; -#endif - - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = 0; - } - } - break; - case GL_SET: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~0; - } - } - break; - case GL_COPY: - /* do nothing */ - break; - case GL_COPY_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i]; - } - } - break; - case GL_NOOP: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = dest[i]; - } - } - break; - case GL_INVERT: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~dest[i]; - } - } - break; - case GL_AND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] &= dest[i]; - } - } - break; - case GL_NAND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] & dest[i]); - } - } - break; - case GL_OR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i]|= dest[i]; - } - } - break; - case GL_NOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] | dest[i]); - } - } - break; - case GL_XOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] ^= dest[i]; - } - } - break; - case GL_EQUIV: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] ^ dest[i]); - } - } - break; - case GL_AND_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] & ~dest[i]; - } - } - break; - case GL_AND_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] & dest[i]; - } - } - break; - case GL_OR_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] | ~dest[i]; - } - } - break; - case GL_OR_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] | dest[i]; - } - } - break; - default: - /* should never happen */ - _mesa_problem(ctx, "Bad function in rgba_logicop"); - } -} - - - -/* +/** * Apply the current logic operator to a span of RGBA pixels. * We can handle horizontal runs of pixels (spans) or arrays of x/y * pixel coordinates. */ void -_swrast_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ) +_swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan dest[MAX_WIDTH][4]; @@ -472,26 +219,27 @@ _swrast_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span, ASSERT(span->arrayMask & SPAN_RGBA); if (span->arrayMask & SPAN_XY) { - (*swrast->Driver.ReadRGBAPixels)(ctx, span->end, - span->array->x, span->array->y, - dest, span->array->mask); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _swrast_read_alpha_pixels(ctx, span->end, - span->array->x, span->array->y, - dest, span->array->mask); - } + swrast->Driver.ReadRGBAPixels(ctx, rb, span->end, + span->array->x, span->array->y, + dest, span->array->mask); } else { - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, span->end, - span->x, span->y, dest); + _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, dest); } - if (sizeof(GLchan) * 4 == sizeof(GLuint)) { - rgba_logicop_ui(ctx, span->end, span->array->mask, - (GLuint *) rgba, (const GLuint *) dest); - } - else { - rgba_logicop_chan(ctx, 4 * span->end, span->array->mask, - (GLchan *) rgba, (const GLchan *) dest); - } + /* NEW_RENDERBUFFER: XXX make this a runtime test */ +#if CHAN_TYPE == GL_UNSIGNED_BYTE + /* treat 4*GLubyte as GLuint */ + logicop_uint(ctx, span->end, (GLuint *) rgba, + (const GLuint *) dest, span->array->mask); +#elif CHAN_TYPE == GL_UNSIGNED_SHORT + logicop_ushort(ctx, 4 * span->end, (GLushort *) rgba, + (const GLushort *) dest, span->array->mask); +#elif CHAN_TYPE == GL_FLOAT + logicop_uint(ctx, 4 * span->end, (GLuint *) rgba, + (const GLuint *) dest, span->array->mask); +#endif + (void) logicop_ubyte; + (void) logicop_ushort; + (void) logicop_uint; } |