X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_logic.c;h=80ee46c24be08030f89f7c37a2a365ff98124db7;hb=706400f0a7a59bba89eca8e97a1ada45445ee6df;hp=9d61230e63dc4fce26f10e5db090fdd1e1c76115;hpb=f431a3fb4dc1bf860203d79e54657e3a62bc50df;p=mesa.git diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c index 9d61230e63d..80ee46c24be 100644 --- a/src/mesa/swrast/s_logic.c +++ b/src/mesa/swrast/s_logic.c @@ -1,10 +1,8 @@ -/* $Id: s_logic.c,v 1.8 2001/07/13 20:07:37 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 6.5.2 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 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"), @@ -25,487 +23,197 @@ */ -#include "glheader.h" -#include "context.h" -#include "macros.h" +#include "main/glheader.h" +#include "main/context.h" +#include "main/imports.h" +#include "main/macros.h" -#include "s_alphabuf.h" #include "s_context.h" #include "s_logic.h" -#include "s_pb.h" #include "s_span.h" - -/* - * Apply logic op to array of CI pixels. - */ -static void index_logicop( GLcontext *ctx, GLuint n, - GLuint index[], const GLuint dest[], - const GLubyte mask[] ) -{ - GLuint i; - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;iDriver.ReadCI32Span)( ctx, n, x, y, dest ); - index_logicop( ctx, n, index, dest, mask ); -} - - - -/* - * Apply the current logic operator to an array of CI pixels. This is only - * used if the device driver can't do logic ops. +/** + * We do all logic ops on 4-byte GLuints. + * Depending on bytes per pixel, the mask array elements correspond to + * 1, 2 or 4 GLuints. */ -void -_mesa_logicop_ci_pixels( GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - GLuint index[], const GLubyte mask[] ) +#define LOGIC_OP_LOOP(MODE, MASKSTRIDE) \ +do { \ + GLuint i; \ + switch (MODE) { \ + case GL_CLEAR: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = 0; \ + } \ + } \ + break; \ + case GL_SET: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~0; \ + } \ + } \ + break; \ + case GL_COPY: \ + /* do nothing */ \ + break; \ + case GL_COPY_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~src[i]; \ + } \ + } \ + break; \ + case GL_NOOP: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = dest[i]; \ + } \ + } \ + break; \ + case GL_INVERT: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~dest[i]; \ + } \ + } \ + break; \ + case GL_AND: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] &= dest[i]; \ + } \ + } \ + break; \ + case GL_NAND: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~(src[i] & dest[i]); \ + } \ + } \ + break; \ + case GL_OR: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] |= dest[i]; \ + } \ + } \ + break; \ + case GL_NOR: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~(src[i] | dest[i]); \ + } \ + } \ + break; \ + case GL_XOR: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] ^= dest[i]; \ + } \ + } \ + break; \ + case GL_EQUIV: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~(src[i] ^ dest[i]); \ + } \ + } \ + break; \ + case GL_AND_REVERSE: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = src[i] & ~dest[i]; \ + } \ + } \ + break; \ + case GL_AND_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~src[i] & dest[i]; \ + } \ + } \ + break; \ + case GL_OR_REVERSE: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = src[i] | ~dest[i]; \ + } \ + } \ + break; \ + case GL_OR_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i / MASKSTRIDE]) { \ + src[i] = ~src[i] | dest[i]; \ + } \ + } \ + break; \ + default: \ + _mesa_problem(ctx, "bad logicop mode");\ + } \ +} while (0) + + + +static inline void +logicop_uint1(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[], + const GLubyte mask[]) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint dest[PB_SIZE]; - /* Read dest values from frame buffer */ - (*swrast->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask ); - index_logicop( ctx, n, index, dest, mask ); + LOGIC_OP_LOOP(ctx->Color.LogicOp, 1); } - -/* - * 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[] ) +static inline void +logicop_uint2(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[], + const GLubyte mask[]) { - GLuint i; - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;iColor.LogicOp, 2); } -/* - * 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[] ) +static inline void +logicop_uint4(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[], + const GLubyte mask[]) { -#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;iColor.LogicOp, 4); } -/* +/** * Apply the current logic operator to a span of RGBA pixels. - * This is only used if the device driver can't do logic ops. + * We can handle horizontal runs of pixels (spans) or arrays of x/y + * pixel coordinates. */ void -_mesa_logicop_rgba_span( GLcontext *ctx, - GLuint n, GLint x, GLint y, - GLchan rgba[][4], const GLubyte mask[] ) +_swrast_logicop_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, + SWspan *span) { - GLchan dest[MAX_WIDTH][4]; - _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest ); - if (sizeof(GLchan) * 4 == sizeof(GLuint)) { - rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest); - } - else { - rgba_logicop_chan(ctx, 4 * n, mask, - (GLchan *) rgba, (const GLchan *) dest); - } -} + void *rbPixels; + ASSERT(span->end < MAX_WIDTH); + ASSERT(span->arrayMask & SPAN_RGBA); + ASSERT(rb->DataType == span->array->ChanType); + rbPixels = _swrast_get_dest_rgba(ctx, rb, span); -/* - * Apply the current logic operator to an array of RGBA pixels. - * This is only used if the device driver can't do logic ops. - */ -void -_mesa_logicop_rgba_pixels( GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - GLchan rgba[][4], const GLubyte mask[] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLchan dest[PB_SIZE][4]; - (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask ); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask ); + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + /* treat 4*GLubyte as GLuint */ + logicop_uint1(ctx, span->end, + (GLuint *) span->array->rgba8, + (const GLuint *) rbPixels, span->array->mask); } - if (sizeof(GLchan) * 4 == sizeof(GLuint)) { - rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest); + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + /* treat 2*GLushort as GLuint */ + logicop_uint2(ctx, 2 * span->end, + (GLuint *) span->array->rgba16, + (const GLuint *) rbPixels, span->array->mask); } else { - rgba_logicop_chan(ctx, 4 * n, mask, - (GLchan *) rgba, (const GLchan *) dest); + logicop_uint4(ctx, 4 * span->end, + (GLuint *) span->array->attribs[FRAG_ATTRIB_COL0], + (const GLuint *) rbPixels, span->array->mask); } }