Преглед изворни кода

llvmpipe: add support for nested / overlapping queries

OpenGL doesn't support this but d3d10 does.
It is a bit of a pain as it is necessary to keep track of queries
still active at the end of a scene, which is also why I cheat a bit
and limit the amount of simultaneously active queries to (arbitrary)
16 (simplifies things because don't have to deal with a real list
that way). I can't think of a reason why you'd really want large
numbers of overlapping/nested queries so it is hopefully fine.
(This only affects queries which need to be binned.)

v2: don't copy remainder of array when deleting an entry simply replace
the deleted entry with the last one (order doesn't matter).

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
tags/mesa-9.2-rc1
Roland Scheidegger пре 12 година
родитељ
комит
2e4da1f594

+ 2
- 2
src/gallium/drivers/llvmpipe/lp_context.h Прегледај датотеку

struct pipe_query_data_pipeline_statistics pipeline_statistics; struct pipe_query_data_pipeline_statistics pipeline_statistics;
unsigned active_statistics_queries; unsigned active_statistics_queries;


unsigned dirty; /**< Mask of LP_NEW_x flags */
unsigned active_occlusion_queries;


unsigned active_occlusion_query;
unsigned dirty; /**< Mask of LP_NEW_x flags */


/** Mapped vertex buffers */ /** Mapped vertex buffers */
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];

+ 3
- 3
src/gallium/drivers/llvmpipe/lp_query.c Прегледај датотеку

break; break;
case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE: case PIPE_QUERY_OCCLUSION_PREDICATE:
llvmpipe->active_occlusion_query++;
llvmpipe->active_occlusion_queries++;
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
break; break;
default: default:
break; break;
case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE: case PIPE_QUERY_OCCLUSION_PREDICATE:
assert(llvmpipe->active_occlusion_query);
llvmpipe->active_occlusion_query--;
assert(llvmpipe->active_occlusion_queries);
llvmpipe->active_occlusion_queries--;
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
break; break;
default: default:

+ 2
- 0
src/gallium/drivers/llvmpipe/lp_rast.h Прегледај датотеку

/* Rasterizer output size going to jit fs, width/height */ /* Rasterizer output size going to jit fs, width/height */
#define LP_RASTER_BLOCK_SIZE 4 #define LP_RASTER_BLOCK_SIZE 4


#define LP_MAX_ACTIVE_BINNED_QUERIES 16



struct lp_rasterizer_task; struct lp_rasterizer_task;



+ 1
- 1
src/gallium/drivers/llvmpipe/lp_scene.h Прегледај датотеку

struct lp_fence *fence; struct lp_fence *fence;


/* The queries still active at end of scene */ /* The queries still active at end of scene */
struct llvmpipe_query *active_queries[3];
struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
unsigned num_active_queries; unsigned num_active_queries;


/* Framebuffer mappings - valid only between begin_rasterization() /* Framebuffer mappings - valid only between begin_rasterization()

+ 28
- 26
src/gallium/drivers/llvmpipe/lp_setup.c Прегледај датотеку

struct lp_scene *scene = setup->scene; struct lp_scene *scene = setup->scene;
struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen); struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen);


scene->num_active_queries = 0;
if (setup->active_query[PIPE_QUERY_OCCLUSION_COUNTER]) {
scene->active_queries[scene->num_active_queries] =
setup->active_query[PIPE_QUERY_OCCLUSION_COUNTER];
scene->num_active_queries++;
}
if (setup->active_query[PIPE_QUERY_OCCLUSION_PREDICATE]) {
scene->active_queries[scene->num_active_queries] =
setup->active_query[PIPE_QUERY_OCCLUSION_PREDICATE];
scene->num_active_queries++;
}
if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
scene->active_queries[scene->num_active_queries] =
setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS];
scene->num_active_queries++;
}
scene->num_active_queries = setup->active_binned_queries;
memcpy(scene->active_queries, setup->active_queries,
scene->num_active_queries * sizeof(scene->active_queries[0]));


lp_scene_end_binning(scene); lp_scene_end_binning(scene);


return; return;


/* init the query to its beginning state */ /* init the query to its beginning state */
assert(setup->active_query[pq->type] == NULL);

