#pragma once

// TODO: this should be derived from a slang header
// See https://github.com/shader-slang/slang/issues/7005
// clang-format off
#define SLANG_RHI_CAPABILITIES(x) \
    x(Invalid) \
    x(textualTarget) \
    x(hlsl) \
    x(glsl) \
    x(c) \
    x(cpp) \
    x(cuda) \
    x(metal) \
    x(spirv) \
    x(wgsl) \
    x(slangvm) \
    x(glsl_spirv_1_0) \
    x(glsl_spirv_1_1) \
    x(glsl_spirv_1_2) \
    x(glsl_spirv_1_3) \
    x(glsl_spirv_1_4) \
    x(glsl_spirv_1_5) \
    x(glsl_spirv_1_6) \
    x(_spirv_1_0) \
    x(_spirv_1_1) \
    x(_spirv_1_2) \
    x(_spirv_1_3) \
    x(_spirv_1_4) \
    x(_spirv_1_5) \
    x(_spirv_1_6) \
    x(_GLSL_130) \
    x(_GLSL_140) \
    x(_GLSL_150) \
    x(_GLSL_330) \
    x(_GLSL_400) \
    x(_GLSL_410) \
    x(_GLSL_420) \
    x(_GLSL_430) \
    x(_GLSL_440) \
    x(_GLSL_450) \
    x(_GLSL_460) \
    x(metallib_2_3) \
    x(metallib_2_4) \
    x(metallib_3_0) \
    x(metallib_3_1) \
    x(_sm_4_0) \
    x(_sm_4_1) \
    x(_sm_5_0) \
    x(_sm_5_1) \
    x(_sm_6_0) \
    x(_sm_6_1) \
    x(_sm_6_2) \
    x(_sm_6_3) \
    x(_sm_6_4) \
    x(_sm_6_5) \
    x(_sm_6_6) \
    x(_sm_6_7) \
    x(_sm_6_8) \
    x(_sm_6_9) \
    x(hlsl_nvapi) \
    x(hlsl_2018) \
    x(_cuda_sm_1_0) \
    x(_cuda_sm_2_0) \
    x(_cuda_sm_3_0) \
    x(_cuda_sm_3_5) \
    x(_cuda_sm_4_0) \
    x(_cuda_sm_5_0) \
    x(_cuda_sm_6_0) \
    x(_cuda_sm_7_0) \
    x(_cuda_sm_8_0) \
    x(_cuda_sm_9_0) \
    x(optix_coopvec) \
    x(vertex) \
    x(fragment) \
    x(compute) \
    x(hull) \
    x(domain) \
    x(geometry) \
    x(dispatch) \
    x(_raygen) \
    x(_intersection) \
    x(_anyhit) \
    x(_closesthit) \
    x(_callable) \
    x(_miss) \
    x(_mesh) \
    x(_amplification) \
    x(SPV_EXT_fragment_shader_interlock) \
    x(SPV_EXT_physical_storage_buffer) \
    x(SPV_EXT_fragment_fully_covered) \
    x(SPV_EXT_descriptor_indexing) \
    x(SPV_EXT_shader_atomic_float_add) \
    x(SPV_EXT_shader_atomic_float16_add) \
    x(SPV_EXT_shader_atomic_float_min_max) \
    x(SPV_EXT_mesh_shader) \
    x(SPV_EXT_demote_to_helper_invocation) \
    x(SPV_KHR_maximal_reconvergence) \
    x(SPV_KHR_quad_control) \
    x(SPV_KHR_fragment_shader_barycentric) \
    x(SPV_KHR_non_semantic_info) \
    x(SPV_KHR_device_group) \
    x(SPV_KHR_ray_tracing) \
    x(SPV_KHR_ray_query) \
    x(SPV_KHR_ray_tracing_position_fetch) \
    x(SPV_KHR_shader_clock) \
    x(SPV_NV_shader_subgroup_partitioned) \
    x(SPV_KHR_subgroup_rotate) \
    x(SPV_NV_ray_tracing_motion_blur) \
    x(SPV_NV_shader_invocation_reorder) \
    x(SPV_NV_cluster_acceleration_structure) \
    x(SPV_NV_linear_swept_spheres) \
    x(SPV_NV_shader_image_footprint) \
    x(SPV_KHR_compute_shader_derivatives) \
    x(SPV_GOOGLE_user_type) \
    x(SPV_EXT_replicated_composites) \
    x(SPV_KHR_vulkan_memory_model) \
    x(SPV_NV_cooperative_vector) \
    x(SPV_KHR_cooperative_matrix) \
    x(SPV_NV_tensor_addressing) \
    x(SPV_NV_cooperative_matrix2) \
    x(spvDeviceGroup) \
    x(spvAtomicFloat32AddEXT) \
    x(spvAtomicFloat16AddEXT) \
    x(spvAtomicFloat64AddEXT) \
    x(spvInt64Atomics) \
    x(spvAtomicFloat32MinMaxEXT) \
    x(spvAtomicFloat16MinMaxEXT) \
    x(spvAtomicFloat64MinMaxEXT) \
    x(spvDerivativeControl) \
    x(spvImageQuery) \
    x(spvImageGatherExtended) \
    x(spvSparseResidency) \
    x(spvImageFootprintNV) \
    x(spvMinLod) \
    x(spvFragmentShaderPixelInterlockEXT) \
    x(spvFragmentBarycentricKHR) \
    x(spvFragmentFullyCoveredEXT) \
    x(spvGroupNonUniformBallot) \
    x(spvGroupNonUniformShuffle) \
    x(spvGroupNonUniformArithmetic) \
    x(spvGroupNonUniformQuad) \
    x(spvGroupNonUniformVote) \
    x(spvGroupNonUniformPartitionedNV) \
    x(spvGroupNonUniformRotateKHR) \
    x(spvRayTracingMotionBlurNV) \
    x(spvMeshShadingEXT) \
    x(spvRayTracingKHR) \
    x(spvRayTracingPositionFetchKHR) \
    x(spvRayQueryKHR) \
    x(spvRayQueryPositionFetchKHR) \
    x(spvShaderInvocationReorderNV) \
    x(spirv_nv) \
    x(spvRayTracingClusterAccelerationStructureNV) \
    x(spvRayTracingLinearSweptSpheresGeometryNV) \
    x(spvShaderClockKHR) \
    x(spvShaderNonUniformEXT) \
    x(spvShaderNonUniform) \
    x(spvDemoteToHelperInvocationEXT) \
    x(spvDemoteToHelperInvocation) \
    x(spvReplicatedCompositesEXT) \
    x(spvCooperativeVectorNV) \
    x(spvCooperativeVectorTrainingNV) \
    x(spvCooperativeMatrixKHR) \
    x(spvCooperativeMatrixReductionsNV) \
    x(spvCooperativeMatrixConversionsNV) \
    x(spvCooperativeMatrixPerElementOperationsNV) \
    x(spvCooperativeMatrixTensorAddressingNV) \
    x(spvCooperativeMatrixBlockLoadsNV) \
    x(spvTensorAddressingNV) \
    x(spvMaximalReconvergenceKHR) \
    x(spvQuadControlKHR) \
    x(spvVulkanMemoryModelKHR) \
    x(spvVulkanMemoryModelDeviceScopeKHR) \
    x(_GL_EXT_buffer_reference) \
    x(_GL_EXT_buffer_reference_uvec2) \
    x(_GL_EXT_debug_printf) \
    x(_GL_EXT_demote_to_helper_invocation) \
    x(_GL_EXT_fragment_shader_barycentric) \
    x(_GL_EXT_mesh_shader) \
    x(_GL_EXT_nonuniform_qualifier) \
    x(_GL_EXT_ray_query) \
    x(_GL_EXT_ray_tracing) \
    x(_GL_EXT_ray_tracing_position_fetch) \
    x(_GL_EXT_samplerless_texture_functions) \
    x(_GL_EXT_shader_atomic_float) \
    x(_GL_EXT_shader_atomic_float_min_max) \
    x(_GL_EXT_shader_atomic_float2) \
    x(_GL_EXT_shader_atomic_int64) \
    x(_GL_EXT_shader_explicit_arithmetic_types) \
    x(_GL_EXT_shader_explicit_arithmetic_types_int64) \
    x(_GL_EXT_shader_image_load_store) \
    x(_GL_EXT_shader_realtime_clock) \
    x(_GL_EXT_texture_query_lod) \
    x(_GL_EXT_texture_shadow_lod) \
    x(_GL_EXT_maximal_reconvergence) \
    x(_GL_EXT_shader_quad_control) \
    x(_GL_EXT_device_group) \
    x(_GL_ARB_derivative_control) \
    x(_GL_ARB_fragment_shader_interlock) \
    x(_GL_ARB_gpu_shader5) \
    x(_GL_ARB_shader_image_load_store) \
    x(_GL_ARB_shader_image_size) \
    x(_GL_ARB_texture_multisample) \
    x(_GL_ARB_shader_texture_image_samples) \
    x(_GL_ARB_sparse_texture) \
    x(_GL_ARB_sparse_texture2) \
    x(_GL_ARB_sparse_texture_clamp) \
    x(_GL_ARB_texture_gather) \
    x(_GL_ARB_texture_query_levels) \
    x(_GL_ARB_shader_clock) \
    x(_GL_ARB_gpu_shader_int64) \
    x(_GL_ARB_shader_clock64) \
    x(_GL_KHR_memory_scope_semantics) \
    x(_GL_KHR_shader_subgroup_arithmetic) \
    x(_GL_KHR_shader_subgroup_ballot) \
    x(_GL_KHR_shader_subgroup_basic) \
    x(_GL_KHR_shader_subgroup_clustered) \
    x(_GL_KHR_shader_subgroup_quad) \
    x(_GL_KHR_shader_subgroup_shuffle) \
    x(_GL_KHR_shader_subgroup_shuffle_relative) \
    x(_GL_KHR_shader_subgroup_vote) \
    x(_GL_KHR_shader_subgroup_rotate) \
    x(_GL_NV_compute_shader_derivatives) \
    x(_GL_NV_fragment_shader_barycentric) \
    x(_GL_NV_gpu_shader5) \
    x(_GL_NV_ray_tracing) \
    x(_GL_NV_ray_tracing_motion_blur) \
    x(_GL_NV_shader_atomic_fp16_vector) \
    x(_GL_NV_shader_invocation_reorder) \
    x(_GL_NV_shader_subgroup_partitioned) \
    x(_GL_NV_shader_texture_footprint) \
    x(_GL_NV_cluster_acceleration_structure) \
    x(_GL_NV_cooperative_vector)
// clang-format on

namespace rhi {

#define SLANG_RHI_CAPABILITIES_x(x) x,

enum class Capability
{
    SLANG_RHI_CAPABILITIES(SLANG_RHI_CAPABILITIES_x) _Count,
};

#undef SLANG_RHI_CAPABILITIES_x

} // namespace rhi
