queue.cpp revision c6db1b3396384186aab5b685fe1fd540e17b3a62
1//
2// Copyright 2012 Francisco Jerez
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20// SOFTWARE.
21//
22
23#include <algorithm>
24
25#include "core/queue.hpp"
26#include "core/event.hpp"
27#include "pipe/p_screen.h"
28#include "pipe/p_context.h"
29
30using namespace clover;
31
32_cl_command_queue::_cl_command_queue(context &ctx, device &dev,
33                                     cl_command_queue_properties props) :
34   ctx(ctx), dev(dev), __props(props) {
35   pipe = dev.pipe->context_create(dev.pipe, NULL);
36   if (!pipe)
37      throw error(CL_INVALID_DEVICE);
38}
39
40_cl_command_queue::~_cl_command_queue() {
41   pipe->destroy(pipe);
42}
43
44void
45_cl_command_queue::flush() {
46   pipe_screen *screen = dev.pipe;
47   pipe_fence_handle *fence = NULL;
48
49   if (!queued_events.empty()) {
50      // Find out which events have already been signalled.
51      auto first = queued_events.begin();
52      auto last = std::find_if(queued_events.begin(), queued_events.end(),
53                               [](event_ptr &ev) { return !ev->signalled(); });
54
55      // Flush and fence them.
56      pipe->flush(pipe, &fence);
57      std::for_each(first, last, [&](event_ptr &ev) { ev->fence(fence); });
58      screen->fence_reference(screen, &fence, NULL);
59      queued_events.erase(first, last);
60   }
61}
62
63void
64_cl_command_queue::sequence(clover::hard_event *ev) {
65   if (!queued_events.empty())
66      queued_events.back()->chain(ev);
67
68   queued_events.push_back(ev);
69}
70