#ifndef VULKAN_SHADER_CONST_HPP_
#define VULKAN_SHADER_CONST_HPP_

// This header file defines constants shared by C++ and GLSL. It is included from
// "common.glsl"; because of this, all code must be preprocessor-only so that it is
// both valid GLSL as well as valid C++.

#define GLSL_MAT_FIXED_COLOR (1 << 0)

#define GLSL_AMBIENT_FACTOR 0.5

#define GLSL_COLOR_IMAGE_INDEX 0
#define GLSL_NORMALMAP_IMAGE_INDEX 1
#define GLSL_LIGHTMAP_IMAGE_INDEX 2
#define GLSL_SPECULARMAP_IMAGE_INDEX 3
#define GLSL_BIASMAP_IMAGE_INDEX 4
#define GLSL_IMAGE_COUNT 5
#define GLSL_IMAGE_METADATA_INDEX 5

#define GLSL_COMBINE_COLOR_INDEX 0
#define GLSL_COMBINE_LIGHT_INDEX 1
#define GLSL_COMBINE_PARTICLES_INDEX 2
#define GLSL_COMBINE_NORMALS_INDEX 3
#define GLSL_COMBINE_POS_SPEC_INDEX 4
#define GLSL_COMBINE_GOD_RAYS_INDEX 5

#define GLSL_GUI_DESCRIPTOR_SET 0

#define GLSL_WORLD_FRAME_DESCRIPTOR_SET 0
#define GLSL_WORLD_MATERIAL_DESCRIPTOR_SET 1
#define GLSL_WORLD_MODEL_DESCRIPTOR_SET 2
#define GLSL_WORLD_TEX_TABLE_DESCRIPTOR_SET 3

// The frame descriptor set must match the one from world so that we can reuse `worldFrameData.glsl`.
#define GLSL_MODEL_FRAME_DESCRIPTOR_SET GLSL_WORLD_FRAME_DESCRIPTOR_SET
#define GLSL_MODEL_DESCRIPTOR_SET 1

#define GLSL_GBUFFER_DESCSET_NORMAL_INDEX 0
#define GLSL_GBUFFER_DESCSET_POS_SPEC_INDEX 1

#define GLSL_SUNLIGHT_MAX_DEPTH 32.0

#define GLSL_SKYBOX_DATA_INDEX 0
#define GLSL_SKYBOX_STAR_NOISE_INDEX 1
#define GLSL_SKYBOX_SUNMAP_INDEX 2

// The flags in FrameData.
#define GLSL_FRAMEDATA_AMBIENT_OCCLUSION            (1 << 0)
#define GLSL_FRAMEDATA_SHADOWS                      (1 << 1)
#define GLSL_FRAMEDATA_CONEMARCHING                 (1 << 2)
#define GLSL_FRAMEDATA_DEBUG_SPECULAR               (1 << 3)
#define GLSL_FRAMEDATA_DEBUG_REFRACT                (1 << 4)

// The frame descriptor set must match the one from world so that we can reuse `worldFrameData.glsl`.
#define GLSL_PARTICLES_FRAME_DESCRIPTOR_SET GLSL_WORLD_FRAME_DESCRIPTOR_SET
#define GLSL_PARTICLES_EMITTER_DESCRIPTOR_SET 1

#ifdef __cplusplus
#define DECL_GLSL_DEBUGMODE(name, enumval, label) static constexpr int name = enumval;
#include <Vk/ShaderDebugModeList.hpp>
#else
#define DECL_GLSL_DEBUGMODE(name, enumval, label) const int name = enumval;
#include "ShaderDebugModeList.hpp"
#endif

#define GLSL_TERRAIN_FRAME_DESCRIPTOR_SET GLSL_WORLD_FRAME_DESCRIPTOR_SET
#define GLSL_TERRAIN_SVO_DESCRIPTOR_SET 1
#define GLSL_TERRAIN_SKYBOX_DESCRIPTOR_SET 2
#define GLSL_TERRAIN_VOXEL_PALETTE_DESCRIPTOR_SET 3
#define GLSL_TERRAIN_TINT_DESCRIPTOR_SET 4

#define GLSL_SVOUPDATE_WORKGROUP_SIZE 64
#define GLSL_SVOUPDATE_SVO_DESCRIPTOR_SET 0
#define GLSL_SVOUPDATE_LIST_DESCRIPTOR_SET 1

