/*
 * Copyright © 2021 The Fuchsia Authors
 *
 * 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 (including the next
 * paragraph) 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 <zircon/process.h>
#include <zircon/syscalls.h>

#include "inflight_list.h"
#include "mos_bufmgr.h"
#include "mos_bufmgr_priv.h"
#include "simple_allocator.h"
#include <magma.h>
#include <magma_intel_gen_defs.h>
#include <magma_fd.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <mutex>
#include <vector>

#define LOG_VERBOSE(msg, ...) do { \
    if (false) {\
        fprintf(stderr, "%s:%d " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
        fflush(stderr); \
    } \
} while (0)

static inline uint64_t page_size() { return sysconf(_SC_PAGESIZE); }

class MagmaBo;

class MagmaBufMgr : public mos_bufmgr {
public:
    MagmaBufMgr(magma_connection_t connection, uint32_t device_id);
    ~MagmaBufMgr();

    magma_connection_t connection() const { return connection_; }
    magma_handle_t notification_handle() const { return notification_handle_; }

    uint32_t device_id() const { return device_id_; }

    bool Alloc(size_t size, uint8_t align_pow2, uint64_t* addr_out) {
        std::lock_guard<std::mutex> lock(allocator_mutex_);
        return allocator_->Alloc(size, align_pow2, addr_out);
    }

    bool Free(uint64_t addr) {
        std::lock_guard<std::mutex> lock(allocator_mutex_);
        return allocator_->Free(addr);
    }

    MagmaBo* CreateBo(const char *name, unsigned long size);
    MagmaBo* ImportBo(int zx_handle, unsigned long size);

    InflightList* inflight_list() { return &inflight_list_;}

private:
    magma_connection_t connection_ {};
    magma_handle_t notification_handle_{};
    uint32_t device_id_;
    std::mutex allocator_mutex_;
    std::unique_ptr<SimpleAllocator> allocator_ __attribute__((__guarded_by__(allocator_mutex_)));
    InflightList inflight_list_;
};


class MagmaBo : public mos_linux_bo {
public:
    // MagmaBufMgr must outlive MagmaBo.
    MagmaBo(magma_buffer_t buffer, uint64_t size, MagmaBufMgr* bufmgr);

private:
    ~MagmaBo();

public:
    void AddRef() { ref_count_ += 1; }

    void RemoveRef() {
        ref_count_ -= 1;
        int32_t count = ref_count_;
        assert(count >= 0);
        if (count == 0) {
            delete this;
        }
    }

    MagmaBufMgr* magma_bufmgr() const { return static_cast<MagmaBufMgr*>(bufmgr); }

    uint64_t id() { return id_; }

    magma_buffer_t buffer() const { return buffer_; }

    bool is_mapped_gpu() { return is_mapped_gpu_; }

    std::vector<magma_exec_resource>& exec_resources() { return exec_resources_; }

    bool MapGpu();

    void AddExecResource(MagmaBo* bo);

    void clear_exec_resources() { exec_resources_.clear(); }

private:
    std::atomic_int ref_count_{};
    magma_buffer_t buffer_ {};
    uint64_t id_ {};
    bool is_mapped_gpu_= false;
    std::vector<magma_exec_resource> exec_resources_;
};


MagmaBo::MagmaBo(magma_buffer_t buffer, uint64_t size, MagmaBufMgr* bufmgr) :
    buffer_(buffer), id_(magma_get_buffer_id(buffer)) {

    mos_linux_bo::size = size;
    assert(mos_linux_bo::size == size);
    mos_linux_bo::align = 0;
    mos_linux_bo::virt = nullptr;
    mos_linux_bo::bufmgr = bufmgr;
    mos_linux_bo::handle = 0;
    mos_linux_bo::offset = 0;
    mos_linux_bo::offset64 = 0;
    mos_linux_bo::aux_mapped = false;

    AddRef();
}

MagmaBo::~MagmaBo() {
    magma_release_buffer(magma_bufmgr()->connection(), buffer());

    if (is_mapped_gpu_) {
        magma_bufmgr()->Free(offset64);
    }
}

void MagmaBo::AddExecResource(MagmaBo* bo) {
    if (exec_resources_.empty()) {
        // Add this as the first resource.
        exec_resources_.push_back({
            .buffer_id = id(),
            .offset = 0,
            .length = size,
        });
    }
    exec_resources_.push_back({ .buffer_id = bo->id(),
        .offset = 0,
        .length = bo->size}
    );
}

bool MagmaBo::MapGpu() {
    if (is_mapped_gpu_)
        return true;

    if (!magma_bufmgr()->Alloc(size, __builtin_ctz(PAGE_SIZE_64K), &offset64)) {
        LOG_VERBOSE("Alloc failed: size %lu", size);
        return false;
    }

    uint64_t page_count = size / page_size();
    constexpr uint64_t kFlags = MAGMA_GPU_MAP_FLAG_READ | MAGMA_GPU_MAP_FLAG_EXECUTE |
        MAGMA_GPU_MAP_FLAG_WRITE;

    LOG_VERBOSE("MapGpu buffer %lu addr 0x%lx", id(), offset64);

    magma_status_t status = magma_map_buffer_gpu(magma_bufmgr()->connection(),
        buffer(), 0 /*page_offset*/, page_count, offset64, kFlags);

    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_map_buffer_gpu failed: %d", status);
        return false;
    }

    is_mapped_gpu_ = true;

    return true;
}

