Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lp_rast.c 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. /**************************************************************************
  2. *
  3. * Copyright 2009 VMware, Inc.
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial portions
  16. * of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21. * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. #include <limits.h>
  28. #include "util/u_memory.h"
  29. #include "util/u_math.h"
  30. #include "util/u_rect.h"
  31. #include "util/u_surface.h"
  32. #include "util/u_pack_color.h"
  33. #include "os/os_time.h"
  34. #include "lp_scene_queue.h"
  35. #include "lp_debug.h"
  36. #include "lp_fence.h"
  37. #include "lp_perf.h"
  38. #include "lp_query.h"
  39. #include "lp_rast.h"
  40. #include "lp_rast_priv.h"
  41. #include "gallivm/lp_bld_debug.h"
  42. #include "lp_scene.h"
  43. #include "lp_tex_sample.h"
  44. #ifdef DEBUG
  45. int jit_line = 0;
  46. const struct lp_rast_state *jit_state = NULL;
  47. const struct lp_rasterizer_task *jit_task = NULL;
  48. #endif
  49. /**
  50. * Begin rasterizing a scene.
  51. * Called once per scene by one thread.
  52. */
  53. static void
  54. lp_rast_begin( struct lp_rasterizer *rast,
  55. struct lp_scene *scene )
  56. {
  57. rast->curr_scene = scene;
  58. LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
  59. lp_scene_begin_rasterization( scene );
  60. lp_scene_bin_iter_begin( scene );
  61. }
  62. static void
  63. lp_rast_end( struct lp_rasterizer *rast )
  64. {
  65. lp_scene_end_rasterization( rast->curr_scene );
  66. rast->curr_scene = NULL;
  67. }
  68. /**
  69. * Begining rasterization of a tile.
  70. * \param x window X position of the tile, in pixels
  71. * \param y window Y position of the tile, in pixels
  72. */
  73. static void
  74. lp_rast_tile_begin(struct lp_rasterizer_task *task,
  75. const struct cmd_bin *bin)
  76. {
  77. const struct lp_scene *scene = task->scene;
  78. enum lp_texture_usage usage;
  79. LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, bin->x, bin->y);
  80. task->bin = bin;
  81. task->x = bin->x * TILE_SIZE;
  82. task->y = bin->y * TILE_SIZE;
  83. /* reset pointers to color tile(s) */
  84. memset(task->color_tiles, 0, sizeof(task->color_tiles));
  85. /* get pointer to depth/stencil tile */
  86. {
  87. struct pipe_surface *zsbuf = task->scene->fb.zsbuf;
  88. if (zsbuf) {
  89. struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
  90. if (scene->has_depthstencil_clear)
  91. usage = LP_TEX_USAGE_WRITE_ALL;
  92. else
  93. usage = LP_TEX_USAGE_READ_WRITE;
  94. /* "prime" the tile: convert data from linear to tiled if necessary
  95. * and update the tile's layout info.
  96. */
  97. (void) llvmpipe_get_texture_tile(lpt,
  98. zsbuf->u.tex.first_layer,
  99. zsbuf->u.tex.level,
  100. usage,
  101. task->x,
  102. task->y);
  103. /* Get actual pointer to the tile data. Note that depth/stencil
  104. * data is tiled differently than color data.
  105. */
  106. task->depth_tile = lp_rast_get_depth_block_pointer(task,
  107. task->x,
  108. task->y);
  109. assert(task->depth_tile);
  110. }
  111. else {
  112. task->depth_tile = NULL;
  113. }
  114. }
  115. }
  116. /**
  117. * Clear the rasterizer's current color tile.
  118. * This is a bin command called during bin processing.
  119. */
  120. static void
  121. lp_rast_clear_color(struct lp_rasterizer_task *task,
  122. const union lp_rast_cmd_arg arg)
  123. {
  124. const struct lp_scene *scene = task->scene;
  125. if (scene->fb.nr_cbufs) {
  126. unsigned i;
  127. union util_color uc;
  128. if (util_format_is_pure_integer(scene->fb.cbufs[0]->format)) {
  129. /*
  130. * We expect int/uint clear values here, though some APIs
  131. * might disagree (but in any case util_pack_color()
  132. * couldn't handle it)...
  133. */
  134. LP_DBG(DEBUG_RAST, "%s pure int 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
  135. arg.clear_color.ui[0],
  136. arg.clear_color.ui[1],
  137. arg.clear_color.ui[2],
  138. arg.clear_color.ui[3]);
  139. for (i = 0; i < scene->fb.nr_cbufs; i++) {
  140. enum pipe_format format = scene->fb.cbufs[i]->format;
  141. if (util_format_is_pure_sint(format)) {
  142. util_format_write_4i(format, arg.clear_color.i, 0, &uc, 0, 0, 0, 1, 1);
  143. }
  144. else {
  145. assert(util_format_is_pure_uint(format));
  146. util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, 0, 0, 0, 1, 1);
  147. }
  148. util_fill_rect(scene->cbufs[i].map,
  149. scene->fb.cbufs[i]->format,
  150. scene->cbufs[i].stride,
  151. task->x,
  152. task->y,
  153. TILE_SIZE,
  154. TILE_SIZE,
  155. &uc);
  156. }
  157. }
  158. else {
  159. uint8_t clear_color[4];
  160. for (i = 0; i < 4; ++i) {
  161. clear_color[i] = float_to_ubyte(arg.clear_color.f[i]);
  162. }
  163. LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
  164. clear_color[0],
  165. clear_color[1],
  166. clear_color[2],
  167. clear_color[3]);
  168. for (i = 0; i < scene->fb.nr_cbufs; i++) {
  169. util_pack_color(arg.clear_color.f,
  170. scene->fb.cbufs[i]->format, &uc);
  171. util_fill_rect(scene->cbufs[i].map,
  172. scene->fb.cbufs[i]->format,
  173. scene->cbufs[i].stride,
  174. task->x,
  175. task->y,
  176. TILE_SIZE,
  177. TILE_SIZE,
  178. &uc);
  179. }
  180. }
  181. }
  182. LP_COUNT(nr_color_tile_clear);
  183. }
  184. /**
  185. * Clear the rasterizer's current z/stencil tile.
  186. * This is a bin command called during bin processing.
  187. */
  188. static void
  189. lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
  190. const union lp_rast_cmd_arg arg)
  191. {
  192. const struct lp_scene *scene = task->scene;
  193. uint32_t clear_value = arg.clear_zstencil.value;
  194. uint32_t clear_mask = arg.clear_zstencil.mask;
  195. const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
  196. const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
  197. const unsigned block_size = scene->zsbuf.blocksize;
  198. const unsigned dst_stride = scene->zsbuf.stride * TILE_VECTOR_HEIGHT;
  199. uint8_t *dst;
  200. unsigned i, j;
  201. LP_DBG(DEBUG_RAST, "%s: value=0x%08x, mask=0x%08x\n",
  202. __FUNCTION__, clear_value, clear_mask);
  203. /*
  204. * Clear the area of the swizzled depth/depth buffer matching this tile, in
  205. * stripes of TILE_VECTOR_HEIGHT x TILE_SIZE at a time.
  206. *
  207. * The swizzled depth format is such that the depths for
  208. * TILE_VECTOR_HEIGHT x TILE_VECTOR_WIDTH pixels have consecutive offsets.
  209. */
  210. dst = task->depth_tile;
  211. clear_value &= clear_mask;
  212. switch (block_size) {
  213. case 1:
  214. assert(clear_mask == 0xff);
  215. memset(dst, (uint8_t) clear_value, height * width);
  216. break;
  217. case 2:
  218. if (clear_mask == 0xffff) {
  219. for (i = 0; i < height; i++) {
  220. uint16_t *row = (uint16_t *)dst;
  221. for (j = 0; j < width; j++)
  222. *row++ = (uint16_t) clear_value;
  223. dst += dst_stride;
  224. }
  225. }
  226. else {
  227. for (i = 0; i < height; i++) {
  228. uint16_t *row = (uint16_t *)dst;
  229. for (j = 0; j < width; j++) {
  230. uint16_t tmp = ~clear_mask & *row;
  231. *row++ = clear_value | tmp;
  232. }
  233. dst += dst_stride;
  234. }
  235. }
  236. break;
  237. case 4:
  238. if (clear_mask == 0xffffffff) {
  239. for (i = 0; i < height; i++) {
  240. uint32_t *row = (uint32_t *)dst;
  241. for (j = 0; j < width; j++)
  242. *row++ = clear_value;
  243. dst += dst_stride;
  244. }
  245. }
  246. else {
  247. for (i = 0; i < height; i++) {
  248. uint32_t *row = (uint32_t *)dst;
  249. for (j = 0; j < width; j++) {
  250. uint32_t tmp = ~clear_mask & *row;
  251. *row++ = clear_value | tmp;
  252. }
  253. dst += dst_stride;
  254. }
  255. }
  256. break;
  257. default:
  258. assert(0);
  259. break;
  260. }
  261. }
  262. /**
  263. * Run the shader on all blocks in a tile. This is used when a tile is
  264. * completely contained inside a triangle.
  265. * This is a bin command called during bin processing.
  266. */
  267. static void
  268. lp_rast_shade_tile(struct lp_rasterizer_task *task,
  269. const union lp_rast_cmd_arg arg)
  270. {
  271. const struct lp_scene *scene = task->scene;
  272. const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
  273. const struct lp_rast_state *state;
  274. struct lp_fragment_shader_variant *variant;
  275. const unsigned tile_x = task->x, tile_y = task->y;
  276. unsigned x, y;
  277. if (inputs->disable) {
  278. /* This command was partially binned and has been disabled */
  279. return;
  280. }
  281. LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
  282. state = task->state;
  283. assert(state);
  284. if (!state) {
  285. return;
  286. }
  287. variant = state->variant;
  288. /* render the whole 64x64 tile in 4x4 chunks */
  289. for (y = 0; y < TILE_SIZE; y += 4){
  290. for (x = 0; x < TILE_SIZE; x += 4) {
  291. uint8_t *color[PIPE_MAX_COLOR_BUFS];
  292. unsigned stride[PIPE_MAX_COLOR_BUFS];
  293. uint32_t *depth;
  294. unsigned i;
  295. /* color buffer */
  296. for (i = 0; i < scene->fb.nr_cbufs; i++){
  297. stride[i] = scene->cbufs[i].stride;
  298. color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, tile_x + x, tile_y + y);
  299. }
  300. /* depth buffer */
  301. depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
  302. /* run shader on 4x4 block */
  303. BEGIN_JIT_CALL(state, task);
  304. variant->jit_function[RAST_WHOLE]( &state->jit_context,
  305. tile_x + x, tile_y + y,
  306. inputs->frontfacing,
  307. GET_A0(inputs),
  308. GET_DADX(inputs),
  309. GET_DADY(inputs),
  310. color,
  311. depth,
  312. 0xffff,
  313. &task->thread_data,
  314. stride);
  315. END_JIT_CALL();
  316. }
  317. }
  318. }
  319. /**
  320. * Run the shader on all blocks in a tile. This is used when a tile is
  321. * completely contained inside a triangle, and the shader is opaque.
  322. * This is a bin command called during bin processing.
  323. */
  324. static void
  325. lp_rast_shade_tile_opaque(struct lp_rasterizer_task *task,
  326. const union lp_rast_cmd_arg arg)
  327. {
  328. LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
  329. assert(task->state);
  330. if (!task->state) {
  331. return;
  332. }
  333. lp_rast_shade_tile(task, arg);
  334. }
  335. /**
  336. * Compute shading for a 4x4 block of pixels inside a triangle.
  337. * This is a bin command called during bin processing.
  338. * \param x X position of quad in window coords
  339. * \param y Y position of quad in window coords
  340. */
  341. void
  342. lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
  343. const struct lp_rast_shader_inputs *inputs,
  344. unsigned x, unsigned y,
  345. unsigned mask)
  346. {
  347. const struct lp_rast_state *state = task->state;
  348. struct lp_fragment_shader_variant *variant = state->variant;
  349. const struct lp_scene *scene = task->scene;
  350. uint8_t *color[PIPE_MAX_COLOR_BUFS];
  351. unsigned stride[PIPE_MAX_COLOR_BUFS];
  352. void *depth;
  353. unsigned i;
  354. assert(state);
  355. /* Sanity checks */
  356. assert(x < scene->tiles_x * TILE_SIZE);
  357. assert(y < scene->tiles_y * TILE_SIZE);
  358. assert(x % TILE_VECTOR_WIDTH == 0);
  359. assert(y % TILE_VECTOR_HEIGHT == 0);
  360. assert((x % 4) == 0);
  361. assert((y % 4) == 0);
  362. /* color buffer */
  363. for (i = 0; i < scene->fb.nr_cbufs; i++) {
  364. stride[i] = scene->cbufs[i].stride;
  365. color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y);
  366. }
  367. /* depth buffer */
  368. depth = lp_rast_get_depth_block_pointer(task, x, y);
  369. assert(lp_check_alignment(state->jit_context.u8_blend_color, 16));
  370. /* run shader on 4x4 block */
  371. BEGIN_JIT_CALL(state, task);
  372. variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
  373. x, y,
  374. inputs->frontfacing,
  375. GET_A0(inputs),
  376. GET_DADX(inputs),
  377. GET_DADY(inputs),
  378. color,
  379. depth,
  380. mask,
  381. &task->thread_data,
  382. stride);
  383. END_JIT_CALL();
  384. }
  385. /**
  386. * Begin a new occlusion query.
  387. * This is a bin command put in all bins.
  388. * Called per thread.
  389. */
  390. static void
  391. lp_rast_begin_query(struct lp_rasterizer_task *task,
  392. const union lp_rast_cmd_arg arg)
  393. {
  394. struct llvmpipe_query *pq = arg.query_obj;
  395. assert(task->query[pq->type] == NULL);
  396. switch (pq->type) {
  397. case PIPE_QUERY_OCCLUSION_COUNTER:
  398. task->thread_data.vis_counter = 0;
  399. break;
  400. case PIPE_QUERY_PRIMITIVES_GENERATED:
  401. case PIPE_QUERY_PRIMITIVES_EMITTED:
  402. case PIPE_QUERY_SO_STATISTICS:
  403. break;
  404. default:
  405. assert(0);
  406. break;
  407. }
  408. task->query[pq->type] = pq;
  409. }
  410. /**
  411. * End the current occlusion query.
  412. * This is a bin command put in all bins.
  413. * Called per thread.
  414. */
  415. static void
  416. lp_rast_end_query(struct lp_rasterizer_task *task,
  417. const union lp_rast_cmd_arg arg)
  418. {
  419. struct llvmpipe_query *pq = arg.query_obj;
  420. assert(task->query[pq->type] == pq || pq->type == PIPE_QUERY_TIMESTAMP);
  421. switch (pq->type) {
  422. case PIPE_QUERY_OCCLUSION_COUNTER:
  423. pq->count[task->thread_index] += task->thread_data.vis_counter;
  424. break;
  425. case PIPE_QUERY_TIMESTAMP:
  426. pq->count[task->thread_index] = os_time_get_nano();
  427. break;
  428. case PIPE_QUERY_PRIMITIVES_GENERATED:
  429. case PIPE_QUERY_PRIMITIVES_EMITTED:
  430. case PIPE_QUERY_SO_STATISTICS:
  431. break;
  432. default:
  433. assert(0);
  434. break;
  435. }
  436. if (task->query[pq->type] == pq) {
  437. task->query[pq->type] = NULL;
  438. }
  439. }
  440. void
  441. lp_rast_set_state(struct lp_rasterizer_task *task,
  442. const union lp_rast_cmd_arg arg)
  443. {
  444. task->state = arg.state;
  445. }
  446. /**
  447. * Called when we're done writing to a color tile.
  448. */
  449. static void
  450. lp_rast_tile_end(struct lp_rasterizer_task *task)
  451. {
  452. unsigned i;
  453. for (i = 0; i < PIPE_QUERY_TYPES; ++i) {
  454. if (task->query[i]) {
  455. lp_rast_end_query(task, lp_rast_arg_query(task->query[i]));
  456. }
  457. }
  458. /* debug */
  459. memset(task->color_tiles, 0, sizeof(task->color_tiles));
  460. task->depth_tile = NULL;
  461. task->bin = NULL;
  462. }
  463. static lp_rast_cmd_func dispatch[LP_RAST_OP_MAX] =
  464. {
  465. lp_rast_clear_color,
  466. lp_rast_clear_zstencil,
  467. lp_rast_triangle_1,
  468. lp_rast_triangle_2,
  469. lp_rast_triangle_3,
  470. lp_rast_triangle_4,
  471. lp_rast_triangle_5,
  472. lp_rast_triangle_6,
  473. lp_rast_triangle_7,
  474. lp_rast_triangle_8,
  475. lp_rast_triangle_3_4,
  476. lp_rast_triangle_3_16,
  477. lp_rast_triangle_4_16,
  478. lp_rast_shade_tile,
  479. lp_rast_shade_tile_opaque,
  480. lp_rast_begin_query,
  481. lp_rast_end_query,
  482. lp_rast_set_state,
  483. };
  484. static void
  485. do_rasterize_bin(struct lp_rasterizer_task *task,
  486. const struct cmd_bin *bin)
  487. {
  488. const struct cmd_block *block;
  489. unsigned k;
  490. if (0)
  491. lp_debug_bin(bin);
  492. for (block = bin->head; block; block = block->next) {
  493. for (k = 0; k < block->count; k++) {
  494. dispatch[block->cmd[k]]( task, block->arg[k] );
  495. }
  496. }
  497. }
  498. /**
  499. * Rasterize commands for a single bin.
  500. * \param x, y position of the bin's tile in the framebuffer
  501. * Must be called between lp_rast_begin() and lp_rast_end().
  502. * Called per thread.
  503. */
  504. static void
  505. rasterize_bin(struct lp_rasterizer_task *task,
  506. const struct cmd_bin *bin )
  507. {
  508. lp_rast_tile_begin( task, bin );
  509. do_rasterize_bin(task, bin);
  510. lp_rast_tile_end(task);
  511. /* Debug/Perf flags:
  512. */
  513. if (bin->head->count == 1) {
  514. if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE_OPAQUE)
  515. LP_COUNT(nr_pure_shade_opaque_64);
  516. else if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE)
  517. LP_COUNT(nr_pure_shade_64);
  518. }
  519. }
  520. /* An empty bin is one that just loads the contents of the tile and
  521. * stores them again unchanged. This typically happens when bins have
  522. * been flushed for some reason in the middle of a frame, or when
  523. * incremental updates are being made to a render target.
  524. *
  525. * Try to avoid doing pointless work in this case.
  526. */
  527. static boolean
  528. is_empty_bin( const struct cmd_bin *bin )
  529. {
  530. return bin->head == NULL;
  531. }
  532. /**
  533. * Rasterize/execute all bins within a scene.
  534. * Called per thread.
  535. */
  536. static void
  537. rasterize_scene(struct lp_rasterizer_task *task,
  538. struct lp_scene *scene)
  539. {
  540. task->scene = scene;
  541. if (!task->rast->no_rast && !scene->discard) {
  542. /* loop over scene bins, rasterize each */
  543. #if 0
  544. {
  545. unsigned i, j;
  546. for (i = 0; i < scene->tiles_x; i++) {
  547. for (j = 0; j < scene->tiles_y; j++) {
  548. struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
  549. rasterize_bin(task, bin, i, j);
  550. }
  551. }
  552. }
  553. #else
  554. {
  555. struct cmd_bin *bin;
  556. assert(scene);
  557. while ((bin = lp_scene_bin_iter_next(scene))) {
  558. if (!is_empty_bin( bin ))
  559. rasterize_bin(task, bin);
  560. }
  561. }
  562. #endif
  563. }
  564. if (scene->fence) {
  565. lp_fence_signal(scene->fence);
  566. }
  567. task->scene = NULL;
  568. }
  569. /**
  570. * Called by setup module when it has something for us to render.
  571. */
  572. void
  573. lp_rast_queue_scene( struct lp_rasterizer *rast,
  574. struct lp_scene *scene)
  575. {
  576. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  577. if (rast->num_threads == 0) {
  578. /* no threading */
  579. lp_rast_begin( rast, scene );
  580. rasterize_scene( &rast->tasks[0], scene );
  581. lp_rast_end( rast );
  582. rast->curr_scene = NULL;
  583. }
  584. else {
  585. /* threaded rendering! */
  586. unsigned i;
  587. lp_scene_enqueue( rast->full_scenes, scene );
  588. /* signal the threads that there's work to do */
  589. for (i = 0; i < rast->num_threads; i++) {
  590. pipe_semaphore_signal(&rast->tasks[i].work_ready);
  591. }
  592. }
  593. LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
  594. }
  595. void
  596. lp_rast_finish( struct lp_rasterizer *rast )
  597. {
  598. if (rast->num_threads == 0) {
  599. /* nothing to do */
  600. }
  601. else {
  602. int i;
  603. /* wait for work to complete */
  604. for (i = 0; i < rast->num_threads; i++) {
  605. pipe_semaphore_wait(&rast->tasks[i].work_done);
  606. }
  607. }
  608. }
  609. /**
  610. * This is the thread's main entrypoint.
  611. * It's a simple loop:
  612. * 1. wait for work
  613. * 2. do work
  614. * 3. signal that we're done
  615. */
  616. static PIPE_THREAD_ROUTINE( thread_function, init_data )
  617. {
  618. struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
  619. struct lp_rasterizer *rast = task->rast;
  620. boolean debug = false;
  621. while (1) {
  622. /* wait for work */
  623. if (debug)
  624. debug_printf("thread %d waiting for work\n", task->thread_index);
  625. pipe_semaphore_wait(&task->work_ready);
  626. if (rast->exit_flag)
  627. break;
  628. if (task->thread_index == 0) {
  629. /* thread[0]:
  630. * - get next scene to rasterize
  631. * - map the framebuffer surfaces
  632. */
  633. lp_rast_begin( rast,
  634. lp_scene_dequeue( rast->full_scenes, TRUE ) );
  635. }
  636. /* Wait for all threads to get here so that threads[1+] don't
  637. * get a null rast->curr_scene pointer.
  638. */
  639. pipe_barrier_wait( &rast->barrier );
  640. /* do work */
  641. if (debug)
  642. debug_printf("thread %d doing work\n", task->thread_index);
  643. rasterize_scene(task,
  644. rast->curr_scene);
  645. /* wait for all threads to finish with this scene */
  646. pipe_barrier_wait( &rast->barrier );
  647. /* XXX: shouldn't be necessary:
  648. */
  649. if (task->thread_index == 0) {
  650. lp_rast_end( rast );
  651. }
  652. /* signal done with work */
  653. if (debug)
  654. debug_printf("thread %d done working\n", task->thread_index);
  655. pipe_semaphore_signal(&task->work_done);
  656. }
  657. return NULL;
  658. }
  659. /**
  660. * Initialize semaphores and spawn the threads.
  661. */
  662. static void
  663. create_rast_threads(struct lp_rasterizer *rast)
  664. {
  665. unsigned i;
  666. /* NOTE: if num_threads is zero, we won't use any threads */
  667. for (i = 0; i < rast->num_threads; i++) {
  668. pipe_semaphore_init(&rast->tasks[i].work_ready, 0);
  669. pipe_semaphore_init(&rast->tasks[i].work_done, 0);
  670. rast->threads[i] = pipe_thread_create(thread_function,
  671. (void *) &rast->tasks[i]);
  672. }
  673. }
  674. /**
  675. * Create new lp_rasterizer. If num_threads is zero, don't create any
  676. * new threads, do rendering synchronously.
  677. * \param num_threads number of rasterizer threads to create
  678. */
  679. struct lp_rasterizer *
  680. lp_rast_create( unsigned num_threads )
  681. {
  682. struct lp_rasterizer *rast;
  683. unsigned i;
  684. rast = CALLOC_STRUCT(lp_rasterizer);
  685. if (!rast) {
  686. goto no_rast;
  687. }
  688. rast->full_scenes = lp_scene_queue_create();
  689. if (!rast->full_scenes) {
  690. goto no_full_scenes;
  691. }
  692. for (i = 0; i < Elements(rast->tasks); i++) {
  693. struct lp_rasterizer_task *task = &rast->tasks[i];
  694. task->rast = rast;
  695. task->thread_index = i;
  696. }
  697. rast->num_threads = num_threads;
  698. rast->no_rast = debug_get_bool_option("LP_NO_RAST", FALSE);
  699. create_rast_threads(rast);
  700. /* for synchronizing rasterization threads */
  701. pipe_barrier_init( &rast->barrier, rast->num_threads );
  702. memset(lp_dummy_tile, 0, sizeof lp_dummy_tile);
  703. return rast;
  704. no_full_scenes:
  705. FREE(rast);
  706. no_rast:
  707. return NULL;
  708. }
  709. /* Shutdown:
  710. */
  711. void lp_rast_destroy( struct lp_rasterizer *rast )
  712. {
  713. unsigned i;
  714. /* Set exit_flag and signal each thread's work_ready semaphore.
  715. * Each thread will be woken up, notice that the exit_flag is set and
  716. * break out of its main loop. The thread will then exit.
  717. */
  718. rast->exit_flag = TRUE;
  719. for (i = 0; i < rast->num_threads; i++) {
  720. pipe_semaphore_signal(&rast->tasks[i].work_ready);
  721. }
  722. /* Wait for threads to terminate before cleaning up per-thread data */
  723. for (i = 0; i < rast->num_threads; i++) {
  724. pipe_thread_wait(rast->threads[i]);
  725. }
  726. /* Clean up per-thread data */
  727. for (i = 0; i < rast->num_threads; i++) {
  728. pipe_semaphore_destroy(&rast->tasks[i].work_ready);
  729. pipe_semaphore_destroy(&rast->tasks[i].work_done);
  730. }
  731. /* for synchronizing rasterization threads */
  732. pipe_barrier_destroy( &rast->barrier );
  733. lp_scene_queue_destroy(rast->full_scenes);
  734. FREE(rast);
  735. }
  736. /** Return number of rasterization threads */
  737. unsigned
  738. lp_rast_get_num_threads( struct lp_rasterizer *rast )
  739. {
  740. return rast->num_threads;
  741. }