/* This file is generated by vkr_device_object.py. */

#ifndef VKR_QUEUE_GEN_H
#define VKR_QUEUE_GEN_H

#include "vkr_common.h"

#include "venus-protocol/vn_protocol_renderer_fence.h"
#include "venus-protocol/vn_protocol_renderer_semaphore.h"
#include "venus-protocol/vn_protocol_renderer_event.h"

#include "vkr_context.h"
#include "vkr_device.h"

/* create a driver VkFence and update the vkr_fence */
static inline VkResult
vkr_fence_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateFence *args,
   struct vkr_fence *obj)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vn_device_proc_table *vk = &dev->proc_table;

   /* handles in args are replaced */
   vn_replace_vkCreateFence_args_handle(args);
   args->ret = vk->CreateFence(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.fence);
   return args->ret;
}

/* create a vkr_fence */
static inline struct vkr_fence *
vkr_fence_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateFence *args)
{
   struct vkr_fence *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_FENCE, args->pFence);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

   /* handles in args are replaced */
   if (vkr_fence_create_driver_handle(ctx, args, obj) != VK_SUCCESS) {
      free(obj);
      return NULL;
   }

   return obj;
}

/* create a vkr_fence and add it to the vkr_device */
static inline struct vkr_fence *
vkr_fence_create_and_add(
   struct vkr_context *ctx,
   struct vn_command_vkCreateFence *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);

   struct vkr_fence *obj = vkr_fence_create(ctx, args);
   if (!obj)
      return NULL;

   vkr_device_add_object(ctx, dev, &obj->base);
   return obj;
}

/* destroy a driver VkFence */
static inline void
vkr_fence_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroyFence *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vn_device_proc_table *vk = &dev->proc_table;

   /* handles in args are replaced */
   vn_replace_vkDestroyFence_args_handle(args);
   vk->DestroyFence(args->device, args->fence, NULL);
}

/* remove a vkr_fence from the device and destroy it */
static inline void
vkr_fence_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroyFence *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_fence *obj = vkr_fence_from_handle(args->fence);
   if (!obj)
      return;

   vkr_fence_destroy_driver_handle(ctx, args);

   vkr_device_remove_object(ctx, dev, &obj->base);
}

/* create a driver VkSemaphore and update the vkr_semaphore */
static inline VkResult
vkr_semaphore_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateSemaphore *args,
   struct vkr_semaphore *obj)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vn_device_proc_table *vk = &dev->proc_table;

   /* handles in args are replaced */
   vn_replace_vkCreateSemaphore_args_handle(args);
   args->ret = vk->CreateSemaphore(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.semaphore);
   return args->ret;
}

/* create a vkr_semaphore */
static inline struct vkr_semaphore *
vkr_semaphore_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateSemaphore *args)
{
   struct vkr_semaphore *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_SEMAPHORE, args->pSemaphore);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

   /* handles in args are replaced */
   if (vkr_semaphore_create_driver_handle(ctx, args, obj) != VK_SUCCESS) {
      free(obj);
      return NULL;
   }

   return obj;
}

/* create a vkr_semaphore and add it to the vkr_device */
static inline struct vkr_semaphore *
vkr_semaphore_create_and_add(
   struct vkr_context *ctx,
   struct vn_command_vkCreateSemaphore *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);

   struct vkr_semaphore *obj = vkr_semaphore_create(ctx, args);
   if (!obj)
      return NULL;

   vkr_device_add_object(ctx, dev, &obj->base);
   return obj;
}

/* destroy a driver VkSemaphore */
static inline void
vkr_semaphore_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroySemaphore *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vn_device_proc_table *vk = &dev->proc_table;

   /* handles in args are replaced */
   vn_replace_vkDestroySemaphore_args_handle(args);
   vk->DestroySemaphore(args->device, args->semaphore, NULL);
}

/* remove a vkr_semaphore from the device and destroy it */
static inline void
vkr_semaphore_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroySemaphore *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_semaphore *obj = vkr_semaphore_from_handle(args->semaphore);
   if (!obj)
      return;

   vkr_semaphore_destroy_driver_handle(ctx, args);

   vkr_device_remove_object(ctx, dev, &obj->base);
}

/* create a driver VkEvent and update the vkr_event */
static inline VkResult
vkr_event_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateEvent *args,
   struct vkr_event *obj)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vn_device_proc_table *vk = &dev->proc_table;

   /* handles in args are replaced */
   vn_replace_vkCreateEvent_args_handle(args);
   args->ret = vk->CreateEvent(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.event);
   return args->ret;
}

/* create a vkr_event */
static inline struct vkr_event *
vkr_event_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateEvent *args)
{
   struct vkr_event *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_EVENT, args->pEvent);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

   /* handles in args are replaced */
   if (vkr_event_create_driver_handle(ctx, args, obj) != VK_SUCCESS) {
      free(obj);
      return NULL;
   }

   return obj;
}

/* create a vkr_event and add it to the vkr_device */
static inline struct vkr_event *
vkr_event_create_and_add(
   struct vkr_context *ctx,
   struct vn_command_vkCreateEvent *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);

   struct vkr_event *obj = vkr_event_create(ctx, args);
   if (!obj)
      return NULL;

   vkr_device_add_object(ctx, dev, &obj->base);
   return obj;
}

/* destroy a driver VkEvent */
static inline void
vkr_event_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroyEvent *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vn_device_proc_table *vk = &dev->proc_table;

   /* handles in args are replaced */
   vn_replace_vkDestroyEvent_args_handle(args);
   vk->DestroyEvent(args->device, args->event, NULL);
}

/* remove a vkr_event from the device and destroy it */
static inline void
vkr_event_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroyEvent *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_event *obj = vkr_event_from_handle(args->event);
   if (!obj)
      return;

   vkr_event_destroy_driver_handle(ctx, args);

   vkr_device_remove_object(ctx, dev, &obj->base);
}

#endif /* VKR_QUEUE_GEN_H */