static void bufmgr_destroy(struct mos_bufmgr* mos_bufmgr)
{
    LOG_VERBOSE("bufmgr_destroy");

    delete static_cast<MagmaBufMgr*>(mos_bufmgr);
}

static struct mos_linux_bo *bufmgr_bo_alloc_for_render(struct mos_bufmgr *bufmgr,
                  const char *name,
                  unsigned long size,
                  unsigned int alignment,
                  int mem_type)
{
    LOG_VERBOSE("bo_alloc_for_render not implemented");
    return nullptr;
}

static struct mos_linux_bo *bufmgr_bo_alloc(struct mos_bufmgr *mos_bufmgr,
               const char *name,
               unsigned long size,
               unsigned int /*alignment*/,
               int /*mem_type*/)
{
    MagmaBo* bo = static_cast<MagmaBufMgr*>(mos_bufmgr)->CreateBo(name, size);

    if (bo)
        LOG_VERBOSE("bo_alloc '%s' size %lu buffer %lu", name, size, bo->id());

    return bo;
}

struct mos_linux_bo *mos_bo_gem_create_from_prime(struct mos_bufmgr *mos_bufmgr, int prime_fd, int size)
{
    MagmaBo* bo = static_cast<MagmaBufMgr*>(mos_bufmgr)->ImportBo(prime_fd, size);
    if (bo)
        LOG_VERBOSE("bo_create_from_prime size %d buffer %lu", size, bo->id());
    return bo;
}


static uint64_t get_pitch_with_tiling(uint64_t pitch, uint32_t tiling)
{
    switch (tiling) {
        case I915_TILING_NONE:
            return ROUND_UP_TO(pitch, 64);

        case I915_TILING_X:
            return ROUND_UP_TO(pitch, 512);

        case I915_TILING_Y:
            return ROUND_UP_TO(pitch, 128);
    }
    assert(false);
    return 0;
}

static uint64_t get_height_with_tiling(uint64_t height, uint32_t tiling)
{
    switch (tiling) {
        case I915_TILING_NONE:
            return ROUND_UP_TO(height, 2);

        case I915_TILING_X:
            return ROUND_UP_TO(height, 8);

        case I915_TILING_Y:
            return ROUND_UP_TO(height, 32);
    }
    assert(false);
    return 0;
}

static struct mos_linux_bo *bufmgr_bo_alloc_tiled(struct mos_bufmgr *bufmgr, const char *name,
                 int x, int y, int cpp, uint32_t *tiling_mode,
                 unsigned long *pitch, unsigned long flags,
                 int mem_type)
{
    uint32_t tiling = *tiling_mode;
    uint64_t stride = get_pitch_with_tiling(x * cpp, tiling);
    uint64_t height = get_height_with_tiling(y, tiling);
    uint64_t size = ROUND_UP_TO(stride * height, 4096);

    *pitch = stride;

    MagmaBo* bo = static_cast<MagmaBufMgr*>(bufmgr)->CreateBo(name, size);

    if (bo)
        LOG_VERBOSE("bo_alloc_tiled '%s' x %d y %d cpp %d tiling %u size %lu buffer %lu",
            name, x, y, cpp, tiling, size, bo->id());

    return bo;
}

