1d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca/**************************************************************************
2d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca *
3d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * Copyright 2009 VMware, Inc.
4d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * All Rights Reserved.
5d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca *
6d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
7d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * copy of this software and associated documentation files (the
8d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * "Software"), to deal in the Software without restriction, including
9d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish,
10d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to
11d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to
12d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * the following conditions:
13d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca *
14d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * The above copyright notice and this permission notice (including the
15d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * next paragraph) shall be included in all copies or substantial portions
16d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * of the Software.
17d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca *
18d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca *
26d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca **************************************************************************/
27d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca
28ab9438193083b7f9a3180cb9cea45e269131048aBrian Paul#include <limits.h>
29d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca#include "util/u_memory.h"
30aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul#include "util/u_math.h"
31d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell#include "util/u_rect.h"
32156eabbaf996f471458ee2a69078674277b89067Brian Paul#include "util/u_surface.h"
339f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell#include "util/u_pack_color.h"
34d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca
35663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell#include "lp_scene_queue.h"
36a08d6302168341001003da32d42cfcff2311fa04Brian Paul#include "lp_debug.h"
374b70af918dd9040a6987c6a55e76e49f0e3f90bfBrian Paul#include "lp_fence.h"
384aeacdf8530d69d543cb2b997c1e65edb71ae01aBrian Paul#include "lp_perf.h"
3986afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li#include "lp_query.h"
40d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca#include "lp_rast.h"
41921584181eb2f3b2849d150295dfce1dae25dd11José Fonseca#include "lp_rast_priv.h"
42921584181eb2f3b2849d150295dfce1dae25dd11José Fonseca#include "lp_tile_soa.h"
43c61bf363937f40624a5632745630d4f2b9907082Zack Rusin#include "gallivm/lp_bld_debug.h"
44663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell#include "lp_scene.h"
453469715a8a171512cf9b528702e70393f01c6041José Fonseca#include "lp_tex_sample.h"
46d614ced756f2cca64ec83b122da4cd028c08c0ebJosé Fonseca
4789498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
486c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paul#ifdef DEBUG
496c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paulint jit_line = 0;
506c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paulconst struct lp_rast_state *jit_state = NULL;
51efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paulconst struct lp_rasterizer_task *jit_task = NULL;
526c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paul#endif
536c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paul
546c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paul
550639765b2850739af1678f10fc0c5706d5827776Brian Paul/**
560639765b2850739af1678f10fc0c5706d5827776Brian Paul * Begin rasterizing a scene.
570639765b2850739af1678f10fc0c5706d5827776Brian Paul * Called once per scene by one thread.
587505510c7b7c33f3c571647c0398da7e1b823806Brian Paul */
590639765b2850739af1678f10fc0c5706d5827776Brian Paulstatic void
6001b1900084152dbacd4025a31ced25f75666ce59Brian Paullp_rast_begin( struct lp_rasterizer *rast,
615fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell               struct lp_scene *scene )
6284ab7dcf48e87350c0622c533e51aa495f7256c2Keith Whitwell{
63e0e2008f1dcd73a59a184e0ef4c1dd77ac2a1cbfKeith Whitwell
645fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   rast->curr_scene = scene;
654e1334ced68dd25b151250a44af25e8e0d5a33feKeith Whitwell
665fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
67e0e2008f1dcd73a59a184e0ef4c1dd77ac2a1cbfKeith Whitwell
689f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_scene_begin_rasterization( scene );
695fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   lp_scene_bin_iter_begin( scene );
700718c7700533a965d7cd06b4f67b82bbae6e66a1Keith Whitwell}
710718c7700533a965d7cd06b4f67b82bbae6e66a1Keith Whitwell
72e0e2008f1dcd73a59a184e0ef4c1dd77ac2a1cbfKeith Whitwell
7301b1900084152dbacd4025a31ced25f75666ce59Brian Paulstatic void
7401b1900084152dbacd4025a31ced25f75666ce59Brian Paullp_rast_end( struct lp_rasterizer *rast )
750718c7700533a965d7cd06b4f67b82bbae6e66a1Keith Whitwell{
769f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_scene_end_rasterization( rast->curr_scene );
77e0e2008f1dcd73a59a184e0ef4c1dd77ac2a1cbfKeith Whitwell
785fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   rast->curr_scene = NULL;
790639765b2850739af1678f10fc0c5706d5827776Brian Paul
8023df86d851dd6cbce1ddd7a45424c7bf14c04a3eJosé Fonseca#ifdef DEBUG
810639765b2850739af1678f10fc0c5706d5827776Brian Paul   if (0)
8223df86d851dd6cbce1ddd7a45424c7bf14c04a3eJosé Fonseca      debug_printf("Post render scene: tile unswizzle: %u tile swizzle: %u\n",
8323df86d851dd6cbce1ddd7a45424c7bf14c04a3eJosé Fonseca                   lp_tile_unswizzle_count, lp_tile_swizzle_count);
8423df86d851dd6cbce1ddd7a45424c7bf14c04a3eJosé Fonseca#endif
8589498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
8689498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
870639765b2850739af1678f10fc0c5706d5827776Brian Paul
887505510c7b7c33f3c571647c0398da7e1b823806Brian Paul/**
897505510c7b7c33f3c571647c0398da7e1b823806Brian Paul * Begining rasterization of a tile.
907505510c7b7c33f3c571647c0398da7e1b823806Brian Paul * \param x  window X position of the tile, in pixels
917505510c7b7c33f3c571647c0398da7e1b823806Brian Paul * \param y  window Y position of the tile, in pixels
9289498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell */
93b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paulstatic void
940639765b2850739af1678f10fc0c5706d5827776Brian Paullp_rast_tile_begin(struct lp_rasterizer_task *task,
959f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell                   const struct cmd_bin *bin)
9689498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell{
979f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
980639765b2850739af1678f10fc0c5706d5827776Brian Paul   enum lp_texture_usage usage;
990639765b2850739af1678f10fc0c5706d5827776Brian Paul
1009f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, bin->x, bin->y);
1010639765b2850739af1678f10fc0c5706d5827776Brian Paul
1029f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   task->bin = bin;
1039f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   task->x = bin->x * TILE_SIZE;
1049f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   task->y = bin->y * TILE_SIZE;
1050639765b2850739af1678f10fc0c5706d5827776Brian Paul
106d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   /* reset pointers to color tile(s) */
107d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   memset(task->color_tiles, 0, sizeof(task->color_tiles));
1080639765b2850739af1678f10fc0c5706d5827776Brian Paul
1090639765b2850739af1678f10fc0c5706d5827776Brian Paul   /* get pointer to depth/stencil tile */
1100639765b2850739af1678f10fc0c5706d5827776Brian Paul   {
1119f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      struct pipe_surface *zsbuf = task->scene->fb.zsbuf;
1120639765b2850739af1678f10fc0c5706d5827776Brian Paul      if (zsbuf) {
1130639765b2850739af1678f10fc0c5706d5827776Brian Paul         struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
1140639765b2850739af1678f10fc0c5706d5827776Brian Paul
1151e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger         if (scene->has_depthstencil_clear)
1160639765b2850739af1678f10fc0c5706d5827776Brian Paul            usage = LP_TEX_USAGE_WRITE_ALL;
1170639765b2850739af1678f10fc0c5706d5827776Brian Paul         else
1180639765b2850739af1678f10fc0c5706d5827776Brian Paul            usage = LP_TEX_USAGE_READ_WRITE;
1190639765b2850739af1678f10fc0c5706d5827776Brian Paul
1200639765b2850739af1678f10fc0c5706d5827776Brian Paul         /* "prime" the tile: convert data from linear to tiled if necessary
1210639765b2850739af1678f10fc0c5706d5827776Brian Paul          * and update the tile's layout info.
1220639765b2850739af1678f10fc0c5706d5827776Brian Paul          */
1230639765b2850739af1678f10fc0c5706d5827776Brian Paul         (void) llvmpipe_get_texture_tile(lpt,
1244c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                          zsbuf->u.tex.first_layer,
1254c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                          zsbuf->u.tex.level,
1260639765b2850739af1678f10fc0c5706d5827776Brian Paul                                          usage,
1279f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell                                          task->x,
1289f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell                                          task->y);
1290639765b2850739af1678f10fc0c5706d5827776Brian Paul         /* Get actual pointer to the tile data.  Note that depth/stencil
1300639765b2850739af1678f10fc0c5706d5827776Brian Paul          * data is tiled differently than color data.
1310639765b2850739af1678f10fc0c5706d5827776Brian Paul          */
1329f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell         task->depth_tile = lp_rast_get_depth_block_pointer(task,
1339f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell                                                            task->x,
1349f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell                                                            task->y);
1350639765b2850739af1678f10fc0c5706d5827776Brian Paul
1360639765b2850739af1678f10fc0c5706d5827776Brian Paul         assert(task->depth_tile);
1370639765b2850739af1678f10fc0c5706d5827776Brian Paul      }
1380639765b2850739af1678f10fc0c5706d5827776Brian Paul      else {
1390639765b2850739af1678f10fc0c5706d5827776Brian Paul         task->depth_tile = NULL;
1400639765b2850739af1678f10fc0c5706d5827776Brian Paul      }
1410639765b2850739af1678f10fc0c5706d5827776Brian Paul   }
14289498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
14389498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
1447505510c7b7c33f3c571647c0398da7e1b823806Brian Paul
1457505510c7b7c33f3c571647c0398da7e1b823806Brian Paul/**
1467505510c7b7c33f3c571647c0398da7e1b823806Brian Paul * Clear the rasterizer's current color tile.
147ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul * This is a bin command called during bin processing.
1487505510c7b7c33f3c571647c0398da7e1b823806Brian Paul */
1499f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
1505046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paullp_rast_clear_color(struct lp_rasterizer_task *task,
1515046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paul                    const union lp_rast_cmd_arg arg)
15289498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell{
1539f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
1544cdd10cb4b60d85f6c231a26739f7d5e264a05e5Keith Whitwell   const uint8_t *clear_color = arg.clear_color;
1550639765b2850739af1678f10fc0c5706d5827776Brian Paul
156c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell   unsigned i;
157c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell
158a08d6302168341001003da32d42cfcff2311fa04Brian Paul   LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
159295aea04895676aae5b67a7016c62bab8e40b996Keith Whitwell              clear_color[0],
160295aea04895676aae5b67a7016c62bab8e40b996Keith Whitwell              clear_color[1],
161295aea04895676aae5b67a7016c62bab8e40b996Keith Whitwell              clear_color[2],
162295aea04895676aae5b67a7016c62bab8e40b996Keith Whitwell              clear_color[3]);
1634e1334ced68dd25b151250a44af25e8e0d5a33feKeith Whitwell
16437b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca   if (clear_color[0] == clear_color[1] &&
16537b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca       clear_color[1] == clear_color[2] &&
16637b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca       clear_color[2] == clear_color[3]) {
167f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul      /* clear to grayscale value {x, x, x, x} */
1689f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      for (i = 0; i < scene->fb.nr_cbufs; i++) {
169d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell         uint8_t *ptr =
170d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell            lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
1710639765b2850739af1678f10fc0c5706d5827776Brian Paul	 memset(ptr, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
172c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell      }
17337b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca   }
17437b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca   else {
175f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul      /* Non-gray color.
176f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul       * Note: if the swizzled tile layout changes (see TILE_PIXEL) this code
177f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul       * will need to change.  It'll be pretty obvious when clearing no longer
178f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul       * works.
179f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul       */
180f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul      const unsigned chunk = TILE_SIZE / 4;
1819f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      for (i = 0; i < scene->fb.nr_cbufs; i++) {
182d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell         uint8_t *c =
183d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell            lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
184f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul         unsigned j;
1850639765b2850739af1678f10fc0c5706d5827776Brian Paul
186f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul         for (j = 0; j < 4 * TILE_SIZE; j++) {
187f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            memset(c, clear_color[0], chunk);
188f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            c += chunk;
189f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            memset(c, clear_color[1], chunk);
190f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            c += chunk;
191f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            memset(c, clear_color[2], chunk);
192f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            c += chunk;
193f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            memset(c, clear_color[3], chunk);
194f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul            c += chunk;
195f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul         }
196f94a99170ecdc3286408b3628fbae9f45518007eBrian Paul      }
19737b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca   }
1984aeacdf8530d69d543cb2b997c1e65edb71ae01aBrian Paul
1994aeacdf8530d69d543cb2b997c1e65edb71ae01aBrian Paul   LP_COUNT(nr_color_tile_clear);
20089498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
20189498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
2027505510c7b7c33f3c571647c0398da7e1b823806Brian Paul
2039f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
2049f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
2059f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
2069f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
2077505510c7b7c33f3c571647c0398da7e1b823806Brian Paul/**
2087505510c7b7c33f3c571647c0398da7e1b823806Brian Paul * Clear the rasterizer's current z/stencil tile.
209ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul * This is a bin command called during bin processing.
2107505510c7b7c33f3c571647c0398da7e1b823806Brian Paul */
2119f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
2125046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paullp_rast_clear_zstencil(struct lp_rasterizer_task *task,
2135046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paul                       const union lp_rast_cmd_arg arg)
21489498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell{
2159f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
2169fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca   uint32_t clear_value = arg.clear_zstencil.value;
2179fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca   uint32_t clear_mask = arg.clear_zstencil.mask;
2185fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
2195fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
2209f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const unsigned block_size = scene->zsbuf.blocksize;
2219f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const unsigned dst_stride = scene->zsbuf.stride * TILE_VECTOR_HEIGHT;
2225e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   uint8_t *dst;
2235e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   unsigned i, j;
2245e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca
2259fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca   LP_DBG(DEBUG_RAST, "%s: value=0x%08x, mask=0x%08x\n",
2269fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca           __FUNCTION__, clear_value, clear_mask);
2274e1334ced68dd25b151250a44af25e8e0d5a33feKeith Whitwell
2285e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   /*
229db2b6ca504e5046697e3d9262cfd401b8a4971fdBrian Paul    * Clear the area of the swizzled depth/depth buffer matching this tile, in
2305e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca    * stripes of TILE_VECTOR_HEIGHT x TILE_SIZE at a time.
2315e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca    *
2325e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca    * The swizzled depth format is such that the depths for
2335e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca    * TILE_VECTOR_HEIGHT x TILE_VECTOR_WIDTH pixels have consecutive offsets.
2345e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca    */
2355e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca
2360639765b2850739af1678f10fc0c5706d5827776Brian Paul   dst = task->depth_tile;
2370639765b2850739af1678f10fc0c5706d5827776Brian Paul
2389fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca   clear_value &= clear_mask;
2399fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca
2405e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   switch (block_size) {
2415e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   case 1:
2429fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca      assert(clear_mask == 0xff);
2431e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger      memset(dst, (uint8_t) clear_value, height * width);
2445e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca      break;
2455e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   case 2:
2469fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca      if (clear_mask == 0xffff) {
2479fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca         for (i = 0; i < height; i++) {
2489fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            uint16_t *row = (uint16_t *)dst;
2499fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            for (j = 0; j < width; j++)
2509fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca               *row++ = (uint16_t) clear_value;
2519fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            dst += dst_stride;
2529fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca         }
2539fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca      }
2549fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca      else {
2559fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca         for (i = 0; i < height; i++) {
2569fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            uint16_t *row = (uint16_t *)dst;
2579fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            for (j = 0; j < width; j++) {
2589fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca               uint16_t tmp = ~clear_mask & *row;
2599fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca               *row++ = clear_value | tmp;
2609fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            }
2619fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca            dst += dst_stride;
2629fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca         }
2635e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca      }
2645e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca      break;
2655e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   case 4:
2661e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger      if (clear_mask == 0xffffffff) {
2671e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger         for (i = 0; i < height; i++) {
2681e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            uint32_t *row = (uint32_t *)dst;
2691e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            for (j = 0; j < width; j++)
2701e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger               *row++ = clear_value;
2711e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            dst += dst_stride;
2721e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger         }
2731e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger      }
2741e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger      else {
2751e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger         for (i = 0; i < height; i++) {
2761e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            uint32_t *row = (uint32_t *)dst;
2771e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            for (j = 0; j < width; j++) {
2781e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger               uint32_t tmp = ~clear_mask & *row;
2799fe510ef35a783a244d0d54baa50f959a6b781dcJosé Fonseca               *row++ = clear_value | tmp;
2801e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            }
2811e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger            dst += dst_stride;
2821e17178fc40b6a1a54cb3e93c098bdd0d490b88aRoland Scheidegger         }
2835e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca      }
2845e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca      break;
2855e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   default:
2865fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      assert(0);
2875fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      break;
2885e6a9005100ec2636ce9734a5e4535216494cf60José Fonseca   }
28989498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
29089498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
29189498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
292c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell
2930639765b2850739af1678f10fc0c5706d5827776Brian Paul/**
2940639765b2850739af1678f10fc0c5706d5827776Brian Paul * Convert the color tile from tiled to linear layout.
2950639765b2850739af1678f10fc0c5706d5827776Brian Paul * This is generally only done when we're flushing the scene just prior to
2960639765b2850739af1678f10fc0c5706d5827776Brian Paul * SwapBuffers.  If we didn't do this here, we'd have to convert the entire
2970639765b2850739af1678f10fc0c5706d5827776Brian Paul * tiled color buffer to linear layout in the llvmpipe_texture_unmap()
2980639765b2850739af1678f10fc0c5706d5827776Brian Paul * function.  It's better to do it here to take advantage of
2990639765b2850739af1678f10fc0c5706d5827776Brian Paul * threading/parallelism.
3000639765b2850739af1678f10fc0c5706d5827776Brian Paul * This is a bin command which is stored in all bins.
3010639765b2850739af1678f10fc0c5706d5827776Brian Paul */
3029f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
303040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwelllp_rast_store_linear_color( struct lp_rasterizer_task *task )
3040639765b2850739af1678f10fc0c5706d5827776Brian Paul{
3059f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
3060639765b2850739af1678f10fc0c5706d5827776Brian Paul   unsigned buf;
3070639765b2850739af1678f10fc0c5706d5827776Brian Paul
3089f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
3090639765b2850739af1678f10fc0c5706d5827776Brian Paul      struct pipe_surface *cbuf = scene->fb.cbufs[buf];
3104c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const unsigned layer = cbuf->u.tex.first_layer;
3114c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const unsigned level = cbuf->u.tex.level;
3120639765b2850739af1678f10fc0c5706d5827776Brian Paul      struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture);
3132f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell
3142f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell      if (!task->color_tiles[buf])
3152f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell         continue;
3162f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell
3172f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell      llvmpipe_unswizzle_cbuf_tile(lpt,
3184c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   layer,
3192f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell                                   level,
3202f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell                                   task->x, task->y,
3212f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell                                   task->color_tiles[buf]);
322c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell   }
32389498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
32489498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
325ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul
326ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul
327ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul/**
328ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul * Run the shader on all blocks in a tile.  This is used when a tile is
329ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul * completely contained inside a triangle.
330ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul * This is a bin command called during bin processing.
331ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul */
3329f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
3335046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paullp_rast_shade_tile(struct lp_rasterizer_task *task,
3345046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paul                   const union lp_rast_cmd_arg arg)
33589498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell{
3369f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
3374cdd10cb4b60d85f6c231a26739f7d5e264a05e5Keith Whitwell   const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
3381da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   const struct lp_rast_state *state;
3391da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   struct lp_fragment_shader_variant *variant;
3405046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paul   const unsigned tile_x = task->x, tile_y = task->y;
34186dba3e4142276d76ecffc0cd238506df5efe9afJosé Fonseca   unsigned x, y;
34289498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
3436419ecd02ce43a2614822e228f306d4db589f317Keith Whitwell   if (inputs->disable) {
3446419ecd02ce43a2614822e228f306d4db589f317Keith Whitwell      /* This command was partially binned and has been disabled */
3456419ecd02ce43a2614822e228f306d4db589f317Keith Whitwell      return;
3466419ecd02ce43a2614822e228f306d4db589f317Keith Whitwell   }
3476419ecd02ce43a2614822e228f306d4db589f317Keith Whitwell
348a08d6302168341001003da32d42cfcff2311fa04Brian Paul   LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
3494e1334ced68dd25b151250a44af25e8e0d5a33feKeith Whitwell
3501da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   state = task->state;
3511da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   assert(state);
3521da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   if (!state) {
3531da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca      return;
3541da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   }
3551da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   variant = state->variant;
3561da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca
3572797f2bf57562c95a601a67edca3089641215cc4Brian Paul   /* render the whole 64x64 tile in 4x4 chunks */
3582797f2bf57562c95a601a67edca3089641215cc4Brian Paul   for (y = 0; y < TILE_SIZE; y += 4){
3592797f2bf57562c95a601a67edca3089641215cc4Brian Paul      for (x = 0; x < TILE_SIZE; x += 4) {
3602797f2bf57562c95a601a67edca3089641215cc4Brian Paul         uint8_t *color[PIPE_MAX_COLOR_BUFS];
3612797f2bf57562c95a601a67edca3089641215cc4Brian Paul         uint32_t *depth;
3620639765b2850739af1678f10fc0c5706d5827776Brian Paul         unsigned i;
3632797f2bf57562c95a601a67edca3089641215cc4Brian Paul
3642797f2bf57562c95a601a67edca3089641215cc4Brian Paul         /* color buffer */
3659f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell         for (i = 0; i < scene->fb.nr_cbufs; i++)
3660639765b2850739af1678f10fc0c5706d5827776Brian Paul            color[i] = lp_rast_get_color_block_pointer(task, i,
3670639765b2850739af1678f10fc0c5706d5827776Brian Paul                                                       tile_x + x, tile_y + y);
3682797f2bf57562c95a601a67edca3089641215cc4Brian Paul
3692797f2bf57562c95a601a67edca3089641215cc4Brian Paul         /* depth buffer */
3702b3e1ad731d2bd095a680d3120619972a7eb0242Brian Paul         depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
3712797f2bf57562c95a601a67edca3089641215cc4Brian Paul
3720639765b2850739af1678f10fc0c5706d5827776Brian Paul         /* run shader on 4x4 block */
373efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         BEGIN_JIT_CALL(state, task);
37418fb9ff6d8f58a08e559070cf29f26ed0caa567fJosé Fonseca         variant->jit_function[RAST_WHOLE]( &state->jit_context,
375d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                            tile_x + x, tile_y + y,
3760a1c9001037a13b69b157994e7983aa3dee158d3Keith Whitwell                                            inputs->frontfacing,
3779bf8a55c4b29d55320fc2e7875ecf0e9ca164ee8Keith Whitwell                                            GET_A0(inputs),
3789bf8a55c4b29d55320fc2e7875ecf0e9ca164ee8Keith Whitwell                                            GET_DADX(inputs),
3799bf8a55c4b29d55320fc2e7875ecf0e9ca164ee8Keith Whitwell                                            GET_DADY(inputs),
380d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                            color,
381d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                            depth,
382d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                            0xffff,
383d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                            &task->vis_counter);
3846c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paul         END_JIT_CALL();
3852797f2bf57562c95a601a67edca3089641215cc4Brian Paul      }
3862797f2bf57562c95a601a67edca3089641215cc4Brian Paul   }
38789498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
38889498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
389a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
390866e6856d39efe9b1ec739587f420a640ad8618eBrian Paul/**
391d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell * Run the shader on all blocks in a tile.  This is used when a tile is
392d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell * completely contained inside a triangle, and the shader is opaque.
393d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell * This is a bin command called during bin processing.
394d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell */
3959f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
396d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwelllp_rast_shade_tile_opaque(struct lp_rasterizer_task *task,
397d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                          const union lp_rast_cmd_arg arg)
398d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell{
3999f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
400d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   unsigned i;
401d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell
4021da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
4031da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca
4041da10443440800a6f5e4a4e6463737cce27706fdJosé Fonseca   assert(task->state);
405023ca40d80670ac0eee8c755ca5f54b1e7c2712eBrian Paul   if (!task->state) {
406023ca40d80670ac0eee8c755ca5f54b1e7c2712eBrian Paul      return;
407023ca40d80670ac0eee8c755ca5f54b1e7c2712eBrian Paul   }
408023ca40d80670ac0eee8c755ca5f54b1e7c2712eBrian Paul
409d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   /* this will prevent converting the layout from tiled to linear */
4109f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   for (i = 0; i < scene->fb.nr_cbufs; i++) {
411d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell      (void)lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
412d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   }
413d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell
414d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   lp_rast_shade_tile(task, arg);
415d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell}
416d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell
417d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell
418d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell/**
419d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell * Compute shading for a 4x4 block of pixels inside a triangle.
420ffd0759973165368ac8ce07d9bcffeb0acf88e6fBrian Paul * This is a bin command called during bin processing.
4210639765b2850739af1678f10fc0c5706d5827776Brian Paul * \param x  X position of quad in window coords
4220639765b2850739af1678f10fc0c5706d5827776Brian Paul * \param y  Y position of quad in window coords
423866e6856d39efe9b1ec739587f420a640ad8618eBrian Paul */
424d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwellvoid
425d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwelllp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
426d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                         const struct lp_rast_shader_inputs *inputs,
427d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                         unsigned x, unsigned y,
428d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                         unsigned mask)
429a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca{
4304195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell   const struct lp_rast_state *state = task->state;
43118fb9ff6d8f58a08e559070cf29f26ed0caa567fJosé Fonseca   struct lp_fragment_shader_variant *variant = state->variant;
4329f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct lp_scene *scene = task->scene;
433c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell   uint8_t *color[PIPE_MAX_COLOR_BUFS];
43486dba3e4142276d76ecffc0cd238506df5efe9afJosé Fonseca   void *depth;
435c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell   unsigned i;
436a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
437b1659b9213f3eeee440590dfe379f0d193948307Brian Paul   assert(state);
438b1659b9213f3eeee440590dfe379f0d193948307Brian Paul
439a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca   /* Sanity checks */
440c620087432b2055aa9301f19f8b6444080698c90José Fonseca   assert(x < scene->tiles_x * TILE_SIZE);
441c620087432b2055aa9301f19f8b6444080698c90José Fonseca   assert(y < scene->tiles_y * TILE_SIZE);
442a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca   assert(x % TILE_VECTOR_WIDTH == 0);
443a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca   assert(y % TILE_VECTOR_HEIGHT == 0);
444a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
445cdbcd96fdfe2c4d09e9b34cb083664d6b6e0558bBrian Paul   assert((x % 4) == 0);
446cdbcd96fdfe2c4d09e9b34cb083664d6b6e0558bBrian Paul   assert((y % 4) == 0);
447866e6856d39efe9b1ec739587f420a640ad8618eBrian Paul
448a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca   /* color buffer */
4499f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   for (i = 0; i < scene->fb.nr_cbufs; i++) {
4500639765b2850739af1678f10fc0c5706d5827776Brian Paul      color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
4510639765b2850739af1678f10fc0c5706d5827776Brian Paul      assert(lp_check_alignment(color[i], 16));
4520639765b2850739af1678f10fc0c5706d5827776Brian Paul   }
453a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
454a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca   /* depth buffer */
4552b3e1ad731d2bd095a680d3120619972a7eb0242Brian Paul   depth = lp_rast_get_depth_block_pointer(task, x, y);
456a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
457c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell
45885999695829823e459e11822b4846ed1db5c055dJosé Fonseca   assert(lp_check_alignment(state->jit_context.blend_color, 16));
459a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
4600639765b2850739af1678f10fc0c5706d5827776Brian Paul   /* run shader on 4x4 block */
461efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   BEGIN_JIT_CALL(state, task);
462d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell   variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
463d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                         x, y,
4640a1c9001037a13b69b157994e7983aa3dee158d3Keith Whitwell                                         inputs->frontfacing,
4659bf8a55c4b29d55320fc2e7875ecf0e9ca164ee8Keith Whitwell                                         GET_A0(inputs),
4669bf8a55c4b29d55320fc2e7875ecf0e9ca164ee8Keith Whitwell                                         GET_DADX(inputs),
4679bf8a55c4b29d55320fc2e7875ecf0e9ca164ee8Keith Whitwell                                         GET_DADY(inputs),
468d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                         color,
469d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                         depth,
470d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                         mask,
471d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell                                         &task->vis_counter);
4726c1625cc405f0d77523c122cedf3e8003f2aa7bfBrian Paul   END_JIT_CALL();
473a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca}
474a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
475a6676d896ed18426ed3d7e6340347974c1694ca2José Fonseca
476d4b64167b56f780d0dea73193c345622888fbc16Keith Whitwell
47762623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul/**
478040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell * Begin a new occlusion query.
479040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell * This is a bin command put in all bins.
480040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell * Called per thread.
481040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell */
4829f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
483040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwelllp_rast_begin_query(struct lp_rasterizer_task *task,
484040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell                    const union lp_rast_cmd_arg arg)
485040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell{
486040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell   struct llvmpipe_query *pq = arg.query_obj;
487040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell
488040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell   assert(task->query == NULL);
489040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell   task->vis_counter = 0;
490040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell   task->query = pq;
491040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell}
492040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell
493040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell
494040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell/**
495040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell * End the current occlusion query.
496040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell * This is a bin command put in all bins.
497040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell * Called per thread.
498040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell */
4999f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
500040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwelllp_rast_end_query(struct lp_rasterizer_task *task,
501040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell                  const union lp_rast_cmd_arg arg)
502040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell{
503debcb434891756573ed2dc102ad1b673a8dce7daKeith Whitwell   assert(task->query);
504debcb434891756573ed2dc102ad1b673a8dce7daKeith Whitwell   if (task->query) {
505debcb434891756573ed2dc102ad1b673a8dce7daKeith Whitwell      task->query->count[task->thread_index] += task->vis_counter;
506debcb434891756573ed2dc102ad1b673a8dce7daKeith Whitwell      task->query = NULL;
507debcb434891756573ed2dc102ad1b673a8dce7daKeith Whitwell   }
508040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell}
509040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell
510040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell
5114195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwellvoid
5124195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwelllp_rast_set_state(struct lp_rasterizer_task *task,
5134195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell                  const union lp_rast_cmd_arg arg)
5144195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell{
5154195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell   task->state = arg.state;
5164195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell}
5174195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell
5184195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell
519040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell
520040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell/**
52162623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul * Set top row and left column of the tile's pixels to white.  For debugging.
52262623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul */
52362623c4dc5d8b646942bc65e8de350e812945ad1Brian Paulstatic void
52462623c4dc5d8b646942bc65e8de350e812945ad1Brian Pauloutline_tile(uint8_t *tile)
52562623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul{
52662623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   const uint8_t val = 0xff;
52762623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   unsigned i;
52862623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
52962623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   for (i = 0; i < TILE_SIZE; i++) {
53062623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, i, 0, 0) = val;
53162623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, i, 0, 1) = val;
53262623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, i, 0, 2) = val;
53362623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, i, 0, 3) = val;
53462623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
53562623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, 0, i, 0) = val;
53662623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, 0, i, 1) = val;
53762623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, 0, i, 2) = val;
53862623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      TILE_PIXEL(tile, 0, i, 3) = val;
53962623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   }
54062623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul}
54162623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
54262623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
54362623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul/**
54462623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul * Draw grid of gray lines at 16-pixel intervals across the tile to
54562623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul * show the sub-tile boundaries.  For debugging.
54662623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul */
54762623c4dc5d8b646942bc65e8de350e812945ad1Brian Paulstatic void
54862623c4dc5d8b646942bc65e8de350e812945ad1Brian Pauloutline_subtiles(uint8_t *tile)
54962623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul{
55062623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   const uint8_t val = 0x80;
55162623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   const unsigned step = 16;
55262623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   unsigned i, j;
55362623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
5540fccfc9cc0cb7699598f1739d8cd3811175cdf13Brian Paul   for (i = 0; i < TILE_SIZE; i += step) {
55562623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      for (j = 0; j < TILE_SIZE; j++) {
55662623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, i, j, 0) = val;
55762623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, i, j, 1) = val;
55862623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, i, j, 2) = val;
55962623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, i, j, 3) = val;
56062623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
56162623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, j, i, 0) = val;
56262623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, j, i, 1) = val;
56362623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, j, i, 2) = val;
56462623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul         TILE_PIXEL(tile, j, i, 3) = val;
56562623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul      }
56662623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   }
56762623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
56862623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul   outline_tile(tile);
56962623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul}
57062623c4dc5d8b646942bc65e8de350e812945ad1Brian Paul
57137b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca
57237b86aa55c6bb520997c00dbf1a2b38d4aed38ebJosé Fonseca
5737505510c7b7c33f3c571647c0398da7e1b823806Brian Paul/**
5740639765b2850739af1678f10fc0c5706d5827776Brian Paul * Called when we're done writing to a color tile.
5757505510c7b7c33f3c571647c0398da7e1b823806Brian Paul */
5765046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paulstatic void
5770639765b2850739af1678f10fc0c5706d5827776Brian Paullp_rast_tile_end(struct lp_rasterizer_task *task)
57889498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell{
5792b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca#ifdef DEBUG
5802b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca   if (LP_DEBUG & (DEBUG_SHOW_SUBTILES | DEBUG_SHOW_TILES)) {
5819f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      const struct lp_scene *scene = task->scene;
5822b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca      unsigned buf;
5832b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca
5849f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
5852b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca         uint8_t *color = lp_rast_get_color_block_pointer(task, buf,
5862b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca                                                          task->x, task->y);
5872b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca
5882b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca         if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
5892b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca            outline_subtiles(color);
5902b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca         else if (LP_DEBUG & DEBUG_SHOW_TILES)
5912b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca            outline_tile(color);
5922b7fbccfdc96529c5403d5760c74597dfaf51713José Fonseca      }
593c1a04416023e24621e4992caf593e8dfe8d7a2fcKeith Whitwell   }
5940639765b2850739af1678f10fc0c5706d5827776Brian Paul#else
5950639765b2850739af1678f10fc0c5706d5827776Brian Paul   (void) outline_subtiles;
5960639765b2850739af1678f10fc0c5706d5827776Brian Paul#endif
5970639765b2850739af1678f10fc0c5706d5827776Brian Paul
598040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell   lp_rast_store_linear_color(task);
5992f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell
60018452c1e87f79327fbd5f27478028b481ee72a5dKeith Whitwell   if (task->query) {
60118452c1e87f79327fbd5f27478028b481ee72a5dKeith Whitwell      union lp_rast_cmd_arg dummy = {0};
60218452c1e87f79327fbd5f27478028b481ee72a5dKeith Whitwell      lp_rast_end_query(task, dummy);
60318452c1e87f79327fbd5f27478028b481ee72a5dKeith Whitwell   }
60418452c1e87f79327fbd5f27478028b481ee72a5dKeith Whitwell
6050639765b2850739af1678f10fc0c5706d5827776Brian Paul   /* debug */
6060639765b2850739af1678f10fc0c5706d5827776Brian Paul   memset(task->color_tiles, 0, sizeof(task->color_tiles));
6070639765b2850739af1678f10fc0c5706d5827776Brian Paul   task->depth_tile = NULL;
6089f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
6099f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   task->bin = NULL;
61089498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
61189498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
6129f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic lp_rast_cmd_func dispatch[LP_RAST_OP_MAX] =
6139f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell{
6149f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_clear_color,
6159f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_clear_zstencil,
6169f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_1,
6179f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_2,
6189f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_3,
6199f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_4,
6209f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_5,
6219f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_6,
6229f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_7,
6239f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_8,
624c4046d4fda2fe838659bff99bfa17f57f895a943Keith Whitwell   lp_rast_triangle_3_4,
6259f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_triangle_3_16,
6260ff132e5a633170afaed0aea54d01438c895b8abKeith Whitwell   lp_rast_triangle_4_16,
6279f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_shade_tile,
6289f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_shade_tile_opaque,
6299f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_begin_query,
6309f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_end_query,
6314195febeecd2d2f5571afdb90cbb185a4759f50aKeith Whitwell   lp_rast_set_state,
6329f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell};
63347510040a68f5f672aee22eac6c01fb4dd60ec67José Fonseca
63447510040a68f5f672aee22eac6c01fb4dd60ec67José Fonseca
6359f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwellstatic void
6369f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwelldo_rasterize_bin(struct lp_rasterizer_task *task,
6379f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell                 const struct cmd_bin *bin)
6389f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell{
6399f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   const struct cmd_block *block;
6409f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   unsigned k;
6419f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
642f25836d7b2c21e046a725cf13c8649d3981693b7Keith Whitwell   if (0)
643f25836d7b2c21e046a725cf13c8649d3981693b7Keith Whitwell      lp_debug_bin(bin);
644f25836d7b2c21e046a725cf13c8649d3981693b7Keith Whitwell
6459f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   for (block = bin->head; block; block = block->next) {
6469f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      for (k = 0; k < block->count; k++) {
6479f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell         dispatch[block->cmd[k]]( task, block->arg[k] );
6489f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      }
6499f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   }
6509f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell}
6519f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
6522bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
6532bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
6542bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul/**
655b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul * Rasterize commands for a single bin.
65601b1900084152dbacd4025a31ced25f75666ce59Brian Paul * \param x, y  position of the bin's tile in the framebuffer
657b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul * Must be called between lp_rast_begin() and lp_rast_end().
6589509f73c2147a9e225b5ef69a646e5dd711573f5Brian Paul * Called per thread.
659b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul */
66001b1900084152dbacd4025a31ced25f75666ce59Brian Paulstatic void
6615046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paulrasterize_bin(struct lp_rasterizer_task *task,
6629f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell              const struct cmd_bin *bin )
663b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul{
6649f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   lp_rast_tile_begin( task, bin );
665b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul
6669f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   do_rasterize_bin(task, bin);
667b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul
6680639765b2850739af1678f10fc0c5706d5827776Brian Paul   lp_rast_tile_end(task);
669b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul
6704231006e29cbf9fb54c72acf35009f3b18fe62abKeith Whitwell
6719f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   /* Debug/Perf flags:
6729f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell    */
6739f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   if (bin->head->count == 1) {
6749f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE_OPAQUE)
6759f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell         LP_COUNT(nr_pure_shade_opaque_64);
6769f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell      else if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE)
6779f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell         LP_COUNT(nr_pure_shade_64);
6789f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   }
6799f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell}
6809f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
6814231006e29cbf9fb54c72acf35009f3b18fe62abKeith Whitwell
682db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell/* An empty bin is one that just loads the contents of the tile and
683db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell * stores them again unchanged.  This typically happens when bins have
684db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell * been flushed for some reason in the middle of a frame, or when
685db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell * incremental updates are being made to a render target.
686db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell *
687db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell * Try to avoid doing pointless work in this case.
688db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwell */
689da45f49cc63fff06513dc28d9616084fc81798d4Keith Whitwellstatic boolean
690db83ad4b4353ea6f9c755f18bf1455ea78b5bf12Keith Whitwellis_empty_bin( const struct cmd_bin *bin )
691da45f49cc63fff06513dc28d9616084fc81798d4Keith Whitwell{
6929f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   return bin->head == NULL;
693da45f49cc63fff06513dc28d9616084fc81798d4Keith Whitwell}
694da45f49cc63fff06513dc28d9616084fc81798d4Keith Whitwell
695da45f49cc63fff06513dc28d9616084fc81798d4Keith Whitwell
69601b1900084152dbacd4025a31ced25f75666ce59Brian Paul/**
697663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell * Rasterize/execute all bins within a scene.
6989509f73c2147a9e225b5ef69a646e5dd711573f5Brian Paul * Called per thread.
69901b1900084152dbacd4025a31ced25f75666ce59Brian Paul */
700aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paulstatic void
7015046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paulrasterize_scene(struct lp_rasterizer_task *task,
7025fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell                struct lp_scene *scene)
703aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul{
7049f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   task->scene = scene;
70545df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul
70645df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul   if (!task->rast->no_rast) {
70745df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul      /* loop over scene bins, rasterize each */
708aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul#if 0
70945df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul      {
71045df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul         unsigned i, j;
71145df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul         for (i = 0; i < scene->tiles_x; i++) {
71245df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul            for (j = 0; j < scene->tiles_y; j++) {
71345df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul               struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
71445df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul               rasterize_bin(task, bin, i, j);
71545df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul            }
716aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul         }
717aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      }
718aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul#else
71945df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul      {
72045df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul         struct cmd_bin *bin;
721aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
72245df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul         assert(scene);
72345df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul         while ((bin = lp_scene_bin_iter_next(scene))) {
72445df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul            if (!is_empty_bin( bin ))
72545df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul               rasterize_bin(task, bin);
72645df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul         }
727aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      }
728aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul#endif
72945df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul   }
73045df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul
7313bd9aedbac79eec16bfe6f5fc6f6a021eebe769aKeith Whitwell
7323bd9aedbac79eec16bfe6f5fc6f6a021eebe769aKeith Whitwell   if (scene->fence) {
733040e59851ae4c26ce0509d42d2ee71e007b3b3d1Keith Whitwell      lp_fence_signal(scene->fence);
7343bd9aedbac79eec16bfe6f5fc6f6a021eebe769aKeith Whitwell   }
7359f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell
7369f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6Keith Whitwell   task->scene = NULL;
737aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul}
738aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
739aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
740aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul/**
7414e67f10331bfd87560e2900e66f3b942902bc65cBrian Paul * Called by setup module when it has something for us to render.
742aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul */
74301b1900084152dbacd4025a31ced25f75666ce59Brian Paulvoid
7445fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwelllp_rast_queue_scene( struct lp_rasterizer *rast,
7455fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell                     struct lp_scene *scene)
74601b1900084152dbacd4025a31ced25f75666ce59Brian Paul{
74701b1900084152dbacd4025a31ced25f75666ce59Brian Paul   LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
74801b1900084152dbacd4025a31ced25f75666ce59Brian Paul
749aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   if (rast->num_threads == 0) {
750aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* no threading */
7512bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
7525fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      lp_rast_begin( rast, scene );
7532bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
7545fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      rasterize_scene( &rast->tasks[0], scene );
7553bee8c2e7c17893f91f6b62e2db090ef495dca9dBrian Paul
7560639765b2850739af1678f10fc0c5706d5827776Brian Paul      lp_rast_end( rast );
7570639765b2850739af1678f10fc0c5706d5827776Brian Paul
7585fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      rast->curr_scene = NULL;
75901b1900084152dbacd4025a31ced25f75666ce59Brian Paul   }
760aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   else {
761aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* threaded rendering! */
762aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      unsigned i;
763aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
764663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell      lp_scene_enqueue( rast->full_scenes, scene );
7659509f73c2147a9e225b5ef69a646e5dd711573f5Brian Paul
766aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* signal the threads that there's work to do */
767aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      for (i = 0; i < rast->num_threads; i++) {
768aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul         pipe_semaphore_signal(&rast->tasks[i].work_ready);
769aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      }
7705fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   }
7715fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell
7725fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
7735fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell}
7745fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell
7755fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell
7765fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwellvoid
7775fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwelllp_rast_finish( struct lp_rasterizer *rast )
7785fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell{
7795fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   if (rast->num_threads == 0) {
7805fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      /* nothing to do */
7815fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   }
7825fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell   else {
7835fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      int i;
784aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
785aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* wait for work to complete */
786aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      for (i = 0; i < rast->num_threads; i++) {
787aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul         pipe_semaphore_wait(&rast->tasks[i].work_done);
788cdaea049c95031338040b31ff31944c8a001a1ddBrian Paul      }
789cdaea049c95031338040b31ff31944c8a001a1ddBrian Paul   }
79001b1900084152dbacd4025a31ced25f75666ce59Brian Paul}
79101b1900084152dbacd4025a31ced25f75666ce59Brian Paul
79201b1900084152dbacd4025a31ced25f75666ce59Brian Paul
793aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul/**
794aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul * This is the thread's main entrypoint.
795aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul * It's a simple loop:
796aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul *   1. wait for work
797aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul *   2. do work
798aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul *   3. signal that we're done
799aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul */
8001550b0668e8914f12ed314d347f59c89ba42c20cAlexander von Gluckstatic PIPE_THREAD_ROUTINE( thread_function, init_data )
801aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul{
802aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
803aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   struct lp_rasterizer *rast = task->rast;
8049509f73c2147a9e225b5ef69a646e5dd711573f5Brian Paul   boolean debug = false;
805aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
806aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   while (1) {
807aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* wait for work */
808aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      if (debug)
809aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul         debug_printf("thread %d waiting for work\n", task->thread_index);
810aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      pipe_semaphore_wait(&task->work_ready);
811aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
812bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul      if (rast->exit_flag)
813bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul         break;
814bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul
8152bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      if (task->thread_index == 0) {
8162bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul         /* thread[0]:
817663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell          *  - get next scene to rasterize
8182bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul          *  - map the framebuffer surfaces
8192bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul          */
8205fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell         lp_rast_begin( rast,
8215fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell                        lp_scene_dequeue( rast->full_scenes, TRUE ) );
8222bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      }
8232bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
8242bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      /* Wait for all threads to get here so that threads[1+] don't
825663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell       * get a null rast->curr_scene pointer.
8262bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul       */
8272bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      pipe_barrier_wait( &rast->barrier );
8289509f73c2147a9e225b5ef69a646e5dd711573f5Brian Paul
829aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* do work */
830aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      if (debug)
831aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul         debug_printf("thread %d doing work\n", task->thread_index);
8325fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell
8335046f2c1950c44129f6098a7aae14dd50ee1f8a4Brian Paul      rasterize_scene(task,
8345fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell                      rast->curr_scene);
8359509f73c2147a9e225b5ef69a646e5dd711573f5Brian Paul
836663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell      /* wait for all threads to finish with this scene */
8372bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      pipe_barrier_wait( &rast->barrier );
8382bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
8395fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell      /* XXX: shouldn't be necessary:
8405fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell       */
8412bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      if (task->thread_index == 0) {
8422bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul         lp_rast_end( rast );
8432bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul      }
844aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
845aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      /* signal done with work */
846aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      if (debug)
847aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul         debug_printf("thread %d done working\n", task->thread_index);
8485fe2ce28b6e9fba181c13c6f49b57b3dd68fe88eKeith Whitwell
849aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      pipe_semaphore_signal(&task->work_done);
850aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   }
851aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
852aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   return NULL;
853aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul}
854aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
855aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
856aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul/**
857aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul * Initialize semaphores and spawn the threads.
858aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul */
859aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paulstatic void
860aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paulcreate_rast_threads(struct lp_rasterizer *rast)
861aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul{
862aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   unsigned i;
863aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
864aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   /* NOTE: if num_threads is zero, we won't use any threads */
865aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   for (i = 0; i < rast->num_threads; i++) {
866aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      pipe_semaphore_init(&rast->tasks[i].work_ready, 0);
867aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul      pipe_semaphore_init(&rast->tasks[i].work_done, 0);
8681550b0668e8914f12ed314d347f59c89ba42c20cAlexander von Gluck      rast->threads[i] = pipe_thread_create(thread_function,
869aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul                                            (void *) &rast->tasks[i]);
870aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   }
871aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul}
872aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
873aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
874aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
875d7dbc666367438ee9efe748505907b36bba6b66aBrian Paul/**
876d2f0acc2fb52689493d5ac47b69415269968b71bBrian Paul * Create new lp_rasterizer.  If num_threads is zero, don't create any
877d2f0acc2fb52689493d5ac47b69415269968b71bBrian Paul * new threads, do rendering synchronously.
878d2f0acc2fb52689493d5ac47b69415269968b71bBrian Paul * \param num_threads  number of rasterizer threads to create
879d7dbc666367438ee9efe748505907b36bba6b66aBrian Paul */
880d7dbc666367438ee9efe748505907b36bba6b66aBrian Paulstruct lp_rasterizer *
88139be50dcdebe6bcbb48cb6aa8ac151eee811acb1José Fonsecalp_rast_create( unsigned num_threads )
882aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul{
883aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   struct lp_rasterizer *rast;
8840639765b2850739af1678f10fc0c5706d5827776Brian Paul   unsigned i;
885aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
886aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   rast = CALLOC_STRUCT(lp_rasterizer);
887c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca   if (!rast) {
888c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca      goto no_rast;
889c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca   }
890aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
891663750d5564a225b4720f7ee8bea93ffb309fc88Keith Whitwell   rast->full_scenes = lp_scene_queue_create();
892c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca   if (!rast->full_scenes) {
893c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca      goto no_full_scenes;
894c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca   }
895d7dbc666367438ee9efe748505907b36bba6b66aBrian Paul
896aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   for (i = 0; i < Elements(rast->tasks); i++) {
897ec459f2aeca39e51f495cde455ba18d0a9489caaBrian Paul      struct lp_rasterizer_task *task = &rast->tasks[i];
898ec459f2aeca39e51f495cde455ba18d0a9489caaBrian Paul      task->rast = rast;
899ec459f2aeca39e51f495cde455ba18d0a9489caaBrian Paul      task->thread_index = i;
900aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   }
901aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
90239be50dcdebe6bcbb48cb6aa8ac151eee811acb1José Fonseca   rast->num_threads = num_threads;
90339be50dcdebe6bcbb48cb6aa8ac151eee811acb1José Fonseca
90445df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul   rast->no_rast = debug_get_bool_option("LP_NO_RAST", FALSE);
90545df3eb1db7147aca31134723972e1de4f6a7a16Brian Paul
906aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   create_rast_threads(rast);
907aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
9082bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul   /* for synchronizing rasterization threads */
9092bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul   pipe_barrier_init( &rast->barrier, rast->num_threads );
9102bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
9112f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell   memset(lp_swizzled_cbuf, 0, sizeof lp_swizzled_cbuf);
9122f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell
9132f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell   memset(lp_dummy_tile, 0, sizeof lp_dummy_tile);
9142f6d47a7c8d6e69e5154de44115aab9ba35a41d2Keith Whitwell
915aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul   return rast;
916c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca
917c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonsecano_full_scenes:
918c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca   FREE(rast);
919c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonsecano_rast:
920c88f3e0374620f18cf38d9fc3c45d14bc53f62b2José Fonseca   return NULL;
921aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul}
922aab1ceceecbd6449eebce7f5f5b356b1a51552e7Brian Paul
923b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97Brian Paul
92489498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell/* Shutdown:
92589498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell */
92689498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwellvoid lp_rast_destroy( struct lp_rasterizer *rast )
92789498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell{
9280639765b2850739af1678f10fc0c5706d5827776Brian Paul   unsigned i;
9293a06c113c76355fc9622adfe7565c18d9787e9a8Brian Paul
930bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul   /* Set exit_flag and signal each thread's work_ready semaphore.
931bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul    * Each thread will be woken up, notice that the exit_flag is set and
932bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul    * break out of its main loop.  The thread will then exit.
933bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul    */
934bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul   rast->exit_flag = TRUE;
935bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul   for (i = 0; i < rast->num_threads; i++) {
936bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul      pipe_semaphore_signal(&rast->tasks[i].work_ready);
937bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul   }
938bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul
939b704a4e8f332e7f9a38c21ce074cd244cf2fe89eBrian Paul   /* Wait for threads to terminate before cleaning up per-thread data */
940b704a4e8f332e7f9a38c21ce074cd244cf2fe89eBrian Paul   for (i = 0; i < rast->num_threads; i++) {
941b704a4e8f332e7f9a38c21ce074cd244cf2fe89eBrian Paul      pipe_thread_wait(rast->threads[i]);
942b704a4e8f332e7f9a38c21ce074cd244cf2fe89eBrian Paul   }
943b704a4e8f332e7f9a38c21ce074cd244cf2fe89eBrian Paul
944b704a4e8f332e7f9a38c21ce074cd244cf2fe89eBrian Paul   /* Clean up per-thread data */
945bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul   for (i = 0; i < rast->num_threads; i++) {
946bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul      pipe_semaphore_destroy(&rast->tasks[i].work_ready);
947bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul      pipe_semaphore_destroy(&rast->tasks[i].work_done);
948bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul   }
949bc04ae21c10bedcc75d3483784d3eaf7bf090f55Brian Paul
9502bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul   /* for synchronizing rasterization threads */
9512bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul   pipe_barrier_destroy( &rast->barrier );
9522bce5c195f94e2cce8f67c6a8066b0ae408487ceBrian Paul
953bdf753a858a8431f25bba98f8e77cab1ae03808aBrian Paul   lp_scene_queue_destroy(rast->full_scenes);
954bdf753a858a8431f25bba98f8e77cab1ae03808aBrian Paul
95589498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell   FREE(rast);
95689498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell}
95789498d01531cd515c769e570bf799c39fbafc8fbKeith Whitwell
958932374073863379e9da862d6115410889f038154Brian Paul
959932374073863379e9da862d6115410889f038154Brian Paul/** Return number of rasterization threads */
960932374073863379e9da862d6115410889f038154Brian Paulunsigned
961932374073863379e9da862d6115410889f038154Brian Paullp_rast_get_num_threads( struct lp_rasterizer *rast )
962932374073863379e9da862d6115410889f038154Brian Paul{
963932374073863379e9da862d6115410889f038154Brian Paul   return rast->num_threads;
964932374073863379e9da862d6115410889f038154Brian Paul}
96586afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li
96686afe8250edaa2e6129c937a62a695f616c48d70Qicheng Christopher Li
967