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

#ifndef VKR_IMAGE_GEN_H
#define VKR_IMAGE_GEN_H

#include "vkr_common.h"

#include "venus-protocol/vn_protocol_renderer_image.h"
#include "venus-protocol/vn_protocol_renderer_image_view.h"
#include "venus-protocol/vn_protocol_renderer_sampler.h"
#include "venus-protocol/vn_protocol_renderer_sampler_ycbcr_conversion.h"

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

/* create a driver VkImage and update the vkr_image */
static inline VkResult
vkr_image_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateImage *args,
   struct vkr_image *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_vkCreateImage_args_handle(args);
   args->ret = vk->CreateImage(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.image);
   return args->ret;
}

/* create a vkr_image */
static inline struct vkr_image *
vkr_image_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateImage *args)
{
   struct vkr_image *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_IMAGE, args->pImage);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

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

   return obj;
}

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

   struct vkr_image *obj = vkr_image_create(ctx, args);
   if (!obj)
      return NULL;

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

/* destroy a driver VkImage */
static inline void
vkr_image_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroyImage *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_vkDestroyImage_args_handle(args);
   vk->DestroyImage(args->device, args->image, NULL);
}

/* remove a vkr_image from the device and destroy it */
static inline void
vkr_image_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroyImage *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_image *obj = vkr_image_from_handle(args->image);
   if (!obj)
      return;

   vkr_image_destroy_driver_handle(ctx, args);

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

/* create a driver VkImageView and update the vkr_image_view */
static inline VkResult
vkr_image_view_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateImageView *args,
   struct vkr_image_view *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_vkCreateImageView_args_handle(args);
   args->ret = vk->CreateImageView(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.image_view);
   return args->ret;
}

/* create a vkr_image_view */
static inline struct vkr_image_view *
vkr_image_view_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateImageView *args)
{
   struct vkr_image_view *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_IMAGE_VIEW, args->pView);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

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

   return obj;
}

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

   struct vkr_image_view *obj = vkr_image_view_create(ctx, args);
   if (!obj)
      return NULL;

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

/* destroy a driver VkImageView */
static inline void
vkr_image_view_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroyImageView *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_vkDestroyImageView_args_handle(args);
   vk->DestroyImageView(args->device, args->imageView, NULL);
}

/* remove a vkr_image_view from the device and destroy it */
static inline void
vkr_image_view_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroyImageView *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_image_view *obj = vkr_image_view_from_handle(args->imageView);
   if (!obj)
      return;

   vkr_image_view_destroy_driver_handle(ctx, args);

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

/* create a driver VkSampler and update the vkr_sampler */
static inline VkResult
vkr_sampler_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateSampler *args,
   struct vkr_sampler *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_vkCreateSampler_args_handle(args);
   args->ret = vk->CreateSampler(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.sampler);
   return args->ret;
}

/* create a vkr_sampler */
static inline struct vkr_sampler *
vkr_sampler_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateSampler *args)
{
   struct vkr_sampler *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_SAMPLER, args->pSampler);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

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

   return obj;
}

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

   struct vkr_sampler *obj = vkr_sampler_create(ctx, args);
   if (!obj)
      return NULL;

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

/* destroy a driver VkSampler */
static inline void
vkr_sampler_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroySampler *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_vkDestroySampler_args_handle(args);
   vk->DestroySampler(args->device, args->sampler, NULL);
}

/* remove a vkr_sampler from the device and destroy it */
static inline void
vkr_sampler_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroySampler *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_sampler *obj = vkr_sampler_from_handle(args->sampler);
   if (!obj)
      return;

   vkr_sampler_destroy_driver_handle(ctx, args);

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

/* create a driver VkSamplerYcbcrConversion and update the vkr_sampler_ycbcr_conversion */
static inline VkResult
vkr_sampler_ycbcr_conversion_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateSamplerYcbcrConversion *args,
   struct vkr_sampler_ycbcr_conversion *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_vkCreateSamplerYcbcrConversion_args_handle(args);
   args->ret = vk->CreateSamplerYcbcrConversion(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.sampler_ycbcr_conversion);
   return args->ret;
}

/* create a vkr_sampler_ycbcr_conversion */
static inline struct vkr_sampler_ycbcr_conversion *
vkr_sampler_ycbcr_conversion_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateSamplerYcbcrConversion *args)
{
   struct vkr_sampler_ycbcr_conversion *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, args->pYcbcrConversion);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

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

   return obj;
}

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

   struct vkr_sampler_ycbcr_conversion *obj = vkr_sampler_ycbcr_conversion_create(ctx, args);
   if (!obj)
      return NULL;

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

/* destroy a driver VkSamplerYcbcrConversion */
static inline void
vkr_sampler_ycbcr_conversion_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroySamplerYcbcrConversion *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_vkDestroySamplerYcbcrConversion_args_handle(args);
   vk->DestroySamplerYcbcrConversion(args->device, args->ycbcrConversion, NULL);
}

/* remove a vkr_sampler_ycbcr_conversion from the device and destroy it */
static inline void
vkr_sampler_ycbcr_conversion_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroySamplerYcbcrConversion *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_sampler_ycbcr_conversion *obj = vkr_sampler_ycbcr_conversion_from_handle(args->ycbcrConversion);
   if (!obj)
      return;

   vkr_sampler_ycbcr_conversion_destroy_driver_handle(ctx, args);

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

#endif /* VKR_IMAGE_GEN_H */
