/** * Called via ctx->Driver.BeginConditionalRender() */ static void st_BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q, GLenum mode) { struct st_query_object *stq = st_query_object(q); struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; uint m; switch (mode) { case GL_QUERY_WAIT: m = PIPE_RENDER_COND_WAIT; break; case GL_QUERY_NO_WAIT: m = PIPE_RENDER_COND_NO_WAIT; break; case GL_QUERY_BY_REGION_WAIT: m = PIPE_RENDER_COND_BY_REGION_WAIT; break; case GL_QUERY_BY_REGION_NO_WAIT: m = PIPE_RENDER_COND_BY_REGION_NO_WAIT; break; default: assert(0 && "bad mode in st_BeginConditionalRender"); m = PIPE_RENDER_COND_WAIT; } st->render_condition = stq->pq; st->condition_mode = m; pipe->render_condition(pipe, stq->pq, m); }
static void st_CheckQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); assert(!q->Ready); /* we should not get called if Ready is TRUE */ q->Ready = get_query_result(pipe, stq, FALSE); }
static void st_EndQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; struct st_query_object *stq = st_query_object(q); pipe->end_query(pipe, stq->pq); }
static void st_CheckQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; struct st_query_object *stq = st_query_object(q); assert(!q->Ready); /* we should not get called if Ready is TRUE */ q->Ready = pipe->get_query_result(pipe, stq->pq, FALSE, &q->Result); }
static void st_DeleteQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); free_queries(pipe, stq); free(stq); }
static void st_DeleteQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); if (stq->pq) { pipe->destroy_query(pipe, stq->pq); stq->pq = NULL; } free(stq); }
static void st_DeleteQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; struct st_query_object *stq = st_query_object(q); if (stq->pq) { pipe->destroy_query(pipe, stq->pq); stq->pq = NULL; } _mesa_free(stq); }
static void st_CheckQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; struct st_query_object *stq = st_query_object(q); if (!q->Ready) { q->Ready = pipe->get_query_result(pipe, stq->pq, FALSE, &q->Result); } }
static void st_EndQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); st_flush_bitmap_cache(st_context(ctx)); if (q->Target == GL_TIMESTAMP && !stq->pq) { stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP); stq->type = PIPE_QUERY_TIMESTAMP; } pipe->end_query(pipe, stq->pq); }
static void st_WaitQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); /* this function should only be called if we don't have a ready result */ assert(!stq->base.Ready); while (!stq->base.Ready && !get_query_result(pipe, stq, TRUE)) { /* nothing */ } q->Ready = GL_TRUE; }
static void st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); unsigned type; st_flush_bitmap_cache(st_context(ctx)); /* convert GL query type to Gallium query type */ switch (q->Target) { case GL_ANY_SAMPLES_PASSED: /* fall-through */ case GL_SAMPLES_PASSED_ARB: type = PIPE_QUERY_OCCLUSION_COUNTER; break; case GL_PRIMITIVES_GENERATED: type = PIPE_QUERY_PRIMITIVES_GENERATED; break; case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: type = PIPE_QUERY_PRIMITIVES_EMITTED; break; case GL_TIME_ELAPSED_EXT: type = PIPE_QUERY_TIME_ELAPSED; break; default: assert(0 && "unexpected query target in st_BeginQuery()"); return; } if (stq->pq && stq->type != type) { /* free old query of different type */ pipe->destroy_query(pipe, stq->pq); stq->pq = NULL; stq->type = PIPE_QUERY_TYPES; /* an invalid value */ } if (!stq->pq) { stq->pq = pipe->create_query(pipe, type); stq->type = type; } assert(stq->type == type); pipe->begin_query(pipe, stq->pq); }
static void st_BeginQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; struct st_query_object *stq = st_query_object(q); switch (q->Target) { case GL_SAMPLES_PASSED_ARB: if (!stq->pq) stq->pq = pipe->create_query( pipe, PIPE_QUERY_OCCLUSION_COUNTER ); break; default: assert(0); return; } pipe->begin_query(pipe, stq->pq); }
static void st_EndQuery(struct gl_context *ctx, struct gl_query_object *q) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); bool ret = false; st_flush_bitmap_cache(st_context(ctx)); if ((q->Target == GL_TIMESTAMP || q->Target == GL_TIME_ELAPSED) && !stq->pq) { stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP, 0); stq->type = PIPE_QUERY_TIMESTAMP; } if (stq->pq) ret = pipe->end_query(pipe, stq->pq); if (!ret) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndQuery"); return; } }
static void st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct st_query_object *stq = st_query_object(q); unsigned type; st_flush_bitmap_cache(st_context(ctx)); /* convert GL query type to Gallium query type */ switch (q->Target) { case GL_ANY_SAMPLES_PASSED: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: /* fall-through */ case GL_SAMPLES_PASSED_ARB: type = PIPE_QUERY_OCCLUSION_COUNTER; break; case GL_PRIMITIVES_GENERATED: type = PIPE_QUERY_PRIMITIVES_GENERATED; break; case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: type = PIPE_QUERY_PRIMITIVES_EMITTED; break; case GL_TIME_ELAPSED: if (st->has_time_elapsed) type = PIPE_QUERY_TIME_ELAPSED; else type = PIPE_QUERY_TIMESTAMP; break; default: assert(0 && "unexpected query target in st_BeginQuery()"); return; } if (stq->type != type) { /* free old query of different type */ if (stq->pq) { pipe->destroy_query(pipe, stq->pq); stq->pq = NULL; } if (stq->pq_begin) { pipe->destroy_query(pipe, stq->pq_begin); stq->pq_begin = NULL; } stq->type = PIPE_QUERY_TYPES; /* an invalid value */ } if (q->Target == GL_TIME_ELAPSED && type == PIPE_QUERY_TIMESTAMP) { /* Determine time elapsed by emitting two timestamp queries. */ if (!stq->pq_begin) { stq->pq_begin = pipe->create_query(pipe, type); stq->type = type; } pipe->end_query(pipe, stq->pq_begin); } else { if (!stq->pq) { stq->pq = pipe->create_query(pipe, type); stq->type = type; } pipe->begin_query(pipe, stq->pq); } assert(stq->type == type); }
static void st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct st_query_object *stq = st_query_object(q); unsigned type; bool ret = false; st_flush_bitmap_cache(st_context(ctx)); /* convert GL query type to Gallium query type */ switch (q->Target) { case GL_ANY_SAMPLES_PASSED: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: type = PIPE_QUERY_OCCLUSION_PREDICATE; break; case GL_SAMPLES_PASSED_ARB: type = PIPE_QUERY_OCCLUSION_COUNTER; break; case GL_PRIMITIVES_GENERATED: type = PIPE_QUERY_PRIMITIVES_GENERATED; break; case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: type = PIPE_QUERY_PRIMITIVES_EMITTED; break; case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB: type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; break; case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB: type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; break; case GL_TIME_ELAPSED: if (st->has_time_elapsed) type = PIPE_QUERY_TIME_ELAPSED; else type = PIPE_QUERY_TIMESTAMP; break; case GL_VERTICES_SUBMITTED_ARB: case GL_PRIMITIVES_SUBMITTED_ARB: case GL_VERTEX_SHADER_INVOCATIONS_ARB: case GL_TESS_CONTROL_SHADER_PATCHES_ARB: case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: case GL_GEOMETRY_SHADER_INVOCATIONS: case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: case GL_COMPUTE_SHADER_INVOCATIONS_ARB: case GL_CLIPPING_INPUT_PRIMITIVES_ARB: case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: type = PIPE_QUERY_PIPELINE_STATISTICS; break; default: assert(0 && "unexpected query target in st_BeginQuery()"); return; } if (stq->type != type) { /* free old query of different type */ free_queries(pipe, stq); stq->type = PIPE_QUERY_TYPES; /* an invalid value */ } if (q->Target == GL_TIME_ELAPSED && type == PIPE_QUERY_TIMESTAMP) { /* Determine time elapsed by emitting two timestamp queries. */ if (!stq->pq_begin) { stq->pq_begin = pipe->create_query(pipe, type, 0); stq->type = type; } if (stq->pq_begin) ret = pipe->end_query(pipe, stq->pq_begin); } else { if (!stq->pq) { stq->pq = pipe->create_query(pipe, type, q->Stream); stq->type = type; } if (stq->pq) ret = pipe->begin_query(pipe, stq->pq); } if (!ret) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery"); free_queries(pipe, stq); q->Active = GL_FALSE; return; } assert(stq->type == type); }
static void st_StoreQueryResult(struct gl_context *ctx, struct gl_query_object *q, struct gl_buffer_object *buf, intptr_t offset, GLenum pname, GLenum ptype) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_query_object *stq = st_query_object(q); struct st_buffer_object *stObj = st_buffer_object(buf); boolean wait = pname == GL_QUERY_RESULT; enum pipe_query_value_type result_type; int index; /* GL_QUERY_TARGET is a bit of an extension since it has nothing to * do with the GPU end of the query. Write it in "by hand". */ if (pname == GL_QUERY_TARGET) { /* Assume that the data must be LE. The endianness situation wrt CPU and * GPU is incredibly confusing, but the vast majority of GPUs are * LE. When a BE one comes along, this needs some form of resolution. */ unsigned data[2] = { CPU_TO_LE32(q->Target), 0 }; pipe_buffer_write(pipe, stObj->buffer, offset, (ptype == GL_INT64_ARB || ptype == GL_UNSIGNED_INT64_ARB) ? 8 : 4, data); return; } switch (ptype) { case GL_INT: result_type = PIPE_QUERY_TYPE_I32; break; case GL_UNSIGNED_INT: result_type = PIPE_QUERY_TYPE_U32; break; case GL_INT64_ARB: result_type = PIPE_QUERY_TYPE_I64; break; case GL_UNSIGNED_INT64_ARB: result_type = PIPE_QUERY_TYPE_U64; break; default: unreachable("Unexpected result type"); } if (pname == GL_QUERY_RESULT_AVAILABLE) { index = -1; } else if (stq->type == PIPE_QUERY_PIPELINE_STATISTICS) { switch (q->Target) { case GL_VERTICES_SUBMITTED_ARB: index = 0; break; case GL_PRIMITIVES_SUBMITTED_ARB: index = 1; break; case GL_VERTEX_SHADER_INVOCATIONS_ARB: index = 2; break; case GL_GEOMETRY_SHADER_INVOCATIONS: index = 3; break; case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: index = 4; break; case GL_CLIPPING_INPUT_PRIMITIVES_ARB: index = 5; break; case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: index = 6; break; case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: index = 7; break; case GL_TESS_CONTROL_SHADER_PATCHES_ARB: index = 8; break; case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: index = 9; break; case GL_COMPUTE_SHADER_INVOCATIONS_ARB: index = 10; break; default: unreachable("Unexpected target"); } } else { index = 0; } pipe->get_query_result_resource(pipe, stq->pq, wait, result_type, index, stObj->buffer, offset); }