Home | History | Annotate | Download | only in core
      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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 // OTHER DEALINGS IN THE SOFTWARE.
     21 //
     22 
     23 #include "core/queue.hpp"
     24 #include "core/event.hpp"
     25 #include "pipe/p_screen.h"
     26 #include "pipe/p_context.h"
     27 #include "pipe/p_state.h"
     28 
     29 using namespace clover;
     30 
     31 namespace {
     32    void
     33    debug_notify_callback(void *data,
     34                          unsigned *id,
     35                          enum pipe_debug_type type,
     36                          const char *fmt,
     37                          va_list args) {
     38       const command_queue *queue = (const command_queue *)data;
     39       char buffer[1024];
     40       vsnprintf(buffer, sizeof(buffer), fmt, args);
     41       queue->context().notify(buffer);
     42    }
     43 }
     44 
     45 command_queue::command_queue(clover::context &ctx, clover::device &dev,
     46                              cl_command_queue_properties props) :
     47    context(ctx), device(dev), props(props) {
     48    pipe = dev.pipe->context_create(dev.pipe, NULL, PIPE_CONTEXT_COMPUTE_ONLY);
     49    if (!pipe)
     50       throw error(CL_INVALID_DEVICE);
     51 
     52    if (ctx.notify) {
     53       struct pipe_debug_callback cb;
     54       memset(&cb, 0, sizeof(cb));
     55       cb.debug_message = &debug_notify_callback;
     56       cb.data = this;
     57       if (pipe->set_debug_callback)
     58          pipe->set_debug_callback(pipe, &cb);
     59    }
     60 }
     61 
     62 command_queue::~command_queue() {
     63    pipe->destroy(pipe);
     64 }
     65 
     66 void
     67 command_queue::flush() {
     68    pipe_screen *screen = device().pipe;
     69    pipe_fence_handle *fence = NULL;
     70 
     71    std::lock_guard<std::mutex> lock(queued_events_mutex);
     72    if (!queued_events.empty()) {
     73       pipe->flush(pipe, &fence, 0);
     74 
     75       while (!queued_events.empty() &&
     76              queued_events.front()().signalled()) {
     77          queued_events.front()().fence(fence);
     78          queued_events.pop_front();
     79       }
     80 
     81       screen->fence_reference(screen, &fence, NULL);
     82    }
     83 }
     84 
     85 cl_command_queue_properties
     86 command_queue::properties() const {
     87    return props;
     88 }
     89 
     90 bool
     91 command_queue::profiling_enabled() const {
     92    return props & CL_QUEUE_PROFILING_ENABLE;
     93 }
     94 
     95 void
     96 command_queue::sequence(hard_event &ev) {
     97    std::lock_guard<std::mutex> lock(queued_events_mutex);
     98    if (!queued_events.empty())
     99       queued_events.back()().chain(ev);
    100 
    101    queued_events.push_back(ev);
    102 }
    103