summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/os/os_time.c15
-rw-r--r--src/gallium/auxiliary/os/os_time.h7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c51
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c53
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c33
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c2
13 files changed, 147 insertions, 43 deletions
diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c
index 3e9d50a598a..40551252b25 100644
--- a/src/gallium/auxiliary/os/os_time.c
+++ b/src/gallium/auxiliary/os/os_time.c
@@ -36,6 +36,7 @@
#include "pipe/p_config.h"
#if defined(PIPE_OS_UNIX)
+# include <time.h> /* timeval */
# include <sys/time.h> /* timeval */
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
# include <windows.h>
@@ -68,6 +69,20 @@ os_time_get(void)
}
+uint64_t
+os_time_get_nano(void)
+{
+#if defined(PIPE_OS_UNIX)
+ struct timespec tv;
+ clock_gettime(CLOCK_REALTIME, &tv);
+ return tv.tv_nsec + tv.tv_sec * 1000000000LL;
+
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+ return os_time_get() * 1000;
+#endif
+}
+
+
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
void
diff --git a/src/gallium/auxiliary/os/os_time.h b/src/gallium/auxiliary/os/os_time.h
index 7e0f67a76b0..54101a1f546 100644
--- a/src/gallium/auxiliary/os/os_time.h
+++ b/src/gallium/auxiliary/os/os_time.h
@@ -58,6 +58,13 @@ os_time_get(void);
/*
+ * Get the current time in nanoseconds from an unknown base.
+ */
+uint64_t
+os_time_get_nano(void);
+
+
+/*
* Sleep.
*/
#if defined(PIPE_OS_UNIX)
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index fcdc0f82b12..fe6fa3f9390 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -96,7 +96,7 @@ struct llvmpipe_context {
unsigned dirty; /**< Mask of LP_NEW_x flags */
- int active_query_count;
+ unsigned active_occlusion_query;
/** Mapped vertex buffers */
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
index 20c0a1e0bcb..e3021972566 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.c
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -33,6 +33,7 @@
#include "draw/draw_context.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
+#include "os/os_time.h"
#include "lp_context.h"
#include "lp_flush.h"
#include "lp_fence.h"
@@ -51,10 +52,14 @@ llvmpipe_create_query(struct pipe_context *pipe,
{
struct llvmpipe_query *pq;
- assert(type == PIPE_QUERY_OCCLUSION_COUNTER);
+ assert(type < PIPE_QUERY_TYPES);
pq = CALLOC_STRUCT( llvmpipe_query );
+ if (pq) {
+ pq->type = type;
+ }
+
return (struct pipe_query *) pq;
}
@@ -100,7 +105,7 @@ llvmpipe_get_query_result(struct pipe_context *pipe,
if (!lp_fence_signalled(pq->fence)) {
if (!lp_fence_issued(pq->fence))
llvmpipe_flush(pipe, NULL, __FUNCTION__);
-
+
if (!wait)
return FALSE;
@@ -110,8 +115,32 @@ llvmpipe_get_query_result(struct pipe_context *pipe,
/* Sum the results from each of the threads:
*/
*result = 0;
- for (i = 0; i < LP_MAX_THREADS; i++) {
- *result += pq->count[i];
+
+ switch (pq->type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ for (i = 0; i < LP_MAX_THREADS; i++) {
+ *result += pq->count[i];
+ }
+ break;
+ case PIPE_QUERY_TIME_ELAPSED:
+ for (i = 0; i < LP_MAX_THREADS; i++) {
+ if (pq->count[i] > *result) {
+ *result = pq->count[i];
+ }
+ }
+ break;
+ case PIPE_QUERY_TIMESTAMP:
+ for (i = 0; i < LP_MAX_THREADS; i++) {
+ if (pq->count[i] > *result) {
+ *result = pq->count[i];
+ }
+ if (*result == 0)
+ *result = os_time_get_nano();
+ }
+ break;
+ default:
+ assert(0);
+ break;
}
return TRUE;
@@ -136,8 +165,10 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
memset(pq->count, 0, sizeof(pq->count));
lp_setup_begin_query(llvmpipe->setup, pq);
- llvmpipe->active_query_count++;
- llvmpipe->dirty |= LP_NEW_QUERY;
+ if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
+ llvmpipe->active_occlusion_query = TRUE;
+ llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
+ }
}
@@ -149,9 +180,11 @@ llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
lp_setup_end_query(llvmpipe->setup, pq);
- assert(llvmpipe->active_query_count);
- llvmpipe->active_query_count--;
- llvmpipe->dirty |= LP_NEW_QUERY;
+ if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
+ assert(llvmpipe->active_occlusion_query);
+ llvmpipe->active_occlusion_query = FALSE;
+ llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
+ }
}
boolean
diff --git a/src/gallium/drivers/llvmpipe/lp_query.h b/src/gallium/drivers/llvmpipe/lp_query.h
index ef1bc307037..cacbd9d0b8c 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.h
+++ b/src/gallium/drivers/llvmpipe/lp_query.h
@@ -42,8 +42,9 @@ struct llvmpipe_context;
struct llvmpipe_query {
- uint64_t count[LP_MAX_THREADS]; /**< a counter for each thread */
- struct lp_fence *fence; /* fence from last scene this was binned in */
+ uint64_t count[LP_MAX_THREADS]; /* a counter for each thread */
+ struct lp_fence *fence; /* fence from last scene this was binned in */
+ unsigned type; /* PIPE_QUERY_* */
};
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 5c233c06a15..40a8591cabe 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -32,6 +32,8 @@
#include "util/u_surface.h"
#include "util/u_pack_color.h"
+#include "os/os_time.h"
+
#include "lp_scene_queue.h"
#include "lp_debug.h"
#include "lp_fence.h"
@@ -429,9 +431,21 @@ lp_rast_begin_query(struct lp_rasterizer_task *task,
{
struct llvmpipe_query *pq = arg.query_obj;
- assert(task->query == NULL);
- task->vis_counter = 0;
- task->query = pq;
+ assert(task->query[pq->type] == NULL);
+
+ switch (pq->type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ task->vis_counter = 0;
+ break;
+ case PIPE_QUERY_TIME_ELAPSED:
+ task->query_start = os_time_get_nano();
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ task->query[pq->type] = pq;
}
@@ -444,10 +458,26 @@ static void
lp_rast_end_query(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
- assert(task->query);
- if (task->query) {
- task->query->count[task->thread_index] += task->vis_counter;
- task->query = NULL;
+ struct llvmpipe_query *pq = arg.query_obj;
+ assert(task->query[pq->type] == pq || pq->type == PIPE_QUERY_TIMESTAMP);
+
+ switch (pq->type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ pq->count[task->thread_index] += task->vis_counter;
+ break;
+ case PIPE_QUERY_TIME_ELAPSED:
+ pq->count[task->thread_index] = os_time_get_nano() - task->query_start;
+ break;
+ case PIPE_QUERY_TIMESTAMP:
+ pq->count[task->thread_index] = os_time_get_nano();
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ if (task->query[pq->type] == pq) {
+ task->query[pq->type] = NULL;
}
}
@@ -467,9 +497,12 @@ lp_rast_set_state(struct lp_rasterizer_task *task,
static void
lp_rast_tile_end(struct lp_rasterizer_task *task)
{
- if (task->query) {
- union lp_rast_cmd_arg dummy = {0};
- lp_rast_end_query(task, dummy);
+ 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 */
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index dc9739e9ad0..afcf33382f4 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -96,7 +96,8 @@ struct lp_rasterizer_task
/* occlude counter for visiable pixels */
uint32_t vis_counter;
- struct llvmpipe_query *query;
+ uint64_t query_start;
+ struct llvmpipe_query *query[PIPE_QUERY_TYPES];
pipe_semaphore work_ready;
pipe_semaphore work_done;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 3f207d713af..acbde9da983 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -37,6 +37,7 @@
#include "draw/draw_context.h"
#include "gallivm/lp_bld_type.h"
+#include "os/os_time.h"
#include "lp_texture.h"
#include "lp_fence.h"
#include "lp_jit.h"
@@ -126,7 +127,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_OCCLUSION_QUERY:
return 1;
case PIPE_CAP_TIMER_QUERY:
- return 0;
+ case PIPE_CAP_QUERY_TIMESTAMP:
+ return 1;
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
@@ -210,7 +212,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
return 16;
case PIPE_CAP_START_INSTANCE:
- case PIPE_CAP_QUERY_TIMESTAMP:
case PIPE_CAP_TEXTURE_MULTISAMPLE:
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
case PIPE_CAP_CUBE_MAP_ARRAY:
@@ -446,7 +447,11 @@ llvmpipe_fence_finish(struct pipe_screen *screen,
return TRUE;
}
-
+static uint64_t
+llvmpipe_get_timestamp(struct pipe_screen *_screen)
+{
+ return os_time_get_nano();
+}
/**
* Create a new pipe_screen object
@@ -491,6 +496,8 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
screen->base.fence_signalled = llvmpipe_fence_signalled;
screen->base.fence_finish = llvmpipe_fence_finish;
+ screen->base.get_timestamp = llvmpipe_get_timestamp;
+
llvmpipe_init_screen_resource_funcs(&screen->base);
lp_jit_screen_init(screen);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 84defc65054..1d71a87319e 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -232,12 +232,14 @@ begin_binning( struct lp_setup_context *setup )
}
}
- if (setup->active_query) {
- ok = lp_scene_bin_everywhere( scene,
- LP_RAST_OP_BEGIN_QUERY,
- lp_rast_arg_query(setup->active_query) );
- if (!ok)
- return FALSE;
+ for (i = 0; i < PIPE_QUERY_TYPES; ++i) {
+ if (setup->active_query[i]) {
+ ok = lp_scene_bin_everywhere( scene,
+ LP_RAST_OP_BEGIN_QUERY,
+ lp_rast_arg_query(setup->active_query[i]) );
+ if (!ok)
+ return FALSE;
+ }
}
setup->clear.flags = 0;
@@ -1116,11 +1118,16 @@ 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);
+ assert(setup->active_query[pq->type] == NULL);
set_scene_state(setup, SETUP_ACTIVE, "begin_query");
- setup->active_query = pq;
+ 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,
@@ -1146,12 +1153,12 @@ lp_setup_begin_query(struct lp_setup_context *setup,
void
lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
{
- union lp_rast_cmd_arg dummy = { 0 };
-
set_scene_state(setup, SETUP_ACTIVE, "end_query");
- assert(setup->active_query == pq);
- setup->active_query = NULL;
+ 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
@@ -1166,7 +1173,7 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
if (!lp_scene_bin_everywhere(setup->scene,
LP_RAST_OP_END_QUERY,
- dummy)) {
+ lp_rast_arg_query(pq))) {
lp_setup_flush(setup, NULL, __FUNCTION__);
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 7fdd1e735c4..6c86b4b779a 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -89,7 +89,7 @@ struct lp_setup_context
struct lp_scene *scene; /**< current scene being built */
struct lp_fence *last_fence;
- struct llvmpipe_query *active_query;
+ struct llvmpipe_query *active_query[PIPE_QUERY_TYPES];
boolean flatshade_first;
boolean ccw_is_frontface;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 97ca1727c9b..94a21a0158b 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -51,7 +51,7 @@
#define LP_NEW_SAMPLER_VIEW 0x800
#define LP_NEW_VERTEX 0x1000
#define LP_NEW_VS 0x2000
-#define LP_NEW_QUERY 0x4000
+#define LP_NEW_OCCLUSION_QUERY 0x4000
#define LP_NEW_BLEND_COLOR 0x8000
#define LP_NEW_GS 0x10000
#define LP_NEW_SO 0x20000
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 5bb5a7a0b7e..3b826de80c9 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -152,7 +152,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
LP_NEW_RASTERIZER |
LP_NEW_SAMPLER |
LP_NEW_SAMPLER_VIEW |
- LP_NEW_QUERY))
+ LP_NEW_OCCLUSION_QUERY))
llvmpipe_update_fs( llvmpipe );
if (llvmpipe->dirty & (LP_NEW_FS |
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index dcd11b65c8f..c56ce9ee71c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -2493,7 +2493,7 @@ make_variant_key(struct llvmpipe_context *lp,
/* alpha.ref_value is passed in jit_context */
key->flatshade = lp->rasterizer->flatshade;
- if (lp->active_query_count) {
+ if (lp->active_occlusion_query) {
key->occlusion_count = TRUE;
}