/**
 * @brief The maximum order of the nodes in the SVO, after which the SVO space wraps.
 */
#define GLSL_SVO_MAX_ORDER 15

#define GLSL_SVO_VOXEL_BIT (1u << 31)
#define GLSL_SVO_VOXEL_FRAMEPOW_MAKE(n) (n << 28)
#define GLSL_SVO_VOXEL_FRAMEPOW_GET(v) ((v >> 28) & 7)
#define GLSL_SVO_VOXEL_INDEX_MASK 0x00FFFFFF

// The air voxel has index 0 and 1 frame.
#define GLSL_SVO_VOXEL_AIR (GLSL_SVO_VOXEL_BIT)

// Number of entries in a tint table node.
#define GLSL_TINT_TABLE_NODE_SIZE 256
#define GLSL_TINT_TABLE_NODE_RESOLVED (1 << 31)
#define GLSL_TINT_TABLE_BINDING_INDEX 0
#define GLSL_TINT_HASH_TABLE_BINDING_INDEX 1

// The radiance of the brightest light.
#define GLSL_RADIANCE_SCALE 30.0

// Tile-depth shader descriptors.
#define GLSL_TILE_DEPTH_FRAMEDATA_DESCSET 0
#define GLSL_TILE_DEPTH_GBUFFER_DESCSET 1
#define GLSL_TILE_DEPTH_RESULT_DESCSET 2

// Properties of the lighting stage.
#define GLSL_LIGHT_TILE_SIZE 16
#define GLSL_LIGHT_DEPTH_SLICES 48
#define GLSL_LIGHT_MAX_INDEXES 64000000

// Light-cluster-reset shader descriptors.
#define GLSL_LIGHT_CLUSTER_RESET_FRAMEDATA_DESCSET 0
#define GLSL_LIGHT_CLUSTER_RESET_BUFFER_DESCSET 1
#define GLSL_LIGHT_RESET_LOCAL_SIZE 256

// Light-scopes shader descriptors.
#define GLSL_LIGHT_SCOPES_FRAMEDATA_DESCSET 0
#define GLSL_LIGHT_SCOPES_SOURCES_DESCSET 1
#define GLSL_LIGHT_SCOPES_BUFFER_DESCSET 2
#define GLSL_LIGHT_SCOPES_CLUSTERS_DESCSET 3
#define GLSL_LIGHT_SCOPES_DEPTH_DESCSET 4
#define GLSL_LIGHT_SCOPES_LOCAL_SIZE 256

// Light-cluster-alloc shader descriptors.
#define GLSL_LIGHT_COUNT_FRAMEDATA_DESCSET 0
#define GLSL_LIGHT_COUNT_CLUSTERS_DESCSET 1
#define GLSL_LIGHT_COUNT_SCOPES_DESCSET 2
#define GLSL_LIGHT_COUNT_INDEX_DESCSET 3
#define GLSL_LIGHT_COUNT_LOCAL_SIZE 256

// Light-assign shader descriptors.
#define GLSL_LIGHT_ASSIGN_FRAMEDATA_DESCSET 0
#define GLSL_LIGHT_ASSIGN_CLUSTERS_DESCSET 1
#define GLSL_LIGHT_ASSIGN_SCOPES_DESCSET 2
#define GLSL_LIGHT_ASSIGN_INDEX_DESCSET 3
#define GLSL_LIGHT_ASSIGN_LOCAL_SIZE 256

// Light-apply shader descriptors.
#define GLSL_LIGHT_APPLY_FRAMEDATA_DESCSET 0
#define GLSL_LIGHT_APPLY_CLUSTERS_DESCSET 1
#define GLSL_LIGHT_APPLY_INDEX_DESCSET 2
#define GLSL_LIGHT_APPLY_SOURCES_DESCSET 3
#define GLSL_LIGHT_APPLY_GBUFFER_DESCSET 4
#define GLSL_LIGHT_APPLY_IRRADIANCE_DESCSET 5
#define GLSL_LIGHT_APPLY_SVO_DESCSET 6
#define GLSL_LIGHT_APPLY_PALETTE_DESCSET 7

// Cubemap-generator compute shader constants.
#define GLSL_CUBEMAP_GEN_TILE_SIZE 4

#endif