sp_quad_stipple.c revision 4f25420bdd834e81a3e22733304efc5261c2998a
1e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
2e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian/**
3e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian * quad polygon stipple stage
4e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian */
5e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
6e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian#include "sp_context.h"
7e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian#include "sp_headers.h"
8e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian#include "sp_quad.h"
9e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian#include "pipe/p_defines.h"
104f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
11e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
12e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
13e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian/**
14e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian * Apply polygon stipple to quads produced by triangle rasterization
15e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian */
16e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brianstatic void
17e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brianstipple_quad(struct quad_stage *qs, struct quad_header *quad)
18e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian{
19bd35c53143560177a045b314c9b4196c229f4a4cBrian   static const uint bit31 = 1 << 31;
20bd35c53143560177a045b314c9b4196c229f4a4cBrian   static const uint bit30 = 1 << 30;
21bd35c53143560177a045b314c9b4196c229f4a4cBrian
2280362a90d8ad1fca14d7276169fc962f953d936dBrian   if (quad->prim == PRIM_TRI) {
2380362a90d8ad1fca14d7276169fc962f953d936dBrian      struct softpipe_context *softpipe = qs->softpipe;
24bd35c53143560177a045b314c9b4196c229f4a4cBrian      /* need to invert Y to index into OpenGL's stipple pattern */
25017f862de1f857bca29f09794539aaf411014f13Brian      int y0, y1;
26017f862de1f857bca29f09794539aaf411014f13Brian      uint stipple0, stipple1;
27017f862de1f857bca29f09794539aaf411014f13Brian      if (softpipe->rasterizer->origin_lower_left) {
2809f67990abd4bb9b79349be2fca9a6ae850b6f5fBrian         y0 = softpipe->framebuffer.height - 1 - quad->y0;
29017f862de1f857bca29f09794539aaf411014f13Brian         y1 = y0 - 1;
30017f862de1f857bca29f09794539aaf411014f13Brian      }
31017f862de1f857bca29f09794539aaf411014f13Brian      else {
32017f862de1f857bca29f09794539aaf411014f13Brian         y0 = quad->y0;
33017f862de1f857bca29f09794539aaf411014f13Brian         y1 = y0 + 1;
34017f862de1f857bca29f09794539aaf411014f13Brian      }
35017f862de1f857bca29f09794539aaf411014f13Brian      stipple0 = softpipe->poly_stipple.stipple[y0 % 32];
36017f862de1f857bca29f09794539aaf411014f13Brian      stipple1 = softpipe->poly_stipple.stipple[y1 % 32];
37bd35c53143560177a045b314c9b4196c229f4a4cBrian
38bd35c53143560177a045b314c9b4196c229f4a4cBrian#if 1
39271f9dac79a9247de9a57f4d248e404bf1652a13José Fonseca      {
4070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      const int col0 = quad->x0 % 32;
41bd35c53143560177a045b314c9b4196c229f4a4cBrian      if ((stipple0 & (bit31 >> col0)) == 0)
42bd35c53143560177a045b314c9b4196c229f4a4cBrian         quad->mask &= ~MASK_TOP_LEFT;
43bd35c53143560177a045b314c9b4196c229f4a4cBrian
44bd35c53143560177a045b314c9b4196c229f4a4cBrian      if ((stipple0 & (bit30 >> col0)) == 0)
45bd35c53143560177a045b314c9b4196c229f4a4cBrian         quad->mask &= ~MASK_TOP_RIGHT;
46bd35c53143560177a045b314c9b4196c229f4a4cBrian
47bd35c53143560177a045b314c9b4196c229f4a4cBrian      if ((stipple1 & (bit31 >> col0)) == 0)
48bd35c53143560177a045b314c9b4196c229f4a4cBrian         quad->mask &= ~MASK_BOTTOM_LEFT;
49aa0f415c8d5d79d0763fca49d91b1963bf0975f6Keith Whitwell
50bd35c53143560177a045b314c9b4196c229f4a4cBrian      if ((stipple1 & (bit30 >> col0)) == 0)
51bd35c53143560177a045b314c9b4196c229f4a4cBrian         quad->mask &= ~MASK_BOTTOM_RIGHT;
52271f9dac79a9247de9a57f4d248e404bf1652a13José Fonseca      }
53bd35c53143560177a045b314c9b4196c229f4a4cBrian#else
54bd35c53143560177a045b314c9b4196c229f4a4cBrian      /* We'd like to use this code, but we'd need to redefine
55bd35c53143560177a045b314c9b4196c229f4a4cBrian       * MASK_TOP_LEFT to be (1 << 1) and MASK_TOP_RIGHT to be (1 << 0),
56bd35c53143560177a045b314c9b4196c229f4a4cBrian       * and similarly for the BOTTOM bits.  But that may have undesirable
57bd35c53143560177a045b314c9b4196c229f4a4cBrian       * side effects elsewhere.
5880362a90d8ad1fca14d7276169fc962f953d936dBrian       */
59bd35c53143560177a045b314c9b4196c229f4a4cBrian      const int col0 = 30 - (quad->x0 % 32);
6080362a90d8ad1fca14d7276169fc962f953d936dBrian      quad->mask &= (((stipple0 >> col0) & 0x3) |
6180362a90d8ad1fca14d7276169fc962f953d936dBrian                     (((stipple1 >> col0) & 0x3) << 2));
62bd35c53143560177a045b314c9b4196c229f4a4cBrian#endif
63376fb1c23efd437109da88cd2e53fca9d1c77bf2Brian      if (!quad->mask)
64376fb1c23efd437109da88cd2e53fca9d1c77bf2Brian         return;
6580362a90d8ad1fca14d7276169fc962f953d936dBrian   }
66376fb1c23efd437109da88cd2e53fca9d1c77bf2Brian
67376fb1c23efd437109da88cd2e53fca9d1c77bf2Brian   qs->next->run(qs->next, quad);
68e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian}
69e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
70e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
71e4eb97318cbce238c5aaaf11af42c33229274859Brianstatic void stipple_begin(struct quad_stage *qs)
72e4eb97318cbce238c5aaaf11af42c33229274859Brian{
737c306afdaad534cc4b474f07b4970bbf3ea46ff9Keith Whitwell   qs->next->begin(qs->next);
74e4eb97318cbce238c5aaaf11af42c33229274859Brian}
75e4eb97318cbce238c5aaaf11af42c33229274859Brian
76e4eb97318cbce238c5aaaf11af42c33229274859Brian
77f93b9dc09a8f9289d7bd5c0f99c935f28016691emichalstatic void stipple_destroy(struct quad_stage *qs)
78f93b9dc09a8f9289d7bd5c0f99c935f28016691emichal{
79f93b9dc09a8f9289d7bd5c0f99c935f28016691emichal   FREE( qs );
806961769cb23c8b9ed2fb56d8ce6e649848412357michal}
816961769cb23c8b9ed2fb56d8ce6e649848412357michal
826961769cb23c8b9ed2fb56d8ce6e649848412357michal
83e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brianstruct quad_stage *
84e89bd0fbc56ecfb96f3aff926c5891c45221dd37Briansp_quad_polygon_stipple_stage( struct softpipe_context *softpipe )
85e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian{
86e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
87e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
88e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian   stage->softpipe = softpipe;
89e4eb97318cbce238c5aaaf11af42c33229274859Brian   stage->begin = stipple_begin;
90e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian   stage->run = stipple_quad;
916961769cb23c8b9ed2fb56d8ce6e649848412357michal   stage->destroy = stipple_destroy;
92e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian
93e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian   return stage;
94e89bd0fbc56ecfb96f3aff926c5891c45221dd37Brian}
95