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

#ifndef VKR_RENDER_PASS_GEN_H
#define VKR_RENDER_PASS_GEN_H

#include "vkr_common.h"

#include "venus-protocol/vn_protocol_renderer_render_pass.h"
#include "venus-protocol/vn_protocol_renderer_framebuffer.h"

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

/* create a driver VkRenderPass and update the vkr_render_pass */
static inline VkResult
vkr_render_pass_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateRenderPass *args,
   struct vkr_render_pass *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_vkCreateRenderPass_args_handle(args);
   args->ret = vk->CreateRenderPass(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.render_pass);
   return args->ret;
}

/* create a vkr_render_pass */
static inline struct vkr_render_pass *
vkr_render_pass_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateRenderPass *args)
{
   struct vkr_render_pass *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_RENDER_PASS, args->pRenderPass);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

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

   return obj;
}

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

   struct vkr_render_pass *obj = vkr_render_pass_create(ctx, args);
   if (!obj)
      return NULL;

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

/* destroy a driver VkRenderPass */
static inline void
vkr_render_pass_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroyRenderPass *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_vkDestroyRenderPass_args_handle(args);
   vk->DestroyRenderPass(args->device, args->renderPass, NULL);
}

/* remove a vkr_render_pass from the device and destroy it */
static inline void
vkr_render_pass_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroyRenderPass *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_render_pass *obj = vkr_render_pass_from_handle(args->renderPass);
   if (!obj)
      return;

   vkr_render_pass_destroy_driver_handle(ctx, args);

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

/* create a driver VkFramebuffer and update the vkr_framebuffer */
static inline VkResult
vkr_framebuffer_create_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkCreateFramebuffer *args,
   struct vkr_framebuffer *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_vkCreateFramebuffer_args_handle(args);
   args->ret = vk->CreateFramebuffer(args->device, args->pCreateInfo, NULL,
      &obj->base.handle.framebuffer);
   return args->ret;
}

/* create a vkr_framebuffer */
static inline struct vkr_framebuffer *
vkr_framebuffer_create(
   struct vkr_context *ctx,
   struct vn_command_vkCreateFramebuffer *args)
{
   struct vkr_framebuffer *obj = vkr_context_alloc_object(ctx, sizeof(*obj),
      VK_OBJECT_TYPE_FRAMEBUFFER, args->pFramebuffer);
   if (!obj) {
      args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
      return NULL;
   }

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

   return obj;
}

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

   struct vkr_framebuffer *obj = vkr_framebuffer_create(ctx, args);
   if (!obj)
      return NULL;

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

/* destroy a driver VkFramebuffer */
static inline void
vkr_framebuffer_destroy_driver_handle(
   UNUSED struct vkr_context *ctx,
   struct vn_command_vkDestroyFramebuffer *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_vkDestroyFramebuffer_args_handle(args);
   vk->DestroyFramebuffer(args->device, args->framebuffer, NULL);
}

/* remove a vkr_framebuffer from the device and destroy it */
static inline void
vkr_framebuffer_destroy_and_remove(
   struct vkr_context *ctx,
   struct vn_command_vkDestroyFramebuffer *args)
{
   struct vkr_device *dev = vkr_device_from_handle(args->device);
   struct vkr_framebuffer *obj = vkr_framebuffer_from_handle(args->framebuffer);
   if (!obj)
      return;

   vkr_framebuffer_destroy_driver_handle(ctx, args);

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

#endif /* VKR_RENDER_PASS_GEN_H */
