/* SPDX-FileCopyrightText: 2023 Blender Authors
 *
 * SPDX-License-Identifier: GPL-2.0-or-later */

/**
 * Shared code between host and client code-bases.
 */

#pragma once

#include "eevee_camera_shared.hh"
#include "eevee_film_shared.hh"
#include "eevee_hizbuffer_shared.hh"
#include "eevee_raytrace_shared.hh"
#include "eevee_renderbuffers_shared.hh"
#include "eevee_subsurface_shared.hh"
#include "eevee_volume_shared.hh"

#ifndef GPU_SHADER
namespace blender::eevee {
#endif

/* This should be inside "eevee_light_shared.hh" but it would pull a huge header that is not
 * essential for most shaders. This could be moved back if including "eevee_bxdf_lib.glsl" is used
 * only for shading shaders. */
enum [[host_shared]] LightingType : uint32_t {
  LIGHT_DIFFUSE = 0u,
  LIGHT_SPECULAR = 1u,
  LIGHT_TRANSMISSION = 2u,
  LIGHT_VOLUME = 3u,
  /* WORKAROUND: Special value used to tag translucent BSDF with thickness.
   * Fall back to LIGHT_DIFFUSE. */
  LIGHT_TRANSLUCENT_WITH_THICKNESS = 4u,
};

struct [[host_shared]] ShadowSceneData {
  /* Number of shadow rays to shoot for each light. */
  int ray_count;
  /* Number of shadow samples to take for each shadow ray. */
  int step_count;
  /* Bounding radius for a film pixel at 1 unit from the camera. */
  float film_pixel_radius;
  /* Global switch for jittered shadows. */
  bool32_t use_jitter;
  /* Output atomic counter instead of depth. */
  bool32_t use_debug_cost;
  int _pad0;
  int _pad1;
  int _pad2;
};

struct [[host_shared]] SceneData {
  float time;
  float frame;
  uint _pad0;
  uint _pad1;
};

/* Light Clamping. */
struct [[host_shared]] ClampData {
  float sun_threshold;
  float surface_direct;
  float surface_indirect;
  float volume_direct;
  float volume_indirect;
  float direct_scale;
  float indirect_scale;
  int _pad0;
};

/* Emulation of the light path node. */
enum [[host_shared]] RayPipelineType : uint32_t {
  RAY_TYPE_CAMERA,
  RAY_TYPE_SHADOW,
  RAY_TYPE_DIFFUSE,
  RAY_TYPE_GLOSSY,
};

struct [[host_shared]] PipelineInfoData {
  float alpha_hash_scale;
  enum RayPipelineType ray_type;
  /* True if the main camera view has inverted handedness.
   * This is the case if the camera has negative scale on one axis. */
  bool32_t is_main_view_inverted;
  /* WORKAROUND: Usually we would use imageSize to get the number of layers and get this id.
   * However, some implementation return the number of layers from the base texture instead of the
   * texture view (see #146132). So we always pass the correct layer index manually to avoid any
   * platform inconsistency. */
  int gbuffer_additional_data_layer_id;
  /* Use monochromatic transmittance for the forward pipeline. */
  bool32_t use_monochromatic_transmittance;
  /* True if the pipeline can use the raycast node.
   * The value is valid only if `MAT_RAYCAST` is defined. */
  bool32_t can_raycast;
  bool32_t _pad1;
  bool32_t _pad2;
};

/* Combines data from several modules to avoid wasting binding slots. */
struct [[host_shared]] UniformData {
  struct AOData ao;
  struct CameraData camera;
  struct ClampData clamp;
  struct FilmData film;
  struct HiZData hiz;
  struct RenderBuffersInfoData render_pass;
  struct ShadowSceneData shadow;
  struct VolumesInfoData volumes;
  struct SceneData scene;
};

/**
 * World space clip plane equation. Used to render planar light-probes.
 * Moved here to avoid dependencies to light-probe just for this. */
struct [[host_shared]] ClipPlaneData {
  float4 plane;
};

#ifndef GPU_SHADER
}  // namespace blender::eevee
#endif
