clover: Clean up the event profiling code.
Tested-by: Tom Stellard <thomas.stellard@amd.com>
This commit is contained in:
@@ -29,6 +29,8 @@ CPP_SOURCES := \
|
|||||||
core/resource.cpp \
|
core/resource.cpp \
|
||||||
core/sampler.hpp \
|
core/sampler.hpp \
|
||||||
core/sampler.cpp \
|
core/sampler.cpp \
|
||||||
|
core/timestamp.hpp \
|
||||||
|
core/timestamp.cpp \
|
||||||
core/event.hpp \
|
core/event.hpp \
|
||||||
core/event.cpp \
|
core/event.cpp \
|
||||||
core/program.hpp \
|
core/program.hpp \
|
||||||
|
@@ -216,32 +216,37 @@ clEnqueueWaitForEvents(cl_command_queue q, cl_uint num_evs,
|
|||||||
|
|
||||||
PUBLIC cl_int
|
PUBLIC cl_int
|
||||||
clGetEventProfilingInfo(cl_event ev, cl_profiling_info param,
|
clGetEventProfilingInfo(cl_event ev, cl_profiling_info param,
|
||||||
size_t size, void *buf, size_t *size_ret) {
|
size_t size, void *buf, size_t *size_ret) try {
|
||||||
hard_event *hev = dynamic_cast<hard_event *>(ev);
|
hard_event *hev = dynamic_cast<hard_event *>(ev);
|
||||||
soft_event *sev = dynamic_cast<soft_event *>(ev);
|
|
||||||
|
|
||||||
if (!hev && !sev)
|
if (!ev)
|
||||||
return CL_INVALID_EVENT;
|
return CL_INVALID_EVENT;
|
||||||
if (!hev || !(hev->queue()->props() & CL_QUEUE_PROFILING_ENABLE) ||
|
|
||||||
hev->status() != CL_COMPLETE)
|
if (!hev || hev->status() != CL_COMPLETE)
|
||||||
return CL_PROFILING_INFO_NOT_AVAILABLE;
|
return CL_PROFILING_INFO_NOT_AVAILABLE;
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case CL_PROFILING_COMMAND_QUEUED:
|
case CL_PROFILING_COMMAND_QUEUED:
|
||||||
return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_queued());
|
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_queued());
|
||||||
|
|
||||||
case CL_PROFILING_COMMAND_SUBMIT:
|
case CL_PROFILING_COMMAND_SUBMIT:
|
||||||
return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_submit());
|
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_submit());
|
||||||
|
|
||||||
case CL_PROFILING_COMMAND_START:
|
case CL_PROFILING_COMMAND_START:
|
||||||
return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_start());
|
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_start());
|
||||||
|
|
||||||
case CL_PROFILING_COMMAND_END:
|
case CL_PROFILING_COMMAND_END:
|
||||||
return scalar_property<cl_ulong>(buf, size, size_ret, hev->ts_end());
|
return scalar_property<cl_ulong>(buf, size, size_ret, hev->time_end());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CL_INVALID_VALUE;
|
return CL_INVALID_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (lazy<cl_ulong>::undefined_error &e) {
|
||||||
|
return CL_PROFILING_INFO_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
} catch (error &e) {
|
||||||
|
return e.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC cl_int
|
PUBLIC cl_int
|
||||||
|
@@ -37,6 +37,18 @@ _cl_event::_cl_event(clover::context &ctx,
|
|||||||
_cl_event::~_cl_event() {
|
_cl_event::~_cl_event() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cl_event::trigger() {
|
||||||
|
if (!--wait_count) {
|
||||||
|
action_ok(*this);
|
||||||
|
|
||||||
|
while (!__chain.empty()) {
|
||||||
|
__chain.back()->trigger();
|
||||||
|
__chain.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cl_event::abort(cl_int status) {
|
_cl_event::abort(cl_int status) {
|
||||||
__status = status;
|
__status = status;
|
||||||
@@ -64,62 +76,18 @@ _cl_event::chain(clover::event *ev) {
|
|||||||
|
|
||||||
hard_event::hard_event(clover::command_queue &q, cl_command_type command,
|
hard_event::hard_event(clover::command_queue &q, cl_command_type command,
|
||||||
std::vector<clover::event *> deps, action action) :
|
std::vector<clover::event *> deps, action action) :
|
||||||
_cl_event(q.ctx, deps, action, [](event &ev){}),
|
_cl_event(q.ctx, deps, profile(q, action), [](event &ev){}),
|
||||||
__queue(q), __command(command), __fence(NULL),
|
__queue(q), __command(command), __fence(NULL) {
|
||||||
__query_start(NULL), __query_end(NULL) {
|
if (q.profiling_enabled())
|
||||||
|
_time_queued = timestamp::current(q);
|
||||||
|
|
||||||
q.sequence(this);
|
q.sequence(this);
|
||||||
|
|
||||||
if(q.props() & CL_QUEUE_PROFILING_ENABLE) {
|
|
||||||
pipe_screen *screen = q.dev.pipe;
|
|
||||||
__ts_queued = screen->get_timestamp(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger();
|
trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
hard_event::~hard_event() {
|
hard_event::~hard_event() {
|
||||||
pipe_screen *screen = queue()->dev.pipe;
|
pipe_screen *screen = queue()->dev.pipe;
|
||||||
pipe_context *pipe = queue()->pipe;
|
|
||||||
screen->fence_reference(screen, &__fence, NULL);
|
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
|
cl_int
|
||||||
@@ -161,47 +129,24 @@ hard_event::wait() const {
|
|||||||
throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
|
throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
cl_ulong
|
const lazy<cl_ulong> &
|
||||||
hard_event::ts_queued() const {
|
hard_event::time_queued() const {
|
||||||
return __ts_queued;
|
return _time_queued;
|
||||||
}
|
}
|
||||||
|
|
||||||
cl_ulong
|
const lazy<cl_ulong> &
|
||||||
hard_event::ts_submit() const {
|
hard_event::time_submit() const {
|
||||||
return __ts_submit;
|
return _time_submit;
|
||||||
}
|
}
|
||||||
|
|
||||||
cl_ulong
|
const lazy<cl_ulong> &
|
||||||
hard_event::ts_start() {
|
hard_event::time_start() const {
|
||||||
get_query_results();
|
return _time_start;
|
||||||
return __ts_start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cl_ulong
|
const lazy<cl_ulong> &
|
||||||
hard_event::ts_end() {
|
hard_event::time_end() const {
|
||||||
get_query_results();
|
return _time_end;
|
||||||
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
|
void
|
||||||
@@ -210,6 +155,25 @@ hard_event::fence(pipe_fence_handle *fence) {
|
|||||||
screen->fence_reference(screen, &__fence, fence);
|
screen->fence_reference(screen, &__fence, fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event::action
|
||||||
|
hard_event::profile(command_queue &q, const action &action) const {
|
||||||
|
if (q.profiling_enabled()) {
|
||||||
|
return [&q, action] (event &ev) {
|
||||||
|
auto &hev = static_cast<hard_event &>(ev);
|
||||||
|
|
||||||
|
hev._time_submit = timestamp::current(q);
|
||||||
|
hev._time_start = timestamp::query(q);
|
||||||
|
|
||||||
|
action(ev);
|
||||||
|
|
||||||
|
hev._time_end = timestamp::query(q);
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
soft_event::soft_event(clover::context &ctx,
|
soft_event::soft_event(clover::context &ctx,
|
||||||
std::vector<clover::event *> deps,
|
std::vector<clover::event *> deps,
|
||||||
bool __trigger, action action) :
|
bool __trigger, action action) :
|
||||||
@@ -218,18 +182,6 @@ soft_event::soft_event(clover::context &ctx,
|
|||||||
trigger();
|
trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
soft_event::trigger() {
|
|
||||||
if (!--wait_count) {
|
|
||||||
action_ok(*this);
|
|
||||||
|
|
||||||
while (!__chain.empty()) {
|
|
||||||
__chain.back()->trigger();
|
|
||||||
__chain.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_int
|
cl_int
|
||||||
soft_event::status() const {
|
soft_event::status() const {
|
||||||
if (__status < 0)
|
if (__status < 0)
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "core/base.hpp"
|
#include "core/base.hpp"
|
||||||
#include "core/queue.hpp"
|
#include "core/queue.hpp"
|
||||||
|
#include "core/timestamp.hpp"
|
||||||
|
#include "util/lazy.hpp"
|
||||||
|
|
||||||
namespace clover {
|
namespace clover {
|
||||||
typedef struct _cl_event event;
|
typedef struct _cl_event event;
|
||||||
@@ -57,7 +59,7 @@ public:
|
|||||||
action action_ok, action action_fail);
|
action action_ok, action action_fail);
|
||||||
virtual ~_cl_event();
|
virtual ~_cl_event();
|
||||||
|
|
||||||
virtual void trigger() = 0;
|
void trigger();
|
||||||
void abort(cl_int status);
|
void abort(cl_int status);
|
||||||
bool signalled() const;
|
bool signalled() const;
|
||||||
|
|
||||||
@@ -72,10 +74,12 @@ protected:
|
|||||||
void chain(clover::event *ev);
|
void chain(clover::event *ev);
|
||||||
|
|
||||||
cl_int __status;
|
cl_int __status;
|
||||||
|
std::vector<clover::ref_ptr<clover::event>> deps;
|
||||||
|
|
||||||
|
private:
|
||||||
unsigned wait_count;
|
unsigned wait_count;
|
||||||
action action_ok;
|
action action_ok;
|
||||||
action action_fail;
|
action action_fail;
|
||||||
std::vector<clover::ref_ptr<clover::event>> deps;
|
|
||||||
std::vector<clover::ref_ptr<clover::event>> __chain;
|
std::vector<clover::ref_ptr<clover::event>> __chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,29 +103,26 @@ namespace clover {
|
|||||||
action action = [](event &){});
|
action action = [](event &){});
|
||||||
~hard_event();
|
~hard_event();
|
||||||
|
|
||||||
virtual void trigger();
|
|
||||||
|
|
||||||
virtual cl_int status() const;
|
virtual cl_int status() const;
|
||||||
virtual cl_command_queue queue() const;
|
virtual cl_command_queue queue() const;
|
||||||
virtual cl_command_type command() const;
|
virtual cl_command_type command() const;
|
||||||
virtual void wait() const;
|
virtual void wait() const;
|
||||||
|
|
||||||
cl_ulong ts_queued() const;
|
const lazy<cl_ulong> &time_queued() const;
|
||||||
cl_ulong ts_submit() const;
|
const lazy<cl_ulong> &time_submit() const;
|
||||||
cl_ulong ts_start();
|
const lazy<cl_ulong> &time_start() const;
|
||||||
cl_ulong ts_end();
|
const lazy<cl_ulong> &time_end() const;
|
||||||
void get_query_results();
|
|
||||||
|
|
||||||
friend class ::_cl_command_queue;
|
friend class ::_cl_command_queue;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void fence(pipe_fence_handle *fence);
|
virtual void fence(pipe_fence_handle *fence);
|
||||||
|
action profile(command_queue &q, const action &action) const;
|
||||||
|
|
||||||
clover::command_queue &__queue;
|
clover::command_queue &__queue;
|
||||||
cl_command_type __command;
|
cl_command_type __command;
|
||||||
pipe_fence_handle *__fence;
|
pipe_fence_handle *__fence;
|
||||||
cl_ulong __ts_queued, __ts_submit, __ts_start, __ts_end;
|
lazy<cl_ulong> _time_queued, _time_submit, _time_start, _time_end;
|
||||||
struct pipe_query *__query_start, *__query_end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -136,8 +137,6 @@ namespace clover {
|
|||||||
soft_event(clover::context &ctx, std::vector<clover::event *> deps,
|
soft_event(clover::context &ctx, std::vector<clover::event *> deps,
|
||||||
bool trigger, action action = [](event &){});
|
bool trigger, action action = [](event &){});
|
||||||
|
|
||||||
virtual void trigger();
|
|
||||||
|
|
||||||
virtual cl_int status() const;
|
virtual cl_int status() const;
|
||||||
virtual cl_command_queue queue() const;
|
virtual cl_command_queue queue() const;
|
||||||
virtual cl_command_type command() const;
|
virtual cl_command_type command() const;
|
||||||
|
@@ -60,6 +60,16 @@ _cl_command_queue::flush() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cl_command_queue_properties
|
||||||
|
_cl_command_queue::props() const {
|
||||||
|
return __props;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
_cl_command_queue::profiling_enabled() const {
|
||||||
|
return __props & CL_QUEUE_PROFILING_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cl_command_queue::sequence(clover::hard_event *ev) {
|
_cl_command_queue::sequence(clover::hard_event *ev) {
|
||||||
if (!queued_events.empty())
|
if (!queued_events.empty())
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "core/base.hpp"
|
#include "core/base.hpp"
|
||||||
#include "core/context.hpp"
|
#include "core/context.hpp"
|
||||||
|
#include "core/timestamp.hpp"
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
|
|
||||||
namespace clover {
|
namespace clover {
|
||||||
@@ -43,9 +44,8 @@ public:
|
|||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
cl_command_queue_properties props() const {
|
cl_command_queue_properties props() const;
|
||||||
return __props;
|
bool profiling_enabled() const;
|
||||||
}
|
|
||||||
|
|
||||||
clover::context &ctx;
|
clover::context &ctx;
|
||||||
clover::device &dev;
|
clover::device &dev;
|
||||||
@@ -56,6 +56,8 @@ public:
|
|||||||
friend class clover::hard_event;
|
friend class clover::hard_event;
|
||||||
friend struct _cl_sampler;
|
friend struct _cl_sampler;
|
||||||
friend struct _cl_kernel;
|
friend struct _cl_kernel;
|
||||||
|
friend class clover::timestamp::query;
|
||||||
|
friend class clover::timestamp::current;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Serialize a hardware event with respect to the previous ones,
|
/// Serialize a hardware event with respect to the previous ones,
|
||||||
|
63
src/gallium/state_trackers/clover/core/timestamp.cpp
Normal file
63
src/gallium/state_trackers/clover/core/timestamp.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2013 Francisco Jerez
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "core/timestamp.hpp"
|
||||||
|
#include "core/queue.hpp"
|
||||||
|
#include "pipe/p_screen.h"
|
||||||
|
#include "pipe/p_context.h"
|
||||||
|
|
||||||
|
using namespace clover;
|
||||||
|
|
||||||
|
timestamp::query::query(command_queue &q) :
|
||||||
|
q(q),
|
||||||
|
_query(q.pipe->create_query(q.pipe, PIPE_QUERY_TIMESTAMP)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamp::query::query(query &&other) :
|
||||||
|
q(other.q),
|
||||||
|
_query(other._query) {
|
||||||
|
other._query = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamp::query::~query() {
|
||||||
|
if (_query)
|
||||||
|
q.pipe->destroy_query(q.pipe, _query);
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_ulong
|
||||||
|
timestamp::query::operator()() const {
|
||||||
|
pipe_query_result result;
|
||||||
|
|
||||||
|
if (!q.pipe->get_query_result(q.pipe, _query, false, &result))
|
||||||
|
throw error(CL_PROFILING_INFO_NOT_AVAILABLE);
|
||||||
|
|
||||||
|
return result.u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamp::current::current(command_queue &q) :
|
||||||
|
result(q.pipe->screen->get_timestamp(q.pipe->screen)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_ulong
|
||||||
|
timestamp::current::operator()() const {
|
||||||
|
return result;
|
||||||
|
}
|
74
src/gallium/state_trackers/clover/core/timestamp.hpp
Normal file
74
src/gallium/state_trackers/clover/core/timestamp.hpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2013 Francisco Jerez
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CLOVER_CORE_TIMESTAMP_HPP
|
||||||
|
#define CLOVER_CORE_TIMESTAMP_HPP
|
||||||
|
|
||||||
|
#include "core/base.hpp"
|
||||||
|
|
||||||
|
struct pipe_query;
|
||||||
|
|
||||||
|
namespace clover {
|
||||||
|
typedef struct _cl_command_queue command_queue;
|
||||||
|
|
||||||
|
namespace timestamp {
|
||||||
|
///
|
||||||
|
/// Emit a timestamp query that is executed asynchronously by
|
||||||
|
/// the command queue \a q.
|
||||||
|
///
|
||||||
|
class query {
|
||||||
|
public:
|
||||||
|
query(command_queue &q);
|
||||||
|
query(query &&other);
|
||||||
|
~query();
|
||||||
|
|
||||||
|
query &operator=(const query &) = delete;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Retrieve the query results.
|
||||||
|
///
|
||||||
|
cl_ulong operator()() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
command_queue &q;
|
||||||
|
pipe_query *_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get the current timestamp value.
|
||||||
|
///
|
||||||
|
class current {
|
||||||
|
public:
|
||||||
|
current(command_queue &q);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Retrieve the query results.
|
||||||
|
///
|
||||||
|
cl_ulong operator()() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cl_ulong result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user