aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNiels Ole Salscheider <[email protected]>2013-08-09 11:59:25 +0200
committerTom Stellard <[email protected]>2013-08-26 18:25:17 -0700
commit4a3505d5487fbdab773f5c91edd39e8aea6e90af (patch)
tree4effb7fde5dcb5a93e4781fbd7c36567f697c0ba /src
parent4763a032a0a483702d651c539ecf4566ce3fd68b (diff)
st/clover: Profiling support
Signed-off-by: Niels Ole Salscheider <[email protected]> Acked-by: Francisco Jerez <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/clover/api/event.cpp26
-rw-r--r--src/gallium/state_trackers/clover/core/event.cpp116
-rw-r--r--src/gallium/state_trackers/clover/core/event.hpp18
3 files changed, 142 insertions, 18 deletions
diff --git a/src/gallium/state_trackers/clover/api/event.cpp b/src/gallium/state_trackers/clover/api/event.cpp
index 39a647b5ee7..ea1576cebd7 100644
--- a/src/gallium/state_trackers/clover/api/event.cpp
+++ b/src/gallium/state_trackers/clover/api/event.cpp
@@ -217,7 +217,31 @@ clEnqueueWaitForEvents(cl_command_queue q, cl_uint num_evs,
PUBLIC cl_int
clGetEventProfilingInfo(cl_event ev, cl_profiling_info param,
size_t size, void *buf, size_t *size_ret) {
- return CL_PROFILING_INFO_NOT_AVAILABLE;
+ hard_event *hev = dynamic_cast<hard_event *>(ev);
+ soft_event *sev = dynamic_cast<soft_event *>(ev);
+
+ if (!hev && !sev)
+ return CL_INVALID_EVENT;
+ if (!hev || !(hev->queue()->props() & CL_QUEUE_PROFILING_ENABLE) ||
+ hev->status() != CL_COMPLETE)
+ return CL_PROFILING_INFO_NOT_AVAILABLE;
+
+ switch (param) {
+ case CL_PROFILING_COMMAND_QUEUED:
+ return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_queued());
+
+ case CL_PROFILING_COMMAND_SUBMIT:
+ return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_submit());
+
+ case CL_PROFILING_COMMAND_START:
+ return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_start());
+
+ case CL_PROFILING_COMMAND_END:
+ return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_end());
+
+ default:
+ return CL_INVALID_VALUE;
+ }
}
PUBLIC cl_int
diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp
index 93d3b5819c9..de21f0c6e53 100644
--- a/src/gallium/state_trackers/clover/core/event.cpp
+++ b/src/gallium/state_trackers/clover/core/event.cpp
@@ -38,18 +38,6 @@ _cl_event::~_cl_event() {
}
void
-_cl_event::trigger() {
- if (!--wait_count) {
- action_ok(*this);
-
- while (!__chain.empty()) {
- __chain.back()->trigger();
- __chain.pop_back();
- }
- }
-}
-
-void
_cl_event::abort(cl_int status) {
__status = status;
action_fail(*this);
@@ -77,14 +65,61 @@ _cl_event::chain(clover::event *ev) {
hard_event::hard_event(clover::command_queue &q, cl_command_type command,
std::vector<clover::event *> deps, action action) :
_cl_event(q.ctx, deps, action, [](event &ev){}),
- __queue(q), __command(command), __fence(NULL) {
+ __queue(q), __command(command), __fence(NULL),
+ __query_start(NULL), __query_end(NULL) {
q.sequence(this);
+
+ if(q.props() & CL_QUEUE_PROFILING_ENABLE) {
+ pipe_screen *screen = q.dev.pipe;
+ __ts_queued = screen->get_timestamp(screen);
+ }
+
trigger();
}
hard_event::~hard_event() {
pipe_screen *screen = queue()->dev.pipe;
+ pipe_context *pipe = queue()->pipe;
screen->fence_reference(screen, &__fence, NULL);
+
+ if(__query_start) {
+ pipe->destroy_query(pipe, __query_start);
+ __query_start = 0;
+ }
+
+ if(__query_end) {
+ pipe->destroy_query(pipe, __query_end);
+ __query_end = 0;
+ }
+}
+
+void
+hard_event::trigger() {
+ if (!--wait_count) {
+ /* XXX: Currently, a timestamp query gives wrong results for memory
+ * transfers. This is, because we use memcpy instead of the DMA engines. */
+
+ if(queue()->props() & CL_QUEUE_PROFILING_ENABLE) {
+ pipe_context *pipe = queue()->pipe;
+ __query_start = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP);
+ pipe->end_query(queue()->pipe, __query_start);
+ }
+
+ action_ok(*this);
+
+ if(queue()->props() & CL_QUEUE_PROFILING_ENABLE) {
+ pipe_context *pipe = queue()->pipe;
+ pipe_screen *screen = queue()->dev.pipe;
+ __query_end = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP);
+ pipe->end_query(pipe, __query_end);
+ __ts_submit = screen->get_timestamp(screen);
+ }
+
+ while (!__chain.empty()) {
+ __chain.back()->trigger();
+ __chain.pop_back();
+ }
+ }
}
cl_int
@@ -126,6 +161,49 @@ hard_event::wait() const {
throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
}
+cl_ulong
+hard_event::ts_queued() const {
+ return __ts_queued;
+}
+
+cl_ulong
+hard_event::ts_submit() const {
+ return __ts_submit;
+}
+
+cl_ulong
+hard_event::ts_start() {
+ get_query_results();
+ return __ts_start;
+}
+
+cl_ulong
+hard_event::ts_end() {
+ get_query_results();
+ return __ts_end;
+}
+
+void
+hard_event::get_query_results() {
+ pipe_context *pipe = queue()->pipe;
+
+ if(__query_start) {
+ pipe_query_result result;
+ pipe->get_query_result(pipe, __query_start, true, &result);
+ __ts_start = result.u64;
+ pipe->destroy_query(pipe, __query_start);
+ __query_start = 0;
+ }
+
+ if(__query_end) {
+ pipe_query_result result;
+ pipe->get_query_result(pipe, __query_end, true, &result);
+ __ts_end = result.u64;
+ pipe->destroy_query(pipe, __query_end);
+ __query_end = 0;
+ }
+}
+
void
hard_event::fence(pipe_fence_handle *fence) {
pipe_screen *screen = queue()->dev.pipe;
@@ -140,6 +218,18 @@ soft_event::soft_event(clover::context &ctx,
trigger();
}
+void
+soft_event::trigger() {
+ if (!--wait_count) {
+ action_ok(*this);
+
+ while (!__chain.empty()) {
+ __chain.back()->trigger();
+ __chain.pop_back();
+ }
+ }
+}
+
cl_int
soft_event::status() const {
if (__status < 0)
diff --git a/src/gallium/state_trackers/clover/core/event.hpp b/src/gallium/state_trackers/clover/core/event.hpp
index eb8195383ab..de92de07985 100644
--- a/src/gallium/state_trackers/clover/core/event.hpp
+++ b/src/gallium/state_trackers/clover/core/event.hpp
@@ -57,7 +57,7 @@ public:
action action_ok, action action_fail);
virtual ~_cl_event();
- void trigger();
+ virtual void trigger() = 0;
void abort(cl_int status);
bool signalled() const;
@@ -72,12 +72,10 @@ protected:
void chain(clover::event *ev);
cl_int __status;
- std::vector<clover::ref_ptr<clover::event>> deps;
-
-private:
unsigned wait_count;
action action_ok;
action action_fail;
+ std::vector<clover::ref_ptr<clover::event>> deps;
std::vector<clover::ref_ptr<clover::event>> __chain;
};
@@ -101,11 +99,19 @@ namespace clover {
action action = [](event &){});
~hard_event();
+ virtual void trigger();
+
virtual cl_int status() const;
virtual cl_command_queue queue() const;
virtual cl_command_type command() const;
virtual void wait() const;
+ cl_ulong ts_queued() const;
+ cl_ulong ts_submit() const;
+ cl_ulong ts_start();
+ cl_ulong ts_end();
+ void get_query_results();
+
friend class ::_cl_command_queue;
private:
@@ -114,6 +120,8 @@ namespace clover {
clover::command_queue &__queue;
cl_command_type __command;
pipe_fence_handle *__fence;
+ cl_ulong __ts_queued, __ts_submit, __ts_start, __ts_end;
+ struct pipe_query *__query_start, *__query_end;
};
///
@@ -128,6 +136,8 @@ namespace clover {
soft_event(clover::context &ctx, std::vector<clover::event *> deps,
bool trigger, action action = [](event &){});
+ virtual void trigger();
+
virtual cl_int status() const;
virtual cl_command_queue queue() const;
virtual cl_command_type command() const;