setup->active_query[pq->type] = pq;
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); assert(setup->scene);
if (setup->scene) { if (setup->scene) {
{ {
set_scene_state(setup, SETUP_ACTIVE, "end_query"); set_scene_state(setup, SETUP_ACTIVE, "end_query");


if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
assert(setup->active_query[pq->type] == pq);
}

assert(setup->scene); assert(setup->scene);
if (setup->scene) { if (setup->scene) {
/* pq->fence should be the fence of the *last* scene which /* pq->fence should be the fence of the *last* scene which
/* Need to do this now not earlier since it still needs to be marked as /* Need to do this now not earlier since it still needs to be marked as
* active when binning it would cause a flush. * active when binning it would cause a flush.
*/ */
setup->active_query[pq->type] = NULL;
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;
}
} }





+ 2
- 1
src/gallium/drivers/llvmpipe/lp_setup_context.h Прегледај датотеку

struct lp_scene *scene; /**< current scene being built */ struct lp_scene *scene; /**< current scene being built */


struct lp_fence *last_fence; struct lp_fence *last_fence;
struct llvmpipe_query *active_query[PIPE_QUERY_TYPES];
struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
unsigned active_binned_queries;


boolean subdivide_large_triangles; boolean subdivide_large_triangles;
boolean flatshade_first; boolean flatshade_first;

+ 2
- 2
src/gallium/drivers/llvmpipe/lp_setup_line.c Прегледај датотеку

const float (*v1)[4], const float (*v1)[4],
const float (*v2)[4]) const float (*v2)[4])
{ {
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
struct lp_scene *scene = setup->scene; struct lp_scene *scene = setup->scene;
const struct lp_setup_variant_key *key = &setup->setup.variant->key; const struct lp_setup_variant_key *key = &setup->setup.variant->key;
struct lp_rast_triangle *line; struct lp_rast_triangle *line;


LP_COUNT(nr_tris); LP_COUNT(nr_tris);


if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
if (lp_context->active_statistics_queries) {
lp_context->pipeline_statistics.c_primitives++; lp_context->pipeline_statistics.c_primitives++;
} }



+ 2
- 2
src/gallium/drivers/llvmpipe/lp_setup_point.c Прегледај датотеку

try_setup_point( struct lp_setup_context *setup, try_setup_point( struct lp_setup_context *setup,
const float (*v0)[4] ) const float (*v0)[4] )
{ {
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
/* x/y positions in fixed point */ /* x/y positions in fixed point */
const struct lp_setup_variant_key *key = &setup->setup.variant->key; const struct lp_setup_variant_key *key = &setup->setup.variant->key;
const int sizeAttr = setup->psize; const int sizeAttr = setup->psize;


LP_COUNT(nr_tris); LP_COUNT(nr_tris);


if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
if (lp_context->active_statistics_queries) {
lp_context->pipeline_statistics.c_primitives++; lp_context->pipeline_statistics.c_primitives++;
} }



+ 2
- 2
src/gallium/drivers/llvmpipe/lp_setup_tri.c Прегледај датотеку

const float (*v2)[4], const float (*v2)[4],
boolean frontfacing ) boolean frontfacing )
{ {
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
struct lp_scene *scene = setup->scene; struct lp_scene *scene = setup->scene;
const struct lp_setup_variant_key *key = &setup->setup.variant->key; const struct lp_setup_variant_key *key = &setup->setup.variant->key;
struct lp_rast_triangle *tri; struct lp_rast_triangle *tri;


LP_COUNT(nr_tris); LP_COUNT(nr_tris);


if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
if (lp_context->active_statistics_queries) {
lp_context->pipeline_statistics.c_primitives++; lp_context->pipeline_statistics.c_primitives++;
} }



+ 1
- 1
src/gallium/drivers/llvmpipe/lp_state_fs.c Прегледај датотеку

/* alpha.ref_value is passed in jit_context */ /* alpha.ref_value is passed in jit_context */


key->flatshade = lp->rasterizer->flatshade; key->flatshade = lp->rasterizer->flatshade;
if (lp->active_occlusion_query) {
if (lp->active_occlusion_queries) {
key->occlusion_count = TRUE; key->occlusion_count = TRUE;
} }



Loading…
Откажи
Сачувај