示例#1
0
文件: s_logic.c 项目: Ionic/nx-libs
/**
 * 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, struct gl_renderbuffer *rb,
                          const struct sw_span *span, GLchan rgba[][4])
{
   GLchan dest[MAX_WIDTH][4];

   ASSERT(span->end < MAX_WIDTH);
   ASSERT(span->arrayMask & SPAN_RGBA);
   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);

   if (span->arrayMask & SPAN_XY) {
      _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
                         dest, 4 * sizeof(GLchan));
   }
   else {
      _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, dest);
   }

   /* 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;
}
示例#2
0
文件: s_logic.c 项目: Ionic/nx-libs
/*
 * Apply the current logic operator to a span of CI pixels.  This is only
 * used if the device driver can't do logic ops.
 */
void
_swrast_logicop_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb,
                        const struct sw_span *span, GLuint index[])
{
   GLuint dest[MAX_WIDTH];

   ASSERT(span->end < MAX_WIDTH);
   ASSERT(rb->DataType == GL_UNSIGNED_INT);

   /* Read dest values from frame buffer */
   if (span->arrayMask & SPAN_XY) {
      _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
                         dest, sizeof(GLuint));
   }
   else {
      rb->GetRow(ctx, rb, span->end, span->x, span->y, dest);
   }

   logicop_uint(ctx, span->end, index, dest, span->array->mask);
}
示例#3
0
文件: s_stencil.c 项目: Starlink/mesa
/**
 * Apply stencil and depth testing to an array of pixels.
 * This is used both for software and hardware stencil buffers.
 *
 * The comments in this function are a bit sparse but the code is
 * almost identical to stencil_and_ztest_span(), which is well
 * commented.
 *
 * Input:  n - number of pixels in the array
 *         x, y - array of [n] pixel positions
 *         z - array [n] of z values
 *         mask - array [n] of flags  (1=test this pixel, 0=skip the pixel)
 * Output: mask - array [n] of flags (1=stencil and depth test passed)
 * Return: GL_FALSE - all fragments failed the testing
 *         GL_TRUE - one or more fragments passed the testing
 */
static GLboolean
stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
{
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   struct gl_renderbuffer *rb = fb->_StencilBuffer;
   const GLuint n = span->end;
   const GLint *x = span->array->x;
   const GLint *y = span->array->y;
   GLubyte *mask = span->array->mask;

   ASSERT(span->arrayMask & SPAN_XY);
   ASSERT(ctx->Stencil.Enabled);
   ASSERT(n <= MAX_WIDTH);

   if (!rb->GetPointer(ctx, rb, 0, 0)) {
      /* No direct access */
      GLstencil stencil[MAX_WIDTH];
      GLubyte origMask[MAX_WIDTH];

      ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
      _swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte));

      _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));

      (void) do_stencil_test(ctx, face, n, stencil, mask);

      if (ctx->Depth.Test == GL_FALSE) {
         apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
                          n, stencil, mask);
      }
      else {
         _swrast_depth_test_span(ctx, span);

         if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
            GLubyte failmask[MAX_WIDTH];
            GLuint i;
            for (i = 0; i < n; i++) {
               ASSERT(mask[i] == 0 || mask[i] == 1);
               failmask[i] = origMask[i] & (mask[i] ^ 1);
            }
            apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face,
                             n, stencil, failmask);
         }
         if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
            GLubyte passmask[MAX_WIDTH];
            GLuint i;
            for (i = 0; i < n; i++) {
               ASSERT(mask[i] == 0 || mask[i] == 1);
               passmask[i] = origMask[i] & mask[i];
            }
            apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
                             n, stencil, passmask);
         }
      }

      /* Write updated stencil values into hardware stencil buffer */
      rb->PutValues(ctx, rb, n, x, y, stencil, origMask);

      return GL_TRUE;
   }
   else {
      /* Direct access to stencil buffer */

      if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) {
         /* all fragments failed the stencil test, we're done. */
         return GL_FALSE;
      }

      if (ctx->Depth.Test==GL_FALSE) {
         apply_stencil_op_to_pixels(ctx, n, x, y,
                                    ctx->Stencil.ZPassFunc[face], face, mask);
      }
      else {
         GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
         GLuint i;

         _mesa_memcpy(oldmask, mask, n * sizeof(GLubyte));

         _swrast_depth_test_span(ctx, span);

         for (i=0;i<n;i++) {
            ASSERT(mask[i] == 0 || mask[i] == 1);
            passmask[i] = oldmask[i] & mask[i];
            failmask[i] = oldmask[i] & (mask[i] ^ 1);
         }

         if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
            apply_stencil_op_to_pixels(ctx, n, x, y,
                                       ctx->Stencil.ZFailFunc[face],
                                       face, failmask);
         }
         if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
            apply_stencil_op_to_pixels(ctx, n, x, y,
                                       ctx->Stencil.ZPassFunc[face],
                                       face, passmask);
         }
      }

      return GL_TRUE;  /* one or more fragments passed both tests */
   }
}