/** * Put a BeginQuery command into all bins. */ void lp_setup_begin_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) { /* init the query to its beginning state */ assert(setup->active_query == NULL); if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(pq))) { lp_setup_flush_and_restart(setup); if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(pq))) { assert(0); return; } } } setup->active_query = pq; }
/** * Put a BeginQuery command into all bins. */ void lp_setup_begin_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) { /* init the query to its beginning state */ assert(setup->active_query[pq->type] == NULL); set_scene_state(setup, SETUP_ACTIVE, "begin_query"); setup->active_query[pq->type] = pq; /* XXX: It is possible that a query is created before the scene * has been created. This means that setup->scene == NULL resulting * in the query not being binned and thus is ignored. */ if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(pq))) { if (!lp_setup_flush_and_restart(setup)) return; if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(pq))) { return; } } } }
/** * 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); } }
/** * Put a BeginQuery command into all bins. */ void lp_setup_begin_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) { set_scene_state(setup, SETUP_ACTIVE, "begin_query"); if (!(pq->type == PIPE_QUERY_OCCLUSION_COUNTER || pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || pq->type == PIPE_QUERY_PIPELINE_STATISTICS)) return; /* init the query to its beginning state */ assert(setup->active_binned_queries < LP_MAX_ACTIVE_BINNED_QUERIES); /* exceeding list size so just ignore the query */ if (setup->active_binned_queries >= LP_MAX_ACTIVE_BINNED_QUERIES) { return; } assert(setup->active_queries[setup->active_binned_queries] == NULL); setup->active_queries[setup->active_binned_queries] = pq; setup->active_binned_queries++; assert(setup->scene); if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(pq))) { if (!lp_setup_flush_and_restart(setup)) return; if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(pq))) { return; } } setup->scene->had_queries |= TRUE; } }
/** * Called when we're done writing to a color tile. */ static void lp_rast_tile_end(struct lp_rasterizer_task *task) { unsigned i; for (i = 0; i < task->scene->num_active_queries; ++i) { lp_rast_end_query(task, lp_rast_arg_query(task->scene->active_queries[i])); } /* debug */ memset(task->color_tiles, 0, sizeof(task->color_tiles)); task->depth_tile = NULL; task->bin = NULL; }
/** * Called when we're done writing to a color tile. */ static void lp_rast_tile_end(struct lp_rasterizer_task *task) { unsigned i; for (i = 0; i < PIPE_QUERY_TYPES; ++i) { if (task->query[i]) { lp_rast_end_query(task, lp_rast_arg_query(task->query[i])); } } /* debug */ memset(task->color_tiles, 0, sizeof(task->color_tiles)); task->depth_tile = NULL; task->bin = NULL; }
/** * 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"); assert(setup->scene); 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 (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || pq->type == PIPE_QUERY_PIPELINE_STATISTICS || pq->type == PIPE_QUERY_TIMESTAMP) { if (pq->type == PIPE_QUERY_TIMESTAMP && !(setup->scene->tiles_x | setup->scene->tiles_y)) { /* * If there's a zero width/height framebuffer, there's no bins and * hence no rast task is ever run. So fill in something here instead. */ pq->end[0] = os_time_get_nano(); } if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_END_QUERY, lp_rast_arg_query(pq))) { if (!lp_setup_flush_and_restart(setup)) goto fail; if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_END_QUERY, lp_rast_arg_query(pq))) { goto fail; } } setup->scene->had_queries |= TRUE; } } else { lp_fence_reference(&pq->fence, setup->last_fence); } fail: /* Need to do this now not earlier since it still needs to be marked as * active when binning it would cause a flush. */ if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || pq->type == PIPE_QUERY_PIPELINE_STATISTICS) { unsigned i; /* remove from active binned query list */ for (i = 0; i < setup->active_binned_queries; i++) { if (setup->active_queries[i] == pq) break; } assert(i < setup->active_binned_queries); if (i == setup->active_binned_queries) return; setup->active_binned_queries--; setup->active_queries[i] = setup->active_queries[setup->active_binned_queries]; setup->active_queries[setup->active_binned_queries] = NULL; } }
static void begin_binning( struct lp_setup_context *setup ) { struct lp_scene *scene = setup->scene; boolean need_zsload = FALSE; boolean ok; unsigned i, j; assert(scene); assert(scene->fence == NULL); /* Always create a fence: */ scene->fence = lp_fence_create(MAX2(1, setup->num_threads)); /* Initialize the bin flags and x/y coords: */ for (i = 0; i < scene->tiles_x; i++) { for (j = 0; j < scene->tiles_y; j++) { scene->tile[i][j].x = i; scene->tile[i][j].y = j; } } ok = try_update_scene_state(setup); assert(ok); if (setup->fb.zsbuf && ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && util_format_is_depth_and_stencil(setup->fb.zsbuf->format)) need_zsload = TRUE; LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__, (setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load", need_zsload ? "clear": "load"); if (setup->fb.nr_cbufs) { if (setup->clear.flags & PIPE_CLEAR_COLOR) { ok = lp_scene_bin_everywhere( scene, LP_RAST_OP_CLEAR_COLOR, setup->clear.color ); assert(ok); } } if (setup->fb.zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) { if (!need_zsload) scene->has_depthstencil_clear = TRUE; ok = lp_scene_bin_everywhere( scene, LP_RAST_OP_CLEAR_ZSTENCIL, lp_rast_arg_clearzs( setup->clear.zsvalue, setup->clear.zsmask)); assert(ok); } } if (setup->active_query) { ok = lp_scene_bin_everywhere( scene, LP_RAST_OP_BEGIN_QUERY, lp_rast_arg_query(setup->active_query) ); assert(ok); } setup->clear.flags = 0; setup->clear.zsmask = 0; setup->clear.zsvalue = 0; LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__); }