static void bufmgr_bo_reference(struct mos_linux_bo *mos_linux_bo)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);
    LOG_VERBOSE("bo_reference %lu\n", bo->id());
    bo->AddRef();
}

static void bufmgr_bo_unreference(struct mos_linux_bo *mos_linux_bo)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);
    LOG_VERBOSE("bo_unreference %lu", bo->id());
    bo->RemoveRef();
}

static int bufmgr_bo_map(struct mos_linux_bo *mos_linux_bo, int write_enable)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);
    assert(!bo->virt);

    zx_handle_t vmo_handle;
    {
        magma_handle_t handle;
        magma_status_t status = magma_get_buffer_handle2(bo->buffer(), &handle);
        if (status != MAGMA_STATUS_OK) {
          LOG_VERBOSE("magma_get_buffer_handle failed: status %d", status);
          return -1;
        }
        vmo_handle = handle;
    }

    zx_vaddr_t zx_vaddr;
    zx_status_t zx_status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | (write_enable ? ZX_VM_PERM_WRITE : 0),
                                       0 /*vmar_offset*/, vmo_handle, 0 /*offset*/, bo->size, &zx_vaddr);

    zx_handle_close(vmo_handle);

    if (zx_status != ZX_OK) {
      LOG_VERBOSE("zx_vmar_map failed: status %d", zx_status);
      return -1;
    }

    bo->virt = reinterpret_cast<void*>(zx_vaddr);

    LOG_VERBOSE("mapped buffer %lu address %p", bo->id(), bo->virt);
    return 0;
}

static int bufmgr_bo_unmap(struct mos_linux_bo *mos_linux_bo)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);

    zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(), reinterpret_cast<uintptr_t>(bo->virt), bo->size);
    if (status != ZX_OK) {
      LOG_VERBOSE("zx_vmar_unmap failed: %d", status);
      return -1;
    }

    bo->virt = nullptr;

    LOG_VERBOSE("unmapped buffer %lu", bo->id());
    return 0;
}

static int bufmgr_bo_subdata(struct mos_linux_bo *mos_linux_bo, unsigned long offset,
             unsigned long size, const void *data)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);

    assert(offset + size >= offset);
    assert(offset + size <= bo->size);

    if (!bo->virt) {
        LOG_VERBOSE("bo_subdata: not mapped");
        return -1;
    }

    LOG_VERBOSE("bo_subdata %lu offset %lu size %lu", bo->id(), offset, size);

    memcpy(reinterpret_cast<uint8_t*>(bo->virt) + offset, data, size);

    return 0;
}

static int bufmgr_bo_set_softpin(struct mos_linux_bo *bo)
{
    // Never called because buffers mapped at creation.
    assert(false);
    return 0;
}

static int bufmgr_bo_add_softpin_target(struct mos_linux_bo *bo_base, struct mos_linux_bo *target_bo_base, bool /*write_flag*/)
{
    auto bo = static_cast<MagmaBo*>(bo_base);

    auto target_bo = static_cast<MagmaBo*>(target_bo_base);

    bo->AddExecResource(target_bo);

    LOG_VERBOSE("bo_add_softpin_target bo %lu target_bo %lu", bo->id(), target_bo->id());

    return 0;
}

// Stubs
extern int bufmgr_bo_get_subdata(struct mos_linux_bo *bo, unsigned long offset,
                 unsigned long size, void *data);
extern void bufmgr_bo_wait_rendering(struct mos_linux_bo *bo);
extern int bufmgr_bo_pad_to_size(struct mos_linux_bo *bo, uint64_t pad_to_size);
extern int bufmgr_bo_emit_reloc(struct mos_linux_bo *bo, uint32_t offset,
                struct mos_linux_bo *target_bo, uint32_t target_offset,
                uint32_t read_domains, uint32_t write_domain);
extern int bufmgr_bo_emit_reloc2(struct mos_linux_bo *bo, uint32_t offset,
                struct mos_linux_bo *target_bo, uint32_t target_offset,
                uint32_t read_domains, uint32_t write_domain,
                uint64_t presumed_offset);
