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_setup.c 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. /**************************************************************************
  2. *
  3. * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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. /**
  28. * Tiling engine.
  29. *
  30. * Builds per-tile display lists and executes them on calls to
  31. * lp_setup_flush().
  32. */
  33. #include "pipe/p_defines.h"
  34. #include "util/u_inlines.h"
  35. #include "util/u_memory.h"
  36. #include "util/u_pack_color.h"
  37. #include "util/u_surface.h"
  38. #include "lp_scene.h"
  39. #include "lp_scene_queue.h"
  40. #include "lp_buffer.h"
  41. #include "lp_texture.h"
  42. #include "lp_debug.h"
  43. #include "lp_fence.h"
  44. #include "lp_rast.h"
  45. #include "lp_setup_context.h"
  46. #include "lp_screen.h"
  47. #include "lp_winsys.h"
  48. #include "draw/draw_context.h"
  49. #include "draw/draw_vbuf.h"
  50. static void set_scene_state( struct setup_context *, unsigned );
  51. struct lp_scene *
  52. lp_setup_get_current_scene(struct setup_context *setup)
  53. {
  54. if (!setup->scene) {
  55. /* wait for a free/empty scene
  56. */
  57. setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE);
  58. if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */
  59. lp_scene_set_framebuffer_size(setup->scene,
  60. setup->fb.width,
  61. setup->fb.height);
  62. }
  63. return setup->scene;
  64. }
  65. static void
  66. first_triangle( struct setup_context *setup,
  67. const float (*v0)[4],
  68. const float (*v1)[4],
  69. const float (*v2)[4])
  70. {
  71. set_scene_state( setup, SETUP_ACTIVE );
  72. lp_setup_choose_triangle( setup );
  73. setup->triangle( setup, v0, v1, v2 );
  74. }
  75. static void
  76. first_line( struct setup_context *setup,
  77. const float (*v0)[4],
  78. const float (*v1)[4])
  79. {
  80. set_scene_state( setup, SETUP_ACTIVE );
  81. lp_setup_choose_line( setup );
  82. setup->line( setup, v0, v1 );
  83. }
  84. static void
  85. first_point( struct setup_context *setup,
  86. const float (*v0)[4])
  87. {
  88. set_scene_state( setup, SETUP_ACTIVE );
  89. lp_setup_choose_point( setup );
  90. setup->point( setup, v0 );
  91. }
  92. static void reset_context( struct setup_context *setup )
  93. {
  94. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  95. /* Reset derived state */
  96. setup->constants.stored_size = 0;
  97. setup->constants.stored_data = NULL;
  98. setup->fs.stored = NULL;
  99. setup->dirty = ~0;
  100. /* no current bin */
  101. setup->scene = NULL;
  102. /* Reset some state:
  103. */
  104. setup->clear.flags = 0;
  105. /* Have an explicit "start-binning" call and get rid of this
  106. * pointer twiddling?
  107. */
  108. setup->line = first_line;
  109. setup->point = first_point;
  110. setup->triangle = first_triangle;
  111. }
  112. /** Rasterize all scene's bins */
  113. static void
  114. lp_setup_rasterize_scene( struct setup_context *setup,
  115. boolean write_depth )
  116. {
  117. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  118. lp_rasterize_scene(setup->rast,
  119. scene,
  120. &setup->fb,
  121. write_depth);
  122. reset_context( setup );
  123. LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
  124. }
  125. static void
  126. begin_binning( struct setup_context *setup )
  127. {
  128. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  129. LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__,
  130. (setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load",
  131. (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) ? "clear": "load");
  132. if (setup->fb.nr_cbufs) {
  133. if (setup->clear.flags & PIPE_CLEAR_COLOR)
  134. lp_scene_bin_everywhere( scene,
  135. lp_rast_clear_color,
  136. setup->clear.color );
  137. else
  138. lp_scene_bin_everywhere( scene,
  139. lp_rast_load_color,
  140. lp_rast_arg_null() );
  141. }
  142. if (setup->fb.zsbuf) {
  143. if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL)
  144. lp_scene_bin_everywhere( scene,
  145. lp_rast_clear_zstencil,
  146. setup->clear.zstencil );
  147. }
  148. LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__);
  149. }
  150. /* This basically bins and then flushes any outstanding full-screen
  151. * clears.
  152. *
  153. * TODO: fast path for fullscreen clears and no triangles.
  154. */
  155. static void
  156. execute_clears( struct setup_context *setup )
  157. {
  158. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  159. begin_binning( setup );
  160. lp_setup_rasterize_scene( setup, TRUE );
  161. }
  162. static void
  163. set_scene_state( struct setup_context *setup,
  164. unsigned new_state )
  165. {
  166. unsigned old_state = setup->state;
  167. if (old_state == new_state)
  168. return;
  169. LP_DBG(DEBUG_SETUP, "%s old %d new %d\n", __FUNCTION__, old_state, new_state);
  170. switch (new_state) {
  171. case SETUP_ACTIVE:
  172. begin_binning( setup );
  173. break;
  174. case SETUP_CLEARED:
  175. if (old_state == SETUP_ACTIVE) {
  176. assert(0);
  177. return;
  178. }
  179. break;
  180. case SETUP_FLUSHED:
  181. if (old_state == SETUP_CLEARED)
  182. execute_clears( setup );
  183. else
  184. lp_setup_rasterize_scene( setup, TRUE );
  185. break;
  186. }
  187. setup->state = new_state;
  188. }
  189. void
  190. lp_setup_flush( struct setup_context *setup,
  191. unsigned flags )
  192. {
  193. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  194. set_scene_state( setup, SETUP_FLUSHED );
  195. }
  196. void
  197. lp_setup_bind_framebuffer( struct setup_context *setup,
  198. const struct pipe_framebuffer_state *fb )
  199. {
  200. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  201. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  202. set_scene_state( setup, SETUP_FLUSHED );
  203. /* re-get scene pointer, may have a new scene after flushing */
  204. (void) scene;
  205. scene = lp_setup_get_current_scene(setup);
  206. util_copy_framebuffer_state(&setup->fb, fb);
  207. lp_scene_set_framebuffer_size(scene, setup->fb.width, setup->fb.height);
  208. }
  209. void
  210. lp_setup_clear( struct setup_context *setup,
  211. const float *color,
  212. double depth,
  213. unsigned stencil,
  214. unsigned flags )
  215. {
  216. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  217. unsigned i;
  218. LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);
  219. if (flags & PIPE_CLEAR_COLOR) {
  220. for (i = 0; i < 4; ++i)
  221. setup->clear.color.clear_color[i] = float_to_ubyte(color[i]);
  222. }
  223. if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
  224. setup->clear.zstencil.clear_zstencil =
  225. util_pack_z_stencil(setup->fb.zsbuf->format,
  226. depth,
  227. stencil);
  228. }
  229. if (setup->state == SETUP_ACTIVE) {
  230. /* Add the clear to existing scene. In the unusual case where
  231. * both color and depth-stencil are being cleared when there's
  232. * already been some rendering, we could discard the currently
  233. * binned scene and start again, but I don't see that as being
  234. * a common usage.
  235. */
  236. if (flags & PIPE_CLEAR_COLOR)
  237. lp_scene_bin_everywhere( scene,
  238. lp_rast_clear_color,
  239. setup->clear.color );
  240. if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL)
  241. lp_scene_bin_everywhere( scene,
  242. lp_rast_clear_zstencil,
  243. setup->clear.zstencil );
  244. }
  245. else {
  246. /* Put ourselves into the 'pre-clear' state, specifically to try
  247. * and accumulate multiple clears to color and depth_stencil
  248. * buffers which the app or state-tracker might issue
  249. * separately.
  250. */
  251. set_scene_state( setup, SETUP_CLEARED );
  252. setup->clear.flags |= flags;
  253. }
  254. }
  255. /**
  256. * Emit a fence.
  257. */
  258. struct pipe_fence_handle *
  259. lp_setup_fence( struct setup_context *setup )
  260. {
  261. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  262. const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */
  263. struct lp_fence *fence = lp_fence_create(rank);
  264. LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
  265. set_scene_state( setup, SETUP_ACTIVE );
  266. /* insert the fence into all command bins */
  267. lp_scene_bin_everywhere( scene,
  268. lp_rast_fence,
  269. lp_rast_arg_fence(fence) );
  270. return (struct pipe_fence_handle *) fence;
  271. }
  272. void
  273. lp_setup_set_triangle_state( struct setup_context *setup,
  274. unsigned cull_mode,
  275. boolean ccw_is_frontface,
  276. boolean scissor )
  277. {
  278. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  279. setup->ccw_is_frontface = ccw_is_frontface;
  280. setup->cullmode = cull_mode;
  281. setup->triangle = first_triangle;
  282. setup->scissor_test = scissor;
  283. }
  284. void
  285. lp_setup_set_fs_inputs( struct setup_context *setup,
  286. const struct lp_shader_input *input,
  287. unsigned nr )
  288. {
  289. LP_DBG(DEBUG_SETUP, "%s %p %u\n", __FUNCTION__, (void *) input, nr);
  290. memcpy( setup->fs.input, input, nr * sizeof input[0] );
  291. setup->fs.nr_inputs = nr;
  292. }
  293. void
  294. lp_setup_set_fs_functions( struct setup_context *setup,
  295. lp_jit_frag_func jit_function0,
  296. lp_jit_frag_func jit_function1,
  297. boolean opaque )
  298. {
  299. LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function0);
  300. /* FIXME: reference count */
  301. setup->fs.current.jit_function[0] = jit_function0;
  302. setup->fs.current.jit_function[1] = jit_function1;
  303. setup->fs.current.opaque = opaque;
  304. setup->dirty |= LP_SETUP_NEW_FS;
  305. }
  306. void
  307. lp_setup_set_fs_constants(struct setup_context *setup,
  308. struct pipe_buffer *buffer)
  309. {
  310. LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer);
  311. pipe_buffer_reference(&setup->constants.current, buffer);
  312. setup->dirty |= LP_SETUP_NEW_CONSTANTS;
  313. }
  314. void
  315. lp_setup_set_alpha_ref_value( struct setup_context *setup,
  316. float alpha_ref_value )
  317. {
  318. LP_DBG(DEBUG_SETUP, "%s %f\n", __FUNCTION__, alpha_ref_value);
  319. if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) {
  320. setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value;
  321. setup->dirty |= LP_SETUP_NEW_FS;
  322. }
  323. }
  324. void
  325. lp_setup_set_blend_color( struct setup_context *setup,
  326. const struct pipe_blend_color *blend_color )
  327. {
  328. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  329. assert(blend_color);
  330. if(memcmp(&setup->blend_color.current, blend_color, sizeof *blend_color) != 0) {
  331. memcpy(&setup->blend_color.current, blend_color, sizeof *blend_color);
  332. setup->dirty |= LP_SETUP_NEW_BLEND_COLOR;
  333. }
  334. }
  335. void
  336. lp_setup_set_scissor( struct setup_context *setup,
  337. const struct pipe_scissor_state *scissor )
  338. {
  339. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  340. assert(scissor);
  341. if (memcmp(&setup->scissor.current, scissor, sizeof(*scissor)) != 0) {
  342. setup->scissor.current = *scissor; /* struct copy */
  343. setup->dirty |= LP_SETUP_NEW_SCISSOR;
  344. }
  345. }
  346. void
  347. lp_setup_set_flatshade_first( struct setup_context *setup,
  348. boolean flatshade_first )
  349. {
  350. setup->flatshade_first = flatshade_first;
  351. }
  352. void
  353. lp_setup_set_vertex_info( struct setup_context *setup,
  354. struct vertex_info *vertex_info )
  355. {
  356. /* XXX: just silently holding onto the pointer:
  357. */
  358. setup->vertex_info = vertex_info;
  359. }
  360. /**
  361. * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
  362. */
  363. void
  364. lp_setup_set_fragment_sampler_views(struct setup_context *setup,
  365. unsigned num,
  366. struct pipe_sampler_view **views)
  367. {
  368. unsigned i;
  369. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  370. assert(num <= PIPE_MAX_SAMPLERS);
  371. for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
  372. struct pipe_sampler_view *view = i < num ? views[i] : NULL;
  373. if(view) {
  374. struct pipe_texture *tex = view->texture;
  375. struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
  376. struct lp_jit_texture *jit_tex;
  377. jit_tex = &setup->fs.current.jit_context.textures[i];
  378. jit_tex->width = tex->width0;
  379. jit_tex->height = tex->height0;
  380. jit_tex->stride = lp_tex->stride[0];
  381. if(!lp_tex->dt) {
  382. jit_tex->data = lp_tex->data;
  383. }
  384. else {
  385. /*
  386. * XXX: Where should this be unmapped?
  387. */
  388. struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
  389. struct llvmpipe_winsys *winsys = screen->winsys;
  390. jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
  391. PIPE_BUFFER_USAGE_CPU_READ);
  392. assert(jit_tex->data);
  393. }
  394. /* the scene references this texture */
  395. {
  396. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  397. lp_scene_texture_reference(scene, tex);
  398. }
  399. }
  400. }
  401. setup->dirty |= LP_SETUP_NEW_FS;
  402. }
  403. /**
  404. * Is the given texture referenced by any scene?
  405. * Note: we have to check all scenes including any scenes currently
  406. * being rendered and the current scene being built.
  407. */
  408. unsigned
  409. lp_setup_is_texture_referenced( const struct setup_context *setup,
  410. const struct pipe_texture *texture )
  411. {
  412. unsigned i;
  413. /* check the render targets */
  414. for (i = 0; i < setup->fb.nr_cbufs; i++) {
  415. if (setup->fb.cbufs[i]->texture == texture)
  416. return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
  417. }
  418. if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) {
  419. return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
  420. }
  421. /* check textures referenced by the scene */
  422. for (i = 0; i < Elements(setup->scenes); i++) {
  423. if (lp_scene_is_texture_referenced(setup->scenes[i], texture)) {
  424. return PIPE_REFERENCED_FOR_READ;
  425. }
  426. }
  427. return PIPE_UNREFERENCED;
  428. }
  429. /**
  430. * Called by vbuf code when we're about to draw something.
  431. */
  432. void
  433. lp_setup_update_state( struct setup_context *setup )
  434. {
  435. struct lp_scene *scene = lp_setup_get_current_scene(setup);
  436. LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
  437. assert(setup->fs.current.jit_function);
  438. if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
  439. uint8_t *stored;
  440. unsigned i, j;
  441. stored = lp_scene_alloc_aligned(scene, 4 * 16, 16);
  442. /* smear each blend color component across 16 ubyte elements */
  443. for (i = 0; i < 4; ++i) {
  444. uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]);
  445. for (j = 0; j < 16; ++j)
  446. stored[i*16 + j] = c;
  447. }
  448. setup->blend_color.stored = stored;
  449. setup->fs.current.jit_context.blend_color = setup->blend_color.stored;
  450. setup->dirty |= LP_SETUP_NEW_FS;
  451. }
  452. if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
  453. float *stored;
  454. stored = lp_scene_alloc_aligned(scene, 4 * sizeof(int32_t), 16);
  455. stored[0] = (float) setup->scissor.current.minx;
  456. stored[1] = (float) setup->scissor.current.miny;
  457. stored[2] = (float) setup->scissor.current.maxx;
  458. stored[3] = (float) setup->scissor.current.maxy;
  459. setup->scissor.stored = stored;
  460. setup->fs.current.jit_context.scissor_xmin = stored[0];
  461. setup->fs.current.jit_context.scissor_ymin = stored[1];
  462. setup->fs.current.jit_context.scissor_xmax = stored[2];
  463. setup->fs.current.jit_context.scissor_ymax = stored[3];
  464. setup->dirty |= LP_SETUP_NEW_FS;
  465. }
  466. if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {
  467. struct pipe_buffer *buffer = setup->constants.current;
  468. if(buffer) {
  469. unsigned current_size = buffer->size;
  470. const void *current_data = llvmpipe_buffer(buffer)->data;
  471. /* TODO: copy only the actually used constants? */
  472. if(setup->constants.stored_size != current_size ||
  473. !setup->constants.stored_data ||
  474. memcmp(setup->constants.stored_data,
  475. current_data,
  476. current_size) != 0) {
  477. void *stored;
  478. stored = lp_scene_alloc(scene, current_size);
  479. if(stored) {
  480. memcpy(stored,
  481. current_data,
  482. current_size);
  483. setup->constants.stored_size = current_size;
  484. setup->constants.stored_data = stored;
  485. }
  486. }
  487. }
  488. else {
  489. setup->constants.stored_size = 0;
  490. setup->constants.stored_data = NULL;
  491. }
  492. setup->fs.current.jit_context.constants = setup->constants.stored_data;
  493. setup->dirty |= LP_SETUP_NEW_FS;
  494. }
  495. if(setup->dirty & LP_SETUP_NEW_FS) {
  496. if(!setup->fs.stored ||
  497. memcmp(setup->fs.stored,
  498. &setup->fs.current,
  499. sizeof setup->fs.current) != 0) {
  500. /* The fs state that's been stored in the scene is different from
  501. * the new, current state. So allocate a new lp_rast_state object
  502. * and append it to the bin's setup data buffer.
  503. */
  504. struct lp_rast_state *stored =
  505. (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
  506. if(stored) {
  507. memcpy(stored,
  508. &setup->fs.current,
  509. sizeof setup->fs.current);
  510. setup->fs.stored = stored;
  511. /* put the state-set command into all bins */
  512. lp_scene_bin_state_command( scene,
  513. lp_rast_set_state,
  514. lp_rast_arg_state(setup->fs.stored) );
  515. }
  516. }
  517. }
  518. setup->dirty = 0;
  519. assert(setup->fs.stored);
  520. }
  521. /* Only caller is lp_setup_vbuf_destroy()
  522. */
  523. void
  524. lp_setup_destroy( struct setup_context *setup )
  525. {
  526. reset_context( setup );
  527. pipe_buffer_reference(&setup->constants.current, NULL);
  528. /* free the scenes in the 'empty' queue */
  529. while (1) {
  530. struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes, FALSE);
  531. if (!scene)
  532. break;
  533. lp_scene_destroy(scene);
  534. }
  535. lp_rast_destroy( setup->rast );
  536. FREE( setup );
  537. }
  538. /**
  539. * Create a new primitive tiling engine. Plug it into the backend of
  540. * the draw module. Currently also creates a rasterizer to use with
  541. * it.
  542. */
  543. struct setup_context *
  544. lp_setup_create( struct pipe_screen *screen,
  545. struct draw_context *draw )
  546. {
  547. unsigned i;
  548. struct setup_context *setup = CALLOC_STRUCT(setup_context);
  549. if (!setup)
  550. return NULL;
  551. lp_setup_init_vbuf(setup);
  552. setup->empty_scenes = lp_scene_queue_create();
  553. if (!setup->empty_scenes)
  554. goto fail;
  555. setup->rast = lp_rast_create( screen, setup->empty_scenes );
  556. if (!setup->rast)
  557. goto fail;
  558. setup->vbuf = draw_vbuf_stage(draw, &setup->base);
  559. if (!setup->vbuf)
  560. goto fail;
  561. draw_set_rasterize_stage(draw, setup->vbuf);
  562. draw_set_render(draw, &setup->base);
  563. /* create some empty scenes */
  564. for (i = 0; i < MAX_SCENES; i++) {
  565. setup->scenes[i] = lp_scene_create();
  566. lp_scene_enqueue(setup->empty_scenes, setup->scenes[i]);
  567. }
  568. setup->triangle = first_triangle;
  569. setup->line = first_line;
  570. setup->point = first_point;
  571. setup->dirty = ~0;
  572. return setup;
  573. fail:
  574. if (setup->rast)
  575. lp_rast_destroy( setup->rast );
  576. if (setup->vbuf)
  577. ;
  578. if (setup->empty_scenes)
  579. lp_scene_queue_destroy(setup->empty_scenes);
  580. FREE(setup);
  581. return NULL;
  582. }