blob: d1de855c11fb770947019b75f7de09330f361685 [file] [edit]
// Copyright 2018 The clvk authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstring>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <deque>
#include <list>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
#include <vulkan/vulkan.h>
#include "cl_headers.hpp"
#include "icd.hpp"
#include "log.hpp"
enum class object_magic : uint32_t
{
platform = 0x11223344U,
device = 0x22334455U,
context = 0x33445566U,
command_queue = 0x44556677U,
event = 0x55667788U,
program = 0x66778899U,
kernel = 0x778899AAU,
memory_object = 0x8899AABBU,
sampler = 0x99AABBCCU,
semaphore = 0xAABBCCDDU,
};
template <object_magic magic> struct object_magic_header {
object_magic_header() : m_magic(magic) {}
bool is_valid() const { return m_magic == magic; }
private:
object_magic m_magic;
};
struct refcounted {
refcounted() : m_refcount(1) {}
virtual ~refcounted() = default;
void retain() {
unsigned int refcount = m_refcount.fetch_add(1);
cvk_debug_group_fn(loggroup::refcounting, "obj = %p, refcount now %u",
this, refcount + 1);
}
void release() {
unsigned int refcount = m_refcount.fetch_sub(1);
cvk_debug_group_fn(loggroup::refcounting, "obj = %p, refcount now %u",
this, refcount - 1);
if (refcount == 1) {
delete this;
}
}
unsigned int refcount() const { return m_refcount.load(); }
private:
std::atomic<unsigned int> m_refcount;
};
template <typename T> struct refcounted_holder {
refcounted_holder() : m_refcounted(nullptr) {}
refcounted_holder(T* refcounted) : m_refcounted(refcounted) {
if (m_refcounted != nullptr) {
m_refcounted->retain();
}
}
refcounted_holder(const refcounted_holder& other)
: m_refcounted(other.m_refcounted) {
if (m_refcounted != nullptr) {
m_refcounted->retain();
}
}
refcounted_holder(refcounted_holder&& other) noexcept
: m_refcounted(other.m_refcounted) {
other.m_refcounted = nullptr;
}
~refcounted_holder() {
if (m_refcounted != nullptr) {
m_refcounted->release();
}
}
T* operator->() const { return m_refcounted; }
operator T*() const { return m_refcounted; }
refcounted_holder& operator=(const refcounted_holder&) = delete;
refcounted_holder& operator=(const refcounted_holder&&) = delete;
void reset(T* refc) {
if (m_refcounted != nullptr) {
m_refcounted->release();
}
m_refcounted = refc;
if (m_refcounted != nullptr) {
m_refcounted->retain();
}
}
private:
T* m_refcounted;
};