extern int bufmgr_bo_emit_reloc_fence(struct mos_linux_bo *bo, uint32_t offset,
                  struct mos_linux_bo *target_bo,
                  uint32_t target_offset,
                  uint32_t read_domains, uint32_t write_domain);
extern int bufmgr_bo_pin(struct mos_linux_bo *bo, uint32_t alignment);
extern int bufmgr_bo_unpin(struct mos_linux_bo *bo);
extern int bufmgr_bo_get_tiling(struct mos_linux_bo *bo, uint32_t * tiling_mode,
                uint32_t * swizzle_mode);
extern int bufmgr_bo_set_tiling(struct mos_linux_bo *bo, uint32_t * tiling_mode,
                uint32_t stride);
extern int bufmgr_bo_flink(struct mos_linux_bo *bo, uint32_t * name);
extern int bufmgr_bo_exec2(struct mos_linux_bo *bo, int used,
               drm_clip_rect_t *cliprects, int num_cliprects,
               int DR4);
extern int bufmgr_bo_mrb_exec2(struct mos_linux_bo *bo, int used,
            drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
            unsigned int flags);
extern int bufmgr_bo_busy(struct mos_linux_bo *bo);
extern int bufmgr_bo_madvise(struct mos_linux_bo *bo, int madv);
extern int bufmgr_check_aperture_space(struct mos_linux_bo **bo_array, int count);
extern int bufmgr_bo_disable_reuse(struct mos_linux_bo *bo);
extern int bufmgr_bo_is_reusable(struct mos_linux_bo *bo);
extern int bufmgr_get_pipe_from_crtc_id(struct mos_bufmgr *bufmgr, int crtc_id);
extern int bufmgr_bo_references(struct mos_linux_bo *bo, struct mos_linux_bo *target_bo);

MagmaBufMgr::MagmaBufMgr(magma_connection_t connection, uint32_t device_id) :
    connection_(connection), device_id_(device_id) {

    notification_handle_ = magma_get_notification_channel_handle(connection_);

    mos_bufmgr::bo_alloc = bufmgr_bo_alloc;
    mos_bufmgr::bo_alloc_for_render = bufmgr_bo_alloc_for_render;
    mos_bufmgr::bo_alloc_tiled = bufmgr_bo_alloc_tiled;
    mos_bufmgr::bo_reference = bufmgr_bo_reference;
    mos_bufmgr::bo_unreference = bufmgr_bo_unreference;
    mos_bufmgr::bo_map = bufmgr_bo_map;
    mos_bufmgr::bo_unmap = bufmgr_bo_unmap;
    mos_bufmgr::bo_subdata = bufmgr_bo_subdata;
    mos_bufmgr::bo_get_subdata = bufmgr_bo_get_subdata;
    mos_bufmgr::bo_wait_rendering = bufmgr_bo_wait_rendering;
    mos_bufmgr::bo_pad_to_size = bufmgr_bo_pad_to_size;
    mos_bufmgr::bo_emit_reloc = bufmgr_bo_emit_reloc;
    mos_bufmgr::bo_emit_reloc2 = bufmgr_bo_emit_reloc2;
    mos_bufmgr::bo_emit_reloc_fence = bufmgr_bo_emit_reloc_fence;
    mos_bufmgr::bo_pin = bufmgr_bo_pin;
    mos_bufmgr::bo_unpin = bufmgr_bo_unpin;
    mos_bufmgr::bo_get_tiling = bufmgr_bo_get_tiling;
    mos_bufmgr::bo_set_tiling = bufmgr_bo_set_tiling;
    mos_bufmgr::bo_flink = bufmgr_bo_flink;
    mos_bufmgr::bo_exec = bufmgr_bo_exec2;
    mos_bufmgr::bo_mrb_exec = bufmgr_bo_mrb_exec2;
    mos_bufmgr::bo_busy = bufmgr_bo_busy;
    mos_bufmgr::bo_madvise = bufmgr_bo_madvise;
    mos_bufmgr::destroy = bufmgr_destroy;
    mos_bufmgr::check_aperture_space = bufmgr_check_aperture_space;
    mos_bufmgr::bo_disable_reuse = bufmgr_bo_disable_reuse;
    mos_bufmgr::bo_is_reusable = bufmgr_bo_is_reusable;
    mos_bufmgr::get_pipe_from_crtc_id = bufmgr_get_pipe_from_crtc_id;
    mos_bufmgr::bo_references = bufmgr_bo_references;
    mos_bufmgr::bo_set_softpin = bufmgr_bo_set_softpin;
    mos_bufmgr::bo_add_softpin_target = bufmgr_bo_add_softpin_target;

#if DEBUG
    mos_bufmgr::debug = 1;
#else
    mos_bufmgr::debug = 0;
#endif

    constexpr uint64_t kSize = MEMZONE_TOTAL - MEMZONE_SYS_START;
    allocator_ = SimpleAllocator::Create(MEMZONE_SYS_START, kSize);
}

MagmaBufMgr::~MagmaBufMgr() {
    if (connection_) {
        magma_release_connection(connection_);
    }
}

MagmaBo* MagmaBufMgr::CreateBo(const char *name, unsigned long size)
{
    magma_buffer_t buffer;
    uint64_t size_actual;
    magma_status_t status = magma_create_buffer(connection(), size, &size_actual, &buffer);
    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_create_buffer failed: %d", status);
        return nullptr;
    }

    magma_buffer_set_name(connection(), buffer, name);

    auto bo = new MagmaBo(buffer, size_actual, this);

    if (!bo->MapGpu()) {
        bo->RemoveRef();
        return nullptr;
    }

    return bo;
}

MagmaBo* MagmaBufMgr::ImportBo(int handle, unsigned long size)
{
    magma_buffer_t buffer;
    magma_status_t status = magma_import(connection(), handle, &buffer);
    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_import failed: %d", status);
        return nullptr;
    }

    auto bo = new MagmaBo(buffer, magma_get_buffer_size(buffer), this);

    if (!bo->MapGpu()) {
        bo->RemoveRef();
        return nullptr;
    }

    return bo;
}


///////////////////////////////////////////////////////////////////////////////

struct mos_bufmgr* mos_bufmgr_gem_init(int fd, int /*batch_size*/)
{
    magma_device_t unowned_device = get_device_for_magma_fd(fd);
    assert(unowned_device);

    uint32_t device_id;
    {
        uint64_t val;
        magma_status_t status = magma_query2(unowned_device, MAGMA_QUERY_DEVICE_ID, &val);
        if (status != MAGMA_STATUS_OK) {
            LOG_VERBOSE("magma_query2 failed: %d", status);
            return nullptr;
        }
        device_id = static_cast<uint32_t>(val);
    }

    magma_connection_t connection;
    magma_status_t status = magma_create_connection2(unowned_device, &connection);
    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_create_connection2 failed: %d", status);
        return nullptr;
    }

    LOG_VERBOSE("mos_bufmgr_gem_init connected to magma");

    return new MagmaBufMgr(connection, device_id);
}

struct mos_linux_context* mos_gem_context_create(struct mos_bufmgr *mos_bufmgr)
{
    auto bufmgr = static_cast<MagmaBufMgr*>(mos_bufmgr);

    uint32_t context_id;
    magma_status_t status = magma_create_context(bufmgr->connection(), &context_id);
    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_create_context failed: %d", status);
        return nullptr;
    }
    assert(context_id);

    auto context = new mos_linux_context;

    context->ctx_id = context_id;
    context->bufmgr = bufmgr;
    context->pOsContext = NULL;
    context->vm = NULL;

    LOG_VERBOSE("mos_gem_context_create context_id %u", context_id);

    return context;
}

void mos_gem_context_destroy(struct mos_linux_context *context)
{
    LOG_VERBOSE("mos_gem_context_destroy context_id %u", context->ctx_id);

    auto bufmgr = static_cast<MagmaBufMgr*>(context->bufmgr);

    magma_release_context(bufmgr->connection(), context->ctx_id);

    delete context;
}

int mos_bufmgr_gem_get_devid(struct mos_bufmgr *mos_bufmgr)
{
    auto bufmgr = static_cast<MagmaBufMgr*>(mos_bufmgr);

    LOG_VERBOSE("mos_bufmgr_gem_get_devid returning 0x%x", bufmgr->device_id());

    return bufmgr->device_id();
}

bool mos_gem_bo_is_softpin(struct mos_linux_bo *bo)
{
    assert(static_cast<MagmaBo*>(bo)->is_mapped_gpu());
    return true;
}

int mos_gem_bo_context_exec2(struct mos_linux_bo *mos_linux_bo, int used, struct mos_linux_context *ctx,
                           drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
                           unsigned int flags, int *fence) {
    constexpr uint32_t kExpectedFlags = I915_EXEC_BSD|I915_EXEC_BSD_RING1;

    auto bo = static_cast<MagmaBo*>(mos_linux_bo);
    auto bufmgr = static_cast<MagmaBufMgr*>(ctx->bufmgr);

    LOG_VERBOSE("mos_gem_bo_context_exec2 bo %lu used %d context_id %u num_cliprects %d DR4 %d flags 0x%x kExpectedFlags 0x%x",
        bo->id(), used, ctx->ctx_id, num_cliprects, DR4, flags, kExpectedFlags);

    assert((flags & ~kExpectedFlags) == 0); // only these flags

    // TODO(fxbug.78281)
    uint64_t* semaphore_ids = nullptr;

    auto& resources = bo->exec_resources();

    magma_command_buffer command_buffer = {
        .resource_count = resources.size(),
        .batch_buffer_resource_index = 0,
        .batch_start_offset = 0,
        .wait_semaphore_count = 0,
        .signal_semaphore_count = 0,
        .flags = kMagmaIntelGenCommandBufferForVideo,
    };

   // Add to inflight list first to avoid race with any other thread reading completions from the
   // notification channel, in case this thread is preempted just after sending the command buffer
   // and the completion happens quickly.
   bufmgr->inflight_list()->AddAndUpdate(
                             bufmgr->connection(), resources.data(),
                             resources.size());


    magma_status_t status = magma_execute_command_buffer_with_resources2(bo->magma_bufmgr()->connection(),
        ctx->ctx_id,
        &command_buffer,
        resources.data(),
        semaphore_ids);

    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_execute_command_buffer_with_resources failed: %d", status);
        return -1;
    }

    return 0;
}

void mos_gem_bo_clear_relocs(struct mos_linux_bo *bo, int start)
{
    static_cast<MagmaBo*>(bo)->clear_exec_resources();
}

int mos_bo_gem_export_to_prime(struct mos_linux_bo *mos_linux_bo, int *prime_fd)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);

    magma_handle_t handle;
    magma_status_t status = magma_export(bo->magma_bufmgr()->connection(), bo->buffer(), &handle);
    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("magma_export failed: %d", status);
        return -1;
    }

    *prime_fd = handle;
    return 0;
}

int mos_gem_bo_wait(struct mos_linux_bo *mos_linux_bo, int64_t timeout_ns)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);
    auto bufmgr = bo->magma_bufmgr();
    magma_status_t status = bufmgr->inflight_list()->WaitForBuffer(
        bufmgr->connection(),
        bufmgr->notification_handle(),
        bo->id(),
        timeout_ns);
    if (status != MAGMA_STATUS_OK) {
        LOG_VERBOSE("WaitForbuffer failed: %d", status);
        return -1;
    }
    return 0;
}

int bufmgr_bo_busy(struct mos_linux_bo *mos_linux_bo)
{
    auto bo = static_cast<MagmaBo*>(mos_linux_bo);
    auto bufmgr = bo->magma_bufmgr();
    magma_status_t status = bufmgr->inflight_list()->WaitForBuffer(
        bufmgr->connection(),
        bufmgr->notification_handle(),
        bo->id(),
        0 /* timeout_ns */);
    if (status == MAGMA_STATUS_TIMED_OUT) {
        return 1;
    } else if (status == MAGMA_STATUS_OK) {
        return 0;
    } else {
        LOG_VERBOSE("bufmgr_bo_busy failed: %d", status);
        return 0;
    }
}

void bufmgr_bo_wait_rendering(struct mos_linux_bo *bo)
{
    mos_gem_bo_wait(bo, INT64_MAX);
}
