/** * \param fence if non-null, returns pointer to a fence which can be waited on */ void llvmpipe_flush( struct pipe_context *pipe, struct pipe_fence_handle **fence, const char *reason) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); draw_flush(llvmpipe->draw); /* ask the setup module to flush */ lp_setup_flush(llvmpipe->setup, fence, reason); /* Enable to dump BMPs of the color/depth buffers each frame */ if (0) { static unsigned frame_no = 1; char filename[256]; unsigned i; for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[i]); } if (0) { util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); } ++frame_no; } }
/** * Put an EndQuery command into all bins. */ void lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) { set_scene_state(setup, SETUP_ACTIVE, "end_query"); if (pq->type != PIPE_QUERY_TIMESTAMP) { assert(setup->active_query[pq->type] == pq); setup->active_query[pq->type] = NULL; } /* Setup will automatically re-issue any query which carried over a * scene boundary, and the rasterizer automatically "ends" queries * which are active at the end of a scene, so there is no need to * retry this commands on failure. */ if (setup->scene) { /* pq->fence should be the fence of the *last* scene which * contributed to the query result. */ lp_fence_reference(&pq->fence, setup->scene->fence); if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_END_QUERY, lp_rast_arg_query(pq))) { lp_setup_flush(setup, NULL, __FUNCTION__); } } else { lp_fence_reference(&pq->fence, setup->last_fence); } }
void lp_setup_clear( struct lp_setup_context *setup, const union pipe_color_union *color, double depth, unsigned stencil, unsigned flags ) { unsigned i; /* * Note any of these (max 9) clears could fail (but at most there should * be just one failure!). This avoids doing the previous succeeded * clears again (we still clear tiles twice if a clear command succeeded * partially for one buffer). */ if (flags & PIPE_CLEAR_DEPTHSTENCIL) { unsigned flagszs = flags & PIPE_CLEAR_DEPTHSTENCIL; if (!lp_setup_try_clear_zs(setup, depth, stencil, flagszs)) { lp_setup_flush(setup, NULL, __FUNCTION__); if (!lp_setup_try_clear_zs(setup, depth, stencil, flagszs)) assert(0); } } if (flags & PIPE_CLEAR_COLOR) { assert(PIPE_CLEAR_COLOR0 == (1 << 2)); for (i = 0; i < setup->fb.nr_cbufs; i++) { if ((flags & (1 << (2 + i))) && setup->fb.cbufs[i]) { if (!lp_setup_try_clear_color_buffer(setup, color, i)) { lp_setup_flush(setup, NULL, __FUNCTION__); if (!lp_setup_try_clear_color_buffer(setup, color, i)) assert(0); } } } } }
void lp_setup_clear( struct lp_setup_context *setup, const float *color, double depth, unsigned stencil, unsigned flags ) { if (!lp_setup_try_clear( setup, color, depth, stencil, flags )) { lp_setup_flush(setup, 0, NULL, __FUNCTION__); if (!lp_setup_try_clear( setup, color, depth, stencil, flags )) assert(0); } }
void llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); struct lp_fragment_shader *shader = fs; struct lp_fragment_shader_variant *variant; assert(fs != llvmpipe->fs); (void) llvmpipe; /* * XXX: we need to flush the context until we have some sort of reference * counting in fragment shaders as they may still be binned */ draw_flush(llvmpipe->draw); lp_setup_flush(llvmpipe->setup, 0); variant = shader->variants; while(variant) { struct lp_fragment_shader_variant *next = variant->next; unsigned i; for (i = 0; i < Elements(variant->function); i++) { if (variant->function[i]) { if (variant->jit_function[i]) LLVMFreeMachineCodeForFunction(screen->engine, variant->function[i]); LLVMDeleteFunction(variant->function[i]); } } FREE(variant); variant = next; } FREE((void *) shader->base.tokens); FREE(shader); }