13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * quad polygon stipple stage
43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "sp_context.h"
73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "sp_quad.h"
83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "sp_quad_pipe.h"
93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "pipe/p_defines.h"
103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "util/u_memory.h"
113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Apply polygon stipple to quads produced by triangle rasterization
153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr)
183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   static const uint bit31 = 1 << 31;
203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   static const uint bit30 = 1 << 30;
213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned pass = nr;
223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct softpipe_context *softpipe = qs->softpipe;
243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned q;
253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   pass = 0;
273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (q = 0; q < nr; q++)  {
293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      struct quad_header *quad = quads[q];
303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const int col0 = quad->input.x0 % 32;
323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const int y0 = quad->input.y0;
333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const int y1 = y0 + 1;
343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const uint stipple0 = softpipe->poly_stipple.stipple[y0 % 32];
353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const uint stipple1 = softpipe->poly_stipple.stipple[y1 % 32];
363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* turn off quad mask bits that fail the stipple test */
383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if ((stipple0 & (bit31 >> col0)) == 0)
393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         quad->inout.mask &= ~MASK_TOP_LEFT;
403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if ((stipple0 & (bit30 >> col0)) == 0)
423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         quad->inout.mask &= ~MASK_TOP_RIGHT;
433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if ((stipple1 & (bit31 >> col0)) == 0)
453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         quad->inout.mask &= ~MASK_BOTTOM_LEFT;
463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if ((stipple1 & (bit30 >> col0)) == 0)
483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         quad->inout.mask &= ~MASK_BOTTOM_RIGHT;
493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (quad->inout.mask)
513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         quads[pass++] = quad;
523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   qs->next->run(qs->next, quads, pass);
553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void stipple_begin(struct quad_stage *qs)
593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   qs->next->begin(qs->next);
613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void stipple_destroy(struct quad_stage *qs)
653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   FREE( qs );
673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct quad_stage *
713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgsp_quad_polygon_stipple_stage( struct softpipe_context *softpipe )
723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->softpipe = softpipe;
763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->begin = stipple_begin;
773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->run = stipple_quad;
783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->destroy = stipple_destroy;
793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return stage;
813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
82