+ /* Prefer the per-screen function */
+ if (screen->get_timestamp) {
+ return screen->get_timestamp(screen);
+ }
+ else {
+ /* Fall back to the per-context function */
+ assert(pipe->get_timestamp);
+ return pipe->get_timestamp(pipe);
+ }
+}
+
+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 = PIPE_STAT_QUERY_IA_VERTICES;
+ break;
+ case GL_PRIMITIVES_SUBMITTED_ARB:
+ index = PIPE_STAT_QUERY_IA_PRIMITIVES;
+ break;
+ case GL_VERTEX_SHADER_INVOCATIONS_ARB:
+ index = PIPE_STAT_QUERY_VS_INVOCATIONS;
+ break;
+ case GL_GEOMETRY_SHADER_INVOCATIONS:
+ index = PIPE_STAT_QUERY_GS_INVOCATIONS;
+ break;
+ case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
+ index = PIPE_STAT_QUERY_GS_PRIMITIVES;
+ break;
+ case GL_CLIPPING_INPUT_PRIMITIVES_ARB:
+ index = PIPE_STAT_QUERY_C_INVOCATIONS;
+ break;
+ case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB:
+ index = PIPE_STAT_QUERY_C_PRIMITIVES;
+ break;
+ case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
+ index = PIPE_STAT_QUERY_PS_INVOCATIONS;
+ break;
+ case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
+ index = PIPE_STAT_QUERY_HS_INVOCATIONS;
+ break;
+ case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
+ index = PIPE_STAT_QUERY_DS_INVOCATIONS;
+ break;
+ case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
+ index = PIPE_STAT_QUERY_CS_INVOCATIONS;
+ break;
+ default:
+ unreachable("Unexpected target");
+ }
+ } else {
+ index = 0;
+ }
+
+ pipe->get_query_result_resource(pipe, stq->pq, wait, result_type, index,
+ stObj->buffer, offset